From owner-svn-src-all@FreeBSD.ORG Mon May 21 22:19:20 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id CDAF01065680; Mon, 21 May 2012 22:19:20 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id AE46A8FC0A; Mon, 21 May 2012 22:19:20 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q4LMJKl7076039; Mon, 21 May 2012 22:19:20 GMT (envelope-from melifaro@svn.freebsd.org) Received: (from melifaro@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q4LMJKR9076035; Mon, 21 May 2012 22:19:20 GMT (envelope-from melifaro@svn.freebsd.org) Message-Id: <201205212219.q4LMJKR9076035@svn.freebsd.org> From: "Alexander V. Chernikov" Date: Mon, 21 May 2012 22:19:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r235746 - head/sys/net X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 May 2012 22:19:20 -0000 Author: melifaro Date: Mon May 21 22:19:19 2012 New Revision: 235746 URL: http://svn.freebsd.org/changeset/base/235746 Log: Call bpf_jitter() before acquiring BPF global lock due to malloc() being used inside bpf_jitter. Eliminate bpf_buffer_alloc() and allocate BPF buffers on descriptor creation and BIOCSBLEN ioctl. This permits us not to allocate buffers inside bpf_attachd() which is protected by global lock. Approved by: kib(mentor) MFC in: 4 weeks Modified: head/sys/net/bpf.c head/sys/net/bpf_buffer.c head/sys/net/bpf_buffer.h Modified: head/sys/net/bpf.c ============================================================================== --- head/sys/net/bpf.c Mon May 21 22:17:29 2012 (r235745) +++ head/sys/net/bpf.c Mon May 21 22:19:19 2012 (r235746) @@ -804,7 +804,7 @@ static int bpfopen(struct cdev *dev, int flags, int fmt, struct thread *td) { struct bpf_d *d; - int error; + int error, size; d = malloc(sizeof(*d), M_BPF, M_WAITOK | M_ZERO); error = devfs_set_cdevpriv(d, bpf_dtor); @@ -831,6 +831,10 @@ bpfopen(struct cdev *dev, int flags, int callout_init_mtx(&d->bd_callout, &d->bd_lock, 0); knlist_init_mtx(&d->bd_sel.si_note, &d->bd_lock); + /* Allocate default buffers */ + size = d->bd_bufsize; + bpf_buffer_ioctl_sblen(d, &size); + return (0); } @@ -1664,7 +1668,7 @@ bpf_setf(struct bpf_d *d, struct bpf_pro struct bpf_insn *fcode, *old; u_int wfilter, flen, size; #ifdef BPF_JITTER - bpf_jit_filter *ofunc; + bpf_jit_filter *ofunc, *jfunc; #endif int need_upgrade; #ifdef COMPAT_FREEBSD32 @@ -1695,6 +1699,13 @@ bpf_setf(struct bpf_d *d, struct bpf_pro else fcode = NULL; /* Make compiler happy */ +#ifdef BPF_JITTER + if (fp->bf_insns != NULL) + jfunc = bpf_jitter(fcode, flen); + else + jfunc = NULL; /* Make compiler happy */ +#endif + BPF_LOCK(); if (cmd == BIOCSETWF) { @@ -1755,7 +1766,7 @@ bpf_setf(struct bpf_d *d, struct bpf_pro else { d->bd_rfilter = fcode; #ifdef BPF_JITTER - d->bd_bfilter = bpf_jitter(fcode, flen); + d->bd_bfilter = jfunc; #endif if (cmd == BIOCSETF) reset_d(d); @@ -1827,11 +1838,6 @@ bpf_setif(struct bpf_d *d, struct ifreq */ switch (d->bd_bufmode) { case BPF_BUFMODE_BUFFER: - if (d->bd_sbuf == NULL) - bpf_buffer_alloc(d); - KASSERT(d->bd_sbuf != NULL, ("bpf_setif: bd_sbuf NULL")); - break; - case BPF_BUFMODE_ZBUF: if (d->bd_sbuf == NULL) return (EINVAL); Modified: head/sys/net/bpf_buffer.c ============================================================================== --- head/sys/net/bpf_buffer.c Mon May 21 22:17:29 2012 (r235745) +++ head/sys/net/bpf_buffer.c Mon May 21 22:19:19 2012 (r235746) @@ -93,21 +93,6 @@ static int bpf_maxbufsize = BPF_MAXBUFSI SYSCTL_INT(_net_bpf, OID_AUTO, maxbufsize, CTLFLAG_RW, &bpf_maxbufsize, 0, "Maximum capture buffer in bytes"); -void -bpf_buffer_alloc(struct bpf_d *d) -{ - - KASSERT(d->bd_fbuf == NULL, ("bpf_buffer_alloc: bd_fbuf != NULL")); - KASSERT(d->bd_sbuf == NULL, ("bpf_buffer_alloc: bd_sbuf != NULL")); - KASSERT(d->bd_hbuf == NULL, ("bpf_buffer_alloc: bd_hbuf != NULL")); - - d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_BPF, M_WAITOK); - d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_BPF, M_WAITOK); - d->bd_hbuf = NULL; - d->bd_slen = 0; - d->bd_hlen = 0; -} - /* * Simple data copy to the current kernel buffer. */ @@ -183,18 +168,42 @@ int bpf_buffer_ioctl_sblen(struct bpf_d *d, u_int *i) { u_int size; + caddr_t fbuf, sbuf; - BPFD_LOCK(d); - if (d->bd_bif != NULL) { - BPFD_UNLOCK(d); - return (EINVAL); - } size = *i; if (size > bpf_maxbufsize) *i = size = bpf_maxbufsize; else if (size < BPF_MINBUFSIZE) *i = size = BPF_MINBUFSIZE; + + /* Allocate buffers immediately */ + fbuf = (caddr_t)malloc(size, M_BPF, M_WAITOK); + sbuf = (caddr_t)malloc(size, M_BPF, M_WAITOK); + + BPFD_LOCK(d); + if (d->bd_bif != NULL) { + /* Interface already attached, unable to change buffers */ + BPFD_UNLOCK(d); + free(fbuf, M_BPF); + free(sbuf, M_BPF); + return (EINVAL); + } + + /* Free old buffers if set */ + if (d->bd_fbuf != NULL) + free(d->bd_fbuf, M_BPF); + if (d->bd_sbuf != NULL) + free(d->bd_sbuf, M_BPF); + + /* Fill in new data */ d->bd_bufsize = size; + d->bd_fbuf = fbuf; + d->bd_sbuf = sbuf; + + d->bd_hbuf = NULL; + d->bd_slen = 0; + d->bd_hlen = 0; + BPFD_UNLOCK(d); return (0); } Modified: head/sys/net/bpf_buffer.h ============================================================================== --- head/sys/net/bpf_buffer.h Mon May 21 22:17:29 2012 (r235745) +++ head/sys/net/bpf_buffer.h Mon May 21 22:19:19 2012 (r235746) @@ -36,7 +36,6 @@ #error "no user-serviceable parts inside" #endif -void bpf_buffer_alloc(struct bpf_d *d); void bpf_buffer_append_bytes(struct bpf_d *d, caddr_t buf, u_int offset, void *src, u_int len); void bpf_buffer_append_mbuf(struct bpf_d *d, caddr_t buf, u_int offset,