diff mbox series

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

Message ID 20240820065804.560603-1-ruanjinjie@huawei.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series [-next] net: dsa: Simplify with scoped for each OF child loop | expand

Checks

Context Check Description
netdev/series_format warning Single patches do not need cover letters; Target tree name not specified in the subject
netdev/tree_selection success Guessed tree name to be net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 16 this patch: 16
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 7 of 7 maintainers
netdev/build_clang success Errors and warnings before: 16 this patch: 16
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 16 this patch: 16
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 38 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-08-20--09-00 (tests: 712)

Commit Message

Jinjie Ruan Aug. 20, 2024, 6:58 a.m. UTC
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(-)

Comments

Jakub Kicinski Aug. 22, 2024, 12:18 a.m. UTC | #1
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.
Jinjie Ruan Aug. 22, 2024, 2:07 a.m. UTC | #2
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/
Krzysztof Kozlowski Aug. 22, 2024, 2:39 p.m. UTC | #3
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
Jakub Kicinski Aug. 22, 2024, 2:51 p.m. UTC | #4
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?
Jakub Kicinski Aug. 22, 2024, 3:05 p.m. UTC | #5
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.
Jinjie Ruan Aug. 23, 2024, 2:20 a.m. UTC | #6
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
>
Jinjie Ruan Aug. 23, 2024, 2:22 a.m. UTC | #7
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.
Jinjie Ruan Aug. 23, 2024, 6:35 a.m. UTC | #8
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.
Andrew Lunn Aug. 25, 2024, 11:28 p.m. UTC | #9
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
Jinjie Ruan Aug. 26, 2024, 3:52 a.m. UTC | #10
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
diff mbox series

Patch

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: