2015-12-21 16:52:23

by Julia Lawall

[permalink] [raw]
Subject: [PATCH 0/5] add missing of_node_put

The various for_each device_node iterators performs an of_node_get on each
iteration, so a break out of the loop requires an of_node_put.

The complete semantic patch that fixes this problem is
(http://coccinelle.lip6.fr):

// <smpl>
@r@
local idexpression n;
expression e1,e2;
iterator name for_each_node_by_name, for_each_node_by_type,
for_each_compatible_node, for_each_matching_node,
for_each_matching_node_and_match, for_each_child_of_node,
for_each_available_child_of_node, for_each_node_with_property;
iterator i;
statement S;
expression list [n1] es;
@@

(
(
for_each_node_by_name(n,e1) S
|
for_each_node_by_type(n,e1) S
|
for_each_compatible_node(n,e1,e2) S
|
for_each_matching_node(n,e1) S
|
for_each_matching_node_and_match(n,e1,e2) S
|
for_each_child_of_node(e1,n) S
|
for_each_available_child_of_node(e1,n) S
|
for_each_node_with_property(n,e1) S
)
&
i(es,n,...) S
)

@@
local idexpression r.n;
iterator r.i;
expression e;
expression list [r.n1] es;
@@

i(es,n,...) {
...
(
of_node_put(n);
|
e = n
|
return n;
|
+ of_node_put(n);
? return ...;
)
...
}

@@
local idexpression r.n;
iterator r.i;
expression e;
expression list [r.n1] es;
@@

i(es,n,...) {
...
(
of_node_put(n);
|
e = n
|
+ of_node_put(n);
? break;
)
...
}
... when != n

@@
local idexpression r.n;
iterator r.i;
expression e;
identifier l;
expression list [r.n1] es;
@@

i(es,n,...) {
...
(
of_node_put(n);
|
e = n
|
+ of_node_put(n);
? goto l;
)
...
}
...
l: ... when != n// </smpl>

---

drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 1 +
drivers/pinctrl/pinctrl-rockchip.c | 5 ++++-
drivers/pinctrl/pinctrl-tegra-xusb.c | 4 +++-
drivers/pinctrl/pinctrl-tegra.c | 1 +
drivers/pinctrl/sh-pfc/pinctrl.c | 4 +++-
drivers/pinctrl/sirf/pinctrl-sirf.c | 8 ++++++--
6 files changed, 18 insertions(+), 5 deletions(-)


2015-12-21 16:53:28

by Julia Lawall

[permalink] [raw]
Subject: [PATCH 1/5] pinctrl-tegra: add missing of_node_put

for_each_child_of_node performs an of_node_get on each iteration, so a
return from the loop requires an of_node_put.

A simplified version of the semantic patch that fixes this problem is as
follows (http://coccinelle.lip6.fr):

// <smpl>
@@
local idexpression n;
expression e,e1;
@@

for_each_child_of_node(e1,n) {
...
(
of_node_put(n);
|
e = n
|
return n;
|
+ of_node_put(n);
? return ...;
)
...
}
// </smpl>

Signed-off-by: Julia Lawall <[email protected]>

---
drivers/pinctrl/pinctrl-tegra-xusb.c | 4 +++-
drivers/pinctrl/pinctrl-tegra.c | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-tegra-xusb.c b/drivers/pinctrl/pinctrl-tegra-xusb.c
index 84a43e6..bd3aa5a 100644
--- a/drivers/pinctrl/pinctrl-tegra-xusb.c
+++ b/drivers/pinctrl/pinctrl-tegra-xusb.c
@@ -253,8 +253,10 @@ static int tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev *pinctrl,
err = tegra_xusb_padctl_parse_subnode(padctl, np, maps,
&reserved_maps,
num_maps);
- if (err < 0)
+ if (err < 0) {
+ of_node_put(np);
return err;
+ }
}

return 0;
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c
index 0fd7fd2..9da4da2 100644
--- a/drivers/pinctrl/pinctrl-tegra.c
+++ b/drivers/pinctrl/pinctrl-tegra.c
@@ -217,6 +217,7 @@ static int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
if (ret < 0) {
pinctrl_utils_dt_free_map(pctldev, *map,
*num_maps);
+ of_node_put(np);
return ret;
}
}

2015-12-21 16:53:44

by Julia Lawall

[permalink] [raw]
Subject: [PATCH 2/5] pinctrl: sirf: add missing of_node_put

for_each_child_of_node performs an of_node_get on each iteration, so a
return from the loop requires an of_node_put.

A simplified version of the semantic patch that fixes this problem is as
follows (http://coccinelle.lip6.fr):

// <smpl>
@@
local idexpression n;
expression e,e1;
@@

for_each_child_of_node(e1,n) {
...
(
of_node_put(n);
|
e = n
|
return n;
|
+ of_node_put(n);
? return ...;
)
...
}
// </smpl>

Signed-off-by: Julia Lawall <[email protected]>

---
drivers/pinctrl/sirf/pinctrl-sirf.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c
index ae97bdc..18fe46d 100644
--- a/drivers/pinctrl/sirf/pinctrl-sirf.c
+++ b/drivers/pinctrl/sirf/pinctrl-sirf.c
@@ -85,12 +85,16 @@ static int sirfsoc_dt_node_to_map(struct pinctrl_dev *pctldev,
/* calculate number of maps required */
for_each_child_of_node(np_config, np) {
ret = of_property_read_string(np, "sirf,function", &function);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(np);
return ret;
+ }

ret = of_property_count_strings(np, "sirf,pins");
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(np);
return ret;
+ }

count += ret;
}

2015-12-21 16:52:43

by Julia Lawall

[permalink] [raw]
Subject: [PATCH 3/5] pinctrl: sh-pfc: add missing of_node_put

for_each_child_of_node performs an of_node_get on each iteration, so a
goto out of the loop requires an of_node_put.

A simplified version of the semantic patch that fixes this problem is as
follows (http://coccinelle.lip6.fr):

// <smpl>
@@
local idexpression n;
expression e,e1;
identifier l;
@@

for_each_child_of_node(e1,n) {
...
(
of_node_put(n);
|
e = n
|
return n;
|
+ of_node_put(n);
? goto l;
)
...
}
l: ... when != n
// </smpl>

Signed-off-by: Julia Lawall <[email protected]>

---
drivers/pinctrl/sh-pfc/pinctrl.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c
index 863c3e3..87b0a59 100644
--- a/drivers/pinctrl/sh-pfc/pinctrl.c
+++ b/drivers/pinctrl/sh-pfc/pinctrl.c
@@ -273,8 +273,10 @@ static int sh_pfc_dt_node_to_map(struct pinctrl_dev *pctldev,
for_each_child_of_node(np, child) {
ret = sh_pfc_dt_subnode_to_map(pctldev, child, map, num_maps,
&index);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(child);
goto done;
+ }
}

/* If no mapping has been found in child nodes try the config node. */

2015-12-21 16:52:44

by Julia Lawall

[permalink] [raw]
Subject: [PATCH 4/5] pinctrl: rockchip: add missing of_node_put

for_each_child_of_node performs an of_node_get on each iteration, so a
return from the loop requires an of_node_put.

A simplified version of the semantic patch that fixes this problem is as
follows (http://coccinelle.lip6.fr):

// <smpl>
@@
local idexpression n;
expression e,e1;
@@

for_each_child_of_node(e1,n) {
...
(
of_node_put(n);
|
e = n
|
return n;
|
+ of_node_put(n);
? return ...;
)
...
}
// </smpl>

Signed-off-by: Julia Lawall <[email protected]>

---
drivers/pinctrl/pinctrl-rockchip.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 2b88a40..d0305a2 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -1258,8 +1258,10 @@ static int rockchip_pinctrl_parse_functions(struct device_node *np,
func->groups[i] = child->name;
grp = &info->groups[grp_index++];
ret = rockchip_pinctrl_parse_groups(child, grp, info, i++);
- if (ret)
+ if (ret) {
+ of_node_put(child);
return ret;
+ }
}

return 0;
@@ -1304,6 +1306,7 @@ static int rockchip_pinctrl_parse_dt(struct platform_device *pdev,
ret = rockchip_pinctrl_parse_functions(child, info, i++);
if (ret) {
dev_err(&pdev->dev, "failed to parse function\n");
+ of_node_put(child);
return ret;
}
}

2015-12-21 16:52:25

by Julia Lawall

[permalink] [raw]
Subject: [PATCH 5/5] pinctrl: mediatek: add missing of_node_put

for_each_child_of_node performs an of_node_get on each iteration, so a
return from the loop requires an of_node_put.

A simplified version of the semantic patch that fixes this problem is as
follows (http://coccinelle.lip6.fr):

// <smpl>
@@
local idexpression n;
expression e,e1;
@@

for_each_child_of_node(e1,n) {
...
(
of_node_put(n);
|
e = n
|
return n;
|
+ of_node_put(n);
? return ...;
)
...
}
// </smpl>

Signed-off-by: Julia Lawall <[email protected]>

---
drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index 45f3562..ee2287b 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -598,6 +598,7 @@ static int mtk_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
&reserved_maps, num_maps);
if (ret < 0) {
pinctrl_utils_dt_free_map(pctldev, *map, *num_maps);
+ of_node_put(np);
return ret;
}
}

2015-12-21 20:46:12

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH 3/5] pinctrl: sh-pfc: add missing of_node_put

Hi Julia,

Thank you for the patch.

On Monday 21 December 2015 17:39:46 Julia Lawall wrote:
> for_each_child_of_node performs an of_node_get on each iteration, so a
> goto out of the loop requires an of_node_put.
>
> A simplified version of the semantic patch that fixes this problem is as
> follows (http://coccinelle.lip6.fr):
>
> // <smpl>
> @@
> local idexpression n;
> expression e,e1;
> identifier l;
> @@
>
> for_each_child_of_node(e1,n) {
> ...
> (
> of_node_put(n);
>
> e = n
>
> return n;
>
> + of_node_put(n);
> ? goto l;
> )
> ...
> }
> l: ... when != n
> // </smpl>
>
> Signed-off-by: Julia Lawall <[email protected]>

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
> drivers/pinctrl/sh-pfc/pinctrl.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c
> b/drivers/pinctrl/sh-pfc/pinctrl.c index 863c3e3..87b0a59 100644
> --- a/drivers/pinctrl/sh-pfc/pinctrl.c
> +++ b/drivers/pinctrl/sh-pfc/pinctrl.c
> @@ -273,8 +273,10 @@ static int sh_pfc_dt_node_to_map(struct pinctrl_dev
> *pctldev, for_each_child_of_node(np, child) {
> ret = sh_pfc_dt_subnode_to_map(pctldev, child, map, num_maps,
> &index);
> - if (ret < 0)
> + if (ret < 0) {
> + of_node_put(child);
> goto done;
> + }
> }
>
> /* If no mapping has been found in child nodes try the config node. */

--
Regards,

Laurent Pinchart

2015-12-21 21:20:30

by Heiko Stuebner

[permalink] [raw]
Subject: Re: [PATCH 4/5] pinctrl: rockchip: add missing of_node_put

Hi Julia,

Am Montag, 21. Dezember 2015, 17:39:47 schrieb Julia Lawall:
> for_each_child_of_node performs an of_node_get on each iteration, so a
> return from the loop requires an of_node_put.
>
> A simplified version of the semantic patch that fixes this problem is as
> follows (http://coccinelle.lip6.fr):
>
> // <smpl>
> @@
> local idexpression n;
> expression e,e1;
> @@
>
> for_each_child_of_node(e1,n) {
> ...
> (
> of_node_put(n);
>
> e = n
>
> return n;
>
> + of_node_put(n);
> ? return ...;
> )
> ...
> }
> // </smpl>
>
> Signed-off-by: Julia Lawall <[email protected]>

thanks for catching this :-)

I still remember how we talked about that same issue in the phy driver and the
things for_each_child_of_node does when running, so

Reviewed-by: Heiko Stuebner <[email protected]>


Thanks
Heiko

2015-12-22 12:44:29

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 1/5] pinctrl-tegra: add missing of_node_put

On Mon, Dec 21, 2015 at 5:39 PM, Julia Lawall <[email protected]> wrote:

> for_each_child_of_node performs an of_node_get on each iteration, so a
> return from the loop requires an of_node_put.
>
> A simplified version of the semantic patch that fixes this problem is as
> follows (http://coccinelle.lip6.fr):

Patch applied.

Yours,
Linus Walleij

2015-12-22 12:45:25

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 2/5] pinctrl: sirf: add missing of_node_put

On Mon, Dec 21, 2015 at 5:39 PM, Julia Lawall <[email protected]> wrote:

> for_each_child_of_node performs an of_node_get on each iteration, so a
> return from the loop requires an of_node_put.
>
> A simplified version of the semantic patch that fixes this problem is as
> follows (http://coccinelle.lip6.fr):

Patch applied.

Yours,
Linus Walleij

2015-12-22 12:47:23

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 3/5] pinctrl: sh-pfc: add missing of_node_put

On Mon, Dec 21, 2015 at 5:39 PM, Julia Lawall <[email protected]> wrote:

> for_each_child_of_node performs an of_node_get on each iteration, so a
> goto out of the loop requires an of_node_put.
>
> A simplified version of the semantic patch that fixes this problem is as
> follows (http://coccinelle.lip6.fr):

Patch applied with Laurent's ACK.

Geert: since I don't think you're gonna send me more pull
requests before the merge window I went ahead and applied
this directly, OK?

Yours,
Linus Walleij

2015-12-22 12:48:38

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 4/5] pinctrl: rockchip: add missing of_node_put

On Mon, Dec 21, 2015 at 5:39 PM, Julia Lawall <[email protected]> wrote:

> for_each_child_of_node performs an of_node_get on each iteration, so a
> return from the loop requires an of_node_put.
>
> A simplified version of the semantic patch that fixes this problem is as
> follows (http://coccinelle.lip6.fr):

Patch applied with Heiko's review tag.

Yours,
Linus Walleij

2015-12-22 12:49:40

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 5/5] pinctrl: mediatek: add missing of_node_put

On Mon, Dec 21, 2015 at 5:39 PM, Julia Lawall <[email protected]> wrote:

> for_each_child_of_node performs an of_node_get on each iteration, so a
> return from the loop requires an of_node_put.
>
> A simplified version of the semantic patch that fixes this problem is as
> follows (http://coccinelle.lip6.fr):

Patch applied.

Yours,
Linus Walleij

2015-12-22 13:23:05

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 3/5] pinctrl: sh-pfc: add missing of_node_put

Hi Linus,

On Tue, Dec 22, 2015 at 1:47 PM, Linus Walleij <[email protected]> wrote:
> On Mon, Dec 21, 2015 at 5:39 PM, Julia Lawall <[email protected]> wrote:
>> for_each_child_of_node performs an of_node_get on each iteration, so a
>> goto out of the loop requires an of_node_put.
>>
>> A simplified version of the semantic patch that fixes this problem is as
>> follows (http://coccinelle.lip6.fr):
>
> Patch applied with Laurent's ACK.
>
> Geert: since I don't think you're gonna send me more pull
> requests before the merge window I went ahead and applied
> this directly, OK?

You're reading my mind ;-)

Thanks!

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds