On Thu, Feb 19, 2026 at 01:00:05PM +0100, Maciej Fijalkowski wrote:
> On Tue, Feb 17, 2026 at 02:24:43PM +0100, Larysa Zaremba wrote:
> > Current way of handling XDP RxQ info in i40e has following problems:
> > * when xsk_buff_pool is detached, memory model is not unregistered before
> >   registering a new one, this leads to a dangling xsk_buff_pool in the
> >   memory model table
> 
> What is 'memory model table' in this context?
>

I mean the hash table where we register the allocator when registering XDP RxQ 
info.

The paragraph is wrong, we do not have such problem currently, as we do not 
register pass any non-NULL values as allocator. So I will correct the commit 
message.

> I believe you are referring to a case where XDP prog is kept alive on
> interface put you close one socket and then bind the other one?
> 
> > * frag_size is not updated when xsk_buff_pool is detached or when MTU is
> >   changed, this leads to growing tail always failing for multi-buffer
> >   packets.
> 
> Good catch, i now see that i40e_change_mtu() only does the link flap and
> i40e_free_rx_resources() is not called in this path.
> 
> > 
> > Couple XDP RxQ info registering with buffer allocations and unregistering
> > with cleaning the ring.
> > 
> > Fixes: a045d2f2d03d ("i40e: set xdp_rxq_info::frag_size")
> > Signed-off-by: Larysa Zaremba <[email protected]>
> > ---
> >  drivers/net/ethernet/intel/i40e/i40e_main.c | 34 ++++++++++++---------
> >  drivers/net/ethernet/intel/i40e/i40e_txrx.c |  5 +--
> >  2 files changed, 22 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c 
> > b/drivers/net/ethernet/intel/i40e/i40e_main.c
> > index d3bc3207054f..eaa5b65e6daf 100644
> > --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> > +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> > @@ -3577,18 +3577,8 @@ static int i40e_configure_rx_ring(struct i40e_ring 
> > *ring)
> >     if (ring->vsi->type != I40E_VSI_MAIN)
> >             goto skip;
> >  
> > -   if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) {
> > -           err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
> > -                                    ring->queue_index,
> > -                                    ring->q_vector->napi.napi_id,
> > -                                    ring->rx_buf_len);
> > -           if (err)
> > -                   return err;
> > -   }
> > -
> >     ring->xsk_pool = i40e_xsk_pool(ring);
> >     if (ring->xsk_pool) {
> > -           xdp_rxq_info_unreg(&ring->xdp_rxq);
> >             ring->rx_buf_len = xsk_pool_get_rx_frame_size(ring->xsk_pool);
> >             err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
> >                                      ring->queue_index,
> > @@ -3600,17 +3590,23 @@ static int i40e_configure_rx_ring(struct i40e_ring 
> > *ring)
> >                                              MEM_TYPE_XSK_BUFF_POOL,
> >                                              NULL);
> >             if (err)
> > -                   return err;
> > +                   goto unreg_xdp;
> >             dev_info(&vsi->back->pdev->dev,
> >                      "Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx 
> > ring %d\n",
> >                      ring->queue_index);
> >  
> >     } else {
> > +           err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
> > +                                    ring->queue_index,
> > +                                    ring->q_vector->napi.napi_id,
> > +                                    ring->rx_buf_len);
> > +           if (err)
> > +                   return err;
> >             err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
> >                                              MEM_TYPE_PAGE_SHARED,
> >                                              NULL);
> >             if (err)
> > -                   return err;
> > +                   goto unreg_xdp;
> >     }
> >  
> >  skip:
> > @@ -3648,7 +3644,8 @@ static int i40e_configure_rx_ring(struct i40e_ring 
> > *ring)
> >             dev_info(&vsi->back->pdev->dev,
> >                      "Failed to clear LAN Rx queue context on Rx ring %d 
> > (pf_q %d), error: %d\n",
> >                      ring->queue_index, pf_q, err);
> > -           return -ENOMEM;
> > +           err = -ENOMEM;
> > +           goto unreg_xdp;
> >     }
> >  
> >     /* set the context in the HMC */
> > @@ -3657,7 +3654,8 @@ static int i40e_configure_rx_ring(struct i40e_ring 
> > *ring)
> >             dev_info(&vsi->back->pdev->dev,
> >                      "Failed to set LAN Rx queue context on Rx ring %d 
> > (pf_q %d), error: %d\n",
> >                      ring->queue_index, pf_q, err);
> > -           return -ENOMEM;
> > +           err = -ENOMEM;
> > +           goto unreg_xdp;
> >     }
> >  
> >     /* configure Rx buffer alignment */
> > @@ -3665,7 +3663,8 @@ static int i40e_configure_rx_ring(struct i40e_ring 
> > *ring)
> >             if (I40E_2K_TOO_SMALL_WITH_PADDING) {
> >                     dev_info(&vsi->back->pdev->dev,
> >                              "2k Rx buffer is too small to fit standard MTU 
> > and skb_shared_info\n");
> > -                   return -EOPNOTSUPP;
> > +                   err = -EOPNOTSUPP;
> > +                   goto unreg_xdp;
> >             }
> >             clear_ring_build_skb_enabled(ring);
> >     } else {
> > @@ -3695,6 +3694,11 @@ static int i40e_configure_rx_ring(struct i40e_ring 
> > *ring)
> >     }
> >  
> >     return 0;
> > +unreg_xdp:
> > +   if (ring->vsi->type == I40E_VSI_MAIN)
> > +           xdp_rxq_info_unreg(&ring->xdp_rxq);
> > +
> > +   return err;
> >  }
> >  
> >  /**
> > diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c 
> > b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> > index cc0b9efc2637..816179c7e271 100644
> > --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> > +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> > @@ -1470,6 +1470,9 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring)
> >     if (!rx_ring->rx_bi)
> >             return;
> >  
> > +   if (xdp_rxq_info_is_reg(&rx_ring->xdp_rxq))
> > +           xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
> > +
> >     if (rx_ring->xsk_pool) {
> >             i40e_xsk_clean_rx_ring(rx_ring);
> >             goto skip_free;
> > @@ -1527,8 +1530,6 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring)
> >  void i40e_free_rx_resources(struct i40e_ring *rx_ring)
> >  {
> >     i40e_clean_rx_ring(rx_ring);
> > -   if (rx_ring->vsi->type == I40E_VSI_MAIN)
> > -           xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
> >     rx_ring->xdp_prog = NULL;
> >     kfree(rx_ring->rx_bi);
> >     rx_ring->rx_bi = NULL;
> > -- 
> > 2.52.0
> > 

Reply via email to