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);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to