On Mon, Nov 14, 2016 at 10:07:30AM +0100, Martin Pieuchot wrote: > Here's another extracted diff to move forward. Let bpf_allocbufs() > fail when allocating memory, this way we can call it while holding > a mutex. > > ok?
OK bluhm@ > > Index: net/bpf.c > =================================================================== > RCS file: /cvs/src/sys/net/bpf.c,v > retrieving revision 1.150 > diff -u -p -r1.150 bpf.c > --- net/bpf.c 16 Oct 2016 18:05:41 -0000 1.150 > +++ net/bpf.c 14 Nov 2016 09:02:51 -0000 > @@ -92,7 +92,7 @@ int bpf_maxbufsize = BPF_MAXBUFSIZE; > struct bpf_if *bpf_iflist; > LIST_HEAD(, bpf_d) bpf_d_list; > > -void bpf_allocbufs(struct bpf_d *); > +int bpf_allocbufs(struct bpf_d *); > void bpf_ifname(struct ifnet *, struct ifreq *); > int _bpf_mtap(caddr_t, const struct mbuf *, u_int, > void (*)(const void *, void *, size_t)); > @@ -996,6 +996,7 @@ int > bpf_setif(struct bpf_d *d, struct ifreq *ifr) > { > struct bpf_if *bp, *candidate = NULL; > + int error = 0; > int s; > > /* > @@ -1012,30 +1013,33 @@ bpf_setif(struct bpf_d *d, struct ifreq > candidate = bp; > } > > - if (candidate != NULL) { > - /* > - * Allocate the packet buffers if we need to. > - * If we're already attached to requested interface, > - * just flush the buffer. > - */ > - if (d->bd_sbuf == NULL) > - bpf_allocbufs(d); > - s = splnet(); > - if (candidate != d->bd_bif) { > - if (d->bd_bif) > - /* > - * Detach if attached to something else. > - */ > - bpf_detachd(d); > + /* Not found. */ > + if (candidate == NULL) > + return (ENXIO); > > - bpf_attachd(d, candidate); > - } > - bpf_reset_d(d); > - splx(s); > - return (0); > + /* > + * Allocate the packet buffers if we need to. > + * If we're already attached to requested interface, > + * just flush the buffer. > + */ > + s = splnet(); > + if (d->bd_sbuf == NULL) { > + if ((error = bpf_allocbufs(d))) > + goto out; > } > - /* Not found. */ > - return (ENXIO); > + if (candidate != d->bd_bif) { > + if (d->bd_bif) > + /* > + * Detach if attached to something else. > + */ > + bpf_detachd(d); > + > + bpf_attachd(d, candidate); > + } > + bpf_reset_d(d); > +out: > + splx(s); > + return (error); > } > > /* > @@ -1434,13 +1438,23 @@ bpf_catchpacket(struct bpf_d *d, u_char > /* > * Initialize all nonzero fields of a descriptor. > */ > -void > +int > bpf_allocbufs(struct bpf_d *d) > { > - d->bd_fbuf = malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK); > - d->bd_sbuf = malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK); > + d->bd_fbuf = malloc(d->bd_bufsize, M_DEVBUF, M_NOWAIT); > + if (d->bd_fbuf == NULL) > + return (ENOMEM); > + > + d->bd_sbuf = malloc(d->bd_bufsize, M_DEVBUF, M_NOWAIT); > + if (d->bd_sbuf == NULL) { > + free(d->bd_fbuf, M_DEVBUF, d->bd_bufsize); > + return (ENOMEM); > + } > + > d->bd_slen = 0; > d->bd_hlen = 0; > + > + return (0); > } > > void