diff options
author | Dirk Behme <dirk.behme@de.bosch.com> | 2021-03-17 11:20:12 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2021-03-17 12:59:35 +0100 |
commit | 6b2c339df90788ce6aeecee78d6494f262929206 (patch) | |
tree | 9509c9a60854e0af8025b7316d0bdb617859d5be /kernel/softirq.c | |
parent | 5c982c58752118b6c1f295024d3fda5ff22d3c52 (diff) | |
download | linux-6b2c339df90788ce6aeecee78d6494f262929206.tar.bz2 |
softirq: s/BUG/WARN_ONCE/ on tasklet SCHED state not set
Replace BUG() with WARN_ONCE() on wrong tasklet state, in order to:
- increase the verbosity / aid in debugging
- avoid fatal/unrecoverable state
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Dirk Behme <dirk.behme@de.bosch.com>
Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20210317102012.32399-1-erosca@de.adit-jv.com
Diffstat (limited to 'kernel/softirq.c')
-rw-r--r-- | kernel/softirq.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c index 8b44ab9a2f69..8d56bbf852ea 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -531,6 +531,18 @@ void __tasklet_hi_schedule(struct tasklet_struct *t) } EXPORT_SYMBOL(__tasklet_hi_schedule); +static bool tasklet_should_run(struct tasklet_struct *t) +{ + if (test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) + return true; + + WARN_ONCE(1, "tasklet SCHED state not set: %s %pS\n", + t->use_callback ? "callback" : "func", + t->use_callback ? (void *)t->callback : (void *)t->func); + + return false; +} + static void tasklet_action_common(struct softirq_action *a, struct tasklet_head *tl_head, unsigned int softirq_nr) @@ -550,13 +562,12 @@ static void tasklet_action_common(struct softirq_action *a, if (tasklet_trylock(t)) { if (!atomic_read(&t->count)) { - if (!test_and_clear_bit(TASKLET_STATE_SCHED, - &t->state)) - BUG(); - if (t->use_callback) - t->callback(t); - else - t->func(t->data); + if (tasklet_should_run(t)) { + if (t->use_callback) + t->callback(t); + else + t->func(t->data); + } tasklet_unlock(t); continue; } |