From: Paolo Abeni <>
Date: Mon, 8 May 2023 08:17:44 +0200
Subject: [PATCH] revert: "softirq: Let ksoftirqd do its job"

Due to the mentioned commit, when the ksoftirqd processes take charge
of softirq processing, the system can experience high latencies.

In the past a few workarounds have been implemented for specific
side-effects of the above:

commit 1ff688209e2e ("watchdog: core: make sure the watchdog_worker is not deferred")
commit 8d5755b3f77b ("watchdog: softdog: fire watchdog even if softirqs do not get to run")
commit 217f69743681 ("net: busy-poll: allow preemption in sk_busy_loop()")
commit 3c53776e29f8 ("Mark HI and TASKLET softirq synchronous")

but the latency problem still exists in real-life workloads, see the
link below.

The reverted commit intended to solve a live-lock scenario that can now
be addressed with the NAPI threaded mode, introduced with commit
29863d41bb6e ("net: implement threaded-able napi poll loop support"),
and nowadays in a pretty stable status.

While a complete solution to put softirq processing under nice resource
control would be preferable, that has proven to be a very hard task. In
the short term, remove the main pain point, and also simplify a bit the
current softirq implementation.

Note that this change also reverts commit 3c53776e29f8 ("Mark HI and
TASKLET softirq synchronous") and commit 1342d8080f61 ("softirq: Don't
skip softirq execution when softirq thread is parking"), which are
direct follow-ups of the feature commit. A single change is preferred to
avoid known bad intermediate states introduced by a patch series
reverting them individually.

Signed-off-by: Paolo Abeni <>
Tested-by: Jason Xing <>
Reviewed-by: Jakub Kicinski <>
Reviewed-by: Eric Dumazet <>
Reviewed-by: Sebastian Andrzej Siewior <>
Signed-off-by: Sebastian Andrzej Siewior <>
 kernel/softirq.c |   22 ++--------------------
 1 file changed, 2 insertions(+), 20 deletions(-)

Index: linux-6.3.0-rt11/kernel/softirq.c
@ linux-6.3.0-rt11/kernel/softirq.c:83 @ static void wakeup_softirqd(void)
- * If ksoftirqd is scheduled, we do not want to process pending softirqs
- * right now. Let ksoftirqd handle this at its own rate, to get fairness,
- * unless we're doing some of the synchronous softirqs.
- */
-static bool ksoftirqd_running(unsigned long pending)
-	struct task_struct *tsk = __this_cpu_read(ksoftirqd);
-	if (pending & SOFTIRQ_NOW_MASK)
-		return false;
-	return tsk && task_is_running(tsk) && !__kthread_should_park(tsk);
 DEFINE_PER_CPU(int, hardirqs_enabled);
 DEFINE_PER_CPU(int, hardirq_context);
@ linux-6.3.0-rt11/kernel/softirq.c:224 @ void __local_bh_enable_ip(unsigned long
 		goto out;
 	pending = local_softirq_pending();
-	if (!pending || ksoftirqd_running(pending))
+	if (!pending)
 		goto out;
@ linux-6.3.0-rt11/kernel/softirq.c:420 @ static inline bool should_wake_ksoftirqd
 static inline void invoke_softirq(void)
-	if (ksoftirqd_running(local_softirq_pending()))
-		return;
 	if (!force_irqthreads() || !__this_cpu_read(ksoftirqd)) {
@ linux-6.3.0-rt11/kernel/softirq.c:453 @ asmlinkage __visible void do_softirq(voi
 	pending = local_softirq_pending();
-	if (pending && !ksoftirqd_running(pending))
+	if (pending)