]> git.hungrycats.org Git - linux/commitdiff
[PATCH] softirqs: fix latency of softirq processing
authorIngo Molnar <mingo@elte.hu>
Mon, 18 Oct 2004 15:53:48 +0000 (08:53 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Mon, 18 Oct 2004 15:53:48 +0000 (08:53 -0700)
The attached patch fixes a local_bh_enable() buglet: we first enabled
softirqs then did we do local_softirq_pending() - often this is preemptible
code.  So this task could be preempted and there's no guarantee that
softirq processing will occur (except the periodic timer tick).

The race window is small but existent.  This could result in packet
processing latencies or timer expiration latencies - hard to detect and
annoying bugs.

The fix is to invoke softirqs with softirqs enabled but preemption still
disabled.  Patch is against 2.6.9-rc2-mm1.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Cc: <davem@davemloft.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
kernel/softirq.c

index 4a3da9be9f260474d744ad938c5ec07f9b687413..0e1e1356e35ad5596e562876e70f02b40350c11d 100644 (file)
@@ -137,11 +137,17 @@ EXPORT_SYMBOL(do_softirq);
 
 void local_bh_enable(void)
 {
-       __local_bh_enable();
        WARN_ON(irqs_disabled());
-       if (unlikely(!in_interrupt() &&
-                    local_softirq_pending()))
+       /*
+        * Keep preemption disabled until we are done with
+        * softirq processing:
+        */
+       preempt_count() -= SOFTIRQ_OFFSET - 1;
+
+       if (unlikely(!in_interrupt() && local_softirq_pending()))
                invoke_softirq();
+
+       dec_preempt_count();
        preempt_check_resched();
 }
 EXPORT_SYMBOL(local_bh_enable);