diff options
| author | isaki <isaki@NetBSD.org> | 2021-02-09 05:53:14 +0000 |
|---|---|---|
| committer | isaki <isaki@NetBSD.org> | 2021-02-09 05:53:14 +0000 |
| commit | a4d119aaa8989b79c774990eb78c240bfa9a44e7 (patch) | |
| tree | 17d9d524346e04c2fecefe74cd61290cbe69f6e3 /sys/dev | |
| parent | 6533e6e518e4161f9c547a737bf600daa88afe29 (diff) | |
Change the lock conditions to call audio_unlink().
This can remove a different copy of audio_exlock_enter() in audio_unlink()
and can use normal one. Also, in audiodetach(), this can set the exlock
at more natual order (before calling audio_unlink()).
No noticeable functional changes are intended.
Thanks for comments, riastradh@.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/audio/audio.c | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/sys/dev/audio/audio.c b/sys/dev/audio/audio.c index 540bbdcf94c..b9443b8a816 100644 --- a/sys/dev/audio/audio.c +++ b/sys/dev/audio/audio.c @@ -1,4 +1,4 @@ -/* $NetBSD: audio.c,v 1.88 2021/01/15 05:34:49 isaki Exp $ */ +/* $NetBSD: audio.c,v 1.89 2021/02/09 05:53:14 isaki Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -138,7 +138,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.88 2021/01/15 05:34:49 isaki Exp $"); +__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.89 2021/02/09 05:53:14 isaki Exp $"); #ifdef _KERNEL_OPT #include "audio.h" @@ -1334,9 +1334,10 @@ audiodetach(device_t self, int flags) * that hold sc, and any new calls with files that were for sc will * fail. Thus, we now have exclusive access to the softc. */ + sc->sc_exlock = 1; /* - * Nuke all open instances. + * Clean up all open instances. * Here, we no longer need any locks to traverse sc_files. */ while ((file = SLIST_FIRST(&sc->sc_files)) != NULL) { @@ -1359,7 +1360,6 @@ audiodetach(device_t self, int flags) pmf_device_deregister(self); /* Free resources */ - sc->sc_exlock = 1; if (sc->sc_pmixer) { audio_mixer_destroy(sc, sc->sc_pmixer); kmem_free(sc->sc_pmixer, sizeof(*sc->sc_pmixer)); @@ -2396,6 +2396,7 @@ bad: int audio_close(struct audio_softc *sc, audio_file_t *file) { + int error; /* Protect entering new fileops to this file */ atomic_store_relaxed(&file->dying, true); @@ -2410,12 +2411,27 @@ audio_close(struct audio_softc *sc, audio_file_t *file) mutex_exit(sc->sc_lock); } - return audio_unlink(sc, file); + error = audio_exlock_enter(sc); + if (error) { + /* + * If EIO, this sc is about to detach. In this case, even if + * we don't do subsequent _unlink(), audiodetach() will do it. + */ + if (error == EIO) + return error; + + /* XXX This should not happen but what should I do ? */ + panic("%s: can't acquire exlock: errno=%d", __func__, error); + } + error = audio_unlink(sc, file); + audio_exlock_exit(sc); + + return error; } /* * Unlink this file, but not freeing memory here. - * Must be called without sc_lock nor sc_exlock held. + * Must be called with sc_exlock held and without sc_lock held. */ int audio_unlink(struct audio_softc *sc, audio_file_t *file) @@ -2432,25 +2448,6 @@ audio_unlink(struct audio_softc *sc, audio_file_t *file) "sc->sc_popens=%d, sc->sc_ropens=%d", sc->sc_popens, sc->sc_ropens); - /* - * Acquire exlock to protect counters. - * audio_exlock_enter() cannot be used here because we have to go - * forward even if sc_dying is set. - */ - while (__predict_false(sc->sc_exlock != 0)) { - error = cv_timedwait_sig(&sc->sc_exlockcv, sc->sc_lock, - mstohz(AUDIO_TIMEOUT)); - /* XXX what should I do on error? */ - if (error == EWOULDBLOCK) { - mutex_exit(sc->sc_lock); - audio_printf(sc, - "%s: cv_timedwait_sig failed: errno=%d\n", - __func__, error); - return error; - } - } - sc->sc_exlock = 1; - device_active(sc->sc_dev, DVA_SYSTEM); mutex_enter(sc->sc_intr_lock); @@ -2517,7 +2514,6 @@ audio_unlink(struct audio_softc *sc, audio_file_t *file) kauth_cred_free(sc->sc_cred); TRACE(3, "done"); - audio_exlock_exit(sc); return 0; } |
