Looks like it can be related to my commit from May:

    
https://github.com/openbsd/src/commit/b50d0c1cf040666aed872208cd6f6ba609197b11#diff-7922ad1d2f6422aa72d4bacd1bf41909

I'll try to take a look. The steps to reproduce would be handy.

as the first aid I would give a try to apply a reverse patch
to commit above. The reverse patch is below.

hope it helps
regards
sashan

----8<-------8<-------8<-------8<-------8<------------8<----
diff --git b/sys/net/bpf.c a/sys/net/bpf.c
index 5f2a20d593e..6d9554ec502 100644
--- b/sys/net/bpf.c
+++ a/sys/net/bpf.c
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bpf.c,v 1.175 2019/05/18 12:59:32 sashan Exp $        */
+/*     $OpenBSD: bpf.c,v 1.174 2019/04/25 18:24:39 anton Exp $ */
 /*     $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */
 
 /*
@@ -126,6 +126,13 @@ void       bpf_resetd(struct bpf_d *);
 void   bpf_prog_smr(void *);
 void   bpf_d_smr(void *);
 
+/*
+ * Reference count access to descriptor buffers
+ */
+void   bpf_get(struct bpf_d *);
+void   bpf_put(struct bpf_d *);
+
+
 struct rwlock bpf_sysctl_lk = RWLOCK_INITIALIZER("bpfsz");
 
 int
@@ -320,11 +327,13 @@ bpf_detachd(struct bpf_d *d)
 
                d->bd_promisc = 0;
 
+               bpf_get(d);
                mtx_leave(&d->bd_mtx);
                NET_LOCK();
                error = ifpromisc(bp->bif_ifp, 0);
                NET_UNLOCK();
                mtx_enter(&d->bd_mtx);
+               bpf_put(d);
 
                if (error && !(error == EINVAL || error == ENODEV ||
                    error == ENXIO))
@@ -373,6 +382,7 @@ bpfopen(dev_t dev, int flag, int mode, struct proc *p)
        if (flag & FNONBLOCK)
                bd->bd_rtout = -1;
 
+       bpf_get(bd);
        LIST_INSERT_HEAD(&bpf_d_list, bd, bd_list);
 
        return (0);
@@ -393,13 +403,7 @@ bpfclose(dev_t dev, int flag, int mode, struct proc *p)
        bpf_wakeup(d);
        LIST_REMOVE(d, bd_list);
        mtx_leave(&d->bd_mtx);
-
-       /*
-        * Wait for the task to finish here, before proceeding to garbage
-        * collection.
-        */
-       taskq_barrier(systq);
-       smr_call(&d->bd_smr, bpf_d_smr, d);
+       bpf_put(d);
 
        return (0);
 }
@@ -433,6 +437,7 @@ bpfread(dev_t dev, struct uio *uio, int ioflag)
        if (d->bd_bif == NULL)
                return (ENXIO);
 
+       bpf_get(d);
        mtx_enter(&d->bd_mtx);
 
        /*
@@ -538,6 +543,7 @@ bpfread(dev_t dev, struct uio *uio, int ioflag)
        d->bd_in_uiomove = 0;
 out:
        mtx_leave(&d->bd_mtx);
+       bpf_put(d);
 
        return (error);
 }
@@ -556,7 +562,9 @@ bpf_wakeup(struct bpf_d *d)
         * by the KERNEL_LOCK() we have to delay the wakeup to
         * another context to keep the hot path KERNEL_LOCK()-free.
         */
-       task_add(systq, &d->bd_wake_task);
+       bpf_get(d);
+       if (!task_add(systq, &d->bd_wake_task))
+               bpf_put(d);
 }
 
 void
@@ -571,6 +579,7 @@ bpf_wakeup_cb(void *xd)
                csignal(d->bd_pgid, d->bd_sig, d->bd_siguid, d->bd_sigeuid);
 
        selwakeup(&d->bd_sel);
+       bpf_put(d);
 }
 
 int
@@ -588,6 +597,7 @@ bpfwrite(dev_t dev, struct uio *uio, int ioflag)
        if (d->bd_bif == NULL)
                return (ENXIO);
 
+       bpf_get(d);
        ifp = d->bd_bif->bif_ifp;
 
        if (ifp == NULL || (ifp->if_flags & IFF_UP) == 0) {
@@ -621,6 +631,7 @@ bpfwrite(dev_t dev, struct uio *uio, int ioflag)
        NET_UNLOCK();
 
 out:
+       bpf_put(d);
        return (error);
 }
 
@@ -696,6 +707,8 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, 
struct proc *p)
                }
        }
 
+       bpf_get(d);
+
        switch (cmd) {
        default:
                error = EINVAL;
@@ -993,6 +1006,7 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, 
struct proc *p)
                break;
        }
 
+       bpf_put(d);
        return (error);
 }
 
@@ -1180,6 +1194,7 @@ bpfkqfilter(dev_t dev, struct knote *kn)
                return (EINVAL);
        }
 
+       bpf_get(d);
        kn->kn_hook = d;
        SLIST_INSERT_HEAD(klist, kn, kn_selnext);
 
@@ -1199,6 +1214,7 @@ filt_bpfrdetach(struct knote *kn)
        KERNEL_ASSERT_LOCKED();
 
        SLIST_REMOVE(&d->bd_sel.si_note, kn, knote, kn_selnext);
+       bpf_put(d);
 }
 
 int
@@ -1591,6 +1607,25 @@ bpf_d_smr(void *smr)
        free(bd, M_DEVBUF, sizeof(*bd));
 }
 
+void
+bpf_get(struct bpf_d *bd)
+{
+       atomic_inc_int(&bd->bd_ref);
+}
+
+/*
+ * Free buffers currently in use by a descriptor
+ * when the reference count drops to zero.
+ */
+void
+bpf_put(struct bpf_d *bd)
+{
+       if (atomic_dec_int_nv(&bd->bd_ref) > 0)
+               return;
+
+       smr_call(&bd->bd_smr, bpf_d_smr, bd);
+}
+
 void *
 bpfsattach(caddr_t *bpfp, const char *name, u_int dlt, u_int hdrlen)
 {
diff --git b/sys/net/bpfdesc.h a/sys/net/bpfdesc.h
index 130b91c1d9f..de8f6f3e440 100644
--- b/sys/net/bpfdesc.h
+++ a/sys/net/bpfdesc.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bpfdesc.h,v 1.38 2019/05/18 12:59:32 sashan Exp $     */
+/*     $OpenBSD: bpfdesc.h,v 1.37 2019/04/15 21:55:08 sashan Exp $     */
 /*     $NetBSD: bpfdesc.h,v 1.11 1995/09/27 18:30:42 thorpej Exp $     */
 
 /*
@@ -93,6 +93,7 @@ struct bpf_d {
        pid_t           bd_pgid;        /* process or group id for signal */
        uid_t           bd_siguid;      /* uid for process that set pgid */
        uid_t           bd_sigeuid;     /* euid for process that set pgid */
+       u_int           bd_ref;         /* reference count */
        struct selinfo  bd_sel;         /* bsd select info */
        int             bd_unit;        /* logical unit number */
        LIST_ENTRY(bpf_d) bd_list;      /* descriptor list */

Reply via email to