Module Name: src Committed By: isaki Date: Thu Aug 29 13:01:07 UTC 2019
Modified Files: src/sys/dev/audio: audio.c audiovar.h Log Message: Fix lock assertion on async I/O mode. psignal() must be called without any spin locks. Thanks maxv@! To generate a diff of this commit: cvs rdiff -u -r1.29 -r1.30 src/sys/dev/audio/audio.c cvs rdiff -u -r1.4 -r1.5 src/sys/dev/audio/audiovar.h 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.29 src/sys/dev/audio/audio.c:1.30 --- src/sys/dev/audio/audio.c:1.29 Fri Aug 23 09:41:26 2019 +++ src/sys/dev/audio/audio.c Thu Aug 29 13:01:07 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: audio.c,v 1.29 2019/08/23 09:41:26 maxv Exp $ */ +/* $NetBSD: audio.c,v 1.30 2019/08/29 13:01:07 isaki Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -142,7 +142,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.29 2019/08/23 09:41:26 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.30 2019/08/29 13:01:07 isaki Exp $"); #ifdef _KERNEL_OPT #include "audio.h" @@ -5730,6 +5730,36 @@ audio_track_drain(struct audio_softc *sc } /* + * Send signal to process. + * This is intended to be called only from audio_softintr_{rd,wr}. + * Must be called with sc_lock && sc_intr_lock held. + */ +static inline void +audio_psignal(struct audio_softc *sc, pid_t pid, int signum) +{ + proc_t *p; + + KASSERT(mutex_owned(sc->sc_lock)); + KASSERT(mutex_owned(sc->sc_intr_lock)); + KASSERT(pid != 0); + + /* + * psignal() must be called without spin lock held. + * So leave intr_lock temporarily here. + */ + mutex_exit(sc->sc_intr_lock); + + mutex_enter(proc_lock); + p = proc_find(pid); + if (p) + psignal(p, signum); + mutex_exit(proc_lock); + + /* Enter intr_lock again */ + mutex_enter(sc->sc_intr_lock); +} + +/* * This is software interrupt handler for record. * It is called from recording hardware interrupt everytime. * It does: @@ -5747,7 +5777,6 @@ audio_softintr_rd(void *cookie) { struct audio_softc *sc = cookie; audio_file_t *f; - proc_t *p; pid_t pid; mutex_enter(sc->sc_lock); @@ -5767,10 +5796,7 @@ audio_softintr_rd(void *cookie) pid = f->async_audio; if (pid != 0) { TRACEF(4, f, "sending SIGIO %d", pid); - mutex_enter(proc_lock); - if ((p = proc_find(pid)) != NULL) - psignal(p, SIGIO); - mutex_exit(proc_lock); + audio_psignal(sc, pid, SIGIO); } } mutex_exit(sc->sc_intr_lock); @@ -5799,7 +5825,6 @@ audio_softintr_wr(void *cookie) struct audio_softc *sc = cookie; audio_file_t *f; bool found; - proc_t *p; pid_t pid; TRACE(4, "called"); @@ -5826,14 +5851,13 @@ audio_softintr_wr(void *cookie) */ if (track->usrbuf.used <= track->usrbuf_usedlow && !track->is_pause) { + /* For selnotify */ found = true; + /* For SIGIO */ pid = f->async_audio; if (pid != 0) { TRACEF(4, f, "sending SIGIO %d", pid); - mutex_enter(proc_lock); - if ((p = proc_find(pid)) != NULL) - psignal(p, SIGIO); - mutex_exit(proc_lock); + audio_psignal(sc, pid, SIGIO); } } } Index: src/sys/dev/audio/audiovar.h diff -u src/sys/dev/audio/audiovar.h:1.4 src/sys/dev/audio/audiovar.h:1.5 --- src/sys/dev/audio/audiovar.h:1.4 Wed Jun 26 06:57:45 2019 +++ src/sys/dev/audio/audiovar.h Thu Aug 29 13:01:07 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: audiovar.h,v 1.4 2019/06/26 06:57:45 isaki Exp $ */ +/* $NetBSD: audiovar.h,v 1.5 2019/08/29 13:01:07 isaki Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -149,7 +149,8 @@ struct audio_softc { /* * List of opened descriptors. - * Must be protected by sc_intr_lock. + * Must be protected by sc_lock || sc_intr_lock for traversal(FOREACH). + * Must be protected by sc_lock && sc_intr_lock for insertion/removal. */ SLIST_HEAD(, audio_file) sc_files;