From: "David S. Miller" <davem@redhat.com>

Stick this into -mm and see if people bark. :-)

It's from Ingo Molnar, softirq kicks in way too early.
We can probably sysctl this thing, that way everyone gets
what they want probably...



 kernel/softirq.c |   18 +++++++++++++-----
 1 files changed, 13 insertions(+), 5 deletions(-)

diff -puN kernel/softirq.c~delay-ksoftirqd-fallback kernel/softirq.c
--- 25/kernel/softirq.c~delay-ksoftirqd-fallback	2003-07-03 22:08:02.000000000 -0700
+++ 25-akpm/kernel/softirq.c	2003-07-03 22:08:02.000000000 -0700
@@ -59,11 +59,22 @@ static inline void wakeup_softirqd(void)
 		wake_up_process(tsk);
 }
 
+/*
+ * We restart softirq processing MAX_SOFTIRQ_RESTART times,
+ * and we fall back to softirqd after that.
+ *
+ * This number has been established via experimentation.
+ * The two things to balance is latency against fairness -
+ * we want to handle softirqs as soon as possible, but they
+ * should not be able to lock up the box.
+ */
+#define MAX_SOFTIRQ_RESTART 10
+
 asmlinkage void do_softirq(void)
 {
+	int max_restart = MAX_SOFTIRQ_RESTART;
 	__u32 pending;
 	unsigned long flags;
-	__u32 mask;
 
 	if (in_interrupt())
 		return;
@@ -75,7 +86,6 @@ asmlinkage void do_softirq(void)
 	if (pending) {
 		struct softirq_action *h;
 
-		mask = ~pending;
 		local_bh_disable();
 restart:
 		/* Reset the pending bitmask before enabling irqs */
@@ -95,10 +105,8 @@ restart:
 		local_irq_disable();
 
 		pending = local_softirq_pending();
-		if (pending & mask) {
-			mask &= ~pending;
+		if (pending && --max_restart)
 			goto restart;
-		}
 		if (pending)
 			wakeup_softirqd();
 		__local_bh_enable();

_