Hello RT Folks! I'm pleased to announce the 4.19.115-rt49 stable release. You can get this release via the git tree at: git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-stable-rt.git branch: v4.19-rt Head SHA1: 7ef3100b1ce706450de2fa2b76003b1e47e12131 Or to build 4.19.115-rt49 directly, the following patches should be applied: https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.19.tar.xz https://www.kernel.org/pub/linux/kernel/v4.x/patch-4.19.115.xz https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/patch-4.19.115-rt49.patch.xz You can also build from 4.19.115-rt48 by applying the incremental patch: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/incr/patch-4.19.115-rt48-rt49.patch.xz Enjoy! Tom Changes from v4.19.115-rt48: --- Tom Zanussi (1): Linux 4.19.115-rt49 Zhang Xiao (1): tasklet: Address a race resulting in double-enqueue --- include/linux/interrupt.h | 5 ++++- kernel/softirq.c | 6 +++++- localversion-rt | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) --- diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 97d9ba26915e..a3b5edb26bc5 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -579,12 +579,15 @@ enum { TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */ TASKLET_STATE_RUN, /* Tasklet is running (SMP only) */ - TASKLET_STATE_PENDING /* Tasklet is pending */ + TASKLET_STATE_PENDING, /* Tasklet is pending */ + TASKLET_STATE_CHAINED /* Tasklet is chained */ }; #define TASKLET_STATEF_SCHED (1 << TASKLET_STATE_SCHED) #define TASKLET_STATEF_RUN (1 << TASKLET_STATE_RUN) #define TASKLET_STATEF_PENDING (1 << TASKLET_STATE_PENDING) +#define TASKLET_STATEF_CHAINED (1 << TASKLET_STATE_CHAINED) +#define TASKLET_STATEF_RC (TASKLET_STATEF_RUN | TASKLET_STATEF_CHAINED) #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT_FULL) static inline int tasklet_trylock(struct tasklet_struct *t) diff --git a/kernel/softirq.c b/kernel/softirq.c index 25bcf2f2714b..73dae64bfc9c 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -947,6 +947,10 @@ static void __tasklet_schedule_common(struct tasklet_struct *t, * is locked before adding it to the list. */ if (test_bit(TASKLET_STATE_SCHED, &t->state)) { + if (test_and_set_bit(TASKLET_STATE_CHAINED, &t->state)) { + tasklet_unlock(t); + return; + } t->next = NULL; *head->tail = t; head->tail = &(t->next); @@ -1040,7 +1044,7 @@ static void tasklet_action_common(struct softirq_action *a, again: t->func(t->data); - while (!tasklet_tryunlock(t)) { + while (cmpxchg(&t->state, TASKLET_STATEF_RC, 0) != TASKLET_STATEF_RC) { /* * If it got disabled meanwhile, bail out: */ diff --git a/localversion-rt b/localversion-rt index 24707986c321..4b7dca68a5b4 100644 --- a/localversion-rt +++ b/localversion-rt @@ -1 +1 @@ --rt48 +-rt49