linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] drm/amdgpu: fix multiple memory leaks
@ 2019-09-18 16:09 Navid Emamdoost
  2019-09-18 17:31 ` Koenig, Christian
  0 siblings, 1 reply; 16+ messages in thread
From: Navid Emamdoost @ 2019-09-18 16:09 UTC (permalink / raw)
  Cc: emamd001, smccaman, kjlu, Navid Emamdoost, Alex Deucher,
	Christian König, David (ChunMing) Zhou, David Airlie,
	Daniel Vetter, Rex Zhu, Sam Ravnborg, amd-gfx, dri-devel,
	linux-kernel

In acp_hw_init there are some allocations that needs to be released in
case of failure:

1- adev->acp.acp_genpd should be released if any allocation attemp for
adev->acp.acp_cell, adev->acp.acp_res or i2s_pdata fails.
2- all of those allocations should be released if pm_genpd_add_device
fails.

Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
index eba42c752bca..dd3fa85b11c5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
@@ -231,17 +231,21 @@ static int acp_hw_init(void *handle)
 	adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
 							GFP_KERNEL);
 
-	if (adev->acp.acp_cell == NULL)
+	if (adev->acp.acp_cell == NULL) {
+		kfree(adev->acp.acp_genpd);
 		return -ENOMEM;
+	}
 
 	adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
 	if (adev->acp.acp_res == NULL) {
+		kfree(adev->acp.acp_genpd);
 		kfree(adev->acp.acp_cell);
 		return -ENOMEM;
 	}
 
 	i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
 	if (i2s_pdata == NULL) {
+		kfree(adev->acp.acp_genpd);
 		kfree(adev->acp.acp_res);
 		kfree(adev->acp.acp_cell);
 		return -ENOMEM;
@@ -348,6 +352,10 @@ static int acp_hw_init(void *handle)
 		r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
 		if (r) {
 			dev_err(dev, "Failed to add dev to genpd\n");
+			kfree(adev->acp.acp_genpd);
+			kfree(adev->acp.acp_res);
+			kfree(adev->acp.acp_cell);
+			kfree(i2s_pdata);
 			return r;
 		}
 	}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH] drm/amdgpu: fix multiple memory leaks
  2019-09-18 16:09 [PATCH] drm/amdgpu: fix multiple memory leaks Navid Emamdoost
@ 2019-09-18 17:31 ` Koenig, Christian
  2019-09-18 19:05   ` [PATCH v2] " Navid Emamdoost
  0 siblings, 1 reply; 16+ messages in thread
From: Koenig, Christian @ 2019-09-18 17:31 UTC (permalink / raw)
  To: Navid Emamdoost
  Cc: emamd001, smccaman, kjlu, Deucher, Alexander, Zhou,
	David(ChunMing),
	David Airlie, Daniel Vetter, Rex Zhu, Sam Ravnborg, amd-gfx,
	dri-devel, linux-kernel

Am 18.09.19 um 18:09 schrieb Navid Emamdoost:
> In acp_hw_init there are some allocations that needs to be released in
> case of failure:
>
> 1- adev->acp.acp_genpd should be released if any allocation attemp for
> adev->acp.acp_cell, adev->acp.acp_res or i2s_pdata fails.
> 2- all of those allocations should be released if pm_genpd_add_device
> fails.

Good catch, but please use goto error handling instead of adding more 
and more kfree calls.

Regards,
Christian.

>
> Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 10 +++++++++-
>   1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> index eba42c752bca..dd3fa85b11c5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> @@ -231,17 +231,21 @@ static int acp_hw_init(void *handle)
>   	adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
>   							GFP_KERNEL);
>   
> -	if (adev->acp.acp_cell == NULL)
> +	if (adev->acp.acp_cell == NULL) {
> +		kfree(adev->acp.acp_genpd);
>   		return -ENOMEM;
> +	}
>   
>   	adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
>   	if (adev->acp.acp_res == NULL) {
> +		kfree(adev->acp.acp_genpd);
>   		kfree(adev->acp.acp_cell);
>   		return -ENOMEM;
>   	}
>   
>   	i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
>   	if (i2s_pdata == NULL) {
> +		kfree(adev->acp.acp_genpd);
>   		kfree(adev->acp.acp_res);
>   		kfree(adev->acp.acp_cell);
>   		return -ENOMEM;
> @@ -348,6 +352,10 @@ static int acp_hw_init(void *handle)
>   		r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
>   		if (r) {
>   			dev_err(dev, "Failed to add dev to genpd\n");
> +			kfree(adev->acp.acp_genpd);
> +			kfree(adev->acp.acp_res);
> +			kfree(adev->acp.acp_cell);
> +			kfree(i2s_pdata);
>   			return r;
>   		}
>   	}


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2] drm/amdgpu: fix multiple memory leaks
  2019-09-18 17:31 ` Koenig, Christian
@ 2019-09-18 19:05   ` Navid Emamdoost
  2019-09-18 19:45     ` Sven Van Asbroeck
                       ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Navid Emamdoost @ 2019-09-18 19:05 UTC (permalink / raw)
  To: Christian.Koenig
  Cc: emamd001, smccaman, kjlu, Navid Emamdoost, Alex Deucher,
	Christian König, David (ChunMing) Zhou, David Airlie,
	Daniel Vetter, Rex Zhu, Sam Ravnborg, amd-gfx, dri-devel,
	linux-kernel

In acp_hw_init there are some allocations that needs to be released in
case of failure:

1- adev->acp.acp_genpd should be released if any allocation attemp for
adev->acp.acp_cell, adev->acp.acp_res or i2s_pdata fails.
2- all of those allocations should be released if pm_genpd_add_device
fails.

v2: moved the released into goto error handlings

Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 30 +++++++++++++++++--------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
index eba42c752bca..c0db75b71859 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
@@ -184,7 +184,7 @@ static struct device *get_mfd_cell_dev(const char *device_name, int r)
  */
 static int acp_hw_init(void *handle)
 {
-	int r, i;
+	int r, i, ret;
 	uint64_t acp_base;
 	u32 val = 0;
 	u32 count = 0;
@@ -231,20 +231,21 @@ static int acp_hw_init(void *handle)
 	adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
 							GFP_KERNEL);
 
-	if (adev->acp.acp_cell == NULL)
-		return -ENOMEM;
+	if (adev->acp.acp_cell == NULL) {
+		ret = -ENOMEM;
+		goto out1;
+	}
 
 	adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
 	if (adev->acp.acp_res == NULL) {
-		kfree(adev->acp.acp_cell);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto out2;
 	}
 
 	i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
 	if (i2s_pdata == NULL) {
-		kfree(adev->acp.acp_res);
-		kfree(adev->acp.acp_cell);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto out3;
 	}
 
 	switch (adev->asic_type) {
@@ -348,7 +349,8 @@ static int acp_hw_init(void *handle)
 		r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
 		if (r) {
 			dev_err(dev, "Failed to add dev to genpd\n");
-			return r;
+			ret = r;
+			goto out4;
 		}
 	}
 
@@ -393,6 +395,16 @@ static int acp_hw_init(void *handle)
 	val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
 	cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
 	return 0;
+
+out4:
+	kfree(i2s_pdata);
+out3:
+	kfree(adev->acp.acp_res);
+out2:
+	kfree(adev->acp.acp_cell);
+out1:
+	kfree(adev->acp.acp_genpd);
+	return ret;
 }
 
 /**
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v2] drm/amdgpu: fix multiple memory leaks
  2019-09-18 19:05   ` [PATCH v2] " Navid Emamdoost
@ 2019-09-18 19:45     ` Sven Van Asbroeck
  2019-09-19  8:03     ` Koenig, Christian
  2019-09-27 16:37     ` Markus Elfring
  2 siblings, 0 replies; 16+ messages in thread
From: Sven Van Asbroeck @ 2019-09-18 19:45 UTC (permalink / raw)
  To: Navid Emamdoost
  Cc: Christian.Koenig, emamd001, smccaman, kjlu, Alex Deucher,
	David (ChunMing) Zhou, David Airlie, Daniel Vetter, Rex Zhu,
	Sam Ravnborg, amd-gfx, dri-devel, Linux Kernel Mailing List

On Wed, Sep 18, 2019 at 3:09 PM Navid Emamdoost
<navid.emamdoost@gmail.com> wrote:
>
>         i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
>         if (i2s_pdata == NULL) {
> -               kfree(adev->acp.acp_res);
> -               kfree(adev->acp.acp_cell);
> -               return -ENOMEM;
> +               ret = -ENOMEM;
> +               goto out3;
>         }

I don't see a corresponding kfree() for i2s_pdata in acp_hw_fini().
Could this be a memory leak?

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2] drm/amdgpu: fix multiple memory leaks
  2019-09-18 19:05   ` [PATCH v2] " Navid Emamdoost
  2019-09-18 19:45     ` Sven Van Asbroeck
@ 2019-09-19  8:03     ` Koenig, Christian
  2019-09-19 14:28       ` Sven Van Asbroeck
                         ` (2 more replies)
  2019-09-27 16:37     ` Markus Elfring
  2 siblings, 3 replies; 16+ messages in thread
From: Koenig, Christian @ 2019-09-19  8:03 UTC (permalink / raw)
  To: Navid Emamdoost
  Cc: emamd001, smccaman, kjlu, Deucher, Alexander, Zhou,
	David(ChunMing),
	David Airlie, Daniel Vetter, Rex Zhu, Sam Ravnborg, amd-gfx,
	dri-devel, linux-kernel

Am 18.09.19 um 21:05 schrieb Navid Emamdoost:
> In acp_hw_init there are some allocations that needs to be released in
> case of failure:
>
> 1- adev->acp.acp_genpd should be released if any allocation attemp for
> adev->acp.acp_cell, adev->acp.acp_res or i2s_pdata fails.
> 2- all of those allocations should be released if pm_genpd_add_device
> fails.
>
> v2: moved the released into goto error handlings
>
> Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 30 +++++++++++++++++--------
>   1 file changed, 21 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> index eba42c752bca..c0db75b71859 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> @@ -184,7 +184,7 @@ static struct device *get_mfd_cell_dev(const char *device_name, int r)
>    */
>   static int acp_hw_init(void *handle)
>   {
> -	int r, i;
> +	int r, i, ret;
>   	uint64_t acp_base;
>   	u32 val = 0;
>   	u32 count = 0;
> @@ -231,20 +231,21 @@ static int acp_hw_init(void *handle)
>   	adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
>   							GFP_KERNEL);
>   
> -	if (adev->acp.acp_cell == NULL)
> -		return -ENOMEM;
> +	if (adev->acp.acp_cell == NULL) {
> +		ret = -ENOMEM;
> +		goto out1;
> +	}
>   
>   	adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
>   	if (adev->acp.acp_res == NULL) {
> -		kfree(adev->acp.acp_cell);
> -		return -ENOMEM;
> +		ret = -ENOMEM;
> +		goto out2;
>   	}
>   
>   	i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
>   	if (i2s_pdata == NULL) {
> -		kfree(adev->acp.acp_res);
> -		kfree(adev->acp.acp_cell);
> -		return -ENOMEM;
> +		ret = -ENOMEM;
> +		goto out3;
>   	}
>   
>   	switch (adev->asic_type) {
> @@ -348,7 +349,8 @@ static int acp_hw_init(void *handle)
>   		r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
>   		if (r) {
>   			dev_err(dev, "Failed to add dev to genpd\n");
> -			return r;
> +			ret = r;
> +			goto out4;
>   		}
>   	}
>   
> @@ -393,6 +395,16 @@ static int acp_hw_init(void *handle)
>   	val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
>   	cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
>   	return 0;
> +
> +out4:
> +	kfree(i2s_pdata);
> +out3:
> +	kfree(adev->acp.acp_res);
> +out2:
> +	kfree(adev->acp.acp_cell);
> +out1:
> +	kfree(adev->acp.acp_genpd);

kfree on a NULL pointer is harmless, so a single error label should be 
sufficient.

Christian.

> +	return ret;
>   }
>   
>   /**


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2] drm/amdgpu: fix multiple memory leaks
  2019-09-19  8:03     ` Koenig, Christian
@ 2019-09-19 14:28       ` Sven Van Asbroeck
  2019-09-19 16:48         ` Koenig, Christian
  2019-09-30 21:26       ` [PATCH v3] drm/amdgpu: fix multiple memory leaks in acp_hw_init Navid Emamdoost
  2019-09-30 21:31       ` [PATCH v2] drm/amdgpu: fix multiple memory leaks Navid Emamdoost
  2 siblings, 1 reply; 16+ messages in thread
From: Sven Van Asbroeck @ 2019-09-19 14:28 UTC (permalink / raw)
  To: Koenig, Christian
  Cc: Navid Emamdoost, emamd001, smccaman, kjlu, Deucher, Alexander,
	Zhou, David(ChunMing),
	David Airlie, Daniel Vetter, Rex Zhu, Sam Ravnborg, amd-gfx,
	dri-devel, linux-kernel

Hi Christian,

On Thu, Sep 19, 2019 at 4:05 AM Koenig, Christian
<Christian.Koenig@amd.com> wrote:
>
> > +out4:
> > +     kfree(i2s_pdata);
> > +out3:
> > +     kfree(adev->acp.acp_res);
> > +out2:
> > +     kfree(adev->acp.acp_cell);
> > +out1:
> > +     kfree(adev->acp.acp_genpd);
>
> kfree on a NULL pointer is harmless, so a single error label should be
> sufficient.

That is true, but I notice that the adev structure comes from outside this
driver:

static int acp_hw_init(void *handle)
{
...
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
...
}

As far as I can tell, the init() does not explicitly set these to NULL:
adev->acp.acp_res
adev->acp.acp_cell
adev->acp.acp_genpd

I am assuming that core code sets these to NULL, before calling
acp_hw_init(). But is that guaranteed or simply a happy accident?
Ie. if they are NULL today, are they likely to remain NULL tomorrow?

Because calling kfree() on a stale pointer would be, well
not good. Especially not on an error path, which typically
does not receive much testing, if any.

My apologies if I have misinterpreted this, I am not familiar with
this code base.

Sven

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2] drm/amdgpu: fix multiple memory leaks
  2019-09-19 14:28       ` Sven Van Asbroeck
@ 2019-09-19 16:48         ` Koenig, Christian
  0 siblings, 0 replies; 16+ messages in thread
From: Koenig, Christian @ 2019-09-19 16:48 UTC (permalink / raw)
  To: Sven Van Asbroeck
  Cc: Navid Emamdoost, emamd001, smccaman, kjlu, Deucher, Alexander,
	Zhou, David(ChunMing),
	David Airlie, Daniel Vetter, Rex Zhu, Sam Ravnborg, amd-gfx,
	dri-devel, linux-kernel

Am 19.09.19 um 16:28 schrieb Sven Van Asbroeck:
> Hi Christian,
>
> On Thu, Sep 19, 2019 at 4:05 AM Koenig, Christian
> <Christian.Koenig@amd.com> wrote:
>>> +out4:
>>> +     kfree(i2s_pdata);
>>> +out3:
>>> +     kfree(adev->acp.acp_res);
>>> +out2:
>>> +     kfree(adev->acp.acp_cell);
>>> +out1:
>>> +     kfree(adev->acp.acp_genpd);
>> kfree on a NULL pointer is harmless, so a single error label should be
>> sufficient.
> That is true, but I notice that the adev structure comes from outside this
> driver:

adev is a very integral part of the driver and always zero initialized:

adev = kzalloc(sizeof(struct amdgpu_device), GFP_KERNEL);

Regards,
Christian.

>
> static int acp_hw_init(void *handle)
> {
> ...
> struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> ...
> }
>
> As far as I can tell, the init() does not explicitly set these to NULL:
> adev->acp.acp_res
> adev->acp.acp_cell
> adev->acp.acp_genpd
>
> I am assuming that core code sets these to NULL, before calling
> acp_hw_init(). But is that guaranteed or simply a happy accident?
> Ie. if they are NULL today, are they likely to remain NULL tomorrow?
>
> Because calling kfree() on a stale pointer would be, well
> not good. Especially not on an error path, which typically
> does not receive much testing, if any.
>
> My apologies if I have misinterpreted this, I am not familiar with
> this code base.
>
> Sven


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2] drm/amdgpu: fix multiple memory leaks
  2019-09-18 19:05   ` [PATCH v2] " Navid Emamdoost
  2019-09-18 19:45     ` Sven Van Asbroeck
  2019-09-19  8:03     ` Koenig, Christian
@ 2019-09-27 16:37     ` Markus Elfring
  2 siblings, 0 replies; 16+ messages in thread
From: Markus Elfring @ 2019-09-27 16:37 UTC (permalink / raw)
  To: Navid Emamdoost, Christian König, amd-gfx, dri-devel
  Cc: Chunming Zhou, Rex Zhu, Alex Deucher, Sam Ravnborg, David Airlie,
	Daniel Vetter, Navid Emamdoost, Kangjie Lu, Stephen A McCamant,
	linux-kernel, kernel-janitors

> v2: moved the released into goto error handlings

A better version comment should be moved below the triple dashes.


Will the tag “Fixes” be added?


> @@ -393,6 +395,16 @@ static int acp_hw_init(void *handle)
>  	val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
>  	cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
>  	return 0;
> +
> +out4:
> +	kfree(i2s_pdata);
> +out3:
> +	kfree(adev->acp.acp_res);
> +out2:
> +	kfree(adev->acp.acp_cell);
> +out1:
> +	kfree(adev->acp.acp_genpd);
> +	return ret;
>  }
>
>  /**

I suggest to reconsider the label selection according to the Linux coding style.

Regards,
Markus

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v3] drm/amdgpu: fix multiple memory leaks in acp_hw_init
  2019-09-19  8:03     ` Koenig, Christian
  2019-09-19 14:28       ` Sven Van Asbroeck
@ 2019-09-30 21:26       ` Navid Emamdoost
  2019-10-01 11:24         ` Markus Elfring
  2019-10-01 12:19         ` Koenig, Christian
  2019-09-30 21:31       ` [PATCH v2] drm/amdgpu: fix multiple memory leaks Navid Emamdoost
  2 siblings, 2 replies; 16+ messages in thread
From: Navid Emamdoost @ 2019-09-30 21:26 UTC (permalink / raw)
  To: Christian.Koenig
  Cc: emamd001, smccaman, kjlu, Navid Emamdoost, Alex Deucher,
	Christian König, David (ChunMing) Zhou, David Airlie,
	Daniel Vetter, Sam Ravnborg, Rex Zhu, amd-gfx, dri-devel,
	linux-kernel

In acp_hw_init there are some allocations that needs to be released in
case of failure:

1- adev->acp.acp_genpd should be released if any allocation attemp for
adev->acp.acp_cell, adev->acp.acp_res or i2s_pdata fails.
2- all of those allocations should be released if
mfd_add_hotplug_devices or pm_genpd_add_device fail.
3- Release is needed in case of time out values expire.

Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
---
Changes in v2:
	-- moved the releases under goto

Changes in v3:
	-- fixed multiple goto issue
	-- added goto for 3 other failure cases: one when
mfd_add_hotplug_devices fails, and two when time out values expires.
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 41 ++++++++++++++++---------
 1 file changed, 27 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
index eba42c752bca..7809745ec0f1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
@@ -184,12 +184,12 @@ static struct device *get_mfd_cell_dev(const char *device_name, int r)
  */
 static int acp_hw_init(void *handle)
 {
-	int r, i;
+	int r, i, ret;
 	uint64_t acp_base;
 	u32 val = 0;
 	u32 count = 0;
 	struct device *dev;
-	struct i2s_platform_data *i2s_pdata;
+	struct i2s_platform_data *i2s_pdata = NULL;
 
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
@@ -231,20 +231,21 @@ static int acp_hw_init(void *handle)
 	adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
 							GFP_KERNEL);
 
-	if (adev->acp.acp_cell == NULL)
-		return -ENOMEM;
+	if (adev->acp.acp_cell == NULL) {
+		ret = -ENOMEM;
+		goto failure;
+	}
 
 	adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
 	if (adev->acp.acp_res == NULL) {
-		kfree(adev->acp.acp_cell);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto failure;
 	}
 
 	i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
 	if (i2s_pdata == NULL) {
-		kfree(adev->acp.acp_res);
-		kfree(adev->acp.acp_cell);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto failure;
 	}
 
 	switch (adev->asic_type) {
@@ -340,15 +341,18 @@ static int acp_hw_init(void *handle)
 
 	r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell,
 								ACP_DEVS);
-	if (r)
-		return r;
+	if (r) {
+		ret = r;
+		goto failure;
+	}
 
 	for (i = 0; i < ACP_DEVS ; i++) {
 		dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
 		r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
 		if (r) {
 			dev_err(dev, "Failed to add dev to genpd\n");
-			return r;
+			ret = r;
+			goto failure;
 		}
 	}
 
@@ -367,7 +371,8 @@ static int acp_hw_init(void *handle)
 			break;
 		if (--count == 0) {
 			dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
-			return -ETIMEDOUT;
+			ret = -ETIMEDOUT;
+			goto failure;
 		}
 		udelay(100);
 	}
@@ -384,7 +389,8 @@ static int acp_hw_init(void *handle)
 			break;
 		if (--count == 0) {
 			dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
-			return -ETIMEDOUT;
+			ret = -ETIMEDOUT;
+			goto failure;
 		}
 		udelay(100);
 	}
@@ -393,6 +399,13 @@ static int acp_hw_init(void *handle)
 	val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
 	cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
 	return 0;
+
+failure:
+	kfree(i2s_pdata);
+	kfree(adev->acp.acp_res);
+	kfree(adev->acp.acp_cell);
+	kfree(adev->acp.acp_genpd);
+	return ret;
 }
 
 /**
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v2] drm/amdgpu: fix multiple memory leaks
  2019-09-19  8:03     ` Koenig, Christian
  2019-09-19 14:28       ` Sven Van Asbroeck
  2019-09-30 21:26       ` [PATCH v3] drm/amdgpu: fix multiple memory leaks in acp_hw_init Navid Emamdoost
@ 2019-09-30 21:31       ` Navid Emamdoost
  2 siblings, 0 replies; 16+ messages in thread
From: Navid Emamdoost @ 2019-09-30 21:31 UTC (permalink / raw)
  To: Koenig, Christian
  Cc: emamd001, smccaman, kjlu, Deucher, Alexander, Zhou,
	David(ChunMing),
	David Airlie, Daniel Vetter, Rex Zhu, Sam Ravnborg, amd-gfx,
	dri-devel, linux-kernel

On Thu, Sep 19, 2019 at 3:03 AM Koenig, Christian
<Christian.Koenig@amd.com> wrote:
>
> Am 18.09.19 um 21:05 schrieb Navid Emamdoost:
> > In acp_hw_init there are some allocations that needs to be released in
> > case of failure:
> >
> > 1- adev->acp.acp_genpd should be released if any allocation attemp for
> > adev->acp.acp_cell, adev->acp.acp_res or i2s_pdata fails.
> > 2- all of those allocations should be released if pm_genpd_add_device
> > fails.
> >
> > v2: moved the released into goto error handlings
> >
> > Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
> > ---
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 30 +++++++++++++++++--------
> >   1 file changed, 21 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> > index eba42c752bca..c0db75b71859 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> > @@ -184,7 +184,7 @@ static struct device *get_mfd_cell_dev(const char *device_name, int r)
> >    */
> >   static int acp_hw_init(void *handle)
> >   {
> > -     int r, i;
> > +     int r, i, ret;
> >       uint64_t acp_base;
> >       u32 val = 0;
> >       u32 count = 0;
> > @@ -231,20 +231,21 @@ static int acp_hw_init(void *handle)
> >       adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
> >                                                       GFP_KERNEL);
> >
> > -     if (adev->acp.acp_cell == NULL)
> > -             return -ENOMEM;
> > +     if (adev->acp.acp_cell == NULL) {
> > +             ret = -ENOMEM;
> > +             goto out1;
> > +     }
> >
> >       adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
> >       if (adev->acp.acp_res == NULL) {
> > -             kfree(adev->acp.acp_cell);
> > -             return -ENOMEM;
> > +             ret = -ENOMEM;
> > +             goto out2;
> >       }
> >
> >       i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
> >       if (i2s_pdata == NULL) {
> > -             kfree(adev->acp.acp_res);
> > -             kfree(adev->acp.acp_cell);
> > -             return -ENOMEM;
> > +             ret = -ENOMEM;
> > +             goto out3;
> >       }
> >
> >       switch (adev->asic_type) {
> > @@ -348,7 +349,8 @@ static int acp_hw_init(void *handle)
> >               r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
> >               if (r) {
> >                       dev_err(dev, "Failed to add dev to genpd\n");
> > -                     return r;
> > +                     ret = r;
> > +                     goto out4;
> >               }
> >       }
> >
> > @@ -393,6 +395,16 @@ static int acp_hw_init(void *handle)
> >       val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
> >       cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
> >       return 0;
> > +
> > +out4:
> > +     kfree(i2s_pdata);
> > +out3:
> > +     kfree(adev->acp.acp_res);
> > +out2:
> > +     kfree(adev->acp.acp_cell);
> > +out1:
> > +     kfree(adev->acp.acp_genpd);
>
> kfree on a NULL pointer is harmless, so a single error label should be
> sufficient.
>
I fixed this by just using failure label.

> Christian.
>
> > +     return ret;
> >   }
> >
> >   /**
>

In addition to previous cases, I covered 3 more error handling cases
that seemed need to goto failure. One where mfd_add_hotplug_devices
fails and the other two cases where time out values expire.


-- 
Navid.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3] drm/amdgpu: fix multiple memory leaks in acp_hw_init
  2019-09-30 21:26       ` [PATCH v3] drm/amdgpu: fix multiple memory leaks in acp_hw_init Navid Emamdoost
@ 2019-10-01 11:24         ` Markus Elfring
  2019-10-01 12:19         ` Koenig, Christian
  1 sibling, 0 replies; 16+ messages in thread
From: Markus Elfring @ 2019-10-01 11:24 UTC (permalink / raw)
  To: Navid Emamdoost, Christian König, amd-gfx, dri-devel
  Cc: Navid Emamdoost, Kangjie Lu, Stephen McCamant, Alex Deucher,
	Chunming Zhou, Daniel Vetter, David Airlie, Sam Ravnborg,
	Sven Van Asbroeck, LKML, kernel-janitors

> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> @@ -184,12 +184,12 @@ static struct device *get_mfd_cell_dev(const char *device_name, int r)
> +	struct i2s_platform_data *i2s_pdata = NULL;
…

I propose to reconsider this update suggestion.


> @@ -231,20 +231,21 @@ static int acp_hw_init(void *handle)
>  	adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
>  							GFP_KERNEL);
>
> -	if (adev->acp.acp_cell == NULL)
> -		return -ENOMEM;
…

I suggest to keep this source code place unchanged (at the moment).
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/coding-style.rst?id=54ecb8f7028c5eb3d740bb82b0f1d90f2df63c5c#n456


> @@ -393,6 +399,13 @@ static int acp_hw_init(void *handle)
>  	val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
>  	cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
>  	return 0;
> +
> +failure:
> +	kfree(i2s_pdata);
> +	kfree(adev->acp.acp_res);
> +	kfree(adev->acp.acp_cell);
> +	kfree(adev->acp.acp_genpd);
> +	return ret;
>  }
>
>  /**

I would prefer separate jump targets for efficient exception handling.
Please choose more appropriate labels for this function implementation.


> ---

I suggest to replace this second delimiter by a blank line.

Regards,
Markus

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3] drm/amdgpu: fix multiple memory leaks in acp_hw_init
  2019-09-30 21:26       ` [PATCH v3] drm/amdgpu: fix multiple memory leaks in acp_hw_init Navid Emamdoost
  2019-10-01 11:24         ` Markus Elfring
@ 2019-10-01 12:19         ` Koenig, Christian
  2019-10-02  3:46           ` [PATCH v4] " Navid Emamdoost
  2019-10-02  3:47           ` [PATCH v3] " Navid Emamdoost
  1 sibling, 2 replies; 16+ messages in thread
From: Koenig, Christian @ 2019-10-01 12:19 UTC (permalink / raw)
  To: Navid Emamdoost
  Cc: emamd001, smccaman, kjlu, Deucher, Alexander, Zhou,
	David(ChunMing),
	David Airlie, Daniel Vetter, Sam Ravnborg, Rex Zhu, amd-gfx,
	dri-devel, linux-kernel

Am 30.09.19 um 23:26 schrieb Navid Emamdoost:
> In acp_hw_init there are some allocations that needs to be released in
> case of failure:
>
> 1- adev->acp.acp_genpd should be released if any allocation attemp for
> adev->acp.acp_cell, adev->acp.acp_res or i2s_pdata fails.
> 2- all of those allocations should be released if
> mfd_add_hotplug_devices or pm_genpd_add_device fail.
> 3- Release is needed in case of time out values expire.
>
> Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
> ---
> Changes in v2:
> 	-- moved the releases under goto
>
> Changes in v3:
> 	-- fixed multiple goto issue
> 	-- added goto for 3 other failure cases: one when
> mfd_add_hotplug_devices fails, and two when time out values expires.
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 41 ++++++++++++++++---------
>   1 file changed, 27 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> index eba42c752bca..7809745ec0f1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> @@ -184,12 +184,12 @@ static struct device *get_mfd_cell_dev(const char *device_name, int r)
>    */
>   static int acp_hw_init(void *handle)
>   {
> -	int r, i;
> +	int r, i, ret;

Please don't add another "ret" variable, instead always use "r" here.

Apart from that looks good to me,
Christian.

>   	uint64_t acp_base;
>   	u32 val = 0;
>   	u32 count = 0;
>   	struct device *dev;
> -	struct i2s_platform_data *i2s_pdata;
> +	struct i2s_platform_data *i2s_pdata = NULL;
>   
>   	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
>   
> @@ -231,20 +231,21 @@ static int acp_hw_init(void *handle)
>   	adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
>   							GFP_KERNEL);
>   
> -	if (adev->acp.acp_cell == NULL)
> -		return -ENOMEM;
> +	if (adev->acp.acp_cell == NULL) {
> +		ret = -ENOMEM;
> +		goto failure;
> +	}
>   
>   	adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
>   	if (adev->acp.acp_res == NULL) {
> -		kfree(adev->acp.acp_cell);
> -		return -ENOMEM;
> +		ret = -ENOMEM;
> +		goto failure;
>   	}
>   
>   	i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
>   	if (i2s_pdata == NULL) {
> -		kfree(adev->acp.acp_res);
> -		kfree(adev->acp.acp_cell);
> -		return -ENOMEM;
> +		ret = -ENOMEM;
> +		goto failure;
>   	}
>   
>   	switch (adev->asic_type) {
> @@ -340,15 +341,18 @@ static int acp_hw_init(void *handle)
>   
>   	r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell,
>   								ACP_DEVS);
> -	if (r)
> -		return r;
> +	if (r) {
> +		ret = r;
> +		goto failure;
> +	}
>   
>   	for (i = 0; i < ACP_DEVS ; i++) {
>   		dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
>   		r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
>   		if (r) {
>   			dev_err(dev, "Failed to add dev to genpd\n");
> -			return r;
> +			ret = r;
> +			goto failure;
>   		}
>   	}
>   
> @@ -367,7 +371,8 @@ static int acp_hw_init(void *handle)
>   			break;
>   		if (--count == 0) {
>   			dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
> -			return -ETIMEDOUT;
> +			ret = -ETIMEDOUT;
> +			goto failure;
>   		}
>   		udelay(100);
>   	}
> @@ -384,7 +389,8 @@ static int acp_hw_init(void *handle)
>   			break;
>   		if (--count == 0) {
>   			dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
> -			return -ETIMEDOUT;
> +			ret = -ETIMEDOUT;
> +			goto failure;
>   		}
>   		udelay(100);
>   	}
> @@ -393,6 +399,13 @@ static int acp_hw_init(void *handle)
>   	val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
>   	cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
>   	return 0;
> +
> +failure:
> +	kfree(i2s_pdata);
> +	kfree(adev->acp.acp_res);
> +	kfree(adev->acp.acp_cell);
> +	kfree(adev->acp.acp_genpd);
> +	return ret;
>   }
>   
>   /**


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v4] drm/amdgpu: fix multiple memory leaks in acp_hw_init
  2019-10-01 12:19         ` Koenig, Christian
@ 2019-10-02  3:46           ` Navid Emamdoost
  2019-10-02  5:47             ` Markus Elfring
  2019-10-02  6:58             ` Koenig, Christian
  2019-10-02  3:47           ` [PATCH v3] " Navid Emamdoost
  1 sibling, 2 replies; 16+ messages in thread
From: Navid Emamdoost @ 2019-10-02  3:46 UTC (permalink / raw)
  To: Christian.Koenig
  Cc: emamd001, smccaman, kjlu, Navid Emamdoost, Alex Deucher,
	Christian König, David (ChunMing) Zhou, David Airlie,
	Daniel Vetter, Sam Ravnborg, Rex Zhu, amd-gfx, dri-devel,
	linux-kernel

In acp_hw_init there are some allocations that needs to be released in
case of failure:

1- adev->acp.acp_genpd should be released if any allocation attemp for
adev->acp.acp_cell, adev->acp.acp_res or i2s_pdata fails.
2- all of those allocations should be released if
mfd_add_hotplug_devices or pm_genpd_add_device fail.
3- Release is needed in case of time out values expire.

Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 34 ++++++++++++++++---------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
index eba42c752bca..82155ac3288a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
@@ -189,7 +189,7 @@ static int acp_hw_init(void *handle)
 	u32 val = 0;
 	u32 count = 0;
 	struct device *dev;
-	struct i2s_platform_data *i2s_pdata;
+	struct i2s_platform_data *i2s_pdata = NULL;
 
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
@@ -231,20 +231,21 @@ static int acp_hw_init(void *handle)
 	adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
 							GFP_KERNEL);
 
-	if (adev->acp.acp_cell == NULL)
-		return -ENOMEM;
+	if (adev->acp.acp_cell == NULL) {
+		r = -ENOMEM;
+		goto failure;
+	}
 
 	adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
 	if (adev->acp.acp_res == NULL) {
-		kfree(adev->acp.acp_cell);
-		return -ENOMEM;
+		r = -ENOMEM;
+		goto failure;
 	}
 
 	i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
 	if (i2s_pdata == NULL) {
-		kfree(adev->acp.acp_res);
-		kfree(adev->acp.acp_cell);
-		return -ENOMEM;
+		r = -ENOMEM;
+		goto failure;
 	}
 
 	switch (adev->asic_type) {
@@ -341,14 +342,14 @@ static int acp_hw_init(void *handle)
 	r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell,
 								ACP_DEVS);
 	if (r)
-		return r;
+		goto failure;
 
 	for (i = 0; i < ACP_DEVS ; i++) {
 		dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
 		r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
 		if (r) {
 			dev_err(dev, "Failed to add dev to genpd\n");
-			return r;
+			goto failure;
 		}
 	}
 
@@ -367,7 +368,8 @@ static int acp_hw_init(void *handle)
 			break;
 		if (--count == 0) {
 			dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
-			return -ETIMEDOUT;
+			r = -ETIMEDOUT;
+			goto failure;
 		}
 		udelay(100);
 	}
@@ -384,7 +386,8 @@ static int acp_hw_init(void *handle)
 			break;
 		if (--count == 0) {
 			dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
-			return -ETIMEDOUT;
+			r = -ETIMEDOUT;
+			goto failure;
 		}
 		udelay(100);
 	}
@@ -393,6 +396,13 @@ static int acp_hw_init(void *handle)
 	val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
 	cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
 	return 0;
+
+failure:
+	kfree(i2s_pdata);
+	kfree(adev->acp.acp_res);
+	kfree(adev->acp.acp_cell);
+	kfree(adev->acp.acp_genpd);
+	return r;
 }
 
 /**
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v3] drm/amdgpu: fix multiple memory leaks in acp_hw_init
  2019-10-01 12:19         ` Koenig, Christian
  2019-10-02  3:46           ` [PATCH v4] " Navid Emamdoost
@ 2019-10-02  3:47           ` Navid Emamdoost
  1 sibling, 0 replies; 16+ messages in thread
From: Navid Emamdoost @ 2019-10-02  3:47 UTC (permalink / raw)
  To: Koenig, Christian
  Cc: emamd001, smccaman, kjlu, Deucher, Alexander, Zhou,
	David(ChunMing),
	David Airlie, Daniel Vetter, Sam Ravnborg, Rex Zhu, amd-gfx,
	dri-devel, linux-kernel

On Tue, Oct 1, 2019 at 7:19 AM Koenig, Christian
<Christian.Koenig@amd.com> wrote:
>
> Am 30.09.19 um 23:26 schrieb Navid Emamdoost:
> > In acp_hw_init there are some allocations that needs to be released in
> > case of failure:
> >
> > 1- adev->acp.acp_genpd should be released if any allocation attemp for
> > adev->acp.acp_cell, adev->acp.acp_res or i2s_pdata fails.
> > 2- all of those allocations should be released if
> > mfd_add_hotplug_devices or pm_genpd_add_device fail.
> > 3- Release is needed in case of time out values expire.
> >
> > Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
> > ---
> > Changes in v2:
> >       -- moved the releases under goto
> >
> > Changes in v3:
> >       -- fixed multiple goto issue
> >       -- added goto for 3 other failure cases: one when
> > mfd_add_hotplug_devices fails, and two when time out values expires.
> > ---
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 41 ++++++++++++++++---------
> >   1 file changed, 27 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> > index eba42c752bca..7809745ec0f1 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> > @@ -184,12 +184,12 @@ static struct device *get_mfd_cell_dev(const char *device_name, int r)
> >    */
> >   static int acp_hw_init(void *handle)
> >   {
> > -     int r, i;
> > +     int r, i, ret;
>
> Please don't add another "ret" variable, instead always use "r" here.
>
Done!

> Apart from that looks good to me,
> Christian.
>
> >       uint64_t acp_base;
> >       u32 val = 0;
> >       u32 count = 0;
> >       struct device *dev;
> > -     struct i2s_platform_data *i2s_pdata;
> > +     struct i2s_platform_data *i2s_pdata = NULL;
> >
> >       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> >
> > @@ -231,20 +231,21 @@ static int acp_hw_init(void *handle)
> >       adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
> >                                                       GFP_KERNEL);
> >
> > -     if (adev->acp.acp_cell == NULL)
> > -             return -ENOMEM;
> > +     if (adev->acp.acp_cell == NULL) {
> > +             ret = -ENOMEM;
> > +             goto failure;
> > +     }
> >
> >       adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
> >       if (adev->acp.acp_res == NULL) {
> > -             kfree(adev->acp.acp_cell);
> > -             return -ENOMEM;
> > +             ret = -ENOMEM;
> > +             goto failure;
> >       }
> >
> >       i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
> >       if (i2s_pdata == NULL) {
> > -             kfree(adev->acp.acp_res);
> > -             kfree(adev->acp.acp_cell);
> > -             return -ENOMEM;
> > +             ret = -ENOMEM;
> > +             goto failure;
> >       }
> >
> >       switch (adev->asic_type) {
> > @@ -340,15 +341,18 @@ static int acp_hw_init(void *handle)
> >
> >       r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell,
> >                                                               ACP_DEVS);
> > -     if (r)
> > -             return r;
> > +     if (r) {
> > +             ret = r;
> > +             goto failure;
> > +     }
> >
> >       for (i = 0; i < ACP_DEVS ; i++) {
> >               dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
> >               r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
> >               if (r) {
> >                       dev_err(dev, "Failed to add dev to genpd\n");
> > -                     return r;
> > +                     ret = r;
> > +                     goto failure;
> >               }
> >       }
> >
> > @@ -367,7 +371,8 @@ static int acp_hw_init(void *handle)
> >                       break;
> >               if (--count == 0) {
> >                       dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
> > -                     return -ETIMEDOUT;
> > +                     ret = -ETIMEDOUT;
> > +                     goto failure;
> >               }
> >               udelay(100);
> >       }
> > @@ -384,7 +389,8 @@ static int acp_hw_init(void *handle)
> >                       break;
> >               if (--count == 0) {
> >                       dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
> > -                     return -ETIMEDOUT;
> > +                     ret = -ETIMEDOUT;
> > +                     goto failure;
> >               }
> >               udelay(100);
> >       }
> > @@ -393,6 +399,13 @@ static int acp_hw_init(void *handle)
> >       val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
> >       cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
> >       return 0;
> > +
> > +failure:
> > +     kfree(i2s_pdata);
> > +     kfree(adev->acp.acp_res);
> > +     kfree(adev->acp.acp_cell);
> > +     kfree(adev->acp.acp_genpd);
> > +     return ret;
> >   }
> >
> >   /**
>


-- 
Navid.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v4] drm/amdgpu: fix multiple memory leaks in acp_hw_init
  2019-10-02  3:46           ` [PATCH v4] " Navid Emamdoost
@ 2019-10-02  5:47             ` Markus Elfring
  2019-10-02  6:58             ` Koenig, Christian
  1 sibling, 0 replies; 16+ messages in thread
From: Markus Elfring @ 2019-10-02  5:47 UTC (permalink / raw)
  To: Navid Emamdoost, Christian König, Chunming Zhou,
	Alex Deucher, amd-gfx, dri-devel
  Cc: Navid Emamdoost, Kangjie Lu, Stephen McCamant, Daniel Vetter,
	David Airlie, Sam Ravnborg, linux-kernel, kernel-janitors

> ---

Why did you omit the patch change log at this place?


>  drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 34 ++++++++++++++++---------


> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> @@ -189,7 +189,7 @@ static int acp_hw_init(void *handle)
> +	struct i2s_platform_data *i2s_pdata = NULL;
…

I propose to reconsider this update suggestion once more.


> @@ -393,6 +396,13 @@ static int acp_hw_init(void *handle)
>  	val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
>  	cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
>  	return 0;
> +
> +failure:
> +	kfree(i2s_pdata);
> +	kfree(adev->acp.acp_res);
> +	kfree(adev->acp.acp_cell);
> +	kfree(adev->acp.acp_genpd);
> +	return r;
>  }
>
>  /**

Are you going to follow a known programming guideline?
https://wiki.sei.cmu.edu/confluence/display/c/MEM12-C.+Consider+using+a+goto+chain+when+leaving+a+function+on+error+when+using+and+releasing+resources#MEM12-C.Considerusingagotochainwhenleavingafunctiononerrorwhenusingandreleasingresources-CompliantSolution%28copy_process%28%29fromLinuxkernel%29

Regards,
Markus

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v4] drm/amdgpu: fix multiple memory leaks in acp_hw_init
  2019-10-02  3:46           ` [PATCH v4] " Navid Emamdoost
  2019-10-02  5:47             ` Markus Elfring
@ 2019-10-02  6:58             ` Koenig, Christian
  1 sibling, 0 replies; 16+ messages in thread
From: Koenig, Christian @ 2019-10-02  6:58 UTC (permalink / raw)
  To: Navid Emamdoost
  Cc: emamd001, smccaman, kjlu, Deucher, Alexander, Zhou,
	David(ChunMing),
	David Airlie, Daniel Vetter, Sam Ravnborg, Rex Zhu, amd-gfx,
	dri-devel, linux-kernel

Am 02.10.19 um 05:46 schrieb Navid Emamdoost:
> In acp_hw_init there are some allocations that needs to be released in
> case of failure:
>
> 1- adev->acp.acp_genpd should be released if any allocation attemp for
> adev->acp.acp_cell, adev->acp.acp_res or i2s_pdata fails.
> 2- all of those allocations should be released if
> mfd_add_hotplug_devices or pm_genpd_add_device fail.
> 3- Release is needed in case of time out values expire.
>
> Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 34 ++++++++++++++++---------
>   1 file changed, 22 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> index eba42c752bca..82155ac3288a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> @@ -189,7 +189,7 @@ static int acp_hw_init(void *handle)
>   	u32 val = 0;
>   	u32 count = 0;
>   	struct device *dev;
> -	struct i2s_platform_data *i2s_pdata;
> +	struct i2s_platform_data *i2s_pdata = NULL;
>   
>   	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
>   
> @@ -231,20 +231,21 @@ static int acp_hw_init(void *handle)
>   	adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
>   							GFP_KERNEL);
>   
> -	if (adev->acp.acp_cell == NULL)
> -		return -ENOMEM;
> +	if (adev->acp.acp_cell == NULL) {
> +		r = -ENOMEM;
> +		goto failure;
> +	}
>   
>   	adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
>   	if (adev->acp.acp_res == NULL) {
> -		kfree(adev->acp.acp_cell);
> -		return -ENOMEM;
> +		r = -ENOMEM;
> +		goto failure;
>   	}
>   
>   	i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
>   	if (i2s_pdata == NULL) {
> -		kfree(adev->acp.acp_res);
> -		kfree(adev->acp.acp_cell);
> -		return -ENOMEM;
> +		r = -ENOMEM;
> +		goto failure;
>   	}
>   
>   	switch (adev->asic_type) {
> @@ -341,14 +342,14 @@ static int acp_hw_init(void *handle)
>   	r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell,
>   								ACP_DEVS);
>   	if (r)
> -		return r;
> +		goto failure;
>   
>   	for (i = 0; i < ACP_DEVS ; i++) {
>   		dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
>   		r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
>   		if (r) {
>   			dev_err(dev, "Failed to add dev to genpd\n");
> -			return r;
> +			goto failure;
>   		}
>   	}
>   
> @@ -367,7 +368,8 @@ static int acp_hw_init(void *handle)
>   			break;
>   		if (--count == 0) {
>   			dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
> -			return -ETIMEDOUT;
> +			r = -ETIMEDOUT;
> +			goto failure;
>   		}
>   		udelay(100);
>   	}
> @@ -384,7 +386,8 @@ static int acp_hw_init(void *handle)
>   			break;
>   		if (--count == 0) {
>   			dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
> -			return -ETIMEDOUT;
> +			r = -ETIMEDOUT;
> +			goto failure;
>   		}
>   		udelay(100);
>   	}
> @@ -393,6 +396,13 @@ static int acp_hw_init(void *handle)
>   	val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
>   	cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
>   	return 0;
> +
> +failure:
> +	kfree(i2s_pdata);
> +	kfree(adev->acp.acp_res);
> +	kfree(adev->acp.acp_cell);
> +	kfree(adev->acp.acp_genpd);
> +	return r;
>   }
>   
>   /**


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2019-10-02  6:58 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-18 16:09 [PATCH] drm/amdgpu: fix multiple memory leaks Navid Emamdoost
2019-09-18 17:31 ` Koenig, Christian
2019-09-18 19:05   ` [PATCH v2] " Navid Emamdoost
2019-09-18 19:45     ` Sven Van Asbroeck
2019-09-19  8:03     ` Koenig, Christian
2019-09-19 14:28       ` Sven Van Asbroeck
2019-09-19 16:48         ` Koenig, Christian
2019-09-30 21:26       ` [PATCH v3] drm/amdgpu: fix multiple memory leaks in acp_hw_init Navid Emamdoost
2019-10-01 11:24         ` Markus Elfring
2019-10-01 12:19         ` Koenig, Christian
2019-10-02  3:46           ` [PATCH v4] " Navid Emamdoost
2019-10-02  5:47             ` Markus Elfring
2019-10-02  6:58             ` Koenig, Christian
2019-10-02  3:47           ` [PATCH v3] " Navid Emamdoost
2019-09-30 21:31       ` [PATCH v2] drm/amdgpu: fix multiple memory leaks Navid Emamdoost
2019-09-27 16:37     ` Markus Elfring

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).