diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2026-10-27 16:49:36 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-10-29 08:49:31 -0700 |
| commit | db2c610df81e34d497f49b68a0a1681c3f203bdb (patch) | |
| tree | 9cad93e8a656ef5588cd44cb8d4da1cf9a4c62b4 /scripts/basic | |
| parent | fd0909e963ed8f36967bd072ed484be7babe46de (diff) | |
| download | linux-db2c610df81e34d497f49b68a0a1681c3f203bdb.tar.gz linux-db2c610df81e34d497f49b68a0a1681c3f203bdb.zip | |
eth: bnxt: recycle agg buffers when Rx head buffer allocation fails
bnxt_rx_pkt() tries to return the aggregation buffers of a packet
to the ring when the copybreak allocation fails, but the same logic
is missing on the rx_skb_func() failure path. The agg BDs consumed
by the device are then never posted again. The agg ring is only
refilled one-for-one as completions consume its buffers, so each
such failure permanently shrinks it. Under sustained memory pressure
the ring drains completely, and the queue stops receiving anything
that does not fit into the head buffer, even once memory is available
again. Only re-creating the rings (e.g. ifdown / ifup) recovers it.
Commit 296d5b541639 ("bnxt_en: Fix aggregation buffer leak under OOM
condition.") fixed the copybreak path only. Recently
commit bd3beb5c8691 ("eth: bnxt: disable rx-copybreak by default")
made the non-copybreak path the default, re-surfacing the issue.
With XDP, the agg buffers are attached to the xdp_buff as frags by
this point. Their agg ring slots have already been refilled.
We need to keep the original head page (and therefore shinfo)
around until the xdp_buff cleanup.
Note the odd split of ownership here: rx_skb_func() only deals with
the head buffer, the agg buffers stay with the caller in whatever
state they are in, still on the ring without XDP, or frags of the
xdp_buff with XDP. This complicates rx_skb_func() cleaning up all
the buffers (head and frags), which would be more intuitive.
Discovered in production, severe packet loss would persist after
a transient OOM event. Tested on a BCM57504 by failing the head
buffer allocations in bnxt_rx_skb() (bpftrace override() of
should_failslab() and should_fail_alloc_page()) while receiving
1400B ICMPv6 echo requests. 341k packets were dropped on that queue,
enough to drain its 8188 entry agg ring 40 times over, and the queue
kept receiving large frames afterwards with no loss and no new HW drops.
With a frags-capable XDP_PASS program at MTU 9000, receiving 8000B
ICMPv6 echo requests while napi_build_skb() called from
bnxt_rx_multi_page_skb() failed, 9.2k packets were dropped,
the page pools' inflight count stayed flat and
there were no KASAN or DEBUG_PAGEALLOC splats.
Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.")
Fixes: 4c6c123c9af9 ("bnxt: adding bnxt_rx_agg_pages_xdp for aggregated xdp")
Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20261027234940.1267225-2-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'scripts/basic')
0 files changed, 0 insertions, 0 deletions
