Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 1 Mar 2019 09:10:16 +0000 (UTC)
From:      Vincenzo Maffione <vmaffione@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r344696 - head/tools/tools/netmap
Message-ID:  <201903010910.x219AGSG075772@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: vmaffione
Date: Fri Mar  1 09:10:16 2019
New Revision: 344696
URL: https://svnweb.freebsd.org/changeset/base/344696

Log:
  netmap: pkt-gen: fix bug in send_packets()
  
  The send_packets() function was using ring->cur as index to scan
  the transmit ring. This function may also set ring->cur ahead of
  ring->head, in case no more slots are available. However, the function
  also uses nm_ring_space() which looks at ring->head to check how many
  slots are available. If ring->head and ring->cur are different, this
  results in pkt-gen advancing ring->cur beyond ring->tail.
  
  This patch fixes send_packets() (and similar source locations) to
  use ring->head as a index, rather than using ring->cur.
  
  MFC after:	1 week

Modified:
  head/tools/tools/netmap/pkt-gen.c

Modified: head/tools/tools/netmap/pkt-gen.c
==============================================================================
--- head/tools/tools/netmap/pkt-gen.c	Fri Mar  1 08:06:23 2019	(r344695)
+++ head/tools/tools/netmap/pkt-gen.c	Fri Mar  1 09:10:16 2019	(r344696)
@@ -626,10 +626,10 @@ parse_nmr_config(const char* conf, struct nmreq *nmr)
 	char *w, *tok;
 	int i, v;
 
-	nmr->nr_tx_rings = nmr->nr_rx_rings = 0;
-	nmr->nr_tx_slots = nmr->nr_rx_slots = 0;
 	if (conf == NULL || ! *conf)
 		return 0;
+	nmr->nr_tx_rings = nmr->nr_rx_rings = 0;
+	nmr->nr_tx_slots = nmr->nr_rx_slots = 0;
 	w = strdup(conf);
 	for (i = 0, tok = strtok(w, ","); tok; i++, tok = strtok(NULL, ",")) {
 		v = atoi(tok);
@@ -1158,22 +1158,22 @@ static int
 send_packets(struct netmap_ring *ring, struct pkt *pkt, void *frame,
 		int size, struct targ *t, u_int count, int options)
 {
-	u_int n, sent, cur = ring->cur;
+	u_int n, sent, head = ring->head;
 	u_int frags = t->frags;
 	u_int frag_size = t->frag_size;
-	struct netmap_slot *slot = &ring->slot[cur];
+	struct netmap_slot *slot = &ring->slot[head];
 
 	n = nm_ring_space(ring);
 #if 0
 	if (options & (OPT_COPY | OPT_PREFETCH) ) {
 		for (sent = 0; sent < count; sent++) {
-			struct netmap_slot *slot = &ring->slot[cur];
+			struct netmap_slot *slot = &ring->slot[head];
 			char *p = NETMAP_BUF(ring, slot->buf_idx);
 
 			__builtin_prefetch(p);
-			cur = nm_ring_next(ring, cur);
+			head = nm_ring_next(ring, head);
 		}
-		cur = ring->cur;
+		head = ring->head;
 	}
 #endif
 	for (sent = 0; sent < count && n >= frags; sent++, n--) {
@@ -1181,7 +1181,7 @@ send_packets(struct netmap_ring *ring, struct pkt *pkt
 		int buf_changed;
 		u_int tosend = size;
 
-		slot = &ring->slot[cur];
+		slot = &ring->slot[head];
 		p = NETMAP_BUF(ring, slot->buf_idx);
 		buf_changed = slot->flags & NS_BUF_CHANGED;
 
@@ -1200,11 +1200,11 @@ send_packets(struct netmap_ring *ring, struct pkt *pkt
 				slot->len = frag_size;
 				slot->flags = NS_MOREFRAG;
 				if (options & OPT_DUMP)
-					dump_payload(fp, frag_size, ring, cur);
+					dump_payload(fp, frag_size, ring, head);
 				tosend -= frag_size;
 				f += frag_size;
-				cur = nm_ring_next(ring, cur);
-				slot = &ring->slot[cur];
+				head = nm_ring_next(ring, head);
+				slot = &ring->slot[head];
 				fp = NETMAP_BUF(ring, slot->buf_idx);
 			}
 			n -= (frags - 1);
@@ -1223,12 +1223,12 @@ send_packets(struct netmap_ring *ring, struct pkt *pkt
 		}
 		slot->len = tosend;
 		if (options & OPT_DUMP)
-			dump_payload(p, tosend, ring, cur);
-		cur = nm_ring_next(ring, cur);
+			dump_payload(p, tosend, ring, head);
+		head = nm_ring_next(ring, head);
 	}
 	if (sent) {
 		slot->flags |= NS_REPORT;
-		ring->head = ring->cur = cur;
+		ring->head = ring->cur = head;
 	}
 	if (sent < count) {
 		/* tell netmap that we need more slots */
@@ -1329,7 +1329,7 @@ ping_body(void *data)
 		if (n > 0 && n - sent < limit)
 			limit = n - sent;
 		for (m = 0; (unsigned)m < limit; m++) {
-			slot = &ring->slot[ring->cur];
+			slot = &ring->slot[ring->head];
 			slot->len = size;
 			p = NETMAP_BUF(ring, slot->buf_idx);
 
@@ -1345,7 +1345,7 @@ ping_body(void *data)
 				tp->sec = (uint32_t)ts.tv_sec;
 				tp->nsec = (uint32_t)ts.tv_nsec;
 				sent++;
-				ring->head = ring->cur = nm_ring_next(ring, ring->cur);
+				ring->head = ring->cur = nm_ring_next(ring, ring->head);
 			}
 		}
 		if (m > 0)
@@ -1381,7 +1381,7 @@ ping_body(void *data)
 				struct tstamp *tp;
 				int pos;
 
-				slot = &ring->slot[ring->cur];
+				slot = &ring->slot[ring->head];
 				p = NETMAP_BUF(ring, slot->buf_idx);
 
 				clock_gettime(CLOCK_REALTIME_PRECISE, &now);
@@ -1406,7 +1406,7 @@ ping_body(void *data)
 				pos = msb64(t_cur);
 				buckets[pos]++;
 				/* now store it in a bucket */
-				ring->head = ring->cur = nm_ring_next(ring, ring->cur);
+				ring->head = ring->cur = nm_ring_next(ring, ring->head);
 				rx++;
 			}
 		}
@@ -1486,7 +1486,7 @@ pong_body(void *data)
 		D("understood ponger %llu but don't know how to do it",
 			(unsigned long long)n);
 	while (!targ->cancel && (n == 0 || sent < n)) {
-		uint32_t txcur, txavail;
+		uint32_t txhead, txavail;
 //#define BUSYWAIT
 #ifdef BUSYWAIT
 		ioctl(pfd.fd, NIOCRXSYNC, NULL);
@@ -1499,24 +1499,24 @@ pong_body(void *data)
 		}
 #endif
 		txring = NETMAP_TXRING(nifp, targ->nmd->first_tx_ring);
-		txcur = txring->cur;
+		txhead = txring->head;
 		txavail = nm_ring_space(txring);
 		/* see what we got back */
 		for (i = targ->nmd->first_rx_ring; i <= targ->nmd->last_rx_ring; i++) {
 			rxring = NETMAP_RXRING(nifp, i);
 			while (!nm_ring_empty(rxring)) {
 				uint16_t *spkt, *dpkt;
-				uint32_t cur = rxring->cur;
-				struct netmap_slot *slot = &rxring->slot[cur];
+				uint32_t head = rxring->head;
+				struct netmap_slot *slot = &rxring->slot[head];
 				char *src, *dst;
 				src = NETMAP_BUF(rxring, slot->buf_idx);
 				//D("got pkt %p of size %d", src, slot->len);
-				rxring->head = rxring->cur = nm_ring_next(rxring, cur);
+				rxring->head = rxring->cur = nm_ring_next(rxring, head);
 				rx++;
 				if (txavail == 0)
 					continue;
 				dst = NETMAP_BUF(txring,
-				    txring->slot[txcur].buf_idx);
+				    txring->slot[txhead].buf_idx);
 				/* copy... */
 				dpkt = (uint16_t *)dst;
 				spkt = (uint16_t *)src;
@@ -1528,13 +1528,13 @@ pong_body(void *data)
 				dpkt[3] = spkt[0];
 				dpkt[4] = spkt[1];
 				dpkt[5] = spkt[2];
-				txring->slot[txcur].len = slot->len;
-				txcur = nm_ring_next(txring, txcur);
+				txring->slot[txhead].len = slot->len;
+				txhead = nm_ring_next(txring, txhead);
 				txavail--;
 				sent++;
 			}
 		}
-		txring->head = txring->cur = txcur;
+		txring->head = txring->cur = txhead;
 		targ->ctr.pkts = sent;
 #ifdef BUSYWAIT
 		ioctl(pfd.fd, NIOCTXSYNC, NULL);
@@ -1760,30 +1760,30 @@ receive_pcap(u_char *user, const struct pcap_pkthdr * 
 static int
 receive_packets(struct netmap_ring *ring, u_int limit, int dump, uint64_t *bytes)
 {
-	u_int cur, rx, n;
+	u_int head, rx, n;
 	uint64_t b = 0;
 	u_int complete = 0;
 
 	if (bytes == NULL)
 		bytes = &b;
 
-	cur = ring->cur;
+	head = ring->head;
 	n = nm_ring_space(ring);
 	if (n < limit)
 		limit = n;
 	for (rx = 0; rx < limit; rx++) {
-		struct netmap_slot *slot = &ring->slot[cur];
+		struct netmap_slot *slot = &ring->slot[head];
 		char *p = NETMAP_BUF(ring, slot->buf_idx);
 
 		*bytes += slot->len;
 		if (dump)
-			dump_payload(p, slot->len, ring, cur);
+			dump_payload(p, slot->len, ring, head);
 		if (!(slot->flags & NS_MOREFRAG))
 			complete++;
 
-		cur = nm_ring_next(ring, cur);
+		head = nm_ring_next(ring, head);
 	}
-	ring->head = ring->cur = cur;
+	ring->head = ring->cur = head;
 
 	return (complete);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201903010910.x219AGSG075772>