[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <b12e8c5c5d6ab3061d9504de8fbaefcad6bbc385.1629321668.git.christophe.jaillet@wanadoo.fr>
Date: Wed, 18 Aug 2021 23:21:59 +0200
From: Christophe JAILLET <christophe.jaillet@...adoo.fr>
To: leoyang.li@....com
Cc: linuxppc-dev@...ts.ozlabs.org,
linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org,
kernel-janitors@...r.kernel.org,
Christophe JAILLET <christophe.jaillet@...adoo.fr>
Subject: [PATCH] soc: fsl: guts: Fix a resource leak in the error handling path of 'fsl_guts_probe()'
If an error occurs after 'of_find_node_by_path()', the reference taken for
'root' will never be released and some memory will leak.
Instead of adding an error handling path and modifying all the
'return -SOMETHING' into 'goto errorpath', use 'devm_add_action_or_reset()'
to release the reference when needed.
Simplify the remove function accordingly.
As an extra benefit, the 'root' global variable can now be removed as well.
Fixes: 3c0d64e867ed ("soc: fsl: guts: reuse machine name from device tree")
Signed-off-by: Christophe JAILLET <christophe.jaillet@...adoo.fr>
---
Compile tested only
---
drivers/soc/fsl/guts.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index d5e9a5f2c087..4d9476c7b87c 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -28,7 +28,6 @@ struct fsl_soc_die_attr {
static struct guts *guts;
static struct soc_device_attribute soc_dev_attr;
static struct soc_device *soc_dev;
-static struct device_node *root;
/* SoC die attribute definition for QorIQ platform */
@@ -136,14 +135,23 @@ static u32 fsl_guts_get_svr(void)
return svr;
}
+static void fsl_guts_put_root(void *data)
+{
+ struct device_node *root = data;
+
+ of_node_put(root);
+}
+
static int fsl_guts_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
+ struct device_node *root;
struct resource *res;
const struct fsl_soc_die_attr *soc_die;
const char *machine;
u32 svr;
+ int ret;
/* Initialize guts */
guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL);
@@ -159,6 +167,10 @@ static int fsl_guts_probe(struct platform_device *pdev)
/* Register soc device */
root = of_find_node_by_path("/");
+ ret = devm_add_action_or_reset(dev, fsl_guts_put_root, root);
+ if (ret)
+ return ret;
+
if (of_property_read_string(root, "model", &machine))
of_property_read_string_index(root, "compatible", 0, &machine);
if (machine)
@@ -197,7 +209,7 @@ static int fsl_guts_probe(struct platform_device *pdev)
static int fsl_guts_remove(struct platform_device *dev)
{
soc_device_unregister(soc_dev);
- of_node_put(root);
+
return 0;
}
--
2.30.2
Powered by blists - more mailing lists