svn commit: r234955 - head/tools/tools/netmap
Luigi Rizzo
luigi at FreeBSD.org
Thu May 3 15:34:45 UTC 2012
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);
More information about the svn-src-all
mailing list