[RFC PATCH v2 22/25] net/gve: Use PISA memory for RX buffers

From: Luigi Rizzo

Date: Mon Nov 09 2026 - 13:32:50 EST


When dev->pisa_rx_bufs is enabled, allocate GQI-RDA RX packet buffers
with pisa_rx_gfp(dev) so they come from the per-node PISA
allocator, and evict plain pages when a free PISA RX block is available;
DQO-RDA uses page_pool, which checks dev->pisa_rx_bufs directly.

Signed-off-by: Luigi Rizzo <lrizzo@xxxxxxxxxx>
---
drivers/net/ethernet/google/gve/gve_rx.c | 32 ++++++++++++++++--------
1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c
index 89f287b678bf0..85c243bbdeb33 100644
--- a/drivers/net/ethernet/google/gve/gve_rx.c
+++ b/drivers/net/ethernet/google/gve/gve_rx.c
@@ -4,6 +4,7 @@
* Copyright (C) 2015-2021 Google, Inc.
*/

+#include <linux/pisa.h>
#include "gve.h"
#include "gve_adminq.h"
#include "gve_utils.h"
@@ -170,6 +171,8 @@ static int gve_rx_alloc_buffer(struct gve_priv *priv, struct device *dev,
dma_addr_t dma;
int err;

+ if (rx->data.raw_addressing)
+ gfp |= pisa_rx_gfp(dev);
err = gve_alloc_page(priv, dev, &page, &dma, DMA_FROM_DEVICE, gfp);
if (err) {
u64_stats_update_begin(&rx->statss);
@@ -499,13 +502,19 @@ static void gve_rx_flip_buff(struct gve_rx_slot_page_info *page_info, __be64 *sl
*(slot_addr) ^= offset;
}

-static int gve_rx_can_recycle_buffer(struct gve_rx_slot_page_info *page_info)
+static int gve_rx_can_recycle_buffer(struct gve_rx_ring *rx,
+ struct gve_rx_slot_page_info *page_info)
{
int pagecount = page_count(page_info->page);

/* This page is not being used by any SKBs - reuse */
- if (pagecount == page_info->pagecnt_bias)
+ if (pagecount == page_info->pagecnt_bias) {
+ if (rx && rx->data.raw_addressing &&
+ !is_pisa_page(page_info->page) &&
+ pisa_has_free_blocks_rx(&rx->gve->pdev->dev, 0, rx->gve->numa_node))
+ return 0;
return 1;
+ }
/* This page is still being used by an SKB - we can't reuse */
else if (pagecount > page_info->pagecnt_bias)
return 0;
@@ -549,7 +558,7 @@ static struct sk_buff *gve_rx_copy_to_pool(struct gve_rx_ring *rx,

copy_page_info = &rx->qpl_copy_pool[pool_idx];
if (!copy_page_info->can_flip) {
- int recycle = gve_rx_can_recycle_buffer(copy_page_info);
+ int recycle = gve_rx_can_recycle_buffer(NULL, copy_page_info);

if (unlikely(recycle < 0)) {
gve_schedule_reset(rx->gve);
@@ -669,7 +678,7 @@ static struct sk_buff *gve_rx_skb(struct gve_priv *priv, struct gve_rx_ring *rx,
u64_stats_update_end(&rx->statss);
}
} else {
- int recycle = gve_rx_can_recycle_buffer(page_info);
+ int recycle = gve_rx_can_recycle_buffer(rx, page_info);

if (unlikely(recycle < 0)) {
gve_schedule_reset(priv);
@@ -975,7 +984,7 @@ static bool gve_rx_refill_buffers(struct gve_priv *priv, struct gve_rx_ring *rx)
* owns half the page it is impossible to tell which half. Either
* the whole page is free or it needs to be replaced.
*/
- int recycle = gve_rx_can_recycle_buffer(page_info);
+ int recycle = gve_rx_can_recycle_buffer(rx, page_info);

if (recycle < 0) {
if (!rx->data.raw_addressing)
@@ -987,12 +996,15 @@ static bool gve_rx_refill_buffers(struct gve_priv *priv, struct gve_rx_ring *rx)
union gve_rx_data_slot *data_slot =
&rx->data.data_ring[idx];
struct device *dev = &priv->pdev->dev;
- gve_rx_free_buffer(dev, page_info, data_slot);
- page_info->page = NULL;
- if (gve_rx_alloc_buffer(priv, dev, page_info,
- data_slot, rx)) {
+ struct gve_rx_slot_page_info new_info;
+ union gve_rx_data_slot new_slot;
+
+ if (gve_rx_alloc_buffer(priv, dev, &new_info,
+ &new_slot, rx))
break;
- }
+ gve_rx_free_buffer(dev, page_info, data_slot);
+ *page_info = new_info;
+ *data_slot = new_slot;
}
}
fill_cnt++;
--
2.56.0.542.g3ef89b7020-goog