PERFORCE change 131478 for review

Robert Watson rwatson at FreeBSD.org
Sun Dec 23 08:49:29 PST 2007


http://perforce.freebsd.org/chv.cgi?CH=131478

Change 131478 by rwatson at rwatson_cinnamon on 2007/12/23 16:48:44

	Rework setup portion of zero-copy support for libpcap:
	
	- Test environmental variable only once when creating descriptor.
	- Rename environmental variable to BPF_ZEROCOPY to match kernel
	  option
	- If the environmental variable is present, try to set the
	  zero-copy buffer mode, and if that fails, fall back to normal
	  operation (which is what the comment suggests it does; instead
	  it was failing descriptor allocation if the setmode ioctl
	  failed).
	- When mmaping of shared buffers fails, follow the normal error
	  path.
	- Clean up the free path for zero-copy buffers.

Affected files ...

.. //depot/projects/zcopybpf/src/contrib/libpcap/pcap-bpf.c#10 edit
.. //depot/projects/zcopybpf/src/contrib/libpcap/pcap-int.h#6 edit

Differences ...

==== //depot/projects/zcopybpf/src/contrib/libpcap/pcap-bpf.c#10 (text+ko) ====

@@ -788,14 +788,10 @@
 	 * attach to, so we do that here also.
 	 */
 #ifdef BIOCSETBUFMODE
-	if (getenv("BPF_ZERO_COPY")) {
-		bufmode = BPF_BUFMODE_ZBUF;
-		if (ioctl(fd, BIOCSETBUFMODE, (caddr_t)&bufmode) < 0) {
-			snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETBUFMODE: %s",
-			    pcap_strerror(errno));
-			goto bad;
-		}
-
+	bufmode = BPF_BUFMODE_ZBUF;
+	if (getenv("BPF_ZEROCOPY") &&
+	    ioctl(fd, BIOCSETBUFMODE, (caddr_t)&bufmode) == 0) {
+		p->zerocopy = 1;
 		if (ioctl(fd, BIOCGETZMAX, (caddr_t)&zbufmax) < 0) {
 			snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGETZMAX: %s",
 			    pcap_strerror(errno));
@@ -806,8 +802,6 @@
 		 * XXXRW: This logic should be revisited.
 		 */
 		p->zbufsize = 32768;
-		if (p->zbufsize % getpagesize() != 0)
-			p->zbufsize = getpagesize();
 		if (p->zbufsize > zbufmax)
 			p->zbufsize = zbufmax;
 
@@ -816,12 +810,9 @@
 		p->zbuf2 = mmap(NULL, p->zbufsize, PROT_READ | PROT_WRITE,
 		    MAP_ANON, -1, 0);
 		if (p->zbuf1 == MAP_FAILED || p->zbuf2 == MAP_FAILED) {
-			if (p->zbuf1 != MAP_FAILED)
-				munmap(p->zbuf1, p->zbufsize);
-			if (p->zbuf2 != MAP_FAILED)
-				munmap(p->zbuf1, p->zbufsize);
 			snprintf(ebuf, PCAP_ERRBUF_SIZE, "mmap: %s",
 			    pcap_strerror(errno));
+			goto bad;
 		}
 
 		bzero(&bz, sizeof(bz));
@@ -1059,7 +1050,7 @@
 #endif
 	/* set timeout */
 	p->to_ms = to_ms;
-	if (to_ms != 0 && getenv("BPF_ZERO_COPY") == NULL) {
+	if (to_ms != 0 && !p->zerocopy) {
 		/*
 		 * XXX - is this seconds/nanoseconds in AIX?
 		 * (Treating it as such doesn't fix the timeout
@@ -1252,21 +1243,19 @@
 
 	(void)close(fd);
 #ifdef BIOCSETBUFMODE
-	if (p->zbuf1 != NULL)
-		munmap(p->zbuf1, v);
-	if (p->zbuf2 != NULL)
-		munmap(p->zbuf2, v);
 	/*
-	 * If we are using zerocopy, the packet buffer will be referencing
-	 * an address in one of the shared pages, if any.  In which case
-	 * we will not free it.
+	 * In zero-copy mode, p->buffer is just a pointer into one of the two
+	 * memory-mapped buffers, so no need to free it.
 	 */
-	if (getenv("BPF_ZERO_COPY") == NULL && p->buffer != NULL)
-		free(p->buffer);
-#else
+	if (p->zerocopy) {
+		if (p->zbuf1 != MAP_FAILED && p->zbuf1 != NULL)
+			munmap(p->zbuf1, p->zbufsize);
+		if (p->zbuf2 != MAP_FAILED && p->zbuf1 != NULL)
+			munmap(p->zbuf1, p->zbufsize);
+	} else
+#endif
 	if (p->buffer != NULL)
 		free(p->buffer);
-#endif
 	if (p->dlt_list != NULL)
 		free(p->dlt_list);
 	free(p);

==== //depot/projects/zcopybpf/src/contrib/libpcap/pcap-int.h#6 (text+ko) ====

@@ -189,6 +189,7 @@
 	u_char *zbuf1, *zbuf2;
 	u_int zbufsize;
 	u_int timeout;
+	u_int zerocopy;
 
 	/*
 	 * If there's currently a buffer being actively processed, then it is


More information about the p4-projects mailing list