[PATCH -next] net: dsa: Simplify with scoped for each OF child loop

Jinjie Ruan posted 1 patch 1 year, 5 months ago
net/dsa/dsa.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
[PATCH -next] net: dsa: Simplify with scoped for each OF child loop
Posted by Jinjie Ruan 1 year, 5 months ago
Use scoped for_each_available_child_of_node_scoped() when iterating over
device nodes to make code a bit simpler.

Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
 net/dsa/dsa.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 668c729946ea..77d91cbb0686 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -1264,7 +1264,7 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn)
 static int dsa_switch_parse_ports_of(struct dsa_switch *ds,
 				     struct device_node *dn)
 {
-	struct device_node *ports, *port;
+	struct device_node *ports;
 	struct dsa_port *dp;
 	int err = 0;
 	u32 reg;
@@ -1279,17 +1279,14 @@ static int dsa_switch_parse_ports_of(struct dsa_switch *ds,
 		}
 	}
 
-	for_each_available_child_of_node(ports, port) {
+	for_each_available_child_of_node_scoped(ports, port) {
 		err = of_property_read_u32(port, "reg", &reg);
-		if (err) {
-			of_node_put(port);
+		if (err)
 			goto out_put_node;
-		}
 
 		if (reg >= ds->num_ports) {
 			dev_err(ds->dev, "port %pOF index %u exceeds num_ports (%u)\n",
 				port, reg, ds->num_ports);
-			of_node_put(port);
 			err = -EINVAL;
 			goto out_put_node;
 		}
@@ -1297,10 +1294,8 @@ static int dsa_switch_parse_ports_of(struct dsa_switch *ds,
 		dp = dsa_to_port(ds, reg);
 
 		err = dsa_port_parse_of(dp, port);
-		if (err) {
-			of_node_put(port);
+		if (err)
 			goto out_put_node;
-		}
 	}
 
 out_put_node:
-- 
2.34.1
Re: [PATCH -next] net: dsa: Simplify with scoped for each OF child loop
Posted by Jakub Kicinski 1 year, 5 months ago
On Tue, 20 Aug 2024 14:58:04 +0800 Jinjie Ruan wrote:
> Use scoped for_each_available_child_of_node_scoped() when iterating over
> device nodes to make code a bit simpler.

Could you add more info here that confirms this works with gotos?
I don't recall the details but I thought sometimes the scoped
constructs don't do well with gotos. I checked 5 random uses
of this loop and 4 of them didn't have gotos.
Re: [PATCH -next] net: dsa: Simplify with scoped for each OF child loop
Posted by Jinjie Ruan 1 year, 5 months ago

On 2024/8/22 8:18, Jakub Kicinski wrote:
> On Tue, 20 Aug 2024 14:58:04 +0800 Jinjie Ruan wrote:
>> Use scoped for_each_available_child_of_node_scoped() when iterating over
>> device nodes to make code a bit simpler.
> 
> Could you add more info here that confirms this works with gotos?
> I don't recall the details but I thought sometimes the scoped
> constructs don't do well with gotos. I checked 5 random uses
> of this loop and 4 of them didn't have gotos.

Hi, Jakub

From what I understand, for_each_available_child_of_node_scoped() is not
related to gotos, it only let the iterating child node self-declared and
automatic release, so the of_node_put(iterating_child_node) can be removed.

For example, the following use case has goto and use this macro:

Link:
https://lore.kernel.org/all/20240813-b4-cleanup-h-of-node-put-other-v1-6-cfb67323a95c@linaro.org/
Re: [PATCH -next] net: dsa: Simplify with scoped for each OF child loop
Posted by Jakub Kicinski 1 year, 5 months ago
On Thu, 22 Aug 2024 10:07:25 +0800 Jinjie Ruan wrote:
> On 2024/8/22 8:18, Jakub Kicinski wrote:
> > On Tue, 20 Aug 2024 14:58:04 +0800 Jinjie Ruan wrote:  
> >> Use scoped for_each_available_child_of_node_scoped() when iterating over
> >> device nodes to make code a bit simpler.  
> > 
> > Could you add more info here that confirms this works with gotos?
> > I don't recall the details but I thought sometimes the scoped
> > constructs don't do well with gotos. I checked 5 random uses
> > of this loop and 4 of them didn't have gotos.  
> 
> Hi, Jakub
> 
> From what I understand, for_each_available_child_of_node_scoped() is not
> related to gotos, it only let the iterating child node self-declared and
> automatic release, so the of_node_put(iterating_child_node) can be removed.

Could you either test it or disasm the code to double check, please?
Re: [PATCH -next] net: dsa: Simplify with scoped for each OF child loop
Posted by Jinjie Ruan 1 year, 5 months ago

On 2024/8/22 22:51, Jakub Kicinski wrote:
> On Thu, 22 Aug 2024 10:07:25 +0800 Jinjie Ruan wrote:
>> On 2024/8/22 8:18, Jakub Kicinski wrote:
>>> On Tue, 20 Aug 2024 14:58:04 +0800 Jinjie Ruan wrote:  
>>>> Use scoped for_each_available_child_of_node_scoped() when iterating over
>>>> device nodes to make code a bit simpler.  
>>>
>>> Could you add more info here that confirms this works with gotos?
>>> I don't recall the details but I thought sometimes the scoped
>>> constructs don't do well with gotos. I checked 5 random uses
>>> of this loop and 4 of them didn't have gotos.  
>>
>> Hi, Jakub
>>
>> From what I understand, for_each_available_child_of_node_scoped() is not
>> related to gotos, it only let the iterating child node self-declared and
>> automatic release, so the of_node_put(iterating_child_node) can be removed.
> 
> Could you either test it or disasm the code to double check, please?

Hi, Jakub, I test it with a fake device node on QEMU with a simple
example using for_each_available_child_of_node_scoped() and goto out of
the scope of for_each_available_child_of_node_scoped(), the
of_node_put(child) has been called successfully.
Re: [PATCH -next] net: dsa: Simplify with scoped for each OF child loop
Posted by Andrew Lunn 1 year, 5 months ago
On Fri, Aug 23, 2024 at 02:35:04PM +0800, Jinjie Ruan wrote:
> 
> 
> On 2024/8/22 22:51, Jakub Kicinski wrote:
> > On Thu, 22 Aug 2024 10:07:25 +0800 Jinjie Ruan wrote:
> >> On 2024/8/22 8:18, Jakub Kicinski wrote:
> >>> On Tue, 20 Aug 2024 14:58:04 +0800 Jinjie Ruan wrote:  
> >>>> Use scoped for_each_available_child_of_node_scoped() when iterating over
> >>>> device nodes to make code a bit simpler.  
> >>>
> >>> Could you add more info here that confirms this works with gotos?
> >>> I don't recall the details but I thought sometimes the scoped
> >>> constructs don't do well with gotos. I checked 5 random uses
> >>> of this loop and 4 of them didn't have gotos.  
> >>
> >> Hi, Jakub
> >>
> >> From what I understand, for_each_available_child_of_node_scoped() is not
> >> related to gotos, it only let the iterating child node self-declared and
> >> automatic release, so the of_node_put(iterating_child_node) can be removed.
> > 
> > Could you either test it or disasm the code to double check, please?
> 
> Hi, Jakub, I test it with a fake device node on QEMU with a simple
> example using for_each_available_child_of_node_scoped() and goto out of
> the scope of for_each_available_child_of_node_scoped(), the
> of_node_put(child) has been called successfully.

What compiler version?

Please test with 5.1

https://www.kernel.org/doc/html/next/process/changes.html

	Andrew
Re: [PATCH -next] net: dsa: Simplify with scoped for each OF child loop
Posted by Jinjie Ruan 1 year, 5 months ago

On 2024/8/26 7:28, Andrew Lunn wrote:
> On Fri, Aug 23, 2024 at 02:35:04PM +0800, Jinjie Ruan wrote:
>>
>>
>> On 2024/8/22 22:51, Jakub Kicinski wrote:
>>> On Thu, 22 Aug 2024 10:07:25 +0800 Jinjie Ruan wrote:
>>>> On 2024/8/22 8:18, Jakub Kicinski wrote:
>>>>> On Tue, 20 Aug 2024 14:58:04 +0800 Jinjie Ruan wrote:  
>>>>>> Use scoped for_each_available_child_of_node_scoped() when iterating over
>>>>>> device nodes to make code a bit simpler.  
>>>>>
>>>>> Could you add more info here that confirms this works with gotos?
>>>>> I don't recall the details but I thought sometimes the scoped
>>>>> constructs don't do well with gotos. I checked 5 random uses
>>>>> of this loop and 4 of them didn't have gotos.  
>>>>
>>>> Hi, Jakub
>>>>
>>>> From what I understand, for_each_available_child_of_node_scoped() is not
>>>> related to gotos, it only let the iterating child node self-declared and
>>>> automatic release, so the of_node_put(iterating_child_node) can be removed.
>>>
>>> Could you either test it or disasm the code to double check, please?
>>
>> Hi, Jakub, I test it with a fake device node on QEMU with a simple
>> example using for_each_available_child_of_node_scoped() and goto out of
>> the scope of for_each_available_child_of_node_scoped(), the
>> of_node_put(child) has been called successfully.
> 
> What compiler version?
> 
> Please test with 5.1

with 5.1, the result is same and of_node_put(child) has been called
successfully.

The test patch and test result is below (with CONFIG_OF_DYNAMIC=y)

trace event string verifier disabled
rcu: Hierarchical RCU implementation.
rcu:    RCU event tracing is enabled.
rcu:    RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
get ppi-partitions ok!
OF: ====================================== of_node_put interrupt-partition-0
of_get_child_count parts_node 2!
OF: ====================================== of_node_put interrupt-partition-0
OF: of_irq_init: Failed to init /interrupt-controller@1e001000
((ptrval)), parent 00000000



diff --git a/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
b/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
index 43a5a4ab6ff0..79715727ea03 100644
--- a/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
@@ -161,6 +161,16 @@ gic: interrupt-controller@1e001000 {
                interrupt-controller;
                reg = <0x1e001000 0x1000>,
                      <0x1e000100 0x100>;
+
+               ppi-partitions {
+                       ppi_cluster0: interrupt-partition-0 {
+                               affinity = <&A9_0 &A9_1>;
+                       };
+
+                       ppi_cluster1: interrupt-partition-1 {
+                               affinity = <&A9_2 &A9_3>;
+                       };
+               };
        };

        L2: cache-controller@1e00a000 {
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 3be7bd8cd8cd..35e1387453f5 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1468,10 +1468,39 @@ gic_of_init(struct device_node *node, struct
device_node *parent)
 {
        struct gic_chip_data *gic;
        int irq, ret;
+       struct device_node *parts_node;
+       int nr_parts;

        if (WARN_ON(!node))
                return -ENODEV;

+       parts_node = of_get_child_by_name(node, "ppi-partitions");
+       if (!parts_node)
+               return -1;
+
+       pr_err("get ppi-partitions ok!\n");
+
+       nr_parts = of_get_child_count(parts_node);
+
+       if (!nr_parts) {
+               pr_err("of_get_child_count parts_node error!\n");
+               return -1;
+       }
+
+       pr_err("of_get_child_count parts_node %d!\n", nr_parts);
+
+       /*for_each_child_of_node(parts_node, child_node) {
+               if (true) {
+                       pr_err("of_node_put child_node
%s\n",child_node->name);
+                       of_node_put(child_node);
+                       return -1;
+               }
+       }*/
+       for_each_available_child_of_node_scoped(parts_node, child_node) {
+               if (true)
+                       goto exit;
+       }
+
        if (WARN_ON(gic_cnt >= CONFIG_ARM_GIC_MAX_NR))
                return -EINVAL;

@@ -1509,6 +1538,9 @@ gic_of_init(struct device_node *node, struct
device_node *parent)

        gic_cnt++;
        return 0;
+
+exit:
+       return -EINVAL;
 }
 IRQCHIP_DECLARE(gic_400, "arm,gic-400", gic_of_init);
 IRQCHIP_DECLARE(arm11mp_gic, "arm,arm11mp-gic", gic_of_init);
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 110104a936d9..d9ccf3117dff 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -46,8 +46,11 @@ EXPORT_SYMBOL(of_node_get);
  */
 void of_node_put(struct device_node *node)
 {
-       if (node)
+       if (node) {
+               if (!strcmp(node->name, "interrupt-partition-0"))
+                       pr_err("======================================
of_node_put interrupt-partition-0\n");
                kobject_put(&node->kobj);
+       }
 }
 EXPORT_SYMBOL(of_node_put);



> 
> https://www.kernel.org/doc/html/next/process/changes.html
> 
> 	Andrew
Re: [PATCH -next] net: dsa: Simplify with scoped for each OF child loop
Posted by Jinjie Ruan 1 year, 5 months ago

On 2024/8/22 22:51, Jakub Kicinski wrote:
> On Thu, 22 Aug 2024 10:07:25 +0800 Jinjie Ruan wrote:
>> On 2024/8/22 8:18, Jakub Kicinski wrote:
>>> On Tue, 20 Aug 2024 14:58:04 +0800 Jinjie Ruan wrote:  
>>>> Use scoped for_each_available_child_of_node_scoped() when iterating over
>>>> device nodes to make code a bit simpler.  
>>>
>>> Could you add more info here that confirms this works with gotos?
>>> I don't recall the details but I thought sometimes the scoped
>>> constructs don't do well with gotos. I checked 5 random uses
>>> of this loop and 4 of them didn't have gotos.  
>>
>> Hi, Jakub
>>
>> From what I understand, for_each_available_child_of_node_scoped() is not
>> related to gotos, it only let the iterating child node self-declared and
>> automatic release, so the of_node_put(iterating_child_node) can be removed.
> 
> Could you either test it or disasm the code to double check, please?

Thank you! I'll try to test it and double check it.
Re: [PATCH -next] net: dsa: Simplify with scoped for each OF child loop
Posted by Krzysztof Kozlowski 1 year, 5 months ago
On 22/08/2024 04:07, Jinjie Ruan wrote:
> 
> 
> On 2024/8/22 8:18, Jakub Kicinski wrote:
>> On Tue, 20 Aug 2024 14:58:04 +0800 Jinjie Ruan wrote:
>>> Use scoped for_each_available_child_of_node_scoped() when iterating over
>>> device nodes to make code a bit simpler.
>>
>> Could you add more info here that confirms this works with gotos?
>> I don't recall the details but I thought sometimes the scoped
>> constructs don't do well with gotos. I checked 5 random uses
>> of this loop and 4 of them didn't have gotos.
> 
> Hi, Jakub
> 
>>From what I understand, for_each_available_child_of_node_scoped() is not
> related to gotos, it only let the iterating child node self-declared and
> automatic release, so the of_node_put(iterating_child_node) can be removed.
> 
> For example, the following use case has goto and use this macro:
> 
> Link:
> https://lore.kernel.org/all/20240813-b4-cleanup-h-of-node-put-other-v1-6-cfb67323a95c@linaro.org/

Jinjie,
You started this after me, shortly after my series, taking the commit
msgs and subjects, and even using my work as reference or explanation of
your patches. Basically you just copy-paste. That's ok, thouogh, but you
could at least Cc me to tell me that you are doing it to avoid
duplication. That would be nice... And you could *try to* understand
what you are doing, so you can answer to such concerns as Jakub raised.
Otherwise how can we know that your code is correct?

Jakub,
Scoped uses in-place variable declarations, thus earlier jumps over it
are not allowed. The code I was converting did not have such jumps, so
was fine. Not sure if this is the case here, because Jinjie Ruan should
have checked it and explained that it is safe.

Best regards,
Krzysztof
Re: [PATCH -next] net: dsa: Simplify with scoped for each OF child loop
Posted by Jinjie Ruan 1 year, 5 months ago

On 2024/8/22 22:39, Krzysztof Kozlowski wrote:
> On 22/08/2024 04:07, Jinjie Ruan wrote:
>>
>>
>> On 2024/8/22 8:18, Jakub Kicinski wrote:
>>> On Tue, 20 Aug 2024 14:58:04 +0800 Jinjie Ruan wrote:
>>>> Use scoped for_each_available_child_of_node_scoped() when iterating over
>>>> device nodes to make code a bit simpler.
>>>
>>> Could you add more info here that confirms this works with gotos?
>>> I don't recall the details but I thought sometimes the scoped
>>> constructs don't do well with gotos. I checked 5 random uses
>>> of this loop and 4 of them didn't have gotos.
>>
>> Hi, Jakub
>>
>> >From what I understand, for_each_available_child_of_node_scoped() is not
>> related to gotos, it only let the iterating child node self-declared and
>> automatic release, so the of_node_put(iterating_child_node) can be removed.
>>
>> For example, the following use case has goto and use this macro:
>>
>> Link:
>> https://lore.kernel.org/all/20240813-b4-cleanup-h-of-node-put-other-v1-6-cfb67323a95c@linaro.org/
> 
> Jinjie,
> You started this after me, shortly after my series, taking the commit
> msgs and subjects, and even using my work as reference or explanation of
> your patches. Basically you just copy-paste. That's ok, thouogh, but you
> could at least Cc me to tell me that you are doing it to avoid
> duplication. That would be nice... And you could *try to* understand
> what you are doing, so you can answer to such concerns as Jakub raised.
> Otherwise how can we know that your code is correct?

Thank you very much, I'll Cc you for other patches.

> 
> Jakub,
> Scoped uses in-place variable declarations, thus earlier jumps over it
> are not allowed. The code I was converting did not have such jumps, so
> was fine. Not sure if this is the case here, because Jinjie Ruan should
> have checked it and explained that it is safe.
> 
> Best regards,
> Krzysztof
>
Re: [PATCH -next] net: dsa: Simplify with scoped for each OF child loop
Posted by Jakub Kicinski 1 year, 5 months ago
On Thu, 22 Aug 2024 16:39:38 +0200 Krzysztof Kozlowski wrote:
> Jakub,
> Scoped uses in-place variable declarations, thus earlier jumps over it
> are not allowed. The code I was converting did not have such jumps, so
> was fine. Not sure if this is the case here, because Jinjie Ruan should
> have checked it and explained that it is safe.

I see, thank you!

Jinjie Ruan please repost crediting Krzysztof more.