[PATCH 07/16] softirq: Fix nohz pending issue for real

Sebastian Andrzej Siewior
2013-02-13T16:13:16Z

From: Thomas Gleixner <tglx@linutronix.de>

We really need to iterate through all softirqs to find a potentially
blocked runner.

T1 runs softirq X (that cleared pending bit for X)

Interrupt raises softirq Y

T1 gets blocked on a lock and lock owner is not runnable

T1 schedules out

CPU goes idle and complains about pending softirq Y.

Now iterating over all softirqs lets us find the runner for X and
eliminate Y from the to warn about list as well.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
kernel/softirq.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/kernel/softirq.c b/kernel/softirq.c
index 385fcea..1a0145a 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -100,20 +100,15 @@ void softirq_check_pending_idle(void)
{
static int rate_limit;
struct softirq_runner *sr = &__get_cpu_var(softirq_runners);
- u32 warnpending, pending = local_softirq_pending();
+ u32 warnpending = local_softirq_pending();
+ int i;

if (rate_limit >= 10)
return;

- warnpending = pending;
-
- while (pending) {
- struct task_struct *tsk;
- int i = __ffs(pending);