public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] regulator: core: Fix memory leak in regulator_resolve_supply()
@ 2015-07-14 14:21 Javier Martinez Canillas
  2015-07-15  8:01 ` Krzysztof Kozlowski
  0 siblings, 1 reply; 7+ messages in thread
From: Javier Martinez Canillas @ 2015-07-14 14:21 UTC (permalink / raw)
  To: Mark Brown; +Cc: Liam Girdwood, linux-kernel, Javier Martinez Canillas

The regulator_resolve_supply() function calls set_supply() which in turn
calls create_regulator() to allocate a supply regulator.

If an error occurs after set_supply() succeeded, the allocated regulator
has to be freed before propagating the error code.

Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>

---

 drivers/regulator/core.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 68b616580533..325c0f5c13ca 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -109,6 +109,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
 static struct regulator *create_regulator(struct regulator_dev *rdev,
 					  struct device *dev,
 					  const char *supply_name);
+static void _regulator_put(struct regulator *regulator);
 
 static const char *rdev_get_name(struct regulator_dev *rdev)
 {
@@ -1402,8 +1403,11 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
 	/* Cascade always-on state to supply */
 	if (_regulator_is_enabled(rdev)) {
 		ret = regulator_enable(rdev->supply);
-		if (ret < 0)
+		if (ret < 0) {
+			if (rdev->supply)
+				_regulator_put(rdev->supply);
 			return ret;
+		}
 	}
 
 	return 0;
-- 
2.4.3


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

* Re: [PATCH] regulator: core: Fix memory leak in regulator_resolve_supply()
  2015-07-14 14:21 [PATCH] regulator: core: Fix memory leak in regulator_resolve_supply() Javier Martinez Canillas
@ 2015-07-15  8:01 ` Krzysztof Kozlowski
  2015-07-15  8:38   ` Javier Martinez Canillas
  0 siblings, 1 reply; 7+ messages in thread
From: Krzysztof Kozlowski @ 2015-07-15  8:01 UTC (permalink / raw)
  To: Javier Martinez Canillas; +Cc: Mark Brown, Liam Girdwood, linux-kernel

2015-07-14 23:21 GMT+09:00 Javier Martinez Canillas <javier@osg.samsung.com>:
> The regulator_resolve_supply() function calls set_supply() which in turn
> calls create_regulator() to allocate a supply regulator.
>
> If an error occurs after set_supply() succeeded, the allocated regulator
> has to be freed before propagating the error code.
>
> Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
>
> ---
>
>  drivers/regulator/core.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
> index 68b616580533..325c0f5c13ca 100644
> --- a/drivers/regulator/core.c
> +++ b/drivers/regulator/core.c
> @@ -109,6 +109,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
>  static struct regulator *create_regulator(struct regulator_dev *rdev,
>                                           struct device *dev,
>                                           const char *supply_name);
> +static void _regulator_put(struct regulator *regulator);
>
>  static const char *rdev_get_name(struct regulator_dev *rdev)
>  {
> @@ -1402,8 +1403,11 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
>         /* Cascade always-on state to supply */
>         if (_regulator_is_enabled(rdev)) {
>                 ret = regulator_enable(rdev->supply);
> -               if (ret < 0)
> +               if (ret < 0) {
> +                       if (rdev->supply)
> +                               _regulator_put(rdev->supply);

The _regulator_put() reverts more work than create_regulator() did,
e.g.: module_put and rdev->open_count--. Maybe you need a
destroy_regulator() function?

Best regards,
Krzysztof

>                         return ret;
> +               }
>         }
>
>         return 0;
> --
> 2.4.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

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

* Re: [PATCH] regulator: core: Fix memory leak in regulator_resolve_supply()
  2015-07-15  8:01 ` Krzysztof Kozlowski
@ 2015-07-15  8:38   ` Javier Martinez Canillas
  2015-07-15 11:27     ` Mark Brown
  0 siblings, 1 reply; 7+ messages in thread
From: Javier Martinez Canillas @ 2015-07-15  8:38 UTC (permalink / raw)
  To: Krzysztof Kozlowski; +Cc: Mark Brown, Liam Girdwood, linux-kernel

Hello Krzysztof,

Thanks a lot for your feedback.

On 07/15/2015 10:01 AM, Krzysztof Kozlowski wrote:
> 2015-07-14 23:21 GMT+09:00 Javier Martinez Canillas <javier@osg.samsung.com>:
>> The regulator_resolve_supply() function calls set_supply() which in turn
>> calls create_regulator() to allocate a supply regulator.
>>
>> If an error occurs after set_supply() succeeded, the allocated regulator
>> has to be freed before propagating the error code.
>>
>> Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
>>
>> ---
>>
>>  drivers/regulator/core.c | 6 +++++-
>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
>> index 68b616580533..325c0f5c13ca 100644
>> --- a/drivers/regulator/core.c
>> +++ b/drivers/regulator/core.c
>> @@ -109,6 +109,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
>>  static struct regulator *create_regulator(struct regulator_dev *rdev,
>>                                           struct device *dev,
>>                                           const char *supply_name);
>> +static void _regulator_put(struct regulator *regulator);
>>
>>  static const char *rdev_get_name(struct regulator_dev *rdev)
>>  {
>> @@ -1402,8 +1403,11 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
>>         /* Cascade always-on state to supply */
>>         if (_regulator_is_enabled(rdev)) {
>>                 ret = regulator_enable(rdev->supply);
>> -               if (ret < 0)
>> +               if (ret < 0) {
>> +                       if (rdev->supply)
>> +                               _regulator_put(rdev->supply);
> 
> The _regulator_put() reverts more work than create_regulator() did,
> e.g.: module_put and rdev->open_count--. Maybe you need a
> destroy_regulator() function?
>

Yes, it reverts more work than create_regulator() but the intention is to
revert what set_supply() did. If you look at the set_supply() function,
it does supply_rdev->open_count++.

I did indeed missed the module_put() but now looking at the code again, I
wonder if the problem is not that set_supply() is missing a try_module_get()
to be consistent with what the _regulator_get() function does.
 
> Best regards,
> Krzysztof
>

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America

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

* Re: [PATCH] regulator: core: Fix memory leak in regulator_resolve_supply()
  2015-07-15  8:38   ` Javier Martinez Canillas
@ 2015-07-15 11:27     ` Mark Brown
  2015-07-15 12:46       ` Javier Martinez Canillas
  0 siblings, 1 reply; 7+ messages in thread
From: Mark Brown @ 2015-07-15 11:27 UTC (permalink / raw)
  To: Javier Martinez Canillas; +Cc: Krzysztof Kozlowski, Liam Girdwood, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 970 bytes --]

On Wed, Jul 15, 2015 at 10:38:38AM +0200, Javier Martinez Canillas wrote:
> On 07/15/2015 10:01 AM, Krzysztof Kozlowski wrote:

> > The _regulator_put() reverts more work than create_regulator() did,
> > e.g.: module_put and rdev->open_count--. Maybe you need a
> > destroy_regulator() function?

> Yes, it reverts more work than create_regulator() but the intention is to
> revert what set_supply() did. If you look at the set_supply() function,
> it does supply_rdev->open_count++.

> I did indeed missed the module_put() but now looking at the code again, I

Me too, I've dropped the patch.  At first glance everything looked safe
for multiple calls.

> wonder if the problem is not that set_supply() is missing a try_module_get()
> to be consistent with what the _regulator_get() function does.

The problem is more that it's a separate implementation and not just
using _regulator_get() I think.  A separate, rarely used, path is likely
to have this sort of issue.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* Re: [PATCH] regulator: core: Fix memory leak in regulator_resolve_supply()
  2015-07-15 11:27     ` Mark Brown
@ 2015-07-15 12:46       ` Javier Martinez Canillas
  2015-07-15 15:52         ` Mark Brown
  0 siblings, 1 reply; 7+ messages in thread
From: Javier Martinez Canillas @ 2015-07-15 12:46 UTC (permalink / raw)
  To: Mark Brown; +Cc: Krzysztof Kozlowski, Liam Girdwood, linux-kernel

Hello Mark,

On 07/15/2015 01:27 PM, Mark Brown wrote:
> On Wed, Jul 15, 2015 at 10:38:38AM +0200, Javier Martinez Canillas wrote:
>> On 07/15/2015 10:01 AM, Krzysztof Kozlowski wrote:
> 
>>> The _regulator_put() reverts more work than create_regulator() did,
>>> e.g.: module_put and rdev->open_count--. Maybe you need a
>>> destroy_regulator() function?
> 
>> Yes, it reverts more work than create_regulator() but the intention is to
>> revert what set_supply() did. If you look at the set_supply() function,
>> it does supply_rdev->open_count++.
> 
>> I did indeed missed the module_put() but now looking at the code again, I
> 
> Me too, I've dropped the patch.  At first glance everything looked safe
> for multiple calls.
>

Ok.
 
>> wonder if the problem is not that set_supply() is missing a try_module_get()
>> to be consistent with what the _regulator_get() function does.
> 
> The problem is more that it's a separate implementation and not just
> using _regulator_get() I think.  A separate, rarely used, path is likely
> to have this sort of issue.
>

Exactly, do you agree then that a try_module_get() is missing in set_supply()?

It is OK if I add that in the same patch in v2 or do you prefer that to be
in a separate patch?

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America

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

* Re: [PATCH] regulator: core: Fix memory leak in regulator_resolve_supply()
  2015-07-15 12:46       ` Javier Martinez Canillas
@ 2015-07-15 15:52         ` Mark Brown
  2015-07-15 15:56           ` Javier Martinez Canillas
  0 siblings, 1 reply; 7+ messages in thread
From: Mark Brown @ 2015-07-15 15:52 UTC (permalink / raw)
  To: Javier Martinez Canillas; +Cc: Krzysztof Kozlowski, Liam Girdwood, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 638 bytes --]

On Wed, Jul 15, 2015 at 02:46:25PM +0200, Javier Martinez Canillas wrote:
> On 07/15/2015 01:27 PM, Mark Brown wrote:

> > using _regulator_get() I think.  A separate, rarely used, path is likely
> > to have this sort of issue.

> Exactly, do you agree then that a try_module_get() is missing in set_supply()?

> It is OK if I add that in the same patch in v2 or do you prefer that to be
> in a separate patch?

A separate patch would be better, or even better would be something that
just replaces everything there with use of the same code path as _get()
(thanks for volunteering!) but just adding the try_module_get() is fine
for now.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* Re: [PATCH] regulator: core: Fix memory leak in regulator_resolve_supply()
  2015-07-15 15:52         ` Mark Brown
@ 2015-07-15 15:56           ` Javier Martinez Canillas
  0 siblings, 0 replies; 7+ messages in thread
From: Javier Martinez Canillas @ 2015-07-15 15:56 UTC (permalink / raw)
  To: Mark Brown; +Cc: Krzysztof Kozlowski, Liam Girdwood, linux-kernel

Hello Mark,

On 07/15/2015 05:52 PM, Mark Brown wrote:
> On Wed, Jul 15, 2015 at 02:46:25PM +0200, Javier Martinez Canillas wrote:
>> On 07/15/2015 01:27 PM, Mark Brown wrote:
> 
>>> using _regulator_get() I think.  A separate, rarely used, path is likely
>>> to have this sort of issue.
> 
>> Exactly, do you agree then that a try_module_get() is missing in set_supply()?
> 
>> It is OK if I add that in the same patch in v2 or do you prefer that to be
>> in a separate patch?
> 
> A separate patch would be better, or even better would be something that
> just replaces everything there with use of the same code path as _get()
> (thanks for volunteering!) but just adding the try_module_get() is fine
> for now.
> 

I already posted a v2 of the series which adds a try_module_get() as a
separate patch but I'll add to my TODO list at factoring out both code
paths as a follow-up.

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America

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

end of thread, other threads:[~2015-07-15 15:57 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-14 14:21 [PATCH] regulator: core: Fix memory leak in regulator_resolve_supply() Javier Martinez Canillas
2015-07-15  8:01 ` Krzysztof Kozlowski
2015-07-15  8:38   ` Javier Martinez Canillas
2015-07-15 11:27     ` Mark Brown
2015-07-15 12:46       ` Javier Martinez Canillas
2015-07-15 15:52         ` Mark Brown
2015-07-15 15:56           ` Javier Martinez Canillas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox