Browse Source

ALSA: isight: fix locking

Lockdep complains about conflicts between isight->mutex,
ALSA's register_mutex, mm->mmap_sem, and pcm->open_mutex.

This can be fixed by moving the calls to isight_pcm_abort(),
snd_card_disconnect(), and fw_iso_resources_update() out of
isight->mutex.  These functions are designed to be called
asynchronously; the mutex needs to protect only the device
streaming state modified by isight_start/stop_streaming().

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Reported-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Clemens Ladisch 14 years ago
parent
commit
f3f7c1837f
1 changed files with 6 additions and 3 deletions
  1. 6 3
      sound/firewire/isight.c

+ 6 - 3
sound/firewire/isight.c

@@ -692,9 +692,11 @@ static int isight_remove(struct device *dev)
 {
 {
 	struct isight *isight = dev_get_drvdata(dev);
 	struct isight *isight = dev_get_drvdata(dev);
 
 
-	mutex_lock(&isight->mutex);
 	isight_pcm_abort(isight);
 	isight_pcm_abort(isight);
+
 	snd_card_disconnect(isight->card);
 	snd_card_disconnect(isight->card);
+
+	mutex_lock(&isight->mutex);
 	isight_stop_streaming(isight);
 	isight_stop_streaming(isight);
 	mutex_unlock(&isight->mutex);
 	mutex_unlock(&isight->mutex);
 
 
@@ -707,12 +709,13 @@ static void isight_bus_reset(struct fw_unit *unit)
 {
 {
 	struct isight *isight = dev_get_drvdata(&unit->device);
 	struct isight *isight = dev_get_drvdata(&unit->device);
 
 
-	mutex_lock(&isight->mutex);
 	if (fw_iso_resources_update(&isight->resources) < 0) {
 	if (fw_iso_resources_update(&isight->resources) < 0) {
 		isight_pcm_abort(isight);
 		isight_pcm_abort(isight);
+
+		mutex_lock(&isight->mutex);
 		isight_stop_streaming(isight);
 		isight_stop_streaming(isight);
+		mutex_unlock(&isight->mutex);
 	}
 	}
-	mutex_unlock(&isight->mutex);
 }
 }
 
 
 static const struct ieee1394_device_id isight_id_table[] = {
 static const struct ieee1394_device_id isight_id_table[] = {