Re: [PATCH net] net: yield the CPU on every exit of the threaded NAPI poll loop

From: Vitaliy Sochnev

Date: Tue Aug 18 2026 - 13:05:59 EST


> Please try to repro this on Linus's tree and repost if you can.
> Don't recall the exact details but IIRC the preemption is now
> more aggressive.

The patch itself is against current net/master already - that is the tree
I generated and build-tested it on, and the loop there is unchanged:

if (repoll || busy_poll_last_qs) {
rcu_softirq_qs_periodic(last_qs);
cond_resched();
}

if (!repoll)
break;

The exit path still reaches neither call, which is the case the patch is
about. So there is nothing to change in the posting itself; it is the
numbers that come from 6.18.

They come from 6.18 because that is the only kernel this board runs.
Mainline carries just en7581-evb - the AN7581/AN7583 SoC dtsi and the
board DTS exist only in OpenWrt, along with the airoha_eth changes that
have not landed upstream yet.

On preemption - I did measure that. Same board, same load, plain OpenWrt
without the patch, the two halves differing only in the preemption model
(verified in the built kernel .config):

PREEMPT_NONE worst "ip link del" 248.48 s, 8 of 29 samples over 1 s,
8 classic + 48 expedited RCU stalls
PREEMPT_LAZY worst 0.39 s, 0 of 177 samples, no stalls

at the same packet rate, 80862 vs 80036 pkt/s. So you remember right:
with lazy preemption the symptom is gone. What is left is PREEMPT_NONE and
PREEMPT_VOLUNTARY builds.

It is not explained by the NAPI thread being preempted more, though -
nonvoluntary_ctxt_switches on that thread is 4.6/s under LAZY against
13.9/s under PREEMPT_NONE. The interrupt and batching pattern changes
instead. I could not pin the mechanism down, so I am reporting the
measurement rather than a conclusion.

For what it is worth, the reproduction is not specific to this hardware:
threaded NAPI can be turned on for any driver through
/sys/class/net/<dev>/threaded, and what the bug needs on top of that is
little or no interrupt coalescing, so the poll loop is re-entered tens of
thousands of times a second.

If a mainline repro is a hard requirement here, I understand - the 6.18
data and the unchanged code path is what I have.