Module Name: src Committed By: riastradh Date: Sun Oct 10 11:20:29 UTC 2021
Modified Files: src/sys/dev/audio: audio.c Log Message: audio(9): Call hw_if->getdev without sc_lock. Holding sc_lock is not necessary -- I reviewed all ~70 cases in-tree, and none of them rely on state protected by sc_lock. Essentially everything just copies from static data or data initialized at attach time. (Exceptions: tms320av110.c issues a bus_space_read_1, but I don't see any reason why that needs to be serialized; and uaudio.c reads from sc_dying, but that's not necessary and also not protected by sc_lock anyway.) Holding sc_lock is harmful because at least hdafg(4) can trigger module autoload that leads to pserialize_perform, which waits for logic to run at softint serial on all CPUs; at the same time, audio_softintr_rd/wr run at softint serial and take sc_lock, so this leads to deadlock. To generate a diff of this commit: cvs rdiff -u -r1.108 -r1.109 src/sys/dev/audio/audio.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/audio/audio.c diff -u src/sys/dev/audio/audio.c:1.108 src/sys/dev/audio/audio.c:1.109 --- src/sys/dev/audio/audio.c:1.108 Sun Sep 26 01:16:08 2021 +++ src/sys/dev/audio/audio.c Sun Oct 10 11:20:29 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: audio.c,v 1.108 2021/09/26 01:16:08 thorpej Exp $ */ +/* $NetBSD: audio.c,v 1.109 2021/10/10 11:20:29 riastradh Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -114,7 +114,7 @@ * halt_output x x + * halt_input x x + * speaker_ctl x x - * getdev - x + * getdev - - * set_port - x + * get_port - x + * query_devinfo - x @@ -138,7 +138,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.108 2021/09/26 01:16:08 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.109 2021/10/10 11:20:29 riastradh Exp $"); #ifdef _KERNEL_OPT #include "audio.h" @@ -3113,9 +3113,7 @@ audio_ioctl(dev_t dev, struct audio_soft break; case AUDIO_GETDEV: - mutex_enter(sc->sc_lock); error = sc->hw_if->getdev(sc->hw_hdl, (audio_device_t *)addr); - mutex_exit(sc->sc_lock); break; case AUDIO_GETENC: @@ -8291,9 +8289,7 @@ mixer_ioctl(struct audio_softc *sc, u_lo case AUDIO_GETDEV: TRACE(2, "AUDIO_GETDEV"); - mutex_enter(sc->sc_lock); error = sc->hw_if->getdev(sc->hw_hdl, (audio_device_t *)addr); - mutex_exit(sc->sc_lock); break; case AUDIO_MIXER_DEVINFO: