On Tue, Feb 17, 2026 at 02:24:42PM +0100, Larysa Zaremba wrote:
> The only user of frag_size field in XDP RxQ info is
> bpf_xdp_frags_increase_tail(). It clearly expects whole buff size instead
> of DMA write size. Different assumptions in ice driver configuration lead
> to negative tailroom.
> 
> This allows to trigger kernel panic, when using
> XDP_ADJUST_TAIL_GROW_MULTI_BUFF xskxceiver test and changing packet size to
> 6912 and the requested offset to a huge value, e.g.
> XSK_UMEM__MAX_FRAME_SIZE * 100.
> 
> Due to other quirks of the ZC configuration in ice, panic is not observed
> in ZC mode, but tailroom growing still fails when it should not.
> 
> Use fill queue buffer truesize instead of DMA write size in XDP RxQ info.
> Fix ZC mode too by using the new helper.
> 
> Fixes: 2fba7dc5157b ("ice: Add support for XDP multi-buffer on Rx side")
> Reviewed-by: Aleksandr Loktionov <[email protected]>
> Signed-off-by: Larysa Zaremba <[email protected]>
> ---
>  drivers/net/ethernet/intel/ice/ice_base.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice_base.c 
> b/drivers/net/ethernet/intel/ice/ice_base.c
> index 511d803cf0a4..27ab899a4052 100644
> --- a/drivers/net/ethernet/intel/ice/ice_base.c
> +++ b/drivers/net/ethernet/intel/ice/ice_base.c
> @@ -659,7 +659,6 @@ static int ice_vsi_cfg_rxq(struct ice_rx_ring *ring)
>  {
>       struct device *dev = ice_pf_to_dev(ring->vsi->back);
>       u32 num_bufs = ICE_DESC_UNUSED(ring);
> -     u32 rx_buf_len;
>       int err;
>  
>       if (ring->vsi->type == ICE_VSI_PF || ring->vsi->type == ICE_VSI_SF) {
> @@ -669,12 +668,12 @@ static int ice_vsi_cfg_rxq(struct ice_rx_ring *ring)
>                       return err;
>  
>               if (ring->xsk_pool) {
> -                     rx_buf_len =
> -                             xsk_pool_get_rx_frame_size(ring->xsk_pool);

ice_setup_rx_ctx() consumes ring->rx_buf_len. This can't come from
page_pool when you have configured xsk_pool on a given rxq. I believe we
need a setting:

        ring->rx_buf_len =
                xsk_pool_get_rx_frame_size(ring->xsk_pool);

> +                     u32 frag_size =
> +                             xsk_pool_get_rx_frag_step(ring->xsk_pool);
>                       err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
>                                                ring->q_index,
>                                                ring->q_vector->napi.napi_id,
> -                                              rx_buf_len);
> +                                              frag_size);
>                       if (err)
>                               return err;
>                       err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
> @@ -694,7 +693,7 @@ static int ice_vsi_cfg_rxq(struct ice_rx_ring *ring)
>                       err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
>                                                ring->q_index,
>                                                ring->q_vector->napi.napi_id,
> -                                              ring->rx_buf_len);
> +                                              ring->truesize);
>                       if (err)
>                               goto err_destroy_fq;
>  
> -- 
> 2.52.0
> 

Reply via email to