diff options
| author | Mingming Cao <mmc@linux.ibm.com> | 2026-10-13 11:29:21 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-10-20 15:37:49 -0700 |
| commit | c9b95adc755f2396307be676ce838161fb011986 (patch) | |
| tree | 27fb7cbaee81622e7d9bb2bbbd70a6906732d179 /tools/lib/python/kdoc/python_version.py | |
| parent | 1412235447869922eb0ee041a31fab6176e60ab0 (diff) | |
ibmveth: step past bad RX correlators instead of spinning or oopsing
ibmveth_poll() mishandles a bad RX correlator from PHYP in two ways.
If harvest fails or ibmveth_rxq_get_buffer() returns NULL, poll
breaks out without advancing the ring and restarts on the same slot
forever. For an out-of-range correlator it also fires a WARN_ON() and
schedules a reset each pass, but the reset is queued on that CPU and
never runs, and the CPU stalls RCU, so RTNL holders hang too. This
dates from the first commit in Fixes:, which turned the BUG_ON()s
here into WARN_ON() plus a reset.
The range check also accepts a correlator naming an inactive buffer
pool (pools 2 and 3 by default), whose skbuff array is NULL, so the
lookup dereferences NULL in softirq. Pools became inactive with the
second commit in Fixes:.
Validate the correlator in one helper that also rejects a pool with
no skbuff array. On a bad slot, advance the ring, count the drop in
rx_dropped and still schedule the reset, which rebuilds the pools.
The slot has moved, so stay in the budget loop and count it in
frames_processed. Breaking out would complete NAPI, re-arm, and
napi_schedule() with budget left. When the final check finds more
work, queue the NAPI and return instead of going back to
restart_poll: after napi_complete_done() the NAPI is no longer this
call's, and with threaded NAPI and busy polling the kthread can
already be polling it on another CPU. frames_processed is below
budget there, so busy_poll_stop() does not queue it a second time.
Mask the interrupt before queueing, as ibmveth_interrupt() does;
masking after napi_schedule() could land after that kthread has
finished and unmasked, leaving RX masked with nothing scheduled.
Drop a frame whose offset + length does not fit the pool buffer:
copybreak would read past the RX buffer and skb_put() would BUG().
Also drop one shorter than an Ethernet header, which eth_type_trans()
would read past. Read the correlator once per slot and use that value
for the lookup, the bound and the harvest.
The base driver never checked frame bounds, and they have not been
seen in the field, so they have no Fixes: tag of their own. The tags
below are for the correlator hang.
The correlator comes from PHYP, and with the ring advancing a burst
of bad slots would WARN once per slot (and panic with
panic_on_warn), so use a ratelimited netdev_err() instead. Also free
the rx_copybreak skb if harvest fails there.
Add a KUnit case for harvest advancing on errors and extend the
existing cases to an inactive pool. Run against the unfixed driver,
with the calls changed back to its signatures, the first fails and
the others oops.
Found in review of the ibmveth multi-queue RX series (the frame bound by
the Sashiko review of v2 of this series) and confirmed by code
inspection and the KUnit cases above. Hitting either correlator bug
needs PHYP to return a bad correlator, so neither was reproduced on
hardware. Tested with KUnit on qemu pseries (ppc64le), and on a POWER10
LPAR with a ping flood and MTU changes under traffic. No kernel
selftests cover ibmveth.
Fixes: 2c91e2319ed9 ("net: ibmveth: Reset the adapter when unexpected states are detected")
Fixes: 860f242eb534 ("[PATCH] ibmveth change buffer pools dynamically")
Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Link: https://patch.msgid.link/20261013182926.30417-5-mmc@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'tools/lib/python/kdoc/python_version.py')
0 files changed, 0 insertions, 0 deletions
