[PATCH iwl-next v3 1/2] libeth: add __libeth_rx_alloc() to specify allocation flags
From: Luigi Rizzo
Date: Tue Nov 03 2026 - 14:00:10 EST
libeth_rx_alloc() calls page_pool_dev_alloc_netmem(), which always
allocates with GFP_ATOMIC | __GFP_NOWARN. Drivers also use it to fill
their Rx rings at open or on queue reconfiguration, which runs in
process context before the queues' NAPI is enabled. There, the caller
may sleep and GFP_ATOMIC is needlessly restrictive: it can neither
reclaim nor compact, while the initial fill can allocate tens of
thousands of buffers across all queues.
Add __libeth_rx_alloc(), which takes a gfp_t parameter and passes
gfp | __GFP_NOWARN to page_pool_alloc_netmem(), and make
libeth_rx_alloc() its GFP_ATOMIC wrapper.
Signed-off-by: Luigi Rizzo <lrizzo@xxxxxxxxxx>
---
include/net/libeth/rx.h | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/include/net/libeth/rx.h b/include/net/libeth/rx.h
index 0e736846c5e8a..1333850f421a3 100644
--- a/include/net/libeth/rx.h
+++ b/include/net/libeth/rx.h
@@ -96,20 +96,24 @@ int libeth_rx_fq_create(struct libeth_fq *fq, void *napi_dev);
void libeth_rx_fq_destroy(struct libeth_fq *fq);
/**
- * libeth_rx_alloc - allocate a new Rx buffer
+ * __libeth_rx_alloc - allocate a new Rx buffer
* @fq: fill queue to allocate for
* @i: index of the buffer within the queue
+ * @gfp: allocation flags: GFP_KERNEL where the caller may sleep (e.g. the
+ * initial fill of the ring), GFP_ATOMIC from NAPI
*
* Return: DMA address to be passed to HW for Rx on successful allocation,
* ```DMA_MAPPING_ERROR``` otherwise.
*/
-static inline dma_addr_t libeth_rx_alloc(const struct libeth_fq_fp *fq, u32 i)
+static inline dma_addr_t __libeth_rx_alloc(const struct libeth_fq_fp *fq,
+ u32 i, gfp_t gfp)
{
struct libeth_fqe *buf = &fq->fqes[i];
buf->truesize = fq->truesize;
- buf->netmem = page_pool_dev_alloc_netmem(fq->pp, &buf->offset,
- &buf->truesize);
+ buf->netmem = page_pool_alloc_netmem(fq->pp, &buf->offset,
+ &buf->truesize,
+ gfp | __GFP_NOWARN);
if (unlikely(!buf->netmem))
return DMA_MAPPING_ERROR;
@@ -117,6 +121,18 @@ static inline dma_addr_t libeth_rx_alloc(const struct libeth_fq_fp *fq, u32 i)
fq->pp->p.offset;
}
+/**
+ * libeth_rx_alloc - allocate a new Rx buffer from NAPI context
+ * @fq: fill queue to allocate for
+ * @i: index of the buffer within the queue
+ *
+ * Return: as __libeth_rx_alloc().
+ */
+static inline dma_addr_t libeth_rx_alloc(const struct libeth_fq_fp *fq, u32 i)
+{
+ return __libeth_rx_alloc(fq, i, GFP_ATOMIC);
+}
+
void libeth_rx_recycle_slow(netmem_ref netmem);
/**
--
2.56.0.385.gac671c819a-goog