Takashi Iwai adc465
From 678c5b119307c40f9a17152512f9c949d0ec7292 Mon Sep 17 00:00:00 2001
Takashi Iwai adc465
From: Tuomas Tynkkynen <tuomas@tuxera.com>
Takashi Iwai adc465
Date: Fri, 13 Jul 2018 00:54:17 +0300
Takashi Iwai adc465
Subject: [PATCH] staging: bcm2835-audio: Don't leak workqueue if open fails
Takashi Iwai adc465
Git-commit: 678c5b119307c40f9a17152512f9c949d0ec7292
Takashi Iwai adc465
Patch-mainline: v4.19-rc1
Takashi Iwai adc465
References: FATE#324827
Takashi Iwai adc465
Takashi Iwai adc465
Currently, if bcm2835_audio_open() fails partway, the allocated
Takashi Iwai adc465
workqueue is leaked. Avoid that.
Takashi Iwai adc465
Takashi Iwai adc465
While at it, propagate the return value of
Takashi Iwai adc465
bcm2835_audio_open_connection() on failure instead of returning -1.
Takashi Iwai adc465
Takashi Iwai adc465
Signed-off-by: Tuomas Tynkkynen <tuomas@tuxera.com>
Takashi Iwai adc465
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Takashi Iwai adc465
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai adc465
Takashi Iwai adc465
---
Takashi Iwai adc465
 drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c |   16 +++++++-----
Takashi Iwai adc465
 1 file changed, 10 insertions(+), 6 deletions(-)
Takashi Iwai adc465
Takashi Iwai adc465
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
Takashi Iwai adc465
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
Takashi Iwai adc465
@@ -428,16 +428,16 @@ int bcm2835_audio_open(struct bcm2835_al
Takashi Iwai adc465
 		return -ENOMEM;
Takashi Iwai adc465
 
Takashi Iwai adc465
 	ret = bcm2835_audio_open_connection(alsa_stream);
Takashi Iwai adc465
-	if (ret) {
Takashi Iwai adc465
-		ret = -1;
Takashi Iwai adc465
-		goto exit;
Takashi Iwai adc465
-	}
Takashi Iwai adc465
+	if (ret)
Takashi Iwai adc465
+		goto free_wq;
Takashi Iwai adc465
+
Takashi Iwai adc465
 	instance = alsa_stream->instance;
Takashi Iwai adc465
 	LOG_DBG(" instance (%p)\n", instance);
Takashi Iwai adc465
 
Takashi Iwai adc465
 	if (mutex_lock_interruptible(&instance->vchi_mutex)) {
Takashi Iwai adc465
 		LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections);
Takashi Iwai adc465
-		return -EINTR;
Takashi Iwai adc465
+		ret = -EINTR;
Takashi Iwai adc465
+		goto free_wq;
Takashi Iwai adc465
 	}
Takashi Iwai adc465
 	vchi_service_use(instance->vchi_handle[0]);
Takashi Iwai adc465
 
Takashi Iwai adc465
@@ -460,7 +460,11 @@ int bcm2835_audio_open(struct bcm2835_al
Takashi Iwai adc465
 unlock:
Takashi Iwai adc465
 	vchi_service_release(instance->vchi_handle[0]);
Takashi Iwai adc465
 	mutex_unlock(&instance->vchi_mutex);
Takashi Iwai adc465
-exit:
Takashi Iwai adc465
+
Takashi Iwai adc465
+free_wq:
Takashi Iwai adc465
+	if (ret)
Takashi Iwai adc465
+		destroy_workqueue(alsa_stream->my_wq);
Takashi Iwai adc465
+
Takashi Iwai adc465
 	return ret;
Takashi Iwai adc465
 }
Takashi Iwai adc465