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

Reply via email to