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 */