diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-02-04 14:51:26 +0100 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-02-06 16:48:30 +0100 |
| commit | 5a530c8ead06e63e6d4f4997ad5e490575a48f3d (patch) | |
| tree | 8652f14d2cd008edfe6cf415d3d5619f2e05753d | |
| parent | 507692c05636311fffb39dac90d434a078f69215 (diff) | |
| download | linux-5a530c8ead06e63e6d4f4997ad5e490575a48f3d.tar.gz linux-5a530c8ead06e63e6d4f4997ad5e490575a48f3d.tar.bz2 linux-5a530c8ead06e63e6d4f4997ad5e490575a48f3d.zip | |
Revert "net: Remove conditional threaded-NAPI wakeup based on task state."
This reverts commit 03765d5c18084eab40351fda09bc6fc1a343cd07 which is
commit 56364c910691f6d10ba88c964c9041b9ab777bd6 upstream.
It is only for issues around PREEMPT_RT, which is not in the 6.6.y tree,
so revert this for now.
Link: https://lore.kernel.org/r/20260120103833.4kssDD1Y@linutronix.de
Reported-by: Jakub Kicinski <kuba@kernel.org>
Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Wen Yang <wen.yang@linux.dev>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | net/core/dev.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 3724735f62a4..206194bb8fca 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4539,7 +4539,13 @@ static inline void ____napi_schedule(struct softnet_data *sd, */ thread = READ_ONCE(napi->thread); if (thread) { - set_bit(NAPI_STATE_SCHED_THREADED, &napi->state); + /* 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); wake_up_process(thread); return; } @@ -6695,6 +6701,8 @@ static int napi_poll(struct napi_struct *n, struct list_head *repoll) static int napi_thread_wait(struct napi_struct *napi) { + bool woken = false; + set_current_state(TASK_INTERRUPTIBLE); while (!kthread_should_stop()) { @@ -6703,13 +6711,15 @@ static int napi_thread_wait(struct napi_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)) { + if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state) || woken) { 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); |
