summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0001-net-Remove-conditional-threaded-NAPI-wakeup-based-on.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/0001-net-Remove-conditional-threaded-NAPI-wakeup-based-on.patch')
-rw-r--r--debian/patches-rt/0001-net-Remove-conditional-threaded-NAPI-wakeup-based-on.patch75
1 files changed, 75 insertions, 0 deletions
diff --git a/debian/patches-rt/0001-net-Remove-conditional-threaded-NAPI-wakeup-based-on.patch b/debian/patches-rt/0001-net-Remove-conditional-threaded-NAPI-wakeup-based-on.patch
new file mode 100644
index 0000000000..ae507f979e
--- /dev/null
+++ b/debian/patches-rt/0001-net-Remove-conditional-threaded-NAPI-wakeup-based-on.patch
@@ -0,0 +1,75 @@
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Sat, 9 Mar 2024 10:05:09 +0100
+Subject: [PATCH 1/4] net: Remove conditional threaded-NAPI wakeup based on
+ task state.
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz
+
+A NAPI thread is scheduled by first setting NAPI_STATE_SCHED bit. If
+successful (the bit was not yet set) then the NAPI_STATE_SCHED_THREADED
+is set but only if thread's state is not TASK_INTERRUPTIBLE (is
+TASK_RUNNING) followed by task wakeup.
+
+If the task is idle (TASK_INTERRUPTIBLE) then the
+NAPI_STATE_SCHED_THREADED bit is not set. The thread is no relying on
+the bit but always leaving the wait-loop after returning from schedule()
+because there must have been a wakeup.
+
+The smpboot-threads implementation for per-CPU threads requires an
+explicit condition and does not support "if we get out of schedule()
+then there must be something to do".
+
+Removing this optimisation simplifies the following integration.
+
+Set NAPI_STATE_SCHED_THREADED unconditionally on wakeup and rely on it
+in the wait path by removing the `woken' condition.
+
+Acked-by: Jakub Kicinski <kuba@kernel.org>
+Link: https://lore.kernel.org/r/20240309090824.2956805-2-bigeasy@linutronix.de
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ net/core/dev.c | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -4452,13 +4452,7 @@ static inline void ____napi_schedule(str
+ */
+ thread = READ_ONCE(napi->thread);
+ if (thread) {
+- /* Avoid doing set_bit() if the thread is in
+- * INTERRUPTIBLE state, cause napi_thread_wait()
+- * makes sure to proceed with napi polling
+- * if the thread is explicitly woken from here.
+- */
+- if (READ_ONCE(thread->__state) != TASK_INTERRUPTIBLE)
+- set_bit(NAPI_STATE_SCHED_THREADED, &napi->state);
++ set_bit(NAPI_STATE_SCHED_THREADED, &napi->state);
+ wake_up_process(thread);
+ return;
+ }
+@@ -6654,8 +6648,6 @@ static int napi_poll(struct napi_struct
+
+ static int napi_thread_wait(struct napi_struct *napi)
+ {
+- bool woken = false;
+-
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ while (!kthread_should_stop()) {
+@@ -6664,15 +6656,13 @@ static int napi_thread_wait(struct napi_
+ * Testing SCHED bit is not enough because SCHED bit might be
+ * set by some other busy poll thread or by napi_disable().
+ */
+- if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state) || woken) {
++ if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state)) {
+ WARN_ON(!list_empty(&napi->poll_list));
+ __set_current_state(TASK_RUNNING);
+ return 0;
+ }
+
+ schedule();
+- /* woken being true indicates this thread owns this napi. */
+- woken = true;
+ set_current_state(TASK_INTERRUPTIBLE);
+ }
+ __set_current_state(TASK_RUNNING);