On Sun, Feb 12, 2017 at 02:00:19PM +0000, Chris Wilson wrote: > Disabling a tasklet causes it not to run during tasklet_action, but is > put back onto the runnable tasklet list, and a new softirq raised. As > the softirq is raised from within __do_softirq() this causing > __do_softirq() to loop constantly until its timeslice expires and is > transferred to the ksoftirq thread. ksoftirq then permanently spins, > as on each action, the disabled tasklet keeps reraising the softirq. > > Break this vicious cycle by moving the softirq from the action to the > final tasklet_enable(). > > This behaviour appears to be historic (since the first git import). > However, the looping until timeslice duration (to a max of 2ms) was > first introduced in commit c10d73671ad3 ("softirq: reduce latencies"), > with the restart limit restored in commit 34376a50fb1f ("Fix lockup > related to stop_machine being stuck in __do_softirq.") > > Reported-by: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> > Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> > Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> > Cc: Hannes Reinecke <hare@xxxxxxxx> > Cc: Jens Axboe <axboe@xxxxxxxxx> > Cc: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> > Cc: Alexander Potapenko <glider@xxxxxxxxxx> > Cc: Chen Fan <chen.fan.fnst@xxxxxxxxxxxxxx> > Cc: Ingo Molnar <mingo@xxxxxxxxxx> > Cc: "Peter Zijlstra (Intel)" <peterz@xxxxxxxxxxxxx> > Cc: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> > Cc: Johannes Thumshirn <jthumshirn@xxxxxxx> > Cc: Emese Revfy <re.emese@xxxxxxxxx> > Cc: Sagi Grimberg <sagi@xxxxxxxxxxx> > Cc: Eric Dumazet <edumazet@xxxxxxxxxx> > Cc: Tom Herbert <therbert@xxxxxxxxxx> > Cc: Ben Hutchings <bhutchings@xxxxxxxxxxxxxx> > --- > include/linux/interrupt.h | 7 +++++-- > kernel/softirq.c | 2 -- > 2 files changed, 5 insertions(+), 4 deletions(-) > > diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h > index 53144e78a369..12750f00d00d 100644 > --- a/include/linux/interrupt.h > +++ b/include/linux/interrupt.h > @@ -613,8 +613,11 @@ static inline void tasklet_disable(struct tasklet_struct *t) > > static inline void tasklet_enable(struct tasklet_struct *t) > { > - smp_mb__before_atomic(); > - atomic_dec(&t->count); > + if (!atomic_dec_and_test(&t->count)) > + return; > + > + if (test_bit(TASKLET_STATE_SCHED, &t->state)) > + raise_softirq(HI_SOFTIRQ | TASKLET_SOFTIRQ); raise_softirq is not exported, so let's move tasklet_enable() out-of-line and export that. -Chris -- Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx