diff options
author | luigi <luigi@FreeBSD.org> | 2012-02-27 19:05:01 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 2012-02-27 19:05:01 +0000 |
commit | 3ac0fcfb9762b2fd4991f32bff09543ba13df0d0 (patch) | |
tree | a547096f4399bc66370c43d717a40e4b79eb8401 /tools | |
parent | 71d18727cc7b50dc4e7c4d02cab4232fd4b10711 (diff) | |
download | FreeBSD-src-3ac0fcfb9762b2fd4991f32bff09543ba13df0d0.zip FreeBSD-src-3ac0fcfb9762b2fd4991f32bff09543ba13df0d0.tar.gz |
A bunch of netmap fixes:
USERSPACE:
1. add support for devices with different number of rx and tx queues;
2. add better support for zero-copy operation, adding an extra field
to the netmap ring to indicate how many buffers we have already processed
but not yet released (with help from Eddie Kohler);
3. The two changes above unfortunately require an API change, so while
at it add a version field and some spares to the ioctl() argument
to help detect mismatches.
4. update the manual page for the two changes above;
5. update sample applications in tools/tools/netmap
KERNEL:
1. simplify the internal structures moving the global wait queues
to the 'struct netmap_adapter';
2. simplify the functions that map kring<->nic ring indexes
3. normalize device-specific code, helps mainteinance;
4. start exploring the impact of micro-optimizations (prefetch etc.)
in the ixgbe driver.
Use 'legacy' descriptors on the tx ring and prefetch slots gives
about 20% speedup at 900 MHz. Another 7-10% would come from removing
the explict calls to bus_dmamap* in the core (they are effectively
NOPs in this case, but it takes expensive load of the per-buffer
dma maps to figure out that they are all NULL.
Rx performance not investigated.
I am postponing the MFC so i can import a few more improvements
before merging.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/tools/netmap/bridge.c | 22 | ||||
-rw-r--r-- | tools/tools/netmap/pcap.c | 4 | ||||
-rw-r--r-- | tools/tools/netmap/pkt-gen.c | 11 |
3 files changed, 24 insertions, 13 deletions
diff --git a/tools/tools/netmap/bridge.c b/tools/tools/netmap/bridge.c index 2b9122c..1b027d7 100644 --- a/tools/tools/netmap/bridge.c +++ b/tools/tools/netmap/bridge.c @@ -48,7 +48,7 @@ int verbose = 0; } while (0) -char *version = "$Id: bridge.c 9642 2011-11-07 21:39:47Z luigi $"; +char *version = "$Id: bridge.c 10637 2012-02-24 16:36:25Z luigi $"; static int do_abort = 0; @@ -136,6 +136,7 @@ netmap_open(struct my_ring *me, int ringid) bzero(&req, sizeof(req)); strncpy(req.nr_name, me->ifname, sizeof(req.nr_name)); req.nr_ringid = ringid; + req.nr_version = NETMAP_API; err = ioctl(fd, NIOCGINFO, &req); if (err) { D("cannot get info on %s", me->ifname); @@ -162,17 +163,22 @@ netmap_open(struct my_ring *me, int ringid) me->nifp = NETMAP_IF(me->mem, req.nr_offset); me->queueid = ringid; if (ringid & NETMAP_SW_RING) { - me->begin = req.nr_numrings; + me->begin = req.nr_rx_rings; me->end = me->begin + 1; + me->tx = NETMAP_TXRING(me->nifp, req.nr_tx_rings); + me->rx = NETMAP_RXRING(me->nifp, req.nr_rx_rings); } else if (ringid & NETMAP_HW_RING) { + D("XXX check multiple threads"); me->begin = ringid & NETMAP_RING_MASK; me->end = me->begin + 1; + me->tx = NETMAP_TXRING(me->nifp, me->begin); + me->rx = NETMAP_RXRING(me->nifp, me->begin); } else { me->begin = 0; - me->end = req.nr_numrings; + me->end = req.nr_rx_rings; // XXX max of the two + me->tx = NETMAP_TXRING(me->nifp, 0); + me->rx = NETMAP_RXRING(me->nifp, 0); } - me->tx = NETMAP_TXRING(me->nifp, me->begin); - me->rx = NETMAP_RXRING(me->nifp, me->begin); return (0); error: close(me->fd); @@ -294,7 +300,7 @@ howmany(struct my_ring *me, int tx) if (0 && verbose && tot && !tx) D("ring %s %s %s has %d avail at %d", me->ifname, tx ? "tx": "rx", - me->end > me->nifp->ni_num_queues ? + me->end > me->nifp->ni_rx_queues ? "host":"net", tot, NETMAP_TXRING(me->nifp, me->begin)->cur); return tot; @@ -392,8 +398,8 @@ main(int argc, char **argv) D("Wait 2 secs for link to come up..."); sleep(2); D("Ready to go, %s 0x%x/%d <-> %s 0x%x/%d.", - me[0].ifname, me[0].queueid, me[0].nifp->ni_num_queues, - me[1].ifname, me[1].queueid, me[1].nifp->ni_num_queues); + me[0].ifname, me[0].queueid, me[0].nifp->ni_rx_queues, + me[1].ifname, me[1].queueid, me[1].nifp->ni_rx_queues); /* main loop */ signal(SIGINT, sigint_h); diff --git a/tools/tools/netmap/pcap.c b/tools/tools/netmap/pcap.c index f010b83..2a93e82 100644 --- a/tools/tools/netmap/pcap.c +++ b/tools/tools/netmap/pcap.c @@ -257,14 +257,14 @@ netmap_open(struct my_ring *me, int ringid) me->nifp = NETMAP_IF(me->mem, req.nr_offset); me->queueid = ringid; if (ringid & NETMAP_SW_RING) { - me->begin = req.nr_numrings; + me->begin = req.nr_rx_rings; me->end = me->begin + 1; } else if (ringid & NETMAP_HW_RING) { me->begin = ringid & NETMAP_RING_MASK; me->end = me->begin + 1; } else { me->begin = 0; - me->end = req.nr_numrings; + me->end = req.nr_rx_rings; } /* request timestamps for packets */ for (i = me->begin; i < me->end; i++) { diff --git a/tools/tools/netmap/pkt-gen.c b/tools/tools/netmap/pkt-gen.c index 5627e9e..43eeda8 100644 --- a/tools/tools/netmap/pkt-gen.c +++ b/tools/tools/netmap/pkt-gen.c @@ -25,7 +25,7 @@ /* * $FreeBSD$ - * $Id: pkt-gen.c 9827 2011-12-05 11:29:34Z luigi $ + * $Id: pkt-gen.c 10637 2012-02-24 16:36:25Z luigi $ * * Example program to show how to build a multithreaded packet * source/sink using the netmap device. @@ -776,6 +776,7 @@ main(int arc, char **argv) } bzero(&nmr, sizeof(nmr)); + nmr.nr_version = NETMAP_API; /* * Open the netmap device to fetch the number of queues of our * interface. @@ -796,11 +797,12 @@ main(int arc, char **argv) D("map size is %d Kb", nmr.nr_memsize >> 10); } bzero(&nmr, sizeof(nmr)); + nmr.nr_version = NETMAP_API; strncpy(nmr.nr_name, ifname, sizeof(nmr.nr_name)); if ((ioctl(fd, NIOCGINFO, &nmr)) == -1) { D("Unable to get if info for %s", ifname); } - devqueues = nmr.nr_numrings; + devqueues = nmr.nr_rx_rings; } /* validate provided nthreads. */ @@ -841,6 +843,7 @@ main(int arc, char **argv) * We decide to put the first interface registration here to * give time to cards that take a long time to reset the PHY. */ + nmr.nr_version = NETMAP_API; if (ioctl(fd, NIOCREGIF, &nmr) == -1) { D("Unable to register interface %s", ifname); //continue, fail later @@ -904,6 +907,7 @@ main(int arc, char **argv) bzero(&tifreq, sizeof(tifreq)); strncpy(tifreq.nr_name, ifname, sizeof(tifreq.nr_name)); + tifreq.nr_version = NETMAP_API; tifreq.nr_ringid = (g.nthreads > 1) ? (i | NETMAP_HW_RING) : 0; /* @@ -930,7 +934,8 @@ main(int arc, char **argv) targs[i].nmr = tifreq; targs[i].nifp = tnifp; targs[i].qfirst = (g.nthreads > 1) ? i : 0; - targs[i].qlast = (g.nthreads > 1) ? i+1 : tifreq.nr_numrings; + targs[i].qlast = (g.nthreads > 1) ? i+1 : + (td_body == receiver_body ? tifreq.nr_rx_rings : tifreq.nr_tx_rings); targs[i].me = i; targs[i].affinity = g.cpus ? i % g.cpus : -1; if (td_body == sender_body) { |