I added a couple more assertions (spec_vnops.c 1.213). Attached is an updated patch with the ABI change to record who was closing when it shouldn't be possible.
>From 4df657b9ca2112c556eb7aaf7b6ed5b6912603c1 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell <[email protected]> Date: Sat, 16 Apr 2022 11:45:06 +0000 Subject: [PATCH] specfs: Identify which lwp is closing for assertions.
May help with diagnosing: https://mail-index.netbsd.org/current-users/2022/08/09/msg042800.html https://syzkaller.appspot.com/bug?id=47c67ab6d3a87514d0707882a9ad6671beaa8642 XXX kernel ABI change --- sys/miscfs/specfs/spec_vnops.c | 14 ++++++++------ sys/miscfs/specfs/specdev.h | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c index e1e2cbb84071..8b4ed335880a 100644 --- a/sys/miscfs/specfs/spec_vnops.c +++ b/sys/miscfs/specfs/spec_vnops.c @@ -397,7 +397,7 @@ spec_node_init(vnode_t *vp, dev_t rdev) sd->sd_bdevvp = NULL; sd->sd_iocnt = 0; sd->sd_opened = false; - sd->sd_closing = false; + sd->sd_closing = NULL; sn->sn_dev = sd; sd = NULL; } else { @@ -967,7 +967,8 @@ spec_open(void *v) KASSERTMSG(sn->sn_opencnt <= sd->sd_opencnt, "sn_opencnt=%u > sd_opencnt=%u", sn->sn_opencnt, sd->sd_opencnt); - KASSERT(!sd->sd_closing); + KASSERTMSG(sd->sd_closing == NULL, "sd_closing=%p", + sd->sd_closing); sd->sd_opened = true; } else if (sd->sd_opencnt == 1 && sd->sd_opened) { /* @@ -1698,9 +1699,10 @@ spec_close(void *v) if (count == 0) { KASSERTMSG(sn->sn_opencnt == 0, "sn_opencnt=%u", sn->sn_opencnt); - KASSERT(!sd->sd_closing); + KASSERTMSG(sd->sd_closing == NULL, "sd_closing=%p", + sd->sd_closing); sd->sd_opened = false; - sd->sd_closing = true; + sd->sd_closing = curlwp; } mutex_exit(&device_lock); @@ -1750,8 +1752,8 @@ spec_close(void *v) */ mutex_enter(&device_lock); KASSERT(!sd->sd_opened); - KASSERT(sd->sd_closing); - sd->sd_closing = false; + KASSERTMSG(sd->sd_closing == curlwp, "sd_closing=%p", sd->sd_closing); + sd->sd_closing = NULL; cv_broadcast(&specfs_iocv); mutex_exit(&device_lock); diff --git a/sys/miscfs/specfs/specdev.h b/sys/miscfs/specfs/specdev.h index c55ab7aaa90a..4f3d315b5053 100644 --- a/sys/miscfs/specfs/specdev.h +++ b/sys/miscfs/specfs/specdev.h @@ -80,7 +80,7 @@ typedef struct specdev { dev_t sd_rdev; volatile u_int sd_iocnt; /* # bdev/cdev_* operations active */ bool sd_opened; /* true if successfully opened */ - bool sd_closing; /* true when bdev/cdev_close ongoing */ + struct lwp *sd_closing; /* true when bdev/cdev_close ongoing */ } specdev_t; /*
