On Tue, Sep 03, 2024 at 08:05:11PM +0200, Maciej Fijalkowski wrote: > In cases when synchronizing DMA operations is necessary, > xsk_buff_alloc_batch() returns a single buffer instead of the requested > count. Detect such situation when filling HW Rx ring in ZC driver and > use xsk_buff_alloc() in a loop manner so that ring gets the buffers to > be used.
Instead of addressing this on every driver side, let us do this in core by looping over xp_alloc(). Please drop this patch I will follow-up with a fix to core instead. Dries also found an issue that if xp_alloc_batch() is called with max == 0 it still returns a single buffer for dma_need_sync which we will fix as well. > > Reported-and-tested-by: Dries De Winter <[email protected]> > Fixes: db804cfc21e9 ("ice: Use the xsk batched rx allocation interface") > Signed-off-by: Maciej Fijalkowski <[email protected]> > --- > drivers/net/ethernet/intel/ice/ice_xsk.c | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > > diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c > b/drivers/net/ethernet/intel/ice/ice_xsk.c > index 240a7bec242b..889d0a5070d7 100644 > --- a/drivers/net/ethernet/intel/ice/ice_xsk.c > +++ b/drivers/net/ethernet/intel/ice/ice_xsk.c > @@ -449,7 +449,24 @@ static u16 ice_fill_rx_descs(struct xsk_buff_pool *pool, > struct xdp_buff **xdp, > u16 buffs; > int i; > > + if (unlikely(!xsk_buff_can_alloc(pool, count))) > + return 0; > + > buffs = xsk_buff_alloc_batch(pool, xdp, count); > + /* fill the remainder part that batch API did not provide for us, > + * this is usually the case for non-coherent systems that require DMA > + * syncs > + */ > + for (; buffs < count; buffs++) { > + struct xdp_buff *tmp; > + > + tmp = xsk_buff_alloc(pool); > + if (unlikely(!tmp)) > + goto free; > + > + xdp[buffs] = tmp; > + } > + > for (i = 0; i < buffs; i++) { > dma = xsk_buff_xdp_get_dma(*xdp); > rx_desc->read.pkt_addr = cpu_to_le64(dma); > @@ -465,6 +482,13 @@ static u16 ice_fill_rx_descs(struct xsk_buff_pool *pool, > struct xdp_buff **xdp, > } > > return buffs; > + > +free: > + for (i = 0; i < buffs; i++) { > + xsk_buff_free(*xdp); > + xdp++; > + } > + return 0; > } > > /** > -- > 2.34.1 > >
