]> git.karo-electronics.de Git - karo-tx-linux.git/commit
tasklet: ignore disabled tasklet in tasklet_action()
authorXiaotian Feng <xtfeng@gmail.com>
Fri, 9 Nov 2012 03:03:51 +0000 (14:03 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 13 Nov 2012 05:15:17 +0000 (16:15 +1100)
commit7f8056b21b6c6fd25280c7805cef797bf6c03449
tree06fdd2ed00d61a5af099274819c66884c4ffded9
parent2cbd1a1a91c90608c80b913d283c819653d14a11
tasklet: ignore disabled tasklet in tasklet_action()

We met a ksoftirqd 100% issue, the perf top shows kernel is busy with
tasklet_action(), but no actual action is shown.  From dumped kernel,
there's only one disabled tasklet on the tasklet_vec.

tasklet_action might be handled after tasklet is disabled, this will make
disabled tasklet stayed on tasklet_vec.  tasklet_action will not handle
disabled tasklet, but place it on the tail of tasklet_vec, still raise
softirq for this tasklet.  Things will become worse if device driver uses
tasklet_disable on its device remove/close code.  The disabled tasklet
will stay on the vec, frequently __raise_softirq_off() and make ksoftirqd
wakeup even if no tasklets need to be handled.

This patch introduced a new TASKLET_STATE_HI bit to indicate HI_SOFTIRQ,
in tasklet_action(), simply ignore the disabled tasklet and don't raise
the softirq nr.  In my previous patch, I remove tasklet_hi_enable() since
it is the same as tasklet_enable().  So only tasklet_enable() needs to be
modified, if tasklet state is changed from disable to enable, use
__tasklet_schedule() to put it on the right vec.

Signed-off-by: Xiaotian Feng <dannyfeng@tencent.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
include/linux/interrupt.h
kernel/softirq.c