Re: [PATCH net] bnxt: fix head underflow on XDP head-grow
From: Michael Chan
Date: Tue Jun 09 2026 - 00:22:29 EST
On Mon, Jun 8, 2026 at 1:31 PM Joe Damato <joe@xxxxxxx> wrote:
>
> The xdp.py test test_xdp_native_adjst_head_grow_data crashes when run on
> a bnxt machine (and also crashes in NIPA).
>
> It seems that the bug is an underflow in bnxt_rx_multi_page_skb, which
> builds the skb head:
>
> napi_build_skb(data_ptr - bp->rx_offset, rxr->rx_page_size);
>
> The problem with this expression is that in page mode rx_offset is:
>
> bp->rx_offset = NET_IP_ALIGN + XDP_PACKET_HEADROOM;
>
> Which evaluates (at least on x86_64) to 258.
>
> The test test_xdp_native_adjst_head_grow_data tests a case where the
> head is adjusted by -256.
>
> When this test runs, data_ptr is shifted to frag_start + 2 (where
> frag_start = page_address(page) + offset).
>
> Then, bnxt_rx_multi_page_skb is invoked and the napi_build_skb
> expression subtracts 258, landing at an address before frag_start. This
> could be either the previous fragment or the previous physical page when
> the frag_offset is < 256 (e.g. if the fragment started at offset 0).
>
> When the skb is freed, the page pool fragment reference is dropped on
> either the wrong page or the wrong frag of the right page. In either
> case, the corrupted reference count can lead to the page being
> prematurely recycled while still in use. Once (incorrectly) recycled, it
> can be handed out again and on driver teardown this would result in a
> double free.
>
> The commit under fixes updated this code to handle the case where the
> native page size is >= 64k, but it unintentionally broke the head grow
> case.
>
> To fix this, we need to do a bit of math to recover the offset if this
> is a page fragment since it is not passed into rx_skb_func
> (bnxt_rx_multi_page_skb, in this case).
I wonder if we should add an offset field to struct bnxt_sw_rx_bd to
simplify things for page mode. Struct bnxt_sw_rx_agg_bd has the
offset field for a similar purpose. Thanks.
Attachment:
smime.p7s
Description: S/MIME Cryptographic Signature