git: 506336f2cd1f - main - netmap: pkt-gen: init all slots of every tx ring

From: Vincenzo Maffione <vmaffione_at_FreeBSD.org>
Date: Mon, 06 Mar 2023 17:26:26 UTC
The branch main has been updated by vmaffione:

URL: https://cgit.FreeBSD.org/src/commit/?id=506336f2cd1fa0a3ba94bc247d7fad1a71d43ac2

commit 506336f2cd1fa0a3ba94bc247d7fad1a71d43ac2
Author:     Vincenzo Maffione <vmaffione@FreeBSD.org>
AuthorDate: 2023-03-06 17:22:09 +0000
Commit:     Vincenzo Maffione <vmaffione@FreeBSD.org>
CommitDate: 2023-03-06 17:22:09 +0000

    netmap: pkt-gen: init all slots of every tx ring
    
    sender_body() uses OPT_COPY to copy the frame into the destination slot
    for the first 100,000 packets. Then it removes OPT_COPY to improve
    performance. The function always starts with the first tx ring.
    
    If multiple tx rings are in use, it is possible that the initial 100k
    packets will only use the first ring. After OPT_COPY is removed, there
    may come a time when the first ring is full and sender_body() will move
    to the next ring which was never initialized. As a result it will send
    all zero packets. (This was discovered when the receiving NIC reported
    rx errors.)
    
    Before any transmissions, step through every tx ring and set
    NS_BUF_CHANGED on every slot. That will force send_packets() to
    initialize the slot when first used. Since it only copies when
    necessary, it performs better than always setting OPT_COPY. With this
    change, there is no reason for the "drop copy" code.
    
    Submitted by:   Brian Poole <brian90013@gmail.com>
    MFC after:      7 days
---
 tools/tools/netmap/pkt-gen.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/tools/tools/netmap/pkt-gen.c b/tools/tools/netmap/pkt-gen.c
index b06fef05579d..296208018fd4 100644
--- a/tools/tools/netmap/pkt-gen.c
+++ b/tools/tools/netmap/pkt-gen.c
@@ -1604,7 +1604,7 @@ sender_body(void *data)
 	uint64_t n = targ->g->npackets / targ->g->nthreads;
 	uint64_t sent = 0;
 	uint64_t event = 0;
-	int options = targ->g->options | OPT_COPY;
+	int options = targ->g->options;
 	struct timespec nexttime = { 0, 0}; // XXX silence compiler
 	int rate_limit = targ->g->tx_rate;
 	struct pkt *pkt = &targ->pkt;
@@ -1678,6 +1678,19 @@ sender_body(void *data)
 			targ->frags++;
 	}
 	D("frags %u frag_size %u", targ->frags, targ->frag_size);
+
+	/* mark all slots of all rings as changed so initial copy will be done */
+	for (i = targ->nmd->first_tx_ring; i <= targ->nmd->last_tx_ring; i++) {
+		uint32_t j;
+		struct netmap_slot *slot;
+
+		txring = NETMAP_TXRING(nifp, i);
+		for (j = 0; j < txring->num_slots; j++) {
+			slot = &txring->slot[j];
+			slot->flags = NS_BUF_CHANGED;
+		}
+	}
+
 	while (!targ->cancel && (n == 0 || sent < n)) {
 		int rv;
 
@@ -1714,10 +1727,6 @@ sender_body(void *data)
 		/*
 		 * scan our queues and send on those with room
 		 */
-		if (options & OPT_COPY && sent > 100000 && !(targ->g->options & OPT_COPY) ) {
-			D("drop copy");
-			options &= ~OPT_COPY;
-		}
 		for (i = targ->nmd->first_tx_ring; i <= targ->nmd->last_tx_ring; i++) {
 			int m;
 			uint64_t limit = rate_limit ?  tosend : targ->g->burst;