summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2003-09-23 09:42:44 -0700
committerLinus Torvalds <torvalds@home.osdl.org>2003-09-23 09:42:44 -0700
commite4e9bd2354a72b2c0bda061589149dca9cf6fcf7 (patch)
treeff4652fd3f3367fb81abe96fa4fe7b027035850d /kernel
parentb4aaf1ab197b6fc853256a3859ad600ad45bf075 (diff)
[PATCH] Try harder in IRQ context before falling back to ksoftirqd
From: "David S. Miller" <davem@redhat.com> It's from Ingo Molnar. ksoftirqd kicks in way too early, so do more work in interrupt context before falling back. We can probably sysctl this thing, that way everyone gets what they want probably... (has been in -mm since 2.5.71 and I haven't heard a peep).
Diffstat (limited to 'kernel')
-rw-r--r--kernel/softirq.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 43f2f53e4cba..b6ac17978c0e 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -57,11 +57,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;
@@ -73,7 +84,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 */
@@ -93,10 +103,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();