From: Chenguang Zhao <[email protected]> Date: Fri, 17 Jul 2026 09:24:16 +0800
> From: Chenguang Zhao <[email protected]> > > When AF_XDP ZC receives a multi-buffer frame and XDP returns XDP_PASS, > i40e_construct_skb_zc() copied frags incorrectly: memcpy used > skb_frag_page() (page metadata) and __skb_fill_page_desc_noacc() was > given a virtual address instead of a struct page *. > > Drop the custom helper and use xdp_build_skb_from_zc() instead. On > failure, free the xdp buff in the caller. Push the Ethernet header > back before eth_skb_pad()/i40e_process_skb_fields() because > xdp_build_skb_from_zc() already called eth_type_trans(). > > Fixes: 1c9ba9c14658 ("i40e: xsk: add RX multi-buffer support") > Signed-off-by: Chenguang Zhao <[email protected]> Reviewed-by: Alexander Lobakin <[email protected]> One nit below tho. [...] > @@ -372,14 +309,20 @@ static void i40e_handle_xdp_result_zc(struct i40e_ring > *rx_ring, > * BIT(I40E_RXD_QW1_ERROR_SHIFT). This is due to that > * SBP is *not* set in PRT_SBPVSI (default not set). > */ > - skb = i40e_construct_skb_zc(rx_ring, xdp_buff); > + skb = xdp_build_skb_from_zc(xdp_buff); > if (!skb) { > + xsk_buff_free(xdp_buff); > rx_ring->rx_stats.alloc_buff_failed++; > *rx_packets = 0; > *rx_bytes = 0; > return; > } > > + /* xdp_build_skb_from_zc() already ran eth_type_trans(); > + * restore the header for eth_skb_pad()/process_skb_fields(). > + */ The netdev rules prefer generic comment style over what we used in the past for some time already. I.e. /* * xdp_build_skb_from_zc() ... * restore ... */ > + __skb_push(skb, skb->data - skb_mac_header(skb)); > + > if (eth_skb_pad(skb)) { > *rx_packets = 0; > *rx_bytes = 0; Thanks, Olek
