Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/audio Fix lock assertion on async I/O mode.



details:   https://anonhg.NetBSD.org/src/rev/b9eea8442e74
branches:  trunk
changeset: 453855:b9eea8442e74
user:      isaki <isaki%NetBSD.org@localhost>
date:      Thu Aug 29 13:01:07 2019 +0000

description:
Fix lock assertion on async I/O mode.
psignal() must be called without any spin locks.
Thanks maxv@!

diffstat:

 sys/dev/audio/audio.c    |  48 ++++++++++++++++++++++++++++++++++++------------
 sys/dev/audio/audiovar.h |   5 +++--
 2 files changed, 39 insertions(+), 14 deletions(-)

diffs (120 lines):

diff -r 23e6cb632a17 -r b9eea8442e74 sys/dev/audio/audio.c
--- a/sys/dev/audio/audio.c     Thu Aug 29 11:45:29 2019 +0000
+++ b/sys/dev/audio/audio.c     Thu Aug 29 13:01:07 2019 +0000
@@ -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 @@
 }
 
 /*
+ * 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 @@
 {
        struct audio_softc *sc = cookie;
        audio_file_t *f;
-       proc_t *p;
        pid_t pid;
 
        mutex_enter(sc->sc_lock);
@@ -5767,10 +5796,7 @@
                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 @@
        struct audio_softc *sc = cookie;
        audio_file_t *f;
        bool found;
-       proc_t *p;
        pid_t pid;
 
        TRACE(4, "called");
@@ -5826,14 +5851,13 @@
                 */
                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);
                        }
                }
        }
diff -r 23e6cb632a17 -r b9eea8442e74 sys/dev/audio/audiovar.h
--- a/sys/dev/audio/audiovar.h  Thu Aug 29 11:45:29 2019 +0000
+++ b/sys/dev/audio/audiovar.h  Thu Aug 29 13:01:07 2019 +0000
@@ -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 @@
 
        /*
         * 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;
 



Home | Main Index | Thread Index | Old Index