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>