> -----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]>

Reply via email to