From c01281df89b45efb13e61d928aa67e011c7606c9 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Thu, 3 Jun 2021 23:28:14 +0000 Subject: [PATCH] Revert "audio(4): Insert mixers and audioctls into sc_files on open too." This change was incomplete: it needs to do audio_track_drain _before_ removing the file from sc_files; otherwise closing /dev/audio hangs waiting for a wakeup from a hardware interrupt that will never come because it only gets delivered to files listed in sc_files. --- sys/dev/audio/audio.c | 45 +++++++------------------------------------ 1 file changed, 7 insertions(+), 38 deletions(-) diff --git a/sys/dev/audio/audio.c b/sys/dev/audio/audio.c index b74fd417e579..6637211340b1 100644 --- a/sys/dev/audio/audio.c +++ b/sys/dev/audio/audio.c @@ -1343,19 +1343,11 @@ audiodetach(device_t self, int flags) /* * Clean up all open instances. + * Here, we no longer need any locks to traverse sc_files. */ - mutex_enter(sc->sc_lock); while ((file = SLIST_FIRST(&sc->sc_files)) != NULL) { - mutex_enter(sc->sc_intr_lock); - SLIST_REMOVE_HEAD(&sc->sc_files, entry); - mutex_exit(sc->sc_intr_lock); - if (file->ptrack || file->rtrack) { - mutex_exit(sc->sc_lock); - audio_unlink(sc, file); - mutex_enter(sc->sc_lock); - } + audio_unlink(sc, file); } - mutex_exit(sc->sc_lock); pmf_event_deregister(self, PMFE_AUDIO_VOLUME_DOWN, audio_volume_down, true); @@ -1747,11 +1739,6 @@ audioclose(struct file *fp) bound = curlwp_bind(); sc = audio_sc_acquire_fromfile(file, &sc_ref); if (sc) { - mutex_enter(sc->sc_lock); - mutex_enter(sc->sc_intr_lock); - SLIST_REMOVE(&sc->sc_files, file, audio_file, entry); - mutex_exit(sc->sc_intr_lock); - mutex_exit(sc->sc_lock); switch (AUDIODEV(dev)) { case SOUND_DEVICE: case AUDIO_DEVICE: @@ -2609,6 +2596,10 @@ audio_unlink(struct audio_softc *sc, audio_file_t *file) device_active(sc->sc_dev, DVA_SYSTEM); + mutex_enter(sc->sc_intr_lock); + SLIST_REMOVE(&sc->sc_files, file, audio_file, entry); + mutex_exit(sc->sc_intr_lock); + if (file->ptrack) { TRACET(3, file->ptrack, "dropframes=%" PRIu64, file->ptrack->dropframes); @@ -3524,17 +3515,7 @@ audioctl_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt, af->sc = sc; af->dev = dev; - mutex_enter(sc->sc_lock); - if (sc->sc_dying) { - mutex_exit(sc->sc_lock); - kmem_free(af, sizeof(*af)); - fd_abort(curproc, fp, fd); - return ENXIO; - } - mutex_enter(sc->sc_intr_lock); - SLIST_INSERT_HEAD(&sc->sc_files, af, entry); - mutex_exit(sc->sc_intr_lock); - mutex_exit(sc->sc_lock); + /* Not necessary to insert sc_files. */ error = fd_clone(fp, fd, flags, &audio_fileops, af); KASSERTMSG(error == EMOVEFD, "error=%d", error); @@ -8150,18 +8131,6 @@ mixer_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt, af->sc = sc; af->dev = dev; - mutex_enter(sc->sc_lock); - if (sc->sc_dying) { - mutex_exit(sc->sc_lock); - kmem_free(af, sizeof(*af)); - fd_abort(curproc, fp, fd); - return ENXIO; - } - mutex_enter(sc->sc_intr_lock); - SLIST_INSERT_HEAD(&sc->sc_files, af, entry); - mutex_exit(sc->sc_intr_lock); - mutex_exit(sc->sc_lock); - error = fd_clone(fp, fd, flags, &audio_fileops, af); KASSERT(error == EMOVEFD);