On 23/07/2019 11:35, Nishka Dasgupta wrote:
Each iteration of for_each_available_child_of_node puts the previous
node, but in the case of a goto from the middle of the loop, there is
no put, thus causing a memory leak. Add an of_node_put before the
goto in 4 places.
Why not just add it once at the "out" label itself? (Consider the
conditions for the loop terminating naturally)
And if you're cleaning up the refcounting here anyway then I'd also note
that the reference held by the loop iterator makes the extra get/put
inside that loop entirely redundant. It's always worth taking a look at
the wider context rather than just blindly focusing on what a given
script picks up - it's fairly rare that a piece of code has one obvious
issue but is otherwise perfect.
Robin.
Issue found with Coccinelle.
Signed-off-by: Nishka Dasgupta <nishkadg.linux@xxxxxxxxx>
---
drivers/dma/qcom/hidma_mgmt.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/qcom/hidma_mgmt.c b/drivers/dma/qcom/hidma_mgmt.c
index 3022d66e7a33..209adc6ceabe 100644
--- a/drivers/dma/qcom/hidma_mgmt.c
+++ b/drivers/dma/qcom/hidma_mgmt.c
@@ -362,16 +362,22 @@ static int __init hidma_mgmt_of_populate_channels(struct device_node *np)
struct platform_device *new_pdev;
ret = of_address_to_resource(child, 0, &res[0]);
- if (!ret)
+ if (!ret) {
+ of_node_put(child);
goto out;
+ }
ret = of_address_to_resource(child, 1, &res[1]);
- if (!ret)
+ if (!ret) {
+ of_node_put(child);
goto out;
+ }
ret = of_irq_to_resource(child, 0, &res[2]);
- if (ret <= 0)
+ if (ret <= 0) {
+ of_node_put(child);
goto out;
+ }
memset(&pdevinfo, 0, sizeof(pdevinfo));
pdevinfo.fwnode = &child->fwnode;
@@ -386,6 +392,7 @@ static int __init hidma_mgmt_of_populate_channels(struct device_node *np)
new_pdev = platform_device_register_full(&pdevinfo);
if (IS_ERR(new_pdev)) {
ret = PTR_ERR(new_pdev);
+ of_node_put(child);
goto out;
}
of_node_get(child);