Module Name:    src
Committed By:   mrg
Date:           Fri Apr  6 06:15:14 UTC 2012

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

Log Message:
don't hold the thread lock while calling allocm() or freem().  fixes PR#46121


To generate a diff of this commit:
cvs rdiff -u -r1.259 -r1.260 src/sys/dev/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.c
diff -u src/sys/dev/audio.c:1.259 src/sys/dev/audio.c:1.260
--- src/sys/dev/audio.c:1.259	Mon Mar 26 18:26:10 2012
+++ src/sys/dev/audio.c	Fri Apr  6 06:15:13 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: audio.c,v 1.259 2012/03/26 18:26:10 mrg Exp $	*/
+/*	$NetBSD: audio.c,v 1.260 2012/04/06 06:15:13 mrg Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -155,7 +155,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.259 2012/03/26 18:26:10 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.260 2012/04/06 06:15:13 mrg Exp $");
 
 #include "audio.h"
 #if NAUDIO > 0
@@ -390,6 +390,7 @@ audioattach(device_t parent, device_t se
 	mixer_devinfo_t mi;
 	int iclass, mclass, oclass, rclass, props;
 	int record_master_found, record_source_found;
+	bool can_capture, can_playback;
 
 	sc = device_private(self);
 	sc->dev = self;
@@ -452,32 +453,27 @@ audioattach(device_t parent, device_t se
 	aprint_naive("\n");
 	aprint_normal("\n");
 
-	/*
-	 * XXX  Would like to not hold the sc_lock around this whole block
-	 * escpially for audio_alloc_ring(), except that the latter calls
-	 * ->round_blocksize() which demands the thread lock to be taken.
-	 *
-	 * Revisit.
-	 */
 	mutex_enter(sc->sc_lock);
-	if (audio_can_playback(sc)) {
+	can_playback = audio_can_playback(sc);
+	can_capture = audio_can_capture(sc);
+ 	mutex_exit(sc->sc_lock);
+
+	if (can_playback) {
 		error = audio_alloc_ring(sc, &sc->sc_pr,
 		    AUMODE_PLAY, AU_RING_SIZE);
 		if (error) {
 			sc->hw_if = NULL;
- 			mutex_exit(sc->sc_lock);
 			aprint_error("audio: could not allocate play buffer\n");
 			return;
 		}
 	}
-	if (audio_can_capture(sc)) {
+	if (can_capture) {
 		error = audio_alloc_ring(sc, &sc->sc_rr,
 		    AUMODE_RECORD, AU_RING_SIZE);
 		if (error) {
 			if (sc->sc_pr.s.start != 0)
 				audio_free_ring(sc, &sc->sc_pr);
 			sc->hw_if = NULL;
- 			mutex_exit(sc->sc_lock);
 			aprint_error("audio: could not allocate record buffer\n");
 			return;
 		}
@@ -485,6 +481,7 @@ audioattach(device_t parent, device_t se
 
 	sc->sc_lastgain = 128;
 
+	mutex_enter(sc->sc_lock);
 	error = audio_set_defaults(sc, 0);
 	mutex_exit(sc->sc_lock);
 	if (error != 0) {
@@ -885,8 +882,11 @@ audio_alloc_ring(struct audio_softc *sc,
 	if (bufsize < AUMINBUF)
 		bufsize = AUMINBUF;
 	ROUNDSIZE(bufsize);
-	if (hw->round_buffersize)
+	if (hw->round_buffersize) {
+		mutex_enter(sc->sc_lock);
 		bufsize = hw->round_buffersize(hdl, direction, bufsize);
+ 		mutex_exit(sc->sc_lock);
+	}
 	if (hw->allocm)
 		r->s.start = hw->allocm(hdl, direction, bufsize);
 	else

Reply via email to