[PATCH v5 16/19] net/tap: replace use of VLA in transmit burst

Stephen Hemminger stephen at networkplumber.org
Sun Feb 22 18:30:51 CET 2026


Replace the per-packet variable-length iovec array on the stack
with a fixed-size array of TAP_MAX_TX_SEGS + 1 (129) entries,
hoisted to function scope in tap_write_mbufs(). Packets with
more than 128 segments are dropped.

This eliminates the last VLA in the driver.

Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>
---
 drivers/net/tap/rte_eth_tap.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index f2cf7da736..9efdbc7012 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -79,9 +79,15 @@ static_assert(RTE_PMD_TAP_MAX_QUEUES <= RTE_MP_MAX_FD_NUM, "TAP max queues excee
  */
 #define TAP_MAX_RX_SEGS 128
 
+/* Limit on the number of segments per mbuf on Tx */
+#define TAP_MAX_TX_SEGS  128
+
 static_assert(TAP_MAX_RX_SEGS + 1 <= IOV_MAX,
 	      "TAP_MAX_RX_SEGS + 1 (for tun_pi) must not exceed IOV_MAX");
 
+static_assert(TAP_MAX_TX_SEGS + 1 <= IOV_MAX,
+	      "TAP_MAX_TX_SEGS + 1 (for tun_pi) must not exceed IOV_MAX");
+
 #define TAP_RX_OFFLOAD (RTE_ETH_RX_OFFLOAD_SCATTER |	\
 			RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |	\
 			RTE_ETH_RX_OFFLOAD_UDP_CKSUM |	\
@@ -533,13 +539,13 @@ tap_write_mbufs(struct tx_queue *txq, uint16_t num_mbufs,
 			uint16_t *num_packets, unsigned long *num_tx_bytes)
 {
 	struct pmd_process_private *process_private;
+	struct iovec iovecs[TAP_MAX_TX_SEGS + 1];
 	int i;
 
 	process_private = rte_eth_devices[txq->out_port].process_private;
 
 	for (i = 0; i < num_mbufs; i++) {
 		struct rte_mbuf *mbuf = pmbufs[i];
-		struct iovec iovecs[mbuf->nb_segs + 2];
 		struct tun_pi pi = { .flags = 0, .proto = 0x00 };
 		struct rte_mbuf *seg = mbuf;
 		uint64_t l4_ol_flags;
@@ -641,6 +647,10 @@ tap_write_mbufs(struct tx_queue *txq, uint16_t num_mbufs,
 		}
 
 skip_l4_cksum:
+		/* tun_pi header + packet segments must fit in iovecs */
+		if (unlikely(mbuf->nb_segs > TAP_MAX_TX_SEGS))
+			return -1;
+
 		for (j = 0; j < mbuf->nb_segs; j++) {
 			iovecs[k].iov_len = rte_pktmbuf_data_len(seg);
 			iovecs[k].iov_base = rte_pktmbuf_mtod(seg, void *);
@@ -669,7 +679,7 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 	uint16_t num_packets = 0;
 	unsigned long num_tx_bytes = 0;
 	uint32_t max_size;
-	int i;
+	unsigned int i;
 
 	if (unlikely(nb_pkts == 0))
 		return 0;
-- 
2.51.0



More information about the dev mailing list