[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20170212142346.GC14326@nuc-i3427.alporthouse.com>
Date: Sun, 12 Feb 2017 14:23:46 +0000
From: Chris Wilson <chris@...is-wilson.co.uk>
To: linux-kernel@...r.kernel.org
Cc: intel-gfx@...ts.freedesktop.org,
Tvrtko Ursulin <tvrtko.ursulin@...el.com>,
Thomas Gleixner <tglx@...utronix.de>,
Hannes Reinecke <hare@...e.com>, Jens Axboe <axboe@...nel.dk>,
Bjorn Helgaas <bhelgaas@...gle.com>,
Alexander Potapenko <glider@...gle.com>,
Chen Fan <chen.fan.fnst@...fujitsu.com>,
Ingo Molnar <mingo@...nel.org>,
"Peter Zijlstra (Intel)" <peterz@...radead.org>,
Sebastian Andrzej Siewior <bigeasy@...utronix.de>,
Johannes Thumshirn <jthumshirn@...e.de>,
Emese Revfy <re.emese@...il.com>,
Sagi Grimberg <sagi@...mberg.me>,
Eric Dumazet <edumazet@...gle.com>,
Tom Herbert <therbert@...gle.com>,
Ben Hutchings <bhutchings@...arflare.com>
Subject: Re: [PATCH] softirq: Prevent looping on disabled tasklets
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@...el.com>
> Signed-off-by: Chris Wilson <chris@...is-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@...el.com>
> Cc: Thomas Gleixner <tglx@...utronix.de>
> Cc: Hannes Reinecke <hare@...e.com>
> Cc: Jens Axboe <axboe@...nel.dk>
> Cc: Bjorn Helgaas <bhelgaas@...gle.com>
> Cc: Alexander Potapenko <glider@...gle.com>
> Cc: Chen Fan <chen.fan.fnst@...fujitsu.com>
> Cc: Ingo Molnar <mingo@...nel.org>
> Cc: "Peter Zijlstra (Intel)" <peterz@...radead.org>
> Cc: Sebastian Andrzej Siewior <bigeasy@...utronix.de>
> Cc: Johannes Thumshirn <jthumshirn@...e.de>
> Cc: Emese Revfy <re.emese@...il.com>
> Cc: Sagi Grimberg <sagi@...mberg.me>
> Cc: Eric Dumazet <edumazet@...gle.com>
> Cc: Tom Herbert <therbert@...gle.com>
> Cc: Ben Hutchings <bhutchings@...arflare.com>
> ---
> 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
Powered by blists - more mailing lists