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/bluetooth/btmrvl_main.c | 5 ++++- drivers/gpu/drm/tegra/dc.c | 4 +++- drivers/gpu/host1x/bus.c | 4 +++- drivers/leds/leds-88pm860x.c | 1 + drivers/leds/leds-bcm6328.c | 4 +++- drivers/leds/leds-bcm6358.c | 4 +++- drivers/leds/leds-powernv.c | 8 ++++++-- drivers/pinctrl/pinctrl-at91.c | 5 ++++- drivers/soc/ti/knav_qmss_queue.c | 3 +++ 9 files changed, 30 insertions(+), 8 deletions(-)
for_each_matching_node performs an of_node_get on each iteration, so a break 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; @@
for_each_matching_node(n,...) { ... ( of_node_put(n); | e = n | + of_node_put(n); ? break; ) ... } ... when != n // </smpl>
Signed-off-by: Julia Lawall Julia.Lawall@lip6.fr
--- drivers/gpu/drm/tegra/dc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index b4af4ab..f0e6f37 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1945,8 +1945,10 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc) * cases where only a single display controller is used. */ for_each_matching_node(np, tegra_dc_of_match) { - if (np == dc->dev->of_node) + if (np == dc->dev->of_node) { + of_node_put(np); break; + }
value++; }
On Sat, Oct 24, 2015 at 04:42:31PM +0200, Julia Lawall wrote:
for_each_matching_node performs an of_node_get on each iteration, so a break 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; @@
for_each_matching_node(n,...) { ... ( of_node_put(n); | e = n |
- of_node_put(n);
? break; ) ... } ... when != n // </smpl>
Signed-off-by: Julia Lawall Julia.Lawall@lip6.fr
drivers/gpu/drm/tegra/dc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
Applied, thanks.
Thierry
for_each_child_of_node performs an of_node_get on each iteration, so a break 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> @@ expression root,e; local idexpression child; @@
for_each_child_of_node(root, child) { ... when != of_node_put(child) when != e = child ( return child; | + of_node_put(child); ? return ...; ) ... } // </smpl>
Signed-off-by: Julia Lawall Julia.Lawall@lip6.fr
--- drivers/gpu/host1x/bus.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index 4a99c64..c1795a2 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -82,8 +82,10 @@ static int host1x_device_parse_dt(struct host1x_device *device, if (of_match_node(driver->subdevs, np) && of_device_is_available(np)) { err = host1x_subdev_add(device, np); - if (err < 0) + if (err < 0) { + of_node_put(np); return err; + } } }
Hi Julia,
Patches 1-4 have been applied to the LED tree, thanks.
On 10/24/2015 04:42 PM, Julia Lawall wrote:
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):
[...]
dri-devel@lists.freedesktop.org