> -----Original Message----- > From: Luigi Rizzo <[email protected]> > Sent: Monday, October 19, 2026 11:06 PM > To: [email protected] > Cc: [email protected]; Nguyen, Anthony L > <[email protected]>; Kitszel, Przemyslaw > <[email protected]>; Lobakin, Aleksander > <[email protected]>; Andrew Lunn <[email protected]>; > David S . Miller <[email protected]>; Eric Dumazet > <[email protected]>; Luigi Rizzo <[email protected]>; Brian > Vazquez <[email protected]>; Hay, Joshua A <[email protected]>; > Zaremba, Larysa <[email protected]>; Jakub Kicinski > <[email protected]>; Paolo Abeni <[email protected]>; Simon Horman > <[email protected]>; [email protected]; Luigi Rizzo > <[email protected]> > Subject: [PATCH iwl-next v2 2/2] idpf: use GFP_KERNEL for the initial Rx > ring fill > > When idpf fills its Rx rings at open or on queue reconfiguration, the > allocation runs in process context, right after page_pool_create() and > before the queues' NAPI is enabled. Allocating tens of thousands of > buffers across all queues with GFP_ATOMIC is needlessly restrictive when > the caller may sleep. > > In splitq mode, idpf_rx_post_buf_desc() is only used for this initial > fill, so switch its header and payload allocations to > libeth_rx_alloc_gfp(..., GFP_KERNEL). > > In singleq mode, add a gfp_t parameter to > idpf_rx_singleq_buf_hw_alloc_all() and pass GFP_KERNEL from > idpf_rx_buf_alloc_singleq() and GFP_ATOMIC from idpf_rx_singleq_clean(). > > Signed-off-by: Luigi Rizzo <[email protected]> > --- > drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c | 7 ++++--- > drivers/net/ethernet/intel/idpf/idpf_txrx.c | 9 ++++++--- > drivers/net/ethernet/intel/idpf/idpf_txrx.h | 2 +- > 3 files changed, 11 insertions(+), 7 deletions(-) > > diff --git a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c > b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c > index e3ddf18dcbf51..d623e4ab8511f 100644 > --- a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c > +++ b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c > @@ -885,11 +885,12 @@ static void idpf_rx_buf_hw_update(struct > idpf_rx_queue *rxq, u32 val) > * idpf_rx_singleq_buf_hw_alloc_all - Replace used receive buffers > * @rx_q: queue for which the hw buffers are allocated > * @cleaned_count: number of buffers to replace > + * @gfp: GFP_KERNEL for the initial fill, GFP_ATOMIC from NAPI > * > * Returns false if all allocations were successful, true if any fail > */ > bool idpf_rx_singleq_buf_hw_alloc_all(struct idpf_rx_queue *rx_q, > - u16 cleaned_count) > + u16 cleaned_count, gfp_t gfp) > { > struct virtchnl2_singleq_rx_buf_desc *desc; > const struct libeth_fq_fp fq = { > @@ -908,7 +909,7 @@ bool idpf_rx_singleq_buf_hw_alloc_all(struct > idpf_rx_queue *rx_q, > do { > dma_addr_t addr; > > - addr = libeth_rx_alloc(&fq, nta); > + addr = libeth_rx_alloc_gfp(&fq, nta, gfp); > if (addr == DMA_MAPPING_ERROR) > break; > > @@ -1095,7 +1096,7 @@ static int idpf_rx_singleq_clean(struct > idpf_rx_queue *rx_q, int budget) > > page_pool_nid_changed(rx_q->pp, numa_mem_id()); > if (cleaned_count) > - idpf_rx_singleq_buf_hw_alloc_all(rx_q, cleaned_count); > + idpf_rx_singleq_buf_hw_alloc_all(rx_q, cleaned_count, > GFP_ATOMIC); > > u64_stats_update_begin(&rx_q->stats_sync); > u64_stats_add(&rx_q->q_stats.packets, rs.packets); diff --git > a/drivers/net/ethernet/intel/idpf/idpf_txrx.c > b/drivers/net/ethernet/intel/idpf/idpf_txrx.c > index 4311ffa30bb18..b1127ab48ef3f 100644 > --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c > +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c > @@ -600,6 +600,9 @@ static void idpf_post_buf_refill(struct > idpf_sw_queue *refillq, u16 buf_id) > * @bufq: buffer queue to post to > * @buf_id: buffer id to post > * > + * Only used for the initial fill, from process context, so it > + allocates > + * with GFP_KERNEL. > + * > * Return: %false if buffer could not be allocated, %true otherwise. > */ > static bool idpf_rx_post_buf_desc(struct idpf_buf_queue *bufq, u16 > buf_id) @@ -618,7 +621,7 @@ static bool idpf_rx_post_buf_desc(struct > idpf_buf_queue *bufq, u16 buf_id) > fq.fqes = bufq->hdr_buf; > fq.truesize = bufq->hdr_truesize; > > - addr = libeth_rx_alloc(&fq, buf_id); > + addr = libeth_rx_alloc_gfp(&fq, buf_id, GFP_KERNEL); > if (addr == DMA_MAPPING_ERROR) > return false; > > @@ -629,7 +632,7 @@ static bool idpf_rx_post_buf_desc(struct > idpf_buf_queue *bufq, u16 buf_id) > fq.fqes = bufq->buf; > fq.truesize = bufq->truesize; > > - addr = libeth_rx_alloc(&fq, buf_id); > + addr = libeth_rx_alloc_gfp(&fq, buf_id, GFP_KERNEL); > if (addr == DMA_MAPPING_ERROR) > return false; > > @@ -675,7 +678,7 @@ static bool idpf_rx_post_init_bufs(struct > idpf_buf_queue *bufq, > */ > static int idpf_rx_buf_alloc_singleq(struct idpf_rx_queue *rxq) { > - if (idpf_rx_singleq_buf_hw_alloc_all(rxq, rxq->desc_count - 1)) > + if (idpf_rx_singleq_buf_hw_alloc_all(rxq, rxq->desc_count - 1, > +GFP_KERNEL)) > goto err; > > return 0; > diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h > b/drivers/net/ethernet/intel/idpf/idpf_txrx.h > index 93547597efd2a..e27438c78ec79 100644 > --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h > +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h > @@ -1123,7 +1123,7 @@ netdev_tx_t idpf_tx_singleq_frame(struct sk_buff > *skb, > struct idpf_tx_queue *tx_q); > netdev_tx_t idpf_tx_start(struct sk_buff *skb, struct net_device > *netdev); bool idpf_rx_singleq_buf_hw_alloc_all(struct idpf_rx_queue > *rxq, > - u16 cleaned_count); > + u16 cleaned_count, gfp_t gfp); > bool idpf_rx_process_skb_fields(struct sk_buff *skb, > const struct libeth_xdp_buff *xdp, > struct libeth_rq_napi_stats *rs); > -- > 2.56.0.212.g129ede20d9-goog
Reviewed-by: Aleksandr Loktionov <[email protected]>
