From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752044AbbGOIip (ORCPT ); Wed, 15 Jul 2015 04:38:45 -0400 Received: from lists.s-osg.org ([54.187.51.154]:52916 "EHLO lists.s-osg.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751264AbbGOIin (ORCPT ); Wed, 15 Jul 2015 04:38:43 -0400 Subject: Re: [PATCH] regulator: core: Fix memory leak in regulator_resolve_supply() To: Krzysztof Kozlowski References: <1436883709-9337-1-git-send-email-javier@osg.samsung.com> From: Javier Martinez Canillas X-Enigmail-Draft-Status: N1110 Cc: Mark Brown , Liam Girdwood , linux-kernel@vger.kernel.org Message-ID: <55A61C0E.4040707@osg.samsung.com> Date: Wed, 15 Jul 2015 10:38:38 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.0.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 : >> 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 >> >> --- >> >> 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