From owner-p4-projects@FreeBSD.ORG Tue Feb 6 22:08:43 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B8FB916A4A0; Tue, 6 Feb 2007 22:08:42 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 7E19316A49C for ; Tue, 6 Feb 2007 22:08:42 +0000 (UTC) (envelope-from csjp@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 58C7B13C4BA for ; Tue, 6 Feb 2007 22:08:42 +0000 (UTC) (envelope-from csjp@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id l16M8fZn084406 for ; Tue, 6 Feb 2007 22:08:41 GMT (envelope-from csjp@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id l16M8edk084403 for perforce@freebsd.org; Tue, 6 Feb 2007 22:08:40 GMT (envelope-from csjp@freebsd.org) Date: Tue, 6 Feb 2007 22:08:40 GMT Message-Id: <200702062208.l16M8edk084403@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to csjp@freebsd.org using -f From: "Christian S.J. Peron" To: Perforce Change Reviews Cc: Subject: PERFORCE change 114126 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 06 Feb 2007 22:08:43 -0000 http://perforce.freebsd.org/chv.cgi?CH=114126 Change 114126 by csjp@csjp_rnd01 on 2007/02/06 22:08:32 Backup the previous timeout code, this was a mistake. Instead take the following approach: - Implement a new ioctl(2) command: BIOCROTZBUF to manually trigger buffer rotations if the hold buffer is NULL and the store buffer contains some packet data. This ioctl works much like BIOCGETZNEXT only it doesn't may attention to the immediate flag. If we are unable to rotate the buffer, we return NULL back to userspace telling them to try again next wake up. Affected files ... .. //depot/projects/zcopybpf/src/sys/net/bpf.c#12 edit .. //depot/projects/zcopybpf/src/sys/net/bpf.h#7 edit .. //depot/projects/zcopybpf/src/sys/net/bpf_zerocopy.c#12 edit .. //depot/projects/zcopybpf/src/sys/net/bpf_zerocopy.h#4 edit Differences ... ==== //depot/projects/zcopybpf/src/sys/net/bpf.c#12 (text+ko) ==== @@ -310,14 +310,13 @@ } static int -bpf_ioctl_getznext(struct thread *td, struct bpf_d *d, struct bpf_zbuf *bz, - int timed_out) +bpf_ioctl_getznext(struct thread *td, struct bpf_d *d, struct bpf_zbuf *bz) { if (d->bd_bufmode != BPF_BUFMODE_ZBUF) return (EOPNOTSUPP); #ifdef BPF_ZEROCOPY - return (bpf_zerocopy_ioctl_getznext(td, d, bz, timed_out)); + return (bpf_zerocopy_ioctl_getznext(td, d, bz)); #else panic("bpf_ioctl_getznext"); #endif @@ -929,7 +928,7 @@ struct thread *td) { struct bpf_d *d = dev->si_drv1; - int timed_out, error = 0; + int error = 0; /* * Refresh PID associated with this descriptor. @@ -938,13 +937,6 @@ d->bd_pid = td->td_proc->p_pid; if (d->bd_state == BPF_WAITING) callout_stop(&d->bd_callout); - /* - * Before we clobber the BPF state, check to see if this descriptor - * was timed out. If so, we capture that bit of information so we - * can pass it to bpf_ioctl_getznext() so that it knows to rotate - * the buffers. - */ - timed_out = (d->bd_state == BPF_TIMED_OUT) ? 1 : 0; d->bd_state = BPF_IDLE; BPFD_UNLOCK(d); @@ -1287,11 +1279,14 @@ return (bpf_ioctl_getzmax(td, d, (u_int *)addr)); case BIOCGETZNEXT: - return (bpf_ioctl_getznext(td, d, (struct bpf_zbuf *)addr, - timed_out)); + return (bpf_ioctl_getznext(td, d, (struct bpf_zbuf *)addr)); case BIOCSETZBUF: return (bpf_ioctl_setzbuf(td, d, (struct bpf_zbuf *)addr)); + + case BIOCROTZBUF: + return (bpf_zerocopy_ioctl_rotate(td, d, (struct bpf_zbuf *) + addr)); } return (error); } @@ -1730,9 +1725,9 @@ } else if (d->bd_immediate || d->bd_state == BPF_TIMED_OUT) /* - * Immediate mode is set, or the read timeout has - * already expired during a select call. A packet - * arrived, so the reader should be woken up. + * Immediate mode is set, or the read timeout has already + * expired during a select call. A packet arrived, so the + * reader should be woken up. */ do_wakeup = 1; ==== //depot/projects/zcopybpf/src/sys/net/bpf.h#7 (text+ko) ==== @@ -153,7 +153,7 @@ #define BIOCGETZMAX _IOR('B', 128, u_int) #define BIOCGETZNEXT _IOR('B', 129, struct bpf_zbuf) #define BIOCSETZBUF _IOW('B', 130, struct bpf_zbuf) - +#define BIOCROTZBUF _IOR('B', 131, struct bpf_zbuf) /* * Structure prepended to each packet. */ @@ -186,7 +186,10 @@ volatile u_int bzh_kernel_gen; /* Kernel generation number. */ volatile u_int bzh_kernel_len; /* Length of buffer. */ volatile u_int bzh_user_gen; /* User generation number. */ - u_int _bzh_pad[5]; /* Padding out to 32-byte boundary. */ + void *bzh_hbuf; + void *bzh_fbuf; + void *bzh_sbuf; + u_char _bzh_pad[28]; }; /* ==== //depot/projects/zcopybpf/src/sys/net/bpf_zerocopy.c#12 (text+ko) ==== @@ -374,6 +374,9 @@ KASSERT(zb != NULL, ("bpf_zerocopy_bufheld: zb == NULL")); zb->zb_header->bzh_kernel_len = d->bd_hlen; zb->zb_header->bzh_kernel_gen++; + zb->zb_header->bzh_hbuf = d->bd_hbuf; + zb->zb_header->bzh_fbuf = d->bd_fbuf; + zb->zb_header->bzh_sbuf = d->bd_sbuf; } /* @@ -548,7 +551,7 @@ */ int bpf_zerocopy_ioctl_getznext(struct thread *td, struct bpf_d *d, - struct bpf_zbuf *bz, int timed_out) + struct bpf_zbuf *bz) { struct zbuf *zb; @@ -564,9 +567,10 @@ * held buffer. */ BPFD_LOCK(d); - if ((timed_out || d->bd_immediate) && d->bd_hbuf == NULL - && d->bd_slen != 0) + if (d->bd_immediate && d->bd_hbuf == NULL + && d->bd_slen != 0) { ROTATE_BUFFERS(d); + } bzero(bz, sizeof(*bz)); if (d->bd_hbuf != NULL) { zb = (struct zbuf *)d->bd_hbuf; @@ -577,6 +581,23 @@ return (0); } +int +bpf_zerocopy_ioctl_rotate(struct thread *td, struct bpf_d *d, + struct bpf_zbuf *bz) +{ + struct zbuf *bzh; + + BPFD_LOCK(d); + bzero(bz, sizeof(*bz)); + if (d->bd_hbuf == NULL && d->bd_slen != 0) { + ROTATE_BUFFERS(d); + bzh = (struct zbuf *)d->bd_hbuf; + bz->bz_bufa = (void *)bzh->zb_uaddr; + bz->bz_buflen = d->bd_hlen; + } + BPFD_UNLOCK(d); + return (0); +} /* * Ioctl to configure zero-copy buffers -- may be done only once. */ ==== //depot/projects/zcopybpf/src/sys/net/bpf_zerocopy.h#4 (text+ko) ==== @@ -50,10 +50,11 @@ int bpf_zerocopy_ioctl_getzmax(struct thread *td, struct bpf_d *d, u_int *i); int bpf_zerocopy_ioctl_getznext(struct thread *td, struct bpf_d *d, - struct bpf_zbuf *bz, int timed_out); + struct bpf_zbuf *bz); int bpf_zerocopy_ioctl_setzbuf(struct thread *td, struct bpf_d *d, struct bpf_zbuf *bz); int bpf_zerocopy_uiomove(struct bpf_d *d, caddr_t buf, u_int len, struct uio *uio); - +int bpf_zerocopy_ioctl_rotate(struct thread *td, struct bpf_d *d, + struct bpf_zbuf *bz); #endif /* !_NET_BPF_ZEROCOPY_H_ */