On Mon, Mar 15 2021 at 16:44, Eugeniu Rosca wrote: > From: Dirk Behme <dirk.be...@de.bosch.com> > > In case this BUG() is hit, it helps debugging a lot to get an idea > what tasklet is the root cause. So, be slightly more verbose here. > > Signed-off-by: Dirk Behme <dirk.be...@de.bosch.com> > Signed-off-by: Eugeniu Rosca <ero...@de.adit-jv.com> > --- > kernel/softirq.c | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/kernel/softirq.c b/kernel/softirq.c > index 9908ec4a9bfe..a6b602ad48d6 100644 > --- a/kernel/softirq.c > +++ b/kernel/softirq.c > @@ -550,9 +550,13 @@ 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)) > + if (!test_and_clear_bit(TASKLET_STATE_SCHED, > &t->state)) { > + if (t->use_callback) > + pr_emerg("tasklet failed, cb: > %pS\n", t->callback); > + else > + pr_emerg("tasklet failed, func: > %pS\n", t->func); > BUG(); > + } > if (t->use_callback) > t->callback(t); > else
This belongs into unreadable land and actually the BUG() should just be replaced by a WARN_ONCE(). Something like the below. Hmm? Thanks, tglx --- +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 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; }