diff options
Diffstat (limited to 'debian/patches-rt/0327-tasklet-Fix-UP-case-for-tasklet-CHAINED-state.patch')
-rw-r--r-- | debian/patches-rt/0327-tasklet-Fix-UP-case-for-tasklet-CHAINED-state.patch | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/debian/patches-rt/0327-tasklet-Fix-UP-case-for-tasklet-CHAINED-state.patch b/debian/patches-rt/0327-tasklet-Fix-UP-case-for-tasklet-CHAINED-state.patch new file mode 100644 index 000000000..448ee797a --- /dev/null +++ b/debian/patches-rt/0327-tasklet-Fix-UP-case-for-tasklet-CHAINED-state.patch @@ -0,0 +1,52 @@ +From: Tom Zanussi <zanussi@kernel.org> +Date: Tue, 9 Jun 2020 11:04:08 -0500 +Subject: [PATCH 327/342] tasklet: Fix UP case for tasklet CHAINED state +Origin: https://git.kernel.org/cgit/linux/kernel/git/rt/linux-stable-rt.git/commit?id=ca828148bcc43ec7ed745e6bb0c076441138f09f + +commit 62d0a2a30cd0 (tasklet: Address a race resulting in +double-enqueue) addresses a problem that can result in a tasklet being +enqueued on two cpus at the same time by combining the RUN flag with a +new CHAINED flag, and relies on the combination to be present in order +to zero it out, which can never happen on (!SMP and !PREEMPT_RT_FULL) +because the RUN flag is SMP/PREEMPT_RT_FULL-only. + +So make sure the above commit is only applied for the SMP || +PREEMPT_RT_FULL case. + +Fixes: 62d0a2a30cd0 ("tasklet: Address a race resulting in double-enqueue") +Signed-off-by: Tom Zanussi <zanussi@kernel.org> +Reported-by: Ramon Fried <rfried.dev@gmail.com> +Tested-By: Ramon Fried <rfried.dev@gmail.com> +--- + kernel/softirq.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/kernel/softirq.c b/kernel/softirq.c +index 73dae64bfc9c..9bad7a16dc61 100644 +--- a/kernel/softirq.c ++++ b/kernel/softirq.c +@@ -947,10 +947,12 @@ 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 defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT_FULL) + if (test_and_set_bit(TASKLET_STATE_CHAINED, &t->state)) { + tasklet_unlock(t); + return; + } ++#endif + t->next = NULL; + *head->tail = t; + head->tail = &(t->next); +@@ -1044,7 +1046,11 @@ static void tasklet_action_common(struct softirq_action *a, + again: + t->func(t->data); + ++#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT_FULL) + while (cmpxchg(&t->state, TASKLET_STATEF_RC, 0) != TASKLET_STATEF_RC) { ++#else ++ while (!tasklet_tryunlock(t)) { ++#endif + /* + * If it got disabled meanwhile, bail out: + */ |