diff mbox series

ASoC: hdac_hda: Fix unbalanced bus link refcount at probe error

Message ID 20190531143820.10142-1-tiwai@suse.de (mailing list archive)
State New, archived
Headers show
Series ASoC: hdac_hda: Fix unbalanced bus link refcount at probe error | expand

Commit Message

Takashi Iwai May 31, 2019, 2:38 p.m. UTC
The error paths in hdac_hda_codec_probe() don't take care of the bus
link refcount properly, which leave the refcount still high.
This patch addresses them.

Fixes: 6bae5ea94989 ("ASoC: hdac_hda: add asoc extension for legacy HDA codec drivers")
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---

A bug I found while digging for another problem :)

 sound/soc/codecs/hdac_hda.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

Comments

Ranjani Sridharan May 31, 2019, 3:31 p.m. UTC | #1
On Fri, 2019-05-31 at 16:38 +0200, Takashi Iwai wrote:
> The error paths in hdac_hda_codec_probe() don't take care of the bus
> link refcount properly, which leave the refcount still high.
> This patch addresses them.
Hi Takashi,

Thanks for this. But I looked into hdac_hdmi probe and we have a
similar problem there as well. 

Thanks,
Ranjani


> Fixes: 6bae5ea94989 ("ASoC: hdac_hda: add asoc extension for legacy
> HDA codec drivers")
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> ---
> 
> A bug I found while digging for another problem :)
> 
>  sound/soc/codecs/hdac_hda.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/sound/soc/codecs/hdac_hda.c
> b/sound/soc/codecs/hdac_hda.c
> index 7d4940256914..b55deaeb1ebf 100644
> --- a/sound/soc/codecs/hdac_hda.c
> +++ b/sound/soc/codecs/hdac_hda.c
> @@ -475,8 +475,10 @@ static int hdac_hda_dev_probe(struct hdac_device
> *hdev)
>  	snd_hdac_ext_bus_link_get(hdev->bus, hlink);
>  
>  	hda_pvt = hdac_to_hda_priv(hdev);
> -	if (!hda_pvt)
> -		return -ENOMEM;
> +	if (!hda_pvt) {
> +		ret = -ENOMEM;
> +		goto error;
> +	}
>  
>  	/* ASoC specific initialization */
>  	ret = devm_snd_soc_register_component(&hdev->dev,
> @@ -484,12 +486,13 @@ static int hdac_hda_dev_probe(struct
> hdac_device *hdev)
>  					 ARRAY_SIZE(hdac_hda_dais));
>  	if (ret < 0) {
>  		dev_err(&hdev->dev, "failed to register HDA codec
> %d\n", ret);
> -		return ret;
> +		goto error;
>  	}
>  
>  	dev_set_drvdata(&hdev->dev, hda_pvt);
> -	snd_hdac_ext_bus_link_put(hdev->bus, hlink);
>  
> + error:
> +	snd_hdac_ext_bus_link_put(hdev->bus, hlink);
>  	return ret;
>  }
>
Takashi Iwai May 31, 2019, 3:43 p.m. UTC | #2
On Fri, 31 May 2019 17:31:10 +0200,
Ranjani Sridharan wrote:
> 
> On Fri, 2019-05-31 at 16:38 +0200, Takashi Iwai wrote:
> > The error paths in hdac_hda_codec_probe() don't take care of the bus
> > link refcount properly, which leave the refcount still high.
> > This patch addresses them.
> Hi Takashi,
> 
> Thanks for this. But I looked into hdac_hdmi probe and we have a
> similar problem there as well. 

Well, hdac_hdmi is a bit different.  It seems managing the link at
runtime PM.  The link put is called at suspend, while get again at
resume.

What I'm not sure for now is whether it's safe to assume the device
being suspended at the driver removal.  If this is always correct, the
link put should have been called already by runtime suspend at removal
time.

Still the code is a bit too fragile, yeah...


Takashi
diff mbox series

Patch

diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c
index 7d4940256914..b55deaeb1ebf 100644
--- a/sound/soc/codecs/hdac_hda.c
+++ b/sound/soc/codecs/hdac_hda.c
@@ -475,8 +475,10 @@  static int hdac_hda_dev_probe(struct hdac_device *hdev)
 	snd_hdac_ext_bus_link_get(hdev->bus, hlink);
 
 	hda_pvt = hdac_to_hda_priv(hdev);
-	if (!hda_pvt)
-		return -ENOMEM;
+	if (!hda_pvt) {
+		ret = -ENOMEM;
+		goto error;
+	}
 
 	/* ASoC specific initialization */
 	ret = devm_snd_soc_register_component(&hdev->dev,
@@ -484,12 +486,13 @@  static int hdac_hda_dev_probe(struct hdac_device *hdev)
 					 ARRAY_SIZE(hdac_hda_dais));
 	if (ret < 0) {
 		dev_err(&hdev->dev, "failed to register HDA codec %d\n", ret);
-		return ret;
+		goto error;
 	}
 
 	dev_set_drvdata(&hdev->dev, hda_pvt);
-	snd_hdac_ext_bus_link_put(hdev->bus, hlink);
 
+ error:
+	snd_hdac_ext_bus_link_put(hdev->bus, hlink);
 	return ret;
 }