From: "Jasper Tran O'Leary" <jtranoleary@google.com>
To: stephen@networkplumber.org
Cc: dev@dpdk.org, "Jasper Tran O'Leary" <jtranoleary@google.com>,
Joshua Washington <joshwash@google.com>
Subject: [PATCH 2/4] net/gve: remove variable length array in rx refill
Date: Fri, 27 Mar 2026 00:18:25 +0000 [thread overview]
Message-ID: <20260327001827.3385001-3-jtranoleary@google.com> (raw)
In-Reply-To: <20260327001827.3385001-1-jtranoleary@google.com>
The new_bufs array in gve_rx_refill_dqo was being allocated on the
stack as a variable length array. With a large descriptor count, this
could lead to excessive stack usage or potential stack overflows, and
triggers -Wvla warnings during compilation.
To fix this, replace the stack array with a buffer allocated on the
heap during queue setup. This buffer, refill_bufs, is stored in the
rxq structure and is sized to the queue's descriptor count. This moves
the allocation from the datapath stack to the heap at initialization,
resolving the stack overflow risk while maintaining the efficiency of a
single bulk mbuf allocation.
Signed-off-by: Jasper Tran O'Leary <jtranoleary@google.com>
Reviewed-by: Joshua Washington <joshwash@google.com>
---
drivers/net/gve/gve_ethdev.h | 1 +
drivers/net/gve/gve_rx_dqo.c | 27 +++++++++++++++++++++------
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h
index 2d570d0..8fd098c 100644
--- a/drivers/net/gve/gve_ethdev.h
+++ b/drivers/net/gve/gve_ethdev.h
@@ -250,6 +250,7 @@ struct gve_rx_queue {
/* Only valid for DQO_RDA queue format */
struct gve_rx_queue *bufq;
+ struct rte_mbuf **refill_bufs;
uint8_t is_gqi_qpl;
};
diff --git a/drivers/net/gve/gve_rx_dqo.c b/drivers/net/gve/gve_rx_dqo.c
index 3aa82b3..8035aee 100644
--- a/drivers/net/gve/gve_rx_dqo.c
+++ b/drivers/net/gve/gve_rx_dqo.c
@@ -40,12 +40,12 @@ static inline void
gve_rx_refill_dqo(struct gve_rx_queue *rxq)
{
volatile struct gve_rx_desc_dqo *rx_buf_desc;
- struct rte_mbuf *new_bufs[rxq->nb_rx_desc];
uint16_t rx_mask = rxq->nb_rx_desc - 1;
uint16_t next_avail = rxq->bufq_tail;
struct rte_eth_dev *dev;
uint16_t nb_refill;
uint64_t dma_addr;
+ rte_iova_t iova;
int16_t buf_id;
int diag;
int i;
@@ -54,7 +54,7 @@ gve_rx_refill_dqo(struct gve_rx_queue *rxq)
if (nb_refill < rxq->free_thresh)
return;
- diag = rte_pktmbuf_alloc_bulk(rxq->mpool, new_bufs, nb_refill);
+ diag = rte_pktmbuf_alloc_bulk(rxq->mpool, rxq->refill_bufs, nb_refill);
if (unlikely(diag < 0)) {
rxq->stats.no_mbufs_bulk++;
rxq->stats.no_mbufs += nb_refill;
@@ -76,12 +76,14 @@ gve_rx_refill_dqo(struct gve_rx_queue *rxq)
PMD_DRV_DP_LOG(ERR,
"No free entries in sw_ring for port %d, queue %d.",
rxq->port_id, rxq->queue_id);
- rte_pktmbuf_free_bulk(new_bufs + i, nb_refill - i);
+ rte_pktmbuf_free_bulk(rxq->refill_bufs + i,
+ nb_refill - i);
nb_refill = i;
break;
}
- rxq->sw_ring[buf_id] = new_bufs[i];
- dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_bufs[i]));
+ rxq->sw_ring[buf_id] = rxq->refill_bufs[i];
+ iova = rte_mbuf_data_iova_default(rxq->refill_bufs[i]);
+ dma_addr = rte_cpu_to_le_64(iova);
rx_buf_desc->buf_id = buf_id;
rx_buf_desc->header_buf_addr = 0;
rx_buf_desc->buf_addr = dma_addr;
@@ -247,6 +249,7 @@ gve_rx_queue_release_dqo(struct rte_eth_dev *dev, uint16_t qid)
gve_release_rxq_mbufs_dqo(q);
rte_free(q->sw_ring);
rte_free(q->completed_buf_list);
+ rte_free(q->refill_bufs);
rte_memzone_free(q->compl_ring_mz);
rte_memzone_free(q->mz);
rte_memzone_free(q->qres_mz);
@@ -363,6 +366,16 @@ gve_rx_queue_setup_dqo(struct rte_eth_dev *dev, uint16_t queue_id,
goto free_rxq_sw_ring;
}
+ /* Allocate buffer for reallocating mbufs */
+ rxq->refill_bufs = rte_zmalloc_socket("gve rx refill bufs",
+ nb_desc * sizeof(*rxq->refill_bufs), RTE_CACHE_LINE_SIZE,
+ socket_id);
+ if (rxq->refill_bufs == NULL) {
+ PMD_DRV_LOG(ERR, "Failed to allocate rx refill bufs.");
+ err = -ENOMEM;
+ goto free_rxq_completed_buf_list;
+ }
+
/* Allocate RX buffer queue */
mz = rte_eth_dma_zone_reserve(dev, "rx_ring", queue_id,
nb_desc * sizeof(struct gve_rx_desc_dqo),
@@ -370,7 +383,7 @@ gve_rx_queue_setup_dqo(struct rte_eth_dev *dev, uint16_t queue_id,
if (mz == NULL) {
PMD_DRV_LOG(ERR, "Failed to reserve DMA memory for RX buffer queue");
err = -ENOMEM;
- goto free_rxq_completed_buf_list;
+ goto free_rxq_refill_bufs;
}
rxq->rx_ring = (struct gve_rx_desc_dqo *)mz->addr;
rxq->rx_ring_phys_addr = mz->iova;
@@ -412,6 +425,8 @@ free_rxq_cq_mz:
rte_memzone_free(rxq->compl_ring_mz);
free_rxq_mz:
rte_memzone_free(rxq->mz);
+free_rxq_refill_bufs:
+ rte_free(rxq->refill_bufs);
free_rxq_completed_buf_list:
rte_free(rxq->completed_buf_list);
free_rxq_sw_ring:
--
2.53.0.1118.gaef5881109-goog
next prev parent reply other threads:[~2026-03-27 0:19 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-27 0:18 [PATCH 0/4] net/gve: clean up minor issues Jasper Tran O'Leary
2026-03-27 0:18 ` [PATCH 1/4] net/gve: fix comma operator compiler warning Jasper Tran O'Leary
2026-03-27 0:18 ` Jasper Tran O'Leary [this message]
2026-03-27 0:18 ` [PATCH 3/4] net/gve: add checks for flow rule struct padding Jasper Tran O'Leary
2026-03-27 0:18 ` [PATCH 4/4] net/gve: add minor fixes to flow rule code Jasper Tran O'Leary
2026-04-05 16:19 ` [PATCH 0/4] net/gve: clean up minor issues Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260327001827.3385001-3-jtranoleary@google.com \
--to=jtranoleary@google.com \
--cc=dev@dpdk.org \
--cc=joshwash@google.com \
--cc=stephen@networkplumber.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox