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 |
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.
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/
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
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?
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.
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 >
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.
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.
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
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 --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", ®); - 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:
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(-)