Module Name:    src
Committed By:   isaki
Date:           Tue Feb  9 05:53:14 UTC 2021

Modified Files:
        src/sys/dev/audio: audio.c

Log Message:
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@.


To generate a diff of this commit:
cvs rdiff -u -r1.88 -r1.89 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.88 src/sys/dev/audio/audio.c:1.89
--- src/sys/dev/audio/audio.c:1.88	Fri Jan 15 05:34:49 2021
+++ src/sys/dev/audio/audio.c	Tue Feb  9 05:53:14 2021
@@ -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, audi
 		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, aud
 	    "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, aud
 		kauth_cred_free(sc->sc_cred);
 
 	TRACE(3, "done");
-	audio_exlock_exit(sc);
 
 	return 0;
 }

Reply via email to