Skip to content

Commit 4cd13c2

Browse files
Eric DumazetIngo Molnar
authored andcommitted
softirq: Let ksoftirqd do its job
A while back, Paolo and Hannes sent an RFC patch adding threaded-able napi poll loop support : (https://patchwork.ozlabs.org/patch/620657/) The problem seems to be that softirqs are very aggressive and are often handled by the current process, even if we are under stress and that ksoftirqd was scheduled, so that innocent threads would have more chance to make progress. This patch makes sure that if ksoftirq is running, we let it perform the softirq work. Jonathan Corbet summarized the issue in https://lwn.net/Articles/687617/ Tested: - NIC receiving traffic handled by CPU 0 - UDP receiver running on CPU 0, using a single UDP socket. - Incoming flood of UDP packets targeting the UDP socket. Before the patch, the UDP receiver could almost never get CPU cycles and could only receive ~2,000 packets per second. After the patch, CPU cycles are split 50/50 between user application and ksoftirqd/0, and we can effectively read ~900,000 packets per second, a huge improvement in DOS situation. (Note that more packets are now dropped by the NIC itself, since the BH handlers get less CPU cycles to drain RX ring buffer) Since the load runs in well identified threads context, an admin can more easily tune process scheduling parameters if needed. Reported-by: Paolo Abeni <pabeni@redhat.com> Reported-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: David Miller <davem@davemloft.net> Cc: Hannes Frederic Sowa <hannes@redhat.com> Cc: Jesper Dangaard Brouer <jbrouer@redhat.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rik van Riel <riel@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/1472665349.14381.356.camel@edumazet-glaptop3.roam.corp.google.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent b8129a1 commit 4cd13c2

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

kernel/softirq.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ static void wakeup_softirqd(void)
7777
wake_up_process(tsk);
7878
}
7979

80+
/*
81+
* If ksoftirqd is scheduled, we do not want to process pending softirqs
82+
* right now. Let ksoftirqd handle this at its own rate, to get fairness.
83+
*/
84+
static bool ksoftirqd_running(void)
85+
{
86+
struct task_struct *tsk = __this_cpu_read(ksoftirqd);
87+
88+
return tsk && (tsk->state == TASK_RUNNING);
89+
}
90+
8091
/*
8192
* preempt_count and SOFTIRQ_OFFSET usage:
8293
* - preempt_count is changed by SOFTIRQ_OFFSET on entering or leaving
@@ -313,7 +324,7 @@ asmlinkage __visible void do_softirq(void)
313324

314325
pending = local_softirq_pending();
315326

316-
if (pending)
327+
if (pending && !ksoftirqd_running())
317328
do_softirq_own_stack();
318329

319330
local_irq_restore(flags);
@@ -340,6 +351,9 @@ void irq_enter(void)
340351

341352
static inline void invoke_softirq(void)
342353
{
354+
if (ksoftirqd_running())
355+
return;
356+
343357
if (!force_irqthreads) {
344358
#ifdef CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK
345359
/*

0 commit comments

Comments
 (0)