summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2012-02-27 19:05:01 +0000
committerluigi <luigi@FreeBSD.org>2012-02-27 19:05:01 +0000
commit3ac0fcfb9762b2fd4991f32bff09543ba13df0d0 (patch)
treea547096f4399bc66370c43d717a40e4b79eb8401 /tools
parent71d18727cc7b50dc4e7c4d02cab4232fd4b10711 (diff)
downloadFreeBSD-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.c22
-rw-r--r--tools/tools/netmap/pcap.c4
-rw-r--r--tools/tools/netmap/pkt-gen.c11
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) {
OpenPOWER on IntegriCloud