From 9aaab4177c82e5ccd961eb6e22691c31ca4b82ce Mon Sep 17 00:00:00 2001 From: Jupyung Lee Date: Tue, 10 Nov 2009 17:31:54 +0900 Subject: [PATCH] softirqs: Add missing preemption point in ksoftirqd commit ca0b4bfa5994856bbcf4227e29f9c73722efaef2 in tip. In its current implementation, ksoftirq() includes a series of primitives related with kernel preemption and irq on/off, in the following order: preempt_disable() ... (1) local_irq_disable() ... (2) __preempt_enable_no_resched() ... (3) local_irq_enable() ... (4) A problem arises if a task is woken up between (1) and (2) because it is not given a chance to preempt the currently running process until interrupts are enabled at (4). At this point the the kernel is preemptible, but there is no explicit reschedule point. This is only true for a preempt-rt enabled kernel as !preempt-rt has preemption disabled at that point via local_bh_disable(). A simple suggestion to resolve the problem is to add a reschedule point, preempt_check_resched(), just after (4). [ tglx: Modified: delete __preempt_enable_no_resched() and add preempt_enable() after local_irq_enable() ] Signed-off-by: Jupyung Lee Signed-off-by: Thomas Gleixner Signed-off-by: Paul Gortmaker --- kernel/softirq.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/kernel/softirq.c b/kernel/softirq.c index 533b72c..c35f72b 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -1032,10 +1032,10 @@ sleep_more: goto sleep_more; } per_cpu(softirq_running, cpu) |= softirq_mask; - __preempt_enable_no_resched(); set_softirq_pending(local_softirq_pending() & ~softirq_mask); local_bh_disable(); local_irq_enable(); + preempt_enable(); h = &softirq_vec[data->nr]; if (h) -- 1.7.0.4