Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 May 2012 15:34:45 +0000 (UTC)
From:      Luigi Rizzo <luigi@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r234955 - head/tools/tools/netmap
Message-ID:  <201205031534.q43FYjIR049204@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: luigi
Date: Thu May  3 15:34:44 2012
New Revision: 234955
URL: http://svn.freebsd.org/changeset/base/234955

Log:
  - correct a bug in pcap_dispatch(): a count of 0 means infinity.
  
  - in pcap_dispatch(), issue a prefetch on the buffer before the
    callback, this may save a little bit of time if the client
    is very fast.
  
  - in pcap_inject(), use a fast copy routine, which also helps
    saving a few nanoseconds with fast clients.

Modified:
  head/tools/tools/netmap/pcap.c

Modified: head/tools/tools/netmap/pcap.c
==============================================================================
--- head/tools/tools/netmap/pcap.c	Thu May  3 15:25:11 2012	(r234954)
+++ head/tools/tools/netmap/pcap.c	Thu May  3 15:34:44 2012	(r234955)
@@ -49,6 +49,34 @@ int verbose = 0;
         __FUNCTION__, __LINE__, ##__VA_ARGS__);		\
 	} while (0)
 
+inline void prefetch (const void *x)
+{
+	__asm volatile("prefetcht0 %0" :: "m" (*(const unsigned long *)x));
+}
+
+// XXX only for multiples of 64 bytes, non overlapped.
+static inline void
+pkt_copy(const void *_src, void *_dst, int l)
+{
+        const uint64_t *src = _src;
+        uint64_t *dst = _dst;
+#define likely(x)       __builtin_expect(!!(x), 1)
+#define unlikely(x)       __builtin_expect(!!(x), 0)
+        if (unlikely(l >= 1024)) {
+                bcopy(src, dst, l);
+                return;
+        }
+        for (; l > 0; l-=64) {
+                *dst++ = *src++;
+                *dst++ = *src++;
+                *dst++ = *src++;
+                *dst++ = *src++;
+                *dst++ = *src++;
+                *dst++ = *src++;
+                *dst++ = *src++;
+                *dst++ = *src++;
+        }
+}
 
 /*
  * We redefine here a number of structures that are in pcap.h
@@ -479,21 +507,21 @@ pcap_setfilter(__unused pcap_t *p, __unu
 int
 pcap_datalink(__unused pcap_t *p)
 {
-	D("");
+	D("returns 1");
 	return 1;	// ethernet
 }
 
 const char *
 pcap_datalink_val_to_name(int dlt)
 {
-	D("%d", dlt);
+	D("%d returns DLT_EN10MB", dlt);
 	return "DLT_EN10MB";
 }
 
 const char *
 pcap_datalink_val_to_description(int dlt)
 {
-	D("%d", dlt);
+	D("%d returns Ethernet link", dlt);
 	return "Ethernet link";
 }
 
@@ -525,7 +553,8 @@ pcap_open_live(const char *device, __unu
 {
 	struct my_ring *me;
 
-	D("request to open %s", device);
+	D("request to open %s snaplen %d promisc %d timeout %dms",
+		device, snaplen, promisc, to_ms);
 	me = calloc(1, sizeof(*me));
 	if (me == NULL) {
 		D("failed to allocate struct for %s", device);
@@ -610,6 +639,8 @@ pcap_dispatch(pcap_t *p, int cnt, pcap_h
 	u_int si;
 
 	ND("cnt %d", cnt);
+	if (cnt == 0)
+		cnt = -1;
 	/* scan all rings */
 	for (si = me->begin; si < me->end; si++) {
 		struct netmap_ring *ring = NETMAP_RXRING(me->nifp, si);
@@ -617,6 +648,10 @@ pcap_dispatch(pcap_t *p, int cnt, pcap_h
 		if (ring->avail == 0)
 			continue;
 		me->hdr.ts = ring->ts;
+		/*
+		 * XXX a proper prefetch should be done as
+		 *	prefetch(i); callback(i-1); ...
+		 */
 		while ((cnt == -1 || cnt != got) && ring->avail > 0) {
 			u_int i = ring->cur;
 			u_int idx = ring->slot[i].buf_idx;
@@ -626,6 +661,7 @@ pcap_dispatch(pcap_t *p, int cnt, pcap_h
 				sleep(2);
 			}
 			u_char *buf = (u_char *)NETMAP_BUF(ring, idx);
+			prefetch(buf);
 			me->hdr.len = me->hdr.caplen = ring->slot[i].len;
 			// D("call %p len %d", p, me->hdr.len);
 			callback(user, &me->hdr, buf);
@@ -660,7 +696,7 @@ pcap_inject(pcap_t *p, const void *buf, 
 		}
 		u_char *dst = (u_char *)NETMAP_BUF(ring, idx);
 		ring->slot[i].len = size;
-		bcopy(buf, dst, size);
+		pkt_copy(buf, dst, size);
 		ring->cur = NETMAP_RING_NEXT(ring, i);
 		ring->avail--;
 		// if (ring->avail == 0) ioctl(me->fd, NIOCTXSYNC, NULL);



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