NetBSD Problem Report #60332
From www@netbsd.org Sun Jun 14 23:48:44 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits)
client-signature RSA-PSS (2048 bits))
(Client CN "mail.netbsd.org", Issuer "R13" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id A7B721A923A
for <gnats-bugs@gnats.NetBSD.org>; Sun, 14 Jun 2026 23:48:44 +0000 (UTC)
Message-Id: <20260614234843.6EEC61A923B@mollari.NetBSD.org>
Date: Sun, 14 Jun 2026 23:48:43 +0000 (UTC)
From: mrg@eterna23.net
Reply-To: mrg@eterna23.net
To: gnats-bugs@NetBSD.org
Subject: system crashed when ^C on midiplay hung and i turned the synth off
X-Send-Pr-Version: www-1.0
X-From4GNATS: "mrg@eterna23.net via gnats" <gnats-admin@NetBSD.org>
>Number: 60332
>Category: kern
>Synopsis: system crashed when ^C on midiplay hung and i turned the synth off
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Jun 14 23:50:00 +0000 2026
>Last-Modified: Mon Jun 15 00:45:00 +0000 2026
>Originator: matthew green
>Release: 11 RC1.
>Organization:
people's front against (bozotic) www (softwar foundation)
>Environment:
Thinkpad A475, amd64
NetBSD 11.0_RC1 (_wreakage_) #4: Mon Mar 16 00:36:38 PDT 2026
>Description:
i was running "midiplay" against a synth when i realised i'd sent it
the wrong file, so i hit ^C and was waiting for it to complete (this
can take a long time depending on how much midi data is buffered),
but something was wrong with the host at this point, as it never finished
(the midi track wasn't nearly this long). eventually i turned the synth
off as a hope it would kill the midiplay and i could turn it back on and
keep working, but unfortunately it crashed at this point (i have a core
file). before i turned the synth off, i did inspect midiplay process as
best as i could. this is what i found before crash:
ps output:
mrg 1256 0.0 0.1 23936 8684 pts/1 DE+ 11:32PM 0:00.04 (midiplay)
crash outout:
1256 1256 3 0 0 ffff891e4127f400 midiplay midiwr
crash> bt/a ffff891e4127f400
trace: pid 1256 lid 1256 at 0xffffa384b727ba80
sleepq_block() at sleepq_block+0xee
cv_wait() at cv_wait+0xca
midiclose() at midiclose+0x4e
cdev_close() at cdev_close+0x91
spec_close() at spec_close+0x22e
VOP_CLOSE() at VOP_CLOSE+0x40
vn_close() at vn_close+0x34
sequencerclose() at sequencerclose+0xe7
cdev_close() at cdev_close+0x91
spec_close() at spec_close+0x22e
VOP_CLOSE() at VOP_CLOSE+0x40
vn_close() at vn_close+0x34
closef() at closef+0x9a
fd_free() at fd_free+0xfa
exit1() at exit1+0x119
sys_exit() at sys_exit+0x3b
syscall() at syscall+0x9d
--- syscall (number 1) ---
syscall+0x9d:
crash>
the dmesg after rebooting shows what happened:
vnode 0xffff89201a78ccc0 flags 0x8010<MPSAFE,DEADCHECK>
tag VT_NON(0) type VCHR(4) mount 0xffff8920c27b0000 typedata 0xffff8920403742c0
usecount 3 writecount 0 holdcount 0
size 0 writesize 0 numoutput 0
data 0x0 lock 0xffff89201a78ce80
state RECLAIMING key(0xffff8920c27b0000 0)
lrulisthd 0xffffffff8148f9d0
panic: state is RECLAIMING, usecount 3, expected ACTIVE at genfs_lock:400
cpu1: Begin traceback...
vpanic() at netbsd:vpanic+0x171
vnpanic() at netbsd:vnpanic+0x49
_vstate_assert() at netbsd:_vstate_assert+0x19f
genfs_lock() at netbsd:genfs_lock+0x46
VOP_LOCK() at netbsd:VOP_LOCK+0xcc
vn_lock() at netbsd:vn_lock+0xb0
spec_close() at netbsd:spec_close+0x291
VOP_CLOSE() at netbsd:VOP_CLOSE+0x40
vn_close() at netbsd:vn_close+0x34
sequencerclose() at netbsd:sequencerclose+0xe7
cdev_close() at netbsd:cdev_close+0x91
spec_close() at netbsd:spec_close+0x22e
VOP_CLOSE() at netbsd:VOP_CLOSE+0x40
vn_close() at netbsd:vn_close+0x34
closef() at netbsd:closef+0x9a
fd_free() at netbsd:fd_free+0xfa
exit1() at netbsd:exit1+0x119
sys_exit() at netbsd:sys_exit+0x3b
syscall() at netbsd:syscall+0x9d
--- syscall (number 1) ---
i have a core file, but i did not keep matching sources for this, not
even a netbsd.gdb, so i'd have to recreate from a partial guess of
changes. (it would likely be not very long before the kernel was
built, so march 15 or so.)
midi device involved with crash:
umidi0 at uhub5 port 2 configuration 1 interface 0
umidi0: KORG INC. (0x0944) microKORG XL (0x010b), rev 1.10/1.00, addr 3
umidi0: (genuine USB-MIDI)
umidi0: out=2, in=2
midi1 at umidi0: <0 >0 on umidi0
midi2 at umidi0: <1 >1 on umidi0
>How-To-Repeat:
not sure. i've used ^C a lot of times and it never did this before.
>Fix:
>Audit-Trail:
From: Taylor R Campbell <riastradh@NetBSD.org>
To: mrg@eterna23.net
Cc: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Subject: Re: kern/60332: system crashed when ^C on midiplay hung and i turned the synth off
Date: Mon, 15 Jun 2026 00:38:23 +0000
This is a multi-part message in MIME format.
--=_U+89j2l9CEBqI2aSXBW9qNw7GOwXDlcv
Content-Transfer-Encoding: quoted-printable
Looks like a combination of two issues:
1. Various paths set sc->pbus but don't obviously cv_broadcast
sc->wchan.
2. midi detach path is all kinds of bogus.
First one should be easy to fix (if it is wrong to cv_broadcast -- or
at least cv_signal -- then it is wrong to set sc->pbus =3D 0).
Second one I started to work on a few years ago but didn't get around
to testing, and comments like this one make me suspect a bunch more
work is needed (along the lines of
https://www.NetBSD.org/gallery/presentations/riastradh/eurobsdcon2022/opend=
etach.pdf).
--=_U+89j2l9CEBqI2aSXBW9qNw7GOwXDlcv
Content-Type: text/plain; charset="ISO-8859-1"; name="midipbuswakeup"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="midipbuswakeup.patch"
diff -r 19f84c00a20a sys/dev/midi.c
--- a/sys/dev/midi.c Tue Jun 02 22:13:00 2026 +0000
+++ b/sys/dev/midi.c Mon Jun 15 00:36:11 2026 +0000
@@ -1074,6 +1074,7 @@ midi_xmt_asense(void *arg)
}
if (!armed) {
sc->pbus =3D 0;
+ cv_broadcast(&sc->wchan);
callout_schedule(&sc->xmt_asense_co, MIDI_XMT_ASENSE_PERIOD);
}
mutex_exit(sc->lock);
@@ -1240,6 +1241,7 @@ midi_poll_out(struct midi_softc *sc)
MIDI_BUF_CONSUMER_WBACK(mb,buf);
}
sc->pbus =3D 0;
+ cv_broadcast(&sc->wchan);
callout_schedule(&sc->xmt_asense_co, MIDI_XMT_ASENSE_PERIOD);
return error;
}
--=_U+89j2l9CEBqI2aSXBW9qNw7GOwXDlcv
Content-Type: text/plain; charset="ISO-8859-1"; name="mididetach"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="mididetach.patch"
>From e9452840b638680300b876bb31223f432bbf873e Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Sun, 26 Dec 2021 12:17:30 +0000
Subject: [PATCH 1/4] midi(4): Force devices to close before waiting for ref=
cnt
to drain.
Might even render the refcnt unnecessary, not sure yet.
---
sys/dev/midi.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/sys/dev/midi.c b/sys/dev/midi.c
index 6710c3a6dcca..6e644f23c6ec 100644
--- a/sys/dev/midi.c
+++ b/sys/dev/midi.c
@@ -208,14 +208,6 @@ mididetach(device_t self, int flags)
sc->dying =3D 1;
cv_broadcast(&sc->wchan);
cv_broadcast(&sc->rchan);
-
- if (--sc->refcnt >=3D 0) {
- (void)cv_timedwait(&sc->detach_cv, sc->lock, hz * 60);
- if (sc->refcnt >=3D 0) {
- aprint_error_dev(self, "refcnt failed to drain,"
- " bashing my brains out anyway\n");
- }
- }
mutex_exit(sc->lock);
=20
/* locate the major number */
@@ -232,6 +224,16 @@ mididetach(device_t self, int flags)
mn =3D device_unit(self);
vdevgone(maj, mn, mn, VCHR);
=20
+ mutex_enter(sc->lock);
+ if (--sc->refcnt >=3D 0) {
+ (void)cv_timedwait(&sc->detach_cv, sc->lock, hz * 60);
+ if (sc->refcnt >=3D 0) {
+ aprint_error_dev(self, "refcnt failed to drain,"
+ " bashing my brains out anyway\n");
+ }
+ }
+ mutex_exit(sc->lock);
+
if (!(sc->props & MIDI_PROP_NO_OUTPUT)) {
evcnt_detach(&sc->xmt.bytesDiscarded);
evcnt_detach(&sc->xmt.incompleteMessages);
>From c47e7566d2458cc868951e9dd1853b54cf612904 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Sun, 26 Dec 2021 12:19:50 +0000
Subject: [PATCH 2/4] umidi(4): Omit needless reference counting.
Detaching the mididevs waits for these operations to complete anyway,
so there's no need for another layer of reference counting.
---
sys/dev/usb/umidi.c | 21 +--------------------
1 file changed, 1 insertion(+), 20 deletions(-)
diff --git a/sys/dev/usb/umidi.c b/sys/dev/usb/umidi.c
index 2dccf19a6f31..ef5a32302ce8 100644
--- a/sys/dev/usb/umidi.c
+++ b/sys/dev/usb/umidi.c
@@ -209,9 +209,6 @@ struct umidi_softc {
=20
kmutex_t sc_lock;
kcondvar_t sc_cv;
- kcondvar_t sc_detach_cv;
-
- int sc_refcnt;
};
=20
#ifdef UMIDI_DEBUG
@@ -365,8 +362,6 @@ umidi_attach(device_t parent, device_t self, void *aux)
=20
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
cv_init(&sc->sc_cv, "umidopcl");
- cv_init(&sc->sc_detach_cv, "umidetcv");
- sc->sc_refcnt =3D 0;
=20
err =3D alloc_all_endpoints(sc);
if (err !=3D USBD_NORMAL_COMPLETION) {
@@ -459,9 +454,6 @@ umidi_detach(device_t self, int flags)
=20
mutex_enter(&sc->sc_lock);
sc->sc_dying =3D 1;
- if (--sc->sc_refcnt >=3D 0)
- if (cv_timedwait(&sc->sc_detach_cv, &sc->sc_lock, hz * 60))
- aprint_error_dev(self, ": didn't detach\n");
mutex_exit(&sc->sc_lock);
=20
detach_all_mididevs(sc, flags);
@@ -472,7 +464,6 @@ umidi_detach(device_t self, int flags)
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
=20
mutex_destroy(&sc->sc_lock);
- cv_destroy(&sc->sc_detach_cv);
cv_destroy(&sc->sc_cv);
=20
return 0;
@@ -531,7 +522,7 @@ void
umidi_close(void *addr)
{
struct umidi_mididev *mididev =3D addr;
- struct umidi_softc *sc =3D mididev->sc;
+ struct umidi_softc *sc __diagused =3D mididev->sc;
=20
KASSERT(mutex_owned(&sc->sc_lock));
=20
@@ -540,16 +531,11 @@ umidi_close(void *addr)
=20
mididev->closing =3D 1;
=20
- sc->sc_refcnt++;
-
if ((mididev->flags & FWRITE) && mididev->out_jack)
close_out_jack(mididev->out_jack);
if ((mididev->flags & FREAD) && mididev->in_jack)
close_in_jack(mididev->in_jack);
=20
- if (--sc->sc_refcnt < 0)
- cv_broadcast(&sc->sc_detach_cv);
-
mididev->opened =3D 0;
mididev->closing =3D 0;
}
@@ -1754,8 +1740,6 @@ out_jack_output(struct umidi_jack *out_jack, u_char *=
src, int len, int cin)
if (!out_jack->opened)
return ENODEV; /* XXX as it was, is this the right errno? */
=20
- sc->sc_refcnt++;
-
#ifdef UMIDI_DEBUG
if (umididebug >=3D 100)
microtime(&umidi_tv);
@@ -1814,9 +1798,6 @@ out_jack_output(struct umidi_jack *out_jack, u_char *=
src, int len, int cin)
kpreempt_enable();
}
=20
- if (--sc->sc_refcnt < 0)
- cv_broadcast(&sc->sc_detach_cv);
-
return 0;
}
=20
>From c80fc9a00fff9723d4027cb115789f87b875dd61 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Sun, 26 Dec 2021 12:22:13 +0000
Subject: [PATCH 3/4] umidi(4): Read sc_dying only under the lock.
---
sys/dev/usb/umidi.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/sys/dev/usb/umidi.c b/sys/dev/usb/umidi.c
index ef5a32302ce8..894d4f73bc5a 100644
--- a/sys/dev/usb/umidi.c
+++ b/sys/dev/usb/umidi.c
@@ -1815,10 +1815,14 @@ in_intr(struct usbd_xfer *xfer, void *priv,
unsigned char *data;
uint32_t count;
=20
- if (ep->sc->sc_dying || !ep->num_open)
+ if (!ep->num_open)
return;
=20
mutex_enter(&sc->sc_lock);
+ if (sc->sc_dying) {
+ mutex_exit(&sc->sc_lock);
+ return;
+ }
usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
if (0 =3D=3D count % UMIDI_PACKET_SIZE) {
DPRINTFN(200,("%s: input endpoint %p transfer length %u\n",
@@ -1884,10 +1888,11 @@ out_intr(struct usbd_xfer *xfer, void *priv,
struct umidi_softc *sc =3D ep->sc;
uint32_t count;
=20
- if (sc->sc_dying)
- return;
-
mutex_enter(&sc->sc_lock);
+ if (sc->sc_dying) {
+ mutex_exit(&sc->sc_lock);
+ return;
+ }
#ifdef UMIDI_DEBUG
if (umididebug >=3D 200)
microtime(&umidi_tv);
>From 36a62333fb44e8a584117429e2ff63e33f59e9e2 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Mon, 1 May 2023 10:00:05 +0000
Subject: [PATCH 4/4] midi(4): Make sure open failure doesn't leave the state
open.
---
sys/dev/midi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sys/dev/midi.c b/sys/dev/midi.c
index 6e644f23c6ec..027a868064ef 100644
--- a/sys/dev/midi.c
+++ b/sys/dev/midi.c
@@ -849,7 +849,7 @@ midiopen(dev_t dev, int flags, int ifmt, struct lwp *l)
sc->rcv_expect_asense =3D 0;
sc->rcv_quiescent =3D 0;
sc->rcv_eof =3D 0;
- sc->isopen++;
+ sc->isopen =3D 1;
sc->flags =3D flags;
sc->pbus =3D 0;
sc->async =3D 0;
@@ -863,6 +863,8 @@ midiopen(dev_t dev, int flags, int ifmt, struct lwp *l)
=20
error =3D hw->open(sc->hw_hdl, flags, midi_in, midi_out, sc);
if (error) {
+ KASSERT(sc->sc_isopen =3D=3D 1);
+ sc->isopen =3D 0;
mutex_exit(sc->lock);
return error;
}
--=_U+89j2l9CEBqI2aSXBW9qNw7GOwXDlcv--
From: Taylor R Campbell <riastradh@NetBSD.org>
To: mrg@eterna23.net
Cc: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Subject: Re: kern/60332: system crashed when ^C on midiplay hung and i turned the synth off
Date: Mon, 15 Jun 2026 00:42:13 +0000
> Date: Mon, 15 Jun 2026 00:38:23 +0000
> From: Taylor R Campbell <riastradh@NetBSD.org>
>=20
> Second one I started to work on a few years ago but didn't get around
> to testing, and comments like this one make me suspect a bunch more
> work is needed (along the lines of
> https://www.NetBSD.org/gallery/presentations/riastradh/eurobsdcon2022/ope=
ndetach.pdf).
Comments like this one, I mean:
224 /*
225 * Nuke the vnodes for any open instances (calls close).
226 * Will wait until any activity on the device nodes has ceased.
227 *
228 * XXXAD NOT YET.
229 *
230 * XXXAD NEED TO PREVENT NEW REFERENCES THROUGH AUDIO_ENTER().
231 */
232 mn =3D device_unit(self);
233 vdevgone(maj, mn, mn, VCHR);
https://nxr.NetBSD.org/xref/src/sys/dev/midi.c?r=3D1.101#224
(Contact us)
$NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.