diff options
| author | Andrew Morton <akpm@osdl.org> | 2003-09-23 09:42:44 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-09-23 09:42:44 -0700 |
| commit | e4e9bd2354a72b2c0bda061589149dca9cf6fcf7 (patch) | |
| tree | ff4652fd3f3367fb81abe96fa4fe7b027035850d /kernel | |
| parent | b4aaf1ab197b6fc853256a3859ad600ad45bf075 (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.c | 18 |
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(); |
