[PATCH] macintosh/windfarm_smu_sat: Add missing of_node_put()

2023-03-29 Thread Liang He
We call of_node_get() in wf_sat_probe() after sat is created,
so we need the of_node_put() before *kfree(sat)*.

Fixes: ac171c46667c ("[PATCH] powerpc: Thermal control for dual core G5s")
Signed-off-by: Liang He 
---
 drivers/macintosh/windfarm_smu_sat.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/macintosh/windfarm_smu_sat.c 
b/drivers/macintosh/windfarm_smu_sat.c
index ebc4256a9e4a..089f2743a070 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -171,6 +171,7 @@ static void wf_sat_release(struct kref *ref)
 
if (sat->nr >= 0)
sats[sat->nr] = NULL;
+   of_node_put(sat->node);
kfree(sat);
 }
 
-- 
2.25.1



[PATCH] powerpc/mpc5xxx: Add missing fwnode_handle_put()

2023-03-21 Thread Liang He
In mpc5xxx_fwnode_get_bus_frequency(), we should add
fwnode_handle_put() when break out of the iteration
fwnode_for_each_parent_node() as it will automatically
increase and decrease the refcounter.

Fixes: de06fba62af6 ("powerpc/mpc5xxx: Switch mpc5xxx_get_bus_frequency() to 
use fwnode")
Signed-off-by: Liang He 
---
 arch/powerpc/sysdev/mpc5xxx_clocks.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/sysdev/mpc5xxx_clocks.c 
b/arch/powerpc/sysdev/mpc5xxx_clocks.c
index c5bf7e1b3780..58cee28e2399 100644
--- a/arch/powerpc/sysdev/mpc5xxx_clocks.c
+++ b/arch/powerpc/sysdev/mpc5xxx_clocks.c
@@ -25,8 +25,10 @@ unsigned long mpc5xxx_fwnode_get_bus_frequency(struct 
fwnode_handle *fwnode)
 
fwnode_for_each_parent_node(fwnode, parent) {
ret = fwnode_property_read_u32(parent, "bus-frequency", 
_freq);
-   if (!ret)
+   if (!ret) {
+   fwnode_handle_put(parent);
return bus_freq;
+   }
}
 
return 0;
-- 
2.25.1



[PATCH] serial: ucc_uart: Add of_node_put() in ucc_uart_remove()

2022-12-05 Thread Liang He
In ucc_uart_probe(), we have added proper of_node_put() in the failure
paths. However, we miss it before we free *qe_port* in the remove() function.

Signed-off-by: Liang He 
---
 drivers/tty/serial/ucc_uart.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c
index 82cf14dd3d43..461d54de6351 100644
--- a/drivers/tty/serial/ucc_uart.c
+++ b/drivers/tty/serial/ucc_uart.c
@@ -1469,6 +1469,8 @@ static int ucc_uart_remove(struct platform_device *ofdev)
 
uart_remove_one_port(_uart_driver, _port->port);
 
+   of_node_put(qe_port->np);
+
kfree(qe_port);
 
return 0;
-- 
2.25.1



Re:Re: [PATCH v2] powerpc: kernel: legacy_serial: Fix missing of_node_put() in add_legacy_soc_port()

2022-09-05 Thread Liang He



At 2022-09-05 11:25:38, "Michael Ellerman"  wrote:
>Liang He  writes:
>> We should call of_node_put() for the reference 'tsi' returned by
>> of_get_parent() which will increase the refcount.
>>
>> Signed-off-by: Liang He 
>> ---
>>  changelog:
>>
>>  v2: use more conservative way to call of_node_put()
>>  v1: mov 'of_node_put()' into the 'if' condition
>>
>>  v1 Link: https://lore.kernel.org/all/20220701130203.240023-1-win...@126.com/
>>
>>  arch/powerpc/kernel/legacy_serial.c | 11 ---
>>  1 file changed, 8 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/legacy_serial.c 
>> b/arch/powerpc/kernel/legacy_serial.c
>> index f048c424c525..cca72081b864 100644
>> --- a/arch/powerpc/kernel/legacy_serial.c
>> +++ b/arch/powerpc/kernel/legacy_serial.c
>> @@ -166,7 +166,7 @@ static int __init add_legacy_soc_port(struct device_node 
>> *np,
>>  {
>>  u64 addr;
>>  const __be32 *addrp;
>> -struct device_node *tsi = of_get_parent(np);
>> +struct device_node *tsi;
>>  
>>  /* We only support ports that have a clock frequency properly
>>   * encoded in the device-tree.
>> @@ -194,12 +194,17 @@ static int __init add_legacy_soc_port(struct 
>> device_node *np,
>>  /* Add port, irq will be dealt with later. We passed a translated
>>   * IO port value. It will be fixed up later along with the irq
>>   */
>> -if (of_node_is_type(tsi, "tsi-bridge"))
>> +tsi = of_get_parent(np);
>> +if (of_node_is_type(tsi, "tsi-bridge")) {
>> +of_node_put(tsi);
>>  return add_legacy_port(np, -1, UPIO_TSI, addr, addr,
>> 0, legacy_port_flags, 0);
>> -else
>> +}
>> +else {
>> +of_node_put(tsi);
>>  return add_legacy_port(np, -1, UPIO_MEM, addr, addr,
>> 0, legacy_port_flags, 0);
>> +}
>>  }
>
>The two legs of the else end up with duplicated code except for a single
>parameter to add_legacy_port().
>
>Better would be:
>
>{
>   int iotype;
>...
>
>   tsi = of_get_parent(np);
>   if (of_node_is_type(tsi, "tsi-bridge"))
>   iotype = UPIO_TSI;
>   else
>   iotype = UPIO_MEM;
>
>   of_node_put(tsi);
>return add_legacy_port(np, -1, iotype, addr, addr, 0, 
> legacy_port_flags, 0);
>}
>
>
>cheers

Thanks, 
I will give another version of this patch.

Liang


Re:Re: [PATCH] powerpc/powermac/pfunc_base: Fix refcount leak bug in macio_gpio_init_one()

2022-08-13 Thread Liang He



At 2022-08-02 12:51:08, "Benjamin Herrenschmidt"  
wrote:
>On Sat, 2022-07-16 at 15:31 +0800, Liang He wrote:
>> We should call of_node_put() for the reference 'gparent' escaped
>> out of the for_each_child_of_node() as it has increased the refcount.
>
>Same comment as before. That stuff happens once at boot, there's never
>any dynamic allocation/deallocation of these, they just don't matter,
>but feel free  :-)

>


Thanks for your reply, this is a valuable lesson for me.
I will now begin to learn the detailed difference of dynamic and static 
allocation.


Thanks,
Liang


>> Fixes: 5b9ca526917b ("[PATCH] 3/5 powerpc: Add platform functions
>> interpreter")
>> Signed-off-by: Liang He 
>> ---
>>  arch/powerpc/platforms/powermac/pfunc_base.c | 2 ++
>>  1 file changed, 2 insertions(+)
>> 
>> diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c
>> b/arch/powerpc/platforms/powermac/pfunc_base.c
>> index 9c2947a3edd5..085e0ad20eba 100644
>> --- a/arch/powerpc/platforms/powermac/pfunc_base.c
>> +++ b/arch/powerpc/platforms/powermac/pfunc_base.c
>> @@ -136,6 +136,8 @@ static void __init macio_gpio_init_one(struct
>> macio_chip *macio)
>>  for_each_child_of_node(gparent, gp)
>>  pmf_do_functions(gp, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
>>  
>> +of_node_put(gparent);
>> +
>>  /* Note: We do not at this point implement the "at sleep" or
>> "at wake"
>>   * functions. I yet to find any for GPIOs anyway
>>   */


[PATCH] powerpc/fsl_pci: Remove of_node_put() when reference escaped out

2022-07-20 Thread Liang He
In fsl_pci_assign_primary(), we should remove the of_node_put()
when breaking out of the for_each_matching_node() as the 'np'
is escaped out by global 'fsl_pci_primary'.

Fixes: 905e75c46dba ("powerpc/fsl-pci: Unify pci/pcie initialization code")
Signed-off-by: Liang He 
---
 arch/powerpc/sysdev/fsl_pci.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index e8d072e98b66..aa7faa19c6ef 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -1134,7 +1134,6 @@ void __init fsl_pci_assign_primary(void)
for_each_matching_node(np, pci_ids) {
if (of_device_is_available(np)) {
fsl_pci_primary = np;
-   of_node_put(np);
return;
}
}
-- 
2.25.1



[PATCH] powerpc/powermac/udbg_scc: Fix refcount leak bug in udbg_scc_init()

2022-07-16 Thread Liang He
During the iteration of for_each_child_of_node(), we need to call
of_node_put() for the old references stored in to 'ch_def' and 'ch_a'
as their refcounters have been increased in last iteration.

Fixes: 51d3082fe6e5 ("[PATCH] powerpc: Unify udbg (#2)")
Signed-off-by: Liang He 
---
 arch/powerpc/platforms/powermac/udbg_scc.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/powermac/udbg_scc.c 
b/arch/powerpc/platforms/powermac/udbg_scc.c
index 734df5a32f99..1b7c39e841ee 100644
--- a/arch/powerpc/platforms/powermac/udbg_scc.c
+++ b/arch/powerpc/platforms/powermac/udbg_scc.c
@@ -81,10 +81,14 @@ void __init udbg_scc_init(int force_scc)
if (path != NULL)
stdout = of_find_node_by_path(path);
for_each_child_of_node(escc, ch) {
-   if (ch == stdout)
+   if (ch == stdout) {
+   of_node_put(ch_def);
ch_def = of_node_get(ch);
-   if (of_node_name_eq(ch, "ch-a"))
+   }
+   if (of_node_name_eq(ch, "ch-a")) {
+   of_node_put(ch_a);
ch_a = of_node_get(ch);
+   }
}
if (ch_def == NULL && !force_scc)
goto bail;
-- 
2.25.1



[PATCH] powerpc/powermac/pfunc_base: Fix refcount leak bug in macio_gpio_init_one()

2022-07-16 Thread Liang He
We should call of_node_put() for the reference 'gparent' escaped
out of the for_each_child_of_node() as it has increased the refcount.

Fixes: 5b9ca526917b ("[PATCH] 3/5 powerpc: Add platform functions interpreter")
Signed-off-by: Liang He 
---
 arch/powerpc/platforms/powermac/pfunc_base.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c 
b/arch/powerpc/platforms/powermac/pfunc_base.c
index 9c2947a3edd5..085e0ad20eba 100644
--- a/arch/powerpc/platforms/powermac/pfunc_base.c
+++ b/arch/powerpc/platforms/powermac/pfunc_base.c
@@ -136,6 +136,8 @@ static void __init macio_gpio_init_one(struct macio_chip 
*macio)
for_each_child_of_node(gparent, gp)
pmf_do_functions(gp, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
 
+   of_node_put(gparent);
+
/* Note: We do not at this point implement the "at sleep" or "at wake"
 * functions. I yet to find any for GPIOs anyway
 */
-- 
2.25.1



[PATCH] powerpc/powermac/low_i2c: Fix refcount leak bug in kw_i2c_probe()

2022-07-16 Thread Liang He
We should call of_node_put() for the reference 'parent' returned by
of_get_parent() which has increased the refcount.

Fixes: 730745a5c450 ("[PATCH] 1/5 powerpc: Rework PowerMac i2c part 1")
Signed-off-by: Liang He 
---
 arch/powerpc/platforms/powermac/low_i2c.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/platforms/powermac/low_i2c.c 
b/arch/powerpc/platforms/powermac/low_i2c.c
index c1c430c66dc9..40f3aa432fba 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -627,6 +627,7 @@ static void __init kw_i2c_probe(void)
if (parent == NULL)
continue;
chans = parent->name[0] == 'u' ? 2 : 1;
+   of_node_put(parent);
for (i = 0; i < chans; i++)
kw_i2c_add(host, np, np, i);
} else {
-- 
2.25.1



[PATCH] powerpc/powermac/feature: Fix refcount leak bug

2022-07-16 Thread Liang He
In probe_one_macio(), we should call of_node_put() for the refernece
'node' escaped out of the for_each_node_by_name() which has increased
its refcount. While the 'node' will finally escaped into a global
reference, we should still call of_node_put() in fail path which will
stop global reference creation.

Fixes: 51d3082fe6e5 ("[PATCH] powerpc: Unify udbg (#2)")
Signed-off-by: Liang He 
---
 commit-51d3082fe6e5 first introduces the 'of_find_node_by_name' which
involved the refcounting bug.

 arch/powerpc/platforms/powermac/feature.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/platforms/powermac/feature.c 
b/arch/powerpc/platforms/powermac/feature.c
index 5cc958adba13..0382d20b5619 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -2632,31 +2632,31 @@ static void __init probe_one_macio(const char *name, 
const char *compat, int typ
if (!macio_chips[i].of_node)
break;
if (macio_chips[i].of_node == node)
-   return;
+   goto out_put;
}
 
if (i >= MAX_MACIO_CHIPS) {
printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS 
!\n");
printk(KERN_ERR "pmac_feature: %pOF skipped\n", node);
-   return;
+   goto out_put;
}
addrp = of_get_pci_address(node, 0, , NULL);
if (addrp == NULL) {
printk(KERN_ERR "pmac_feature: %pOF: can't find base !\n",
   node);
-   return;
+   goto out_put;
}
addr = of_translate_address(node, addrp);
if (addr == 0) {
printk(KERN_ERR "pmac_feature: %pOF, can't translate base !\n",
   node);
-   return;
+   goto out_put;
}
base = ioremap(addr, (unsigned long)size);
if (!base) {
printk(KERN_ERR "pmac_feature: %pOF, can't map mac-io chip !\n",
   node);
-   return;
+   goto out_put;
}
if (type == macio_keylargo || type == macio_keylargo2) {
const u32 *did = of_get_property(node, "device-id", NULL);
@@ -2677,6 +2677,11 @@ static void __init probe_one_macio(const char *name, 
const char *compat, int typ
macio_chips[i].rev = *revp;
printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 
0x%p\n",
macio_names[type], macio_chips[i].rev, macio_chips[i].base);
+
+   return;
+
+out_put:
+   of_node_put(node);
 }
 
 static int __init
-- 
2.25.1



[PATCH] powerpc: fsl: pci: Remove of_node_put() in fsl_pci_assign_primary()

2022-07-05 Thread Liang He
for_each_matching_node() will automatically increase and decrease
the refcount. As there is a reference escaped out into global
'fsl_pci_primary', we should not use of_node_put() anymore.

Fixes: 905e75c46dba ("powerpc/fsl-pci: Unify pci/pcie initialization code")
Signed-off-by: Liang He 
---
 arch/powerpc/sysdev/fsl_pci.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 4c986c955951..d23a56276f42 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -1137,7 +1137,6 @@ void __init fsl_pci_assign_primary(void)
for_each_matching_node(np, pci_ids) {
if (of_device_is_available(np)) {
fsl_pci_primary = np;
-   of_node_put(np);
return;
}
}
-- 
2.25.1



[PATCH] powerpc: sysdev: fsl_msi: Add missing of_node_put() for of_parse_phandle()

2022-07-04 Thread Liang He
In fsl_setup_msi_irqs(), we should use of_node_put() for the
refernece 'np' returned by of_parse_phandle() which increases
the refcount.

Fixes: 895d603f945ba ("powerpc/fsl_msi: add support for the fsl, msi property 
in PCI nodes")
Co-authored-by: Miaoqian Lin 
Signed-off-by: Liang He 
---

 There is an incomplete fix: 
 https://lore.kernel.org/all/20220526010935.32138-1-zhengyongj...@huawei.com/

 We should call of_node_put() both in fail path and normal path.

 arch/powerpc/sysdev/fsl_msi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index ef9a5999fa93..73c2d70706c0 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -209,8 +209,10 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int 
nvec, int type)
dev_err(>dev,
"node %pOF has an invalid fsl,msi phandle %u\n",
hose->dn, np->phandle);
+   of_node_put(np);
return -EINVAL;
}
+   of_node_put(np);
}
 
msi_for_each_desc(entry, >dev, MSI_DESC_NOTASSOCIATED) {
-- 
2.25.1



[PATCH] powerpc: fsl: gtm: Remove of_node_get() in fsl_gtm_init()

2022-07-04 Thread Liang He
for_each_compatible_node() will automaitically increase and decrease
the refcount of the device_node object. There is no need to call
additional of_node_get(). It is better to keep the original meaning
of refcounting as there is no any new reference created.

Signed-off-by: Liang He 
---
 I do not understand the whole story of the gtm, so maybe we want to
keep the object always alive by using additional refcounting. Please
check it carefully.


 arch/powerpc/sysdev/fsl_gtm.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c
index 39186ad6b3c3..e13ebd2be416 100644
--- a/arch/powerpc/sysdev/fsl_gtm.c
+++ b/arch/powerpc/sysdev/fsl_gtm.c
@@ -423,7 +423,6 @@ static int __init fsl_gtm_init(void)
 
/* We don't want to lose the node and its ->data */
np->data = gtm;
-   of_node_get(np);
 
continue;
 err:
-- 
2.25.1



[PATCH] soc: fsl: qbman: Fix missing of_node_put() in qbman_init_private_mem()

2022-07-04 Thread Liang He
We should call of_node_put() for the reference returned by
of_parse_phandle() which will increase the refcount.

Fixes: 42d0349784c7 ("soc/fsl/qbman: Add common routine for QBMan private 
allocations")
Co-authored-by: Miaoqian Lin 
Signed-off-by: Liang He 
---
 drivers/soc/fsl/qbman/dpaa_sys.c | 28 
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/soc/fsl/qbman/dpaa_sys.c b/drivers/soc/fsl/qbman/dpaa_sys.c
index 9dd8bb571dbc..6138a68ea699 100644
--- a/drivers/soc/fsl/qbman/dpaa_sys.c
+++ b/drivers/soc/fsl/qbman/dpaa_sys.c
@@ -52,7 +52,8 @@ int qbman_init_private_mem(struct device *dev, int idx, 
dma_addr_t *addr,
rmem = of_reserved_mem_lookup(mem_node);
if (!rmem) {
dev_err(dev, "of_reserved_mem_lookup() returned NULL\n");
-   return -ENODEV;
+   err = -ENODEV;
+   goto out_of_put;
}
*addr = rmem->base;
*size = rmem->size;
@@ -66,24 +67,35 @@ int qbman_init_private_mem(struct device *dev, int idx, 
dma_addr_t *addr,
prop = of_find_property(mem_node, "reg", );
if (!prop) {
prop = devm_kzalloc(dev, sizeof(*prop), GFP_KERNEL);
-   if (!prop)
-   return -ENOMEM;
+   if (!prop) {
+   err = -ENOMEM;
+   goto out_of_put;
+   }
prop->value = res_array = devm_kzalloc(dev, sizeof(__be32) * 4,
   GFP_KERNEL);
-   if (!prop->value)
-   return -ENOMEM;
+   if (!prop->value) {
+   err = -ENOMEM;
+   goto out_of_put;
+   }
res_array[0] = cpu_to_be32(upper_32_bits(*addr));
res_array[1] = cpu_to_be32(lower_32_bits(*addr));
res_array[2] = cpu_to_be32(upper_32_bits(*size));
res_array[3] = cpu_to_be32(lower_32_bits(*size));
prop->length = sizeof(__be32) * 4;
prop->name = devm_kstrdup(dev, "reg", GFP_KERNEL);
-   if (!prop->name)
-   return -ENOMEM;
+   if (!prop->name) {
+   err = -ENOMEM;
+   goto out_of_put;
+   }
err = of_add_property(mem_node, prop);
if (err)
-   return err;
+   goto out_of_put;
}
+   of_node_put(mem_node);
 
return 0;
+
+out_of_put:
+   of_node_put(mem_node);
+   return err;
 }
-- 
2.25.1



[PATCH] powerpc: kernel: pci-common: Fix refcount bug for 'phb->dn'

2022-07-01 Thread Liang He
In pcibios_alloc_controller(), 'phb' is allocated and escaped into
global 'hose_list'. So we should call of_node_get() when a new reference
created into 'phb->dn'. And when phb is freed, we should call
of_node_put() on it.

NOTE: This function is called in the iteration of for_each_xx in
chrp_find_bridges() function. If there is no of_node_get(), the object
maybe prematurely freed.

Signed-off-by: Liang He 
---

 I do not know if we should insert the of_node_put() in or out of the
spin_lock/spin_unlock. Please check it carefully.

 arch/powerpc/kernel/pci-common.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 068410cd54a3..f58dcf3a92bb 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -117,7 +117,7 @@ struct pci_controller *pcibios_alloc_controller(struct 
device_node *dev)
phb->global_number = get_phb_number(dev);
list_add_tail(>list_node, _list);
spin_unlock(_spinlock);
-   phb->dn = dev;
+   phb->dn = of_node_get(dev);
phb->is_dynamic = slab_is_available();
 #ifdef CONFIG_PPC64
if (dev) {
@@ -140,7 +140,7 @@ void pcibios_free_controller(struct pci_controller *phb)
/* Clear bit of phb_bitmap to allow reuse of this PHB number. */
if (phb->global_number < MAX_PHBS)
clear_bit(phb->global_number, phb_bitmap);
-
+   of_node_put(phb->dn);
list_del(>list_node);
spin_unlock(_spinlock);
 
-- 
2.25.1



[PATCH v2] powerpc: kernel: legacy_serial: Fix missing of_node_put() in add_legacy_soc_port()

2022-07-01 Thread Liang He
We should call of_node_put() for the reference 'tsi' returned by
of_get_parent() which will increase the refcount.

Signed-off-by: Liang He 
---
 changelog:

 v2: use more conservative way to call of_node_put()
 v1: mov 'of_node_put()' into the 'if' condition

 v1 Link: https://lore.kernel.org/all/20220701130203.240023-1-win...@126.com/

 arch/powerpc/kernel/legacy_serial.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/legacy_serial.c 
b/arch/powerpc/kernel/legacy_serial.c
index f048c424c525..cca72081b864 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -166,7 +166,7 @@ static int __init add_legacy_soc_port(struct device_node 
*np,
 {
u64 addr;
const __be32 *addrp;
-   struct device_node *tsi = of_get_parent(np);
+   struct device_node *tsi;
 
/* We only support ports that have a clock frequency properly
 * encoded in the device-tree.
@@ -194,12 +194,17 @@ static int __init add_legacy_soc_port(struct device_node 
*np,
/* Add port, irq will be dealt with later. We passed a translated
 * IO port value. It will be fixed up later along with the irq
 */
-   if (of_node_is_type(tsi, "tsi-bridge"))
+   tsi = of_get_parent(np);
+   if (of_node_is_type(tsi, "tsi-bridge")) {
+   of_node_put(tsi);
return add_legacy_port(np, -1, UPIO_TSI, addr, addr,
   0, legacy_port_flags, 0);
-   else
+   }
+   else {
+   of_node_put(tsi);
return add_legacy_port(np, -1, UPIO_MEM, addr, addr,
   0, legacy_port_flags, 0);
+   }
 }
 
 static int __init add_legacy_isa_port(struct device_node *np,
-- 
2.25.1



Re:Re: [PATCH] powerpc: kernel: pci_dn: Add missing of_node_put() for of_get_xx API

2022-07-01 Thread Liang He

At 2022-07-02 03:47:22, "Tyrel Datwyler"  wrote:
>On 7/1/22 06:17, Liang He wrote:
>> In pci_add_device_node_info(), we should use of_node_put() for the
>> reference 'parent' returned by of_get_parent() to keep refcount
>> balance.
>> 
>> Fixes: cca87d303c85 ("powerpc/pci: Refactor pci_dn")
>> Co-authored-by: Miaoqian Lin 
>> Signed-off-by: Liang He 
>> ---
>>  arch/powerpc/kernel/pci_dn.c | 1 +
>>  1 file changed, 1 insertion(+)
>> 
>> diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
>> index 938ab8838ab5..aa221958007e 100644
>> --- a/arch/powerpc/kernel/pci_dn.c
>> +++ b/arch/powerpc/kernel/pci_dn.c
>> @@ -330,6 +330,7 @@ struct pci_dn *pci_add_device_node_info(struct 
>> pci_controller *hose,
>>  INIT_LIST_HEAD(>list);
>>  parent = of_get_parent(dn);
>>  pdn->parent = parent ? PCI_DN(parent) : NULL;
>NACK
>
>pdn->parent is now a long term reference so we should not do a put on parent
>until we pdn->parent is no longer valid.
>
>-Tyrel

Hi, Tyrel

Thanks for reviewing this code.

But I think there is some confusion about the of_get_parent() and I can confirm
my point when I check the 'pci_remove_device_node_info' function, which may be
a second bug.

In pci_remove_device_node_info(), I notice the comment, 'Drop the parent 
pci_dn's ref ...'.
However, of_get_parent() will increase the refcount of the parent, and then the
following of_node_put() will decrease the refcount, so, finally, there is no 
any change.

Back to this case, as the 'pdn->parent' is not the reference of parent 
device_node, it is
device_node's data, so I think it is better to keep the original meaning of 
refcounting, i.e,
add a of_node_put() to keep the refcount balance.

If I have some mis-understanding, please correct me.

Thanks,

Liang

>
>> +of_node_put(parent);
>>  if (pdn->parent)
>>  list_add_tail(>list, >parent->child_list);
>> 


[PATCH v2 2/2] powerpc: cell: iommu: Hold reference returned by of_find_node_by_name()

2022-07-01 Thread Liang He
In cell_iommu_init_disabled(), we should hold the reference returned
by of_find_node_by_name() and use it to call of_node_put() for reference
balance.

Signed-off-by: Liang He 
---
 changelog:

 v2: (1) split v1's two files in to two commits
 (2) using 'check-then-put' coding style
 v1: hold the reference returned by of_find_xxx OF APIs

 v1-link: https://lore.kernel.org/all/20220621075333.4081413-1-win...@126.com/

 arch/powerpc/platforms/cell/iommu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/cell/iommu.c 
b/arch/powerpc/platforms/cell/iommu.c
index 0ca3efeef293..8c7133039566 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -720,8 +720,10 @@ static int __init cell_iommu_init_disabled(void)
cell_disable_iommus();
 
/* If we have no Axon, we set up the spider DMA magic offset */
-   if (of_find_node_by_name(NULL, "axon") == NULL)
+   np = of_find_node_by_name(NULL, "axon");
+   if (!np)
cell_dma_nommu_offset = SPIDER_DMA_OFFSET;
+   of_node_put(np);
 
/* Now we need to check to see where the memory is mapped
 * in PCI space. We assume that all busses use the same dma
-- 
2.25.1



[PATCH v2 1/2] powerpc: cell: cbe_regs: Fix refcount bugs

2022-07-01 Thread Liang He
There are several bugs as following:

(1) In cbe_get_be_node(), we should hold the reference returned by
of_find_xxx and of_get_xxx OF APIs and use it to call of_node_put
(2) In cbe_fill_regs_map(), we should same as above
(3) In cbe_regs_init(), during the iteration of for_each_node_by_type(),
the refcount of 'cpu' will be automatically increased and decreased.
However, there is a reference escaped out into 'map->cpu_node' and
we should properly handle it.

Signed-off-by: Liang He 
---
 chagelog:

 v2: (1) split v1's two files in to two commits
 (2) merge all bugs for cbe_regs.c
 (3) using 'check-then-put' coding style
 v1: only detect bug (1)

 v1-link: https://lore.kernel.org/all/20220621075333.4081413-1-win...@126.com/


 arch/powerpc/platforms/cell/cbe_regs.c | 40 +++---
 1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/cell/cbe_regs.c 
b/arch/powerpc/platforms/cell/cbe_regs.c
index 316e533afc00..3fd3634aa515 100644
--- a/arch/powerpc/platforms/cell/cbe_regs.c
+++ b/arch/powerpc/platforms/cell/cbe_regs.c
@@ -182,9 +182,19 @@ static struct device_node *__init cbe_get_be_node(int 
cpu_id)
if (WARN_ON_ONCE(!cpu_handle))
return np;
 
-   for (i=0; ibe_node) {
-   struct device_node *be, *np;
+   struct device_node *be, *np, *parent_np;
 
be = map->be_node;
 
-   for_each_node_by_type(np, "pervasive")
-   if (of_get_parent(np) == be)
+   for_each_node_by_type(np, "pervasive") {
+   parent_np = of_get_parent(np);
+   if (parent_np == be)
map->pmd_regs = of_iomap(np, 0);
+   of_node_put(parent_np);
+   }
 
-   for_each_node_by_type(np, "CBEA-Internal-Interrupt-Controller")
-   if (of_get_parent(np) == be)
+   for_each_node_by_type(np, "CBEA-Internal-Interrupt-Controller") 
{
+   parent_np = of_get_parent(np);
+   if (parent_np == be)
map->iic_regs = of_iomap(np, 2);
+   of_node_put(parent_np);
+   }
 
-   for_each_node_by_type(np, "mic-tm")
-   if (of_get_parent(np) == be)
+   for_each_node_by_type(np, "mic-tm") {
+   parent_np = of_get_parent(np);
+   if (parent_np == be)
map->mic_tm_regs = of_iomap(np, 0);
+   of_node_put(parent_np);
+   }
} else {
struct device_node *cpu;
/* That hack must die die die ! */
@@ -261,7 +280,8 @@ void __init cbe_regs_init(void)
of_node_put(cpu);
return;
}
-   map->cpu_node = cpu;
+   of_node_put(map->cpu_node);
+   map->cpu_node = of_node_get(cpu);
 
for_each_possible_cpu(i) {
struct cbe_thread_map *thread = _thread_map[i];
-- 
2.25.1



[PATCH] powerpc: 85xx: Fix refcount bugs in ge_imp3a_pci_assign_primary()

2022-07-01 Thread Liang He
for_each_node_by_type() will automatically increase and decrease
the refcount during the iteration. However, there is a reference
escaped into global 'fsl_pci_primary' and we need to handle it.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/85xx/ge_imp3a.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/ge_imp3a.c 
b/arch/powerpc/platforms/85xx/ge_imp3a.c
index 8e827376d97b..e3e8f18825a1 100644
--- a/arch/powerpc/platforms/85xx/ge_imp3a.c
+++ b/arch/powerpc/platforms/85xx/ge_imp3a.c
@@ -89,8 +89,10 @@ static void __init ge_imp3a_pci_assign_primary(void)
of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
of_device_is_compatible(np, "fsl,p2020-pcie")) {
of_address_to_resource(np, 0, );
-   if ((rsrc.start & 0xf) == 0x9000)
-   fsl_pci_primary = np;
+   if ((rsrc.start & 0xf) == 0x9000) {
+   of_node_put(fsl_pci_primary);
+   fsl_pci_primary = of_node_get(np);
+   }
}
}
 #endif
-- 
2.25.1



[PATCH] powerpc: 44x: Add of_node_put() when break out from for_each

2022-07-01 Thread Liang He
In ppc47x_init_irq(), we need to call of_node_put() when there is
a break during the iteration of for_each_node_with_property() which
will automatically increase and decrease the refcount.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/44x/ppc476.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/platforms/44x/ppc476.c 
b/arch/powerpc/platforms/44x/ppc476.c
index 20cc8f80b086..7d9075fb20c9 100644
--- a/arch/powerpc/platforms/44x/ppc476.c
+++ b/arch/powerpc/platforms/44x/ppc476.c
@@ -140,6 +140,7 @@ static void __init ppc47x_init_irq(void)
ppc_md.get_irq = mpic_get_irq;
} else
panic("Unrecognized top level interrupt controller");
+   of_node_put(np);
 }
 
 #ifdef CONFIG_SMP
-- 
2.25.1



[PATCH] powerpc: kernel: pci_dn: Add missing of_node_put() for of_get_xx API

2022-07-01 Thread Liang He
In pci_add_device_node_info(), we should use of_node_put() for the
reference 'parent' returned by of_get_parent() to keep refcount
balance.

Fixes: cca87d303c85 ("powerpc/pci: Refactor pci_dn")
Co-authored-by: Miaoqian Lin 
Signed-off-by: Liang He 
---
 arch/powerpc/kernel/pci_dn.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index 938ab8838ab5..aa221958007e 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -330,6 +330,7 @@ struct pci_dn *pci_add_device_node_info(struct 
pci_controller *hose,
INIT_LIST_HEAD(>list);
parent = of_get_parent(dn);
pdn->parent = parent ? PCI_DN(parent) : NULL;
+   of_node_put(parent);
if (pdn->parent)
list_add_tail(>list, >parent->child_list);
 
-- 
2.25.1



[PATCH] powerpc: kernel: Fix missing of_node_put() in add_legacy_soc_port()

2022-07-01 Thread Liang He
We should call of_node_put() for the reference 'tsi' returned by
of_get_parent() which will increase the refcount.

Signed-off-by: Liang He 
---
 Inserting of_node_put() in the 'if' condition is learned from Orsan:
 
https://lore.kernel.org/all/CA+H2tpH1hN1AJ=6vvgqxw6bz7xqdbzxdaev_oqwmnw+uxqk...@mail.gmail.com/

 I move the of_get_parent() just before its first usage, otherwise, we
 need lots of of_node_put() before the 'return'.

 arch/powerpc/kernel/legacy_serial.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/legacy_serial.c 
b/arch/powerpc/kernel/legacy_serial.c
index f048c424c525..c7e9d7b5df8c 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -166,7 +166,7 @@ static int __init add_legacy_soc_port(struct device_node 
*np,
 {
u64 addr;
const __be32 *addrp;
-   struct device_node *tsi = of_get_parent(np);
+   struct device_node *tsi;
 
/* We only support ports that have a clock frequency properly
 * encoded in the device-tree.
@@ -194,7 +194,8 @@ static int __init add_legacy_soc_port(struct device_node 
*np,
/* Add port, irq will be dealt with later. We passed a translated
 * IO port value. It will be fixed up later along with the irq
 */
-   if (of_node_is_type(tsi, "tsi-bridge"))
+   tsi = of_get_parent(np);
+   if (of_node_is_type(tsi, "tsi-bridge") || (of_node_put(tsi), 0))
return add_legacy_port(np, -1, UPIO_TSI, addr, addr,
   0, legacy_port_flags, 0);
else
-- 
2.25.1



[PATCH] macintosh: Add missing of_node_get() in do_attach()

2022-06-22 Thread Liang He
We need a of_node_get() for of_find_compatible_node() to keep refcount
balance.

Signed-off-by: Liang He 
---
 drivers/macintosh/therm_windtunnel.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/macintosh/therm_windtunnel.c 
b/drivers/macintosh/therm_windtunnel.c
index 9226b74fa08f..bee0510ab1df 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -317,6 +317,7 @@ static void do_attach(struct i2c_adapter *adapter)
if (x.running || strncmp(adapter->name, "uni-n", 5))
return;
 
+   of_node_get(adapter->dev.of_node);
np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,ds1775");
if (np) {
of_node_put(np);
@@ -325,6 +326,7 @@ static void do_attach(struct i2c_adapter *adapter)
i2c_new_scanned_device(adapter, , scan_ds1775, NULL);
}
 
+   of_node_get(adapter->dev.of_node);
np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,adm1030");
if (np) {
of_node_put(np);
-- 
2.25.1



[PATCH] powerpc/pseries: Hold reference and fix refcount leak bugs

2022-06-21 Thread Liang He
In pseries_cpuhp_cache_use_count() and pseries_cpuhp_detach_nodes(),
we need carefully hold the reference returned by
of_find_next_cache_node() and use it to call of_node_put() to keep
refcount balance.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/pseries/hotplug-cpu.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c 
b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 0f8cd8b06432..e0a7ac5db15d 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -619,17 +619,21 @@ static ssize_t dlpar_cpu_add(u32 drc_index)
 static unsigned int pseries_cpuhp_cache_use_count(const struct device_node 
*cachedn)
 {
unsigned int use_count = 0;
-   struct device_node *dn;
+   struct device_node *dn, *tn;
 
WARN_ON(!of_node_is_type(cachedn, "cache"));
 
for_each_of_cpu_node(dn) {
-   if (of_find_next_cache_node(dn) == cachedn)
+   tn = of_find_next_cache_node(dn);
+   of_node_put(tn);
+   if (tn == cachedn)
use_count++;
}
 
for_each_node_by_type(dn, "cache") {
-   if (of_find_next_cache_node(dn) == cachedn)
+   tn = of_find_next_cache_node(dn);
+   of_node_put(tn);
+   if (tn == cachedn)
use_count++;
}
 
@@ -649,10 +653,13 @@ static int pseries_cpuhp_detach_nodes(struct device_node 
*cpudn)
 
dn = cpudn;
while ((dn = of_find_next_cache_node(dn))) {
-   if (pseries_cpuhp_cache_use_count(dn) > 1)
+   if (pseries_cpuhp_cache_use_count(dn) > 1) {
+   of_node_put(dn);
break;
+   }
 
ret = of_changeset_detach_node(, dn);
+   of_node_put(dn);
if (ret)
goto out;
}
-- 
2.25.1



[PATCH] powerpc/83xx: Hold the reference returned by of_find_compatible_node

2022-06-21 Thread Liang He
In mpc832x_spi_init(), we should hold the reference returned by
of_find_compatible_node() and use it to call of_node_put() for
refcount balance.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/83xx/mpc832x_rdb.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c 
b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index bb8caa5071f8..e12cb44e717f 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -162,6 +162,8 @@ static struct spi_board_info mpc832x_spi_boardinfo = {
 
 static int __init mpc832x_spi_init(void)
 {
+   struct device_node *np;
+
par_io_config_pin(3,  0, 3, 0, 1, 0); /* SPI1 MOSI, I/O */
par_io_config_pin(3,  1, 3, 0, 1, 0); /* SPI1 MISO, I/O */
par_io_config_pin(3,  2, 3, 0, 1, 0); /* SPI1 CLK,  I/O */
@@ -175,7 +177,9 @@ static int __init mpc832x_spi_init(void)
 * Don't bother with legacy stuff when device tree contains
 * mmc-spi-slot node.
 */
-   if (of_find_compatible_node(NULL, NULL, "mmc-spi-slot"))
+   np = of_find_compatible_node(NULL, NULL, "mmc-spi-slot");
+   of_node_put(np);
+   if (np)
return 0;
return fsl_spi_init(_spi_boardinfo, 1, mpc83xx_spi_cs_control);
 }
-- 
2.25.1



[PATCH] powerpc/512x: Hold the reference returned by of_find_compatible_node

2022-06-21 Thread Liang He
In mpc5121_clk_provide_migration_support(), we need to hold the
reference returned by of_find_compatible_node() and use it to call
of_node_put for refcount balance.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/512x/clock-commonclk.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c 
b/arch/powerpc/platforms/512x/clock-commonclk.c
index ca475462e95b..42abeba4f698 100644
--- a/arch/powerpc/platforms/512x/clock-commonclk.c
+++ b/arch/powerpc/platforms/512x/clock-commonclk.c
@@ -950,7 +950,7 @@ static void __init mpc5121_clk_register_of_provider(struct 
device_node *np)
  */
 static void __init mpc5121_clk_provide_migration_support(void)
 {
-
+   struct device_node *np;
/*
 * pre-enable those clock items which are not yet appropriately
 * acquired by their peripheral driver
@@ -970,7 +970,9 @@ static void __init 
mpc5121_clk_provide_migration_support(void)
 * unused and so it gets disabled
 */
clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console */
-   if (of_find_compatible_node(NULL, "pci", "fsl,mpc5121-pci"))
+   np = of_find_compatible_node(NULL, "pci", "fsl,mpc5121-pci");
+   of_node_put(np);
+   if (np)
clk_prepare_enable(clks[MPC512x_CLK_PCI]);
 }
 
-- 
2.25.1



[PATCH] powerpc/cell: Hold reference returned by of_find_node_by_xxx APIs

2022-06-21 Thread Liang He
In cell_iommu_init_disabled() and cbe_get_be_node(), we need to
hold the reference returned by of_find_node_by_xxx APIs and use
it to call of_node_put() for refcount balance.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/cell/cbe_regs.c | 10 --
 arch/powerpc/platforms/cell/iommu.c|  5 -
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/cell/cbe_regs.c 
b/arch/powerpc/platforms/cell/cbe_regs.c
index 316e533afc00..09cbdfc070b3 100644
--- a/arch/powerpc/platforms/cell/cbe_regs.c
+++ b/arch/powerpc/platforms/cell/cbe_regs.c
@@ -182,9 +182,15 @@ static struct device_node *__init cbe_get_be_node(int 
cpu_id)
if (WARN_ON_ONCE(!cpu_handle))
return np;
 
-   for (i=0; i

[PATCH] powerpc/pasemi: Fix refcount leak bug

2022-06-20 Thread Liang He
In pas_pci_init(), we need one of_node_put() for of_find_node_by_path()
to keep refcount balance.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/pasemi/pci.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/platforms/pasemi/pci.c 
b/arch/powerpc/platforms/pasemi/pci.c
index 55f0160910bf..4b371fb0d9aa 100644
--- a/arch/powerpc/platforms/pasemi/pci.c
+++ b/arch/powerpc/platforms/pasemi/pci.c
@@ -282,6 +282,7 @@ void __init pas_pci_init(void)
pci_set_flags(PCI_SCAN_ALL_PCIE_DEVS);
 
np = of_find_compatible_node(root, NULL, "pasemi,rootbus");
+   of_node_put(root);
if (np) {
res = pas_add_bridge(np);
of_node_put(np);
-- 
2.25.1



[PATCH] powerpc/powermac: Fix refcount leak bug

2022-06-20 Thread Liang He
In smp_core99_setup(), we need to add of_node_put() to keep refcount
balance.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/powermac/smp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/platforms/powermac/smp.c 
b/arch/powerpc/platforms/powermac/smp.c
index d9df45741ece..5b26a9012d2e 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -711,6 +711,7 @@ static void __init smp_core99_setup(int ncpus)
printk(KERN_INFO "Processor timebase sync using"
   " platform function\n");
}
+   of_node_put(cpus);
}
 
 #else /* CONFIG_PPC64 */
-- 
2.25.1



[PATCH v3] powerpc/powernv: Fix refcount leak bugs

2022-06-20 Thread Liang He
In these driver init functions, there are two kinds of errors:

(1) missing of_put_node() for of_find_compatible_node()'s returned
pointer (refcount incremented)  in fail path or when it is not
used anymore.
(2) missing of_put_node() for 'for_each_xxx' loop's break

These bugs are similar with the ones reported by commit-09700c504d.

Signed-off-by: Liang He 
---
 changelog:

 v3: merge more refcount bugs into one commit
 v2: merge opal-*.c
 v1: send  mising of_node_put patch for each file


 arch/powerpc/platforms/powernv/idle.c   | 1 +
 arch/powerpc/platforms/powernv/opal-core.c  | 2 ++
 arch/powerpc/platforms/powernv/opal-powercap.c  | 6 +-
 arch/powerpc/platforms/powernv/opal-psr.c   | 6 +-
 arch/powerpc/platforms/powernv/opal-sensor-groups.c | 6 +-
 arch/powerpc/platforms/powernv/opal.c   | 1 +
 6 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/idle.c 
b/arch/powerpc/platforms/powernv/idle.c
index 6f94b808dd39..c1b369c7f507 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -1419,6 +1419,7 @@ static int __init pnv_parse_cpuidle_dt(void)
kfree(temp_u32);
kfree(temp_u64);
kfree(temp_string);
+   of_node_put(np);
return rc;
 }
 
diff --git a/arch/powerpc/platforms/powernv/opal-core.c 
b/arch/powerpc/platforms/powernv/opal-core.c
index adcb1a1a2bfe..bb7657115f1d 100644
--- a/arch/powerpc/platforms/powernv/opal-core.c
+++ b/arch/powerpc/platforms/powernv/opal-core.c
@@ -348,6 +348,8 @@ static int __init create_opalcore(void)
if (!dn || ret)
pr_warn("WARNING: Failed to read OPAL base & entry values\n");
 
+   of_node_put(dn);
+
/* Use count to keep track of the program headers */
count = 0;
 
diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c 
b/arch/powerpc/platforms/powernv/opal-powercap.c
index 64506b46e77b..78c359c90093 100644
--- a/arch/powerpc/platforms/powernv/opal-powercap.c
+++ b/arch/powerpc/platforms/powernv/opal-powercap.c
@@ -153,7 +153,7 @@ void __init opal_powercap_init(void)
pcaps = kcalloc(of_get_child_count(powercap), sizeof(*pcaps),
GFP_KERNEL);
if (!pcaps)
-   return;
+   goto out_powercap;
 
powercap_kobj = kobject_create_and_add("powercap", opal_kobj);
if (!powercap_kobj) {
@@ -226,6 +226,7 @@ void __init opal_powercap_init(void)
}
i++;
}
+   of_node_put(powercap);
 
return;
 
@@ -236,6 +237,9 @@ void __init opal_powercap_init(void)
kfree(pcaps[i].pg.name);
}
kobject_put(powercap_kobj);
+   of_node_put(node);
 out_pcaps:
kfree(pcaps);
+out_powercap:
+   of_node_put(powercap);
 }
diff --git a/arch/powerpc/platforms/powernv/opal-psr.c 
b/arch/powerpc/platforms/powernv/opal-psr.c
index 69d7e75950d1..ec32e0a93f08 100644
--- a/arch/powerpc/platforms/powernv/opal-psr.c
+++ b/arch/powerpc/platforms/powernv/opal-psr.c
@@ -135,7 +135,7 @@ void __init opal_psr_init(void)
psr_attrs = kcalloc(of_get_child_count(psr), sizeof(*psr_attrs),
GFP_KERNEL);
if (!psr_attrs)
-   return;
+   goto out_psr;
 
psr_kobj = kobject_create_and_add("psr", opal_kobj);
if (!psr_kobj) {
@@ -162,10 +162,14 @@ void __init opal_psr_init(void)
}
i++;
}
+   of_node_put(psr);
 
return;
 out_kobj:
+   of_node_put(node);
kobject_put(psr_kobj);
 out:
kfree(psr_attrs);
+out_psr:
+   of_node_put(psr);
 }
diff --git a/arch/powerpc/platforms/powernv/opal-sensor-groups.c 
b/arch/powerpc/platforms/powernv/opal-sensor-groups.c
index 8fba7d25ae56..9944376b115c 100644
--- a/arch/powerpc/platforms/powernv/opal-sensor-groups.c
+++ b/arch/powerpc/platforms/powernv/opal-sensor-groups.c
@@ -170,7 +170,7 @@ void __init opal_sensor_groups_init(void)
 
sgs = kcalloc(of_get_child_count(sg), sizeof(*sgs), GFP_KERNEL);
if (!sgs)
-   return;
+   goto out_sg_put;
 
sg_kobj = kobject_create_and_add("sensor_groups", opal_kobj);
if (!sg_kobj) {
@@ -222,6 +222,7 @@ void __init opal_sensor_groups_init(void)
}
i++;
}
+   of_node_put(sg);
 
return;
 
@@ -231,6 +232,9 @@ void __init opal_sensor_groups_init(void)
kfree(sgs[i].sg.attrs);
}
kobject_put(sg_kobj);
+   of_node_put(node);
 out_sgs:
kfree(sgs);
+out_sg_put:
+   of_node_put(sg);
 }
diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 55a8fbfdb5b2..d86cc48a10aa 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -952,6 +952,7 @@ static vo

[PATCH v2] powerpc/sysdev: Fix refcount leak bugs

2022-06-20 Thread Liang He
We need add corresponding of_node_put() to keep refcount balance
in sysdev.

Signed-off-by: Liang He 
---
 changelog:

 v2: (1) merge all sysdev related bug into one commit
 (2) find new bugs in spapr.c and mpic_msgr.c
 v1: find missing of_node_put() in each file


 arch/powerpc/sysdev/fsl_pci.c |  6 +-
 arch/powerpc/sysdev/mpic_msgr.c   | 10 +-
 arch/powerpc/sysdev/xive/native.c | 15 ++-
 arch/powerpc/sysdev/xive/spapr.c  |  1 +
 4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 1011cfea2e32..4c986c955951 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -180,6 +180,7 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
 static bool is_kdump(void)
 {
struct device_node *node;
+   bool ret;
 
node = of_find_node_by_type(NULL, "memory");
if (!node) {
@@ -187,7 +188,10 @@ static bool is_kdump(void)
return false;
}
 
-   return of_property_read_bool(node, "linux,usable-memory");
+   ret = of_property_read_bool(node, "linux,usable-memory");
+   of_node_put(node);
+
+   return ret;
 }
 
 /* atmu setup for fsl pci/pcie controller */
diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c
index 698fefaaa6dd..2ff3a0a0cf3f 100644
--- a/arch/powerpc/sysdev/mpic_msgr.c
+++ b/arch/powerpc/sysdev/mpic_msgr.c
@@ -121,11 +121,13 @@ static unsigned int mpic_msgr_number_of_blocks(void)
 
count += 1;
}
+   of_node_put(aliases);
}
 
return count;
 }
 
+
 static unsigned int mpic_msgr_number_of_registers(void)
 {
return mpic_msgr_number_of_blocks() * MPIC_MSGR_REGISTERS_PER_BLOCK;
@@ -144,12 +146,18 @@ static int mpic_msgr_block_number(struct device_node 
*node)
 
for (index = 0; index < number_of_blocks; ++index) {
struct property *prop;
+   struct device_node *tn;
 
snprintf(buf, sizeof(buf), "mpic-msgr-block%d", index);
prop = of_find_property(aliases, buf, NULL);
-   if (node == of_find_node_by_path(prop->value))
+   tn = of_find_node_by_path(prop->value);
+   if (node == tn) {
+   of_node_put(tn);
break;
+   }
+   of_node_put(tn);
}
+   of_node_put(aliases);
 
return index == number_of_blocks ? -1 : index;
 }
diff --git a/arch/powerpc/sysdev/xive/native.c 
b/arch/powerpc/sysdev/xive/native.c
index d25d8c692909..3925825954bc 100644
--- a/arch/powerpc/sysdev/xive/native.c
+++ b/arch/powerpc/sysdev/xive/native.c
@@ -579,12 +579,12 @@ bool __init xive_native_init(void)
/* Resource 1 is HV window */
if (of_address_to_resource(np, 1, )) {
pr_err("Failed to get thread mgmnt area resource\n");
-   return false;
+   goto err_put;
}
tima = ioremap(r.start, resource_size());
if (!tima) {
pr_err("Failed to map thread mgmnt area\n");
-   return false;
+   goto err_put;
}
 
/* Read number of priorities */
@@ -612,7 +612,7 @@ bool __init xive_native_init(void)
/* Resource 2 is OS window */
if (of_address_to_resource(np, 2, )) {
pr_err("Failed to get thread mgmnt area resource\n");
-   return false;
+   goto err_put;
}
 
xive_tima_os = r.start;
@@ -624,7 +624,7 @@ bool __init xive_native_init(void)
rc = opal_xive_reset(OPAL_XIVE_MODE_EXPL);
if (rc) {
pr_err("Switch to exploitation mode failed with error %lld\n", 
rc);
-   return false;
+   goto err_put;
}
 
/* Setup some dummy HV pool VPs */
@@ -634,10 +634,15 @@ bool __init xive_native_init(void)
if (!xive_core_init(np, _native_ops, tima, TM_QW3_HV_PHYS,
max_prio)) {
opal_xive_reset(OPAL_XIVE_MODE_EMU);
-   return false;
+   goto err_put;
}
+   of_node_put(np);
pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10));
return true;
+
+err_put:
+   of_node_put(np);
+   return false;
 }
 
 static bool xive_native_provision_pages(void)
diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c
index 7d5128676e83..d398823d138e 100644
--- a/arch/powerpc/sysdev/xive/spapr.c
+++ b/arch/powerpc/sysdev/xive/spapr.c
@@ -717,6 +717,7 @@ static bool __init xive_get_max_prio(u8 *max_prio)
}
 
reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", );
+   of_node_put(rootdn);
if (!reg) {
pr_err("Failed to read 'ibm,plat-res-int-priorities' 
property\n");
return false;
-- 
2.25.1



Re:Re: [PATCH] powerpc: kernel: Change the order of of_node_put()

2022-06-20 Thread Liang He



At 2022-06-20 19:11:33, "Christophe Leroy"  wrote:
>Hi,
>
>Le 20/06/2022 à 11:23, Liang He a écrit :
>> 
>> Hi, Christophe.
>> 
>> Sorry to trobule you again.
>> 
>> Now I have found other bugs in same directories (i.e., arch/powerpc/sysdev),
>> with the ones I have sent but not recieved acked-by or confirmed email.
>> 
>> So I need to merge the old ones into the new ones as a PATCH-v2 and then 
>> resend the
>> old ones ?
>> or just use a new PATCH to send only new ones?
>> 
>> I am afraid to make new trouble for maintainers, so can you share your 
>> valuable
>> experience?
>> 
>
>Here is the list of your patches : 
>https://patchwork.ozlabs.org/project/linuxppc-dev/list/?submitter=84258
>
> From my point of view, for all the patches that are still in status 
>"new" it is better than you send a v2 with more things into a single 
>patch. When the patch is in "under review" state, it is better to not 
>update it anymore.
>
>So in the list there are for instance several patches for powernv, so it 
>would be good if you can regroup all of them in a single v2 patch.
>
>Christophe

Thanks, Christophe.

I will follow your rules and try to group the 'new' state ones.

Re:Re: [PATCH] powerpc: kernel: Change the order of of_node_put()

2022-06-20 Thread Liang He



At 2022-06-18 16:48:26, "Christophe Leroy"  wrote:
>
>
>Le 18/06/2022 à 10:03, Liang He a écrit :
>> 
>> 
>> 
>> 
>> 
>> 在 2022-06-18 15:13:13,"Christophe Leroy"  写道:
>>>
>>>
>>> Le 17/06/2022 à 13:26, Liang He a écrit :
>>>> In add_pcspkr(), it is better to call of_node_put() after the
>>>> 'if(!np)' check.
>>>
>>> Why is it better ?
>>>
>>>
>>>
>>> /**
>>>   * of_node_put() - Decrement refcount of a node
>>>   * @node:  Node to dec refcount, NULL is supported to simplify writing of
>>>   * callers
>>>   */
>>> void of_node_put(struct device_node *node)
>>> {
>>> if (node)
>>> kobject_put(>kobj);
>>> }
>>> EXPORT_SYMBOL(of_node_put);
>>>
>>>
>>>
>>> Christophe
>> 
>> Hi, Christophe.
>> 
>> Thanks for your reply and I want to have a discussion.
>> 
>> In my thought, xxx_put(pointer)'s semantic usually means
>> this reference has been used done and will not be used
>> anymore. Is this semantic more reasonable, right?
>> 
>> Besides, if the np is NULL, we can just return and save a cpu
>> time for the xxx_put() call.
>> 
>> Otherwise, I prefer to call it 'use(check)-after-put'.
>> 
>> In fact, I have meet many other 'use(check)-after-put' instances
>> after I send this patch-commit, so I am waiting for this
>> discussion.
>> 
>> This is just my thought, it may be wrong.
>> 
>> Anyway, thanks for your reply.
>
>Well in principle you are right, in an ideal world it should be like 
>that. However, you have to wonder if it is worth the churn. The CPU 
>cycle argument is valid only if that function is used in a hot path. But 
>as we are talking about error handling, it can't be a hot path.
>
>Taking into account the comment associated of of_node_put : "NULL is 
>supported to simplify writing of callers", it means that usage is valid, 
>just like it is with function kfree() after a kmalloc().
>
>So in a new developpement, or when doing real modifications to a driver, 
>that kind of change can be done ideally. However for drivers that have 
>been there for years without any change, ask yourself if it is worth the 
>churn. You spend time on it, you require other people to spend time on 
>it for reviewing and applying your patches and during that time they 
>don't do other things that could have been more usefull.
>
>So unless this change is part of a more global patch, I think it is not 
>worth the effort.
>
>By the way, also for all your other patches, I think you should start 
>doing all the changes locally on your side, and when you are finished 
>try to group things together in bigger patches per area instead of 
>sending one by one. I see you have already started doing that for 
>opal/powernv for instance, but there are still individual powernv/opal 
>in the queue. I think you should group all together in a single patch. 
>And same for other areas, please try to minimise the number of patches. 
>We don't link huge bombs that modify all the kernel at once, but you can 
>group things together, one patch for powerpc core parts, one patch for 
>each platform in arch/powerpc/platforms/ etc ...
>
>
>Christophe


Hi, Christophe.

Sorry to trobule you again.

Now I have found other bugs in same directories (i.e., arch/powerpc/sysdev), 
with the ones I have sent but not recieved acked-by or confirmed email.

So I need to merge the old ones into the new ones as a PATCH-v2 and then resend 
the 
old ones ?
or just use a new PATCH to send only new ones?

I am afraid to make new trouble for maintainers, so can you share your valuable 
experience?

Thanks very much.

Liang




[PATCH] powerpc/embedded6xx/ls_uart: Add missing of_node_put()

2022-06-20 Thread Liang He
In ls_uarts_init(), we need to add a of_node_put() to keep refcount
balance.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/embedded6xx/ls_uart.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/platforms/embedded6xx/ls_uart.c 
b/arch/powerpc/platforms/embedded6xx/ls_uart.c
index 0133e175a0fc..4ecbc55b37c0 100644
--- a/arch/powerpc/platforms/embedded6xx/ls_uart.c
+++ b/arch/powerpc/platforms/embedded6xx/ls_uart.c
@@ -124,6 +124,8 @@ static int __init ls_uarts_init(void)
avr_clock = *(u32*)of_get_property(avr, "clock-frequency", );
phys_addr = ((u32*)of_get_property(avr, "reg", ))[0];
 
+   of_node_put(avr);
+
if (!avr_clock || !phys_addr)
return -EINVAL;
 
-- 
2.25.1



[PATCH] powerpc/powernv: Fix refcount leak bug in idle.c

2022-06-20 Thread Liang He
In pnv_parse_cpuidle_dt(), of_find_node_by_path() will return a node
pointer with refcount incremented. We should use of_node_put() in fail
path or when it is not used anymore.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/powernv/idle.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/platforms/powernv/idle.c 
b/arch/powerpc/platforms/powernv/idle.c
index 6f94b808dd39..c1b369c7f507 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -1419,6 +1419,7 @@ static int __init pnv_parse_cpuidle_dt(void)
kfree(temp_u32);
kfree(temp_u64);
kfree(temp_string);
+   of_node_put(np);
return rc;
 }
 
-- 
2.25.1



[PATCH] powerpc: pseries: Fix refcount bug in ibmebus

2022-06-19 Thread Liang He
In ibmebus_match_path(), we should use of_node_put() to keep
refcount balance.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/pseries/ibmebus.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/ibmebus.c 
b/arch/powerpc/platforms/pseries/ibmebus.c
index 7ee3ed7d6cc2..a870cada7acd 100644
--- a/arch/powerpc/platforms/pseries/ibmebus.c
+++ b/arch/powerpc/platforms/pseries/ibmebus.c
@@ -152,7 +152,11 @@ static const struct dma_map_ops ibmebus_dma_ops = {
 static int ibmebus_match_path(struct device *dev, const void *data)
 {
struct device_node *dn = to_platform_device(dev)->dev.of_node;
-   return (of_find_node_by_path(data) == dn);
+   struct device_node *tn = of_find_node_by_path(data);
+
+   of_node_put(tn);
+
+   return (tn == dn);
 }
 
 static int ibmebus_match_node(struct device *dev, const void *data)
-- 
2.25.1



[PATCH] powerpc/cell: Fix refcount leak bugs

2022-06-19 Thread Liang He
We should use of_node_put() for of_find_node_by_path() and
of_find_node_by_phandle() to keep refcount balance.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/cell/setup.c   | 2 ++
 arch/powerpc/platforms/cell/spu_manage.c  | 2 ++
 arch/powerpc/platforms/cell/spufs/inode.c | 1 +
 3 files changed, 5 insertions(+)

diff --git a/arch/powerpc/platforms/cell/setup.c 
b/arch/powerpc/platforms/cell/setup.c
index 52de014983c9..47eaf75349f2 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -167,6 +167,8 @@ static int __init cell_publish_devices(void)
of_platform_device_create(np, NULL, NULL);
}
 
+   of_node_put(root);
+
/* There is no device for the MIC memory controller, thus we create
 * a platform device for it to attach the EDAC driver to.
 */
diff --git a/arch/powerpc/platforms/cell/spu_manage.c 
b/arch/powerpc/platforms/cell/spu_manage.c
index ae09c5a91b40..f1ac4c742069 100644
--- a/arch/powerpc/platforms/cell/spu_manage.c
+++ b/arch/powerpc/platforms/cell/spu_manage.c
@@ -488,6 +488,8 @@ static void __init init_affinity_node(int cbe)
avoid_ph = vic_dn->phandle;
}
 
+   of_node_put(vic_dn);
+
list_add_tail(>aff_list, _spu->aff_list);
last_spu = spu;
break;
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c 
b/arch/powerpc/platforms/cell/spufs/inode.c
index 34334c32b7f5..320008528edd 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -660,6 +660,7 @@ spufs_init_isolated_loader(void)
return;
 
loader = of_get_property(dn, "loader", );
+   of_node_put(dn);
if (!loader)
return;
 
-- 
2.25.1



[PATCH] powerpc: kernel: Fix refcount bug in legacy_serial.c

2022-06-19 Thread Liang He
In find_legacy_serial_ports(), of_find_node_by_path() will return
a node pointer with refcount incremented. We should use of_node_put()
when it is not used anymore.

Signed-off-by: Liang He 
---
 arch/powerpc/kernel/legacy_serial.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/kernel/legacy_serial.c 
b/arch/powerpc/kernel/legacy_serial.c
index 5c58460b269a..f048c424c525 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -471,6 +471,8 @@ void __init find_legacy_serial_ports(void)
}
 #endif
 
+   of_node_put(stdout);
+
DBG("legacy_serial_console = %d\n", legacy_serial_console);
if (legacy_serial_console >= 0)
setup_legacy_serial_console(legacy_serial_console);
-- 
2.25.1



Re:Re: [PATCH] powerpc: kernel: Change the order of of_node_put()

2022-06-18 Thread Liang He
 
  
At 2022-06-18 16:48:26, "Christophe Leroy"  wrote:
>
>
>Le 18/06/2022 à 10:03, Liang He a écrit :
>> 
>> 
>> 
>> 
>> 
>> 在 2022-06-18 15:13:13,"Christophe Leroy"  写道:
>>>
>>>
>>> Le 17/06/2022 à 13:26, Liang He a écrit :
>>>> In add_pcspkr(), it is better to call of_node_put() after the
>>>> 'if(!np)' check.
>>>
>>> Why is it better ?
>>>
>>>
>>>
>>> /**
>>>   * of_node_put() - Decrement refcount of a node
>>>   * @node:  Node to dec refcount, NULL is supported to simplify writing of
>>>   * callers
>>>   */
>>> void of_node_put(struct device_node *node)
>>> {
>>> if (node)
>>> kobject_put(>kobj);
>>> }
>>> EXPORT_SYMBOL(of_node_put);
>>>
>>>
>>>
>>> Christophe
>> 
>> Hi, Christophe.
>> 
>> Thanks for your reply and I want to have a discussion.
>> 
>> In my thought, xxx_put(pointer)'s semantic usually means
>> this reference has been used done and will not be used
>> anymore. Is this semantic more reasonable, right?
>> 
>> Besides, if the np is NULL, we can just return and save a cpu
>> time for the xxx_put() call.
>> 
>> Otherwise, I prefer to call it 'use(check)-after-put'.
>> 
>> In fact, I have meet many other 'use(check)-after-put' instances
>> after I send this patch-commit, so I am waiting for this
>> discussion.
>> 
>> This is just my thought, it may be wrong.
>> 
>> Anyway, thanks for your reply.
>
>Well in principle you are right, in an ideal world it should be like 
>that. However, you have to wonder if it is worth the churn. The CPU 
>cycle argument is valid only if that function is used in a hot path. But 
>as we are talking about error handling, it can't be a hot path.
>

Thanks very much for this valuable lesson.

>Taking into account the comment associated of of_node_put : "NULL is 
>supported to simplify writing of callers", it means that usage is valid, 
>just like it is with function kfree() after a kmalloc().
>
>So in a new developpement, or when doing real modifications to a driver, 
>that kind of change can be done ideally. However for drivers that have 
>been there for years without any change, ask yourself if it is worth the 
>churn. You spend time on it, you require other people to spend time on 
>it for reviewing and applying your patches and during that time they 
>don't do other things that could have been more usefull.
>

Thanks for you advice, I will keep it in my mind before I send a new patch.

>So unless this change is part of a more global patch, I think it is not 
>worth the effort.
>
>By the way, also for all your other patches, I think you should start 
>doing all the changes locally on your side, and when you are finished 
>try to group things together in bigger patches per area instead of 
>sending one by one. I see you have already started doing that for 
>opal/powernv for instance, but there are still individual powernv/opal 
>in the queue. I think you should group all together in a single patch. 
>And same for other areas, please try to minimise the number of patches. 
>We don't link huge bombs that modify all the kernel at once, but you can 
>group things together, one patch for powerpc core parts, one patch for 
>each platform in arch/powerpc/platforms/ etc ...
>

You are right and I will follow this principle in future patching work.
While It is too exciting for me to begin the patching work , I should have 
grouped my patches.

>
>Christophe

Thanks again, Christophe.

Liang


Re:Re: [PATCH] powerpc: kernel: Change the order of of_node_put()

2022-06-18 Thread Liang He





在 2022-06-18 15:13:13,"Christophe Leroy"  写道:
>
>
>Le 17/06/2022 à 13:26, Liang He a écrit :
>> In add_pcspkr(), it is better to call of_node_put() after the
>> 'if(!np)' check.
>
>Why is it better ?
>
>
>
>/**
>  * of_node_put() - Decrement refcount of a node
>  * @node: Node to dec refcount, NULL is supported to simplify writing of
>  *callers
>  */
>void of_node_put(struct device_node *node)
>{
>   if (node)
>   kobject_put(>kobj);
>}
>EXPORT_SYMBOL(of_node_put);
>
>
>
>Christophe

Hi, Christophe.

Thanks for your reply and I want to have a discussion.

In my thought, xxx_put(pointer)'s semantic usually means 
this reference has been used done and will not be used 
anymore. Is this semantic more reasonable, right?

Besides, if the np is NULL, we can just return and save a cpu 
time for the xxx_put() call.

Otherwise, I prefer to call it 'use(check)-after-put'.  

In fact, I have meet many other 'use(check)-after-put' instances
after I send this patch-commit, so I am waiting for this 
discussion.

This is just my thought, it may be wrong.

Anyway, thanks for your reply.

Liang

>
>
>> 
>> Signed-off-by: Liang He 
>> ---
>>   arch/powerpc/kernel/setup-common.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/arch/powerpc/kernel/setup-common.c 
>> b/arch/powerpc/kernel/setup-common.c
>> index eb0077b302e2..761817d1f4db 100644
>> --- a/arch/powerpc/kernel/setup-common.c
>> +++ b/arch/powerpc/kernel/setup-common.c
>> @@ -563,9 +563,9 @@ static __init int add_pcspkr(void)
>>  int ret;
>>   
>>  np = of_find_compatible_node(NULL, NULL, "pnpPNP,100");
>> -of_node_put(np);
>>  if (!np)
>>  return -ENODEV;
>> +of_node_put(np);
>>   
>>  pd = platform_device_alloc("pcspkr", -1);
>>  if (!pd)


[PATCH] powerpc: perf: Fix refcount leak bug in imc-pmu.c

2022-06-18 Thread Liang He
In update_events_in_group(), of_find_node_by_phandle() will return
a node pointer with refcount incremented. We should use of_node_put()
in fail path or when it is not used anymore.

Signed-off-by: Liang He 
---
 arch/powerpc/perf/imc-pmu.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index d7976ab40d38..d517aba94d1b 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -240,8 +240,10 @@ static int update_events_in_group(struct device_node 
*node, struct imc_pmu *pmu)
ct = of_get_child_count(pmu_events);
 
/* Get the event prefix */
-   if (of_property_read_string(node, "events-prefix", ))
+   if (of_property_read_string(node, "events-prefix", )) {
+   of_node_put(pmu_events);
return 0;
+   }
 
/* Get a global unit and scale data if available */
if (of_property_read_string(node, "scale", _scale))
@@ -255,8 +257,10 @@ static int update_events_in_group(struct device_node 
*node, struct imc_pmu *pmu)
 
/* Allocate memory for the events */
pmu->events = kcalloc(ct, sizeof(struct imc_events), GFP_KERNEL);
-   if (!pmu->events)
+   if (!pmu->events) {
+   of_node_put(pmu_events);
return -ENOMEM;
+   }
 
ct = 0;
/* Parse the events and update the struct */
@@ -266,6 +270,8 @@ static int update_events_in_group(struct device_node *node, 
struct imc_pmu *pmu)
ct++;
}
 
+   of_node_put(pmu_events);
+
/* Allocate memory for attribute group */
attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL);
if (!attr_group) {
-- 
2.25.1



[PATCH] tty: serial: Fix refcount leak bug in ucc_uart.c

2022-06-18 Thread Liang He
In soc_info(), of_find_node_by_type() will return a node pointer
with refcount incremented. We should use of_node_put() when it is
not used anymore.

Signed-off-by: Liang He 
---
 drivers/tty/serial/ucc_uart.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c
index 6000853973c1..3cc9ef08455c 100644
--- a/drivers/tty/serial/ucc_uart.c
+++ b/drivers/tty/serial/ucc_uart.c
@@ -1137,6 +1137,8 @@ static unsigned int soc_info(unsigned int *rev_h, 
unsigned int *rev_l)
/* No compatible property, so try the name. */
soc_string = np->name;
 
+   of_node_put(np);
+
/* Extract the SOC number from the "PowerPC," string */
if ((sscanf(soc_string, "PowerPC,%u", ) != 1) || !soc)
return 0;
-- 
2.25.1



[PATCH v2] powerpc: embedded6xx: Fix refcount leak bugs

2022-06-17 Thread Liang He
In xx_init_xx(), of_find_node_by_type() will return a node pointer
with refcount incremented. We should use of_node_put() when it is
not used anymore.

Signed-off-by: Liang He 
---
 v2: we merge all embedded6xx related bugs into one commit
 v1: we only report the bug in holly_init_pci() of holly.c

 arch/powerpc/platforms/embedded6xx/holly.c| 6 ++
 arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/arch/powerpc/platforms/embedded6xx/holly.c 
b/arch/powerpc/platforms/embedded6xx/holly.c
index 78f2378d9223..bebc5a972694 100644
--- a/arch/powerpc/platforms/embedded6xx/holly.c
+++ b/arch/powerpc/platforms/embedded6xx/holly.c
@@ -123,6 +123,8 @@ static void __init holly_init_pci(void)
if (np)
tsi108_setup_pci(np, HOLLY_PCI_CFG_PHYS, 1);
 
+   of_node_put(np);
+
ppc_md.pci_exclude_device = holly_exclude_device;
if (ppc_md.progress)
ppc_md.progress("tsi108: resources set", 0x100);
@@ -184,6 +186,9 @@ static void __init holly_init_IRQ(void)
tsi108_pci_int_init(cascade_node);
irq_set_handler_data(cascade_pci_irq, mpic);
irq_set_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
+
+   of_node_put(tsi_pci);
+   of_node_put(cascade_node);
 #endif
/* Configure MPIC outputs to CPU0 */
tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
@@ -210,6 +215,7 @@ static void __noreturn holly_restart(char *cmd)
if (bridge) {
prop = of_get_property(bridge, "reg", );
addr = of_translate_address(bridge, prop);
+   of_node_put(bridge);
}
addr += (TSI108_PB_OFFSET + 0x414);
 
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c 
b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index 8b2b42210356..ddf0c652af80 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -135,6 +135,9 @@ static void __init mpc7448_hpc2_init_IRQ(void)
tsi108_pci_int_init(cascade_node);
irq_set_handler_data(cascade_pci_irq, mpic);
irq_set_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
+
+   of_node_put(tsi_pci);
+   of_node_put(cascade_node);
 #endif
/* Configure MPIC outputs to CPU0 */
tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
-- 
2.25.1



[PATCH] powerpc: embedded6xx: Fix refcount leak bug in holly.c

2022-06-17 Thread Liang He
In holly_init_pci(), of_find_node_by_type() will return a node
pointer with refcount incremented. We should use of_node_put()
when it is not used anymore.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/embedded6xx/holly.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/platforms/embedded6xx/holly.c 
b/arch/powerpc/platforms/embedded6xx/holly.c
index 78f2378d9223..a4938505e89a 100644
--- a/arch/powerpc/platforms/embedded6xx/holly.c
+++ b/arch/powerpc/platforms/embedded6xx/holly.c
@@ -122,6 +122,7 @@ static void __init holly_init_pci(void)
np = of_find_node_by_type(NULL, "pci");
if (np)
tsi108_setup_pci(np, HOLLY_PCI_CFG_PHYS, 1);
+   of_node_put(np);
 
ppc_md.pci_exclude_device = holly_exclude_device;
if (ppc_md.progress)
-- 
2.25.1



[PATCH] powerpc: sysdev: Fix refcount leak bug in fsl_pci.c

2022-06-17 Thread Liang He
In is_kdump(), we need a of_node_put() to dec the refcount which is
incremented by of_find_node_by_type().

Signed-off-by: Liang He 
---
 arch/powerpc/sysdev/fsl_pci.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 1011cfea2e32..4c986c955951 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -180,6 +180,7 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
 static bool is_kdump(void)
 {
struct device_node *node;
+   bool ret;
 
node = of_find_node_by_type(NULL, "memory");
if (!node) {
@@ -187,7 +188,10 @@ static bool is_kdump(void)
return false;
}
 
-   return of_property_read_bool(node, "linux,usable-memory");
+   ret = of_property_read_bool(node, "linux,usable-memory");
+   of_node_put(node);
+
+   return ret;
 }
 
 /* atmu setup for fsl pci/pcie controller */
-- 
2.25.1



[PATCH] powerpc: 8xx: Fix refcount leak bug in tqm8xx_setup

2022-06-17 Thread Liang He
In init_ioports(), of_find_node_by_name() will return a node pointer
with refcount incremented. We should use of_node_put() when it is not
used anymore.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/8xx/tqm8xx_setup.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/platforms/8xx/tqm8xx_setup.c 
b/arch/powerpc/platforms/8xx/tqm8xx_setup.c
index 3725d51248df..ffcfd17a5fa3 100644
--- a/arch/powerpc/platforms/8xx/tqm8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/tqm8xx_setup.c
@@ -105,6 +105,9 @@ static void __init init_ioports(void)
if (dnode == NULL)
return;
prop = of_find_property(dnode, "ethernet1", );
+
+   of_node_put(dnode);
+
if (prop == NULL)
return;
 
-- 
2.25.1



[PATCH] cpufreq: pmac32-cpufreq: Fix refcount leak bug

2022-06-17 Thread Liang He
In pmac_cpufreq_init_MacRISC3(), we need to add corresponding
of_node_put() for the three node pointers whose refcount have
been incremented by of_find_node_by_name().

Signed-off-by: Liang He 
---
 drivers/cpufreq/pmac32-cpufreq.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c
index 20f64a8b0a35..4b8ee2014da6 100644
--- a/drivers/cpufreq/pmac32-cpufreq.c
+++ b/drivers/cpufreq/pmac32-cpufreq.c
@@ -470,6 +470,10 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node 
*cpunode)
if (slew_done_gpio_np)
slew_done_gpio = read_gpio(slew_done_gpio_np);
 
+   of_node_put(volt_gpio_np);
+   of_node_put(freq_gpio_np);
+   of_node_put(slew_done_gpio_np);
+
/* If we use the frequency GPIOs, calculate the min/max speeds based
 * on the bus frequencies
 */
-- 
2.25.1



[PATCH] powerpc: powernv: opal-core: Fix refcount leak bug

2022-06-17 Thread Liang He
In create_opalcore(), of_find_node_by_name() will return a node
pointer with refcount incremented. We should use of_node_put()
when it is not used anymore.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/powernv/opal-core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/opal-core.c 
b/arch/powerpc/platforms/powernv/opal-core.c
index adcb1a1a2bfe..bb7657115f1d 100644
--- a/arch/powerpc/platforms/powernv/opal-core.c
+++ b/arch/powerpc/platforms/powernv/opal-core.c
@@ -348,6 +348,8 @@ static int __init create_opalcore(void)
if (!dn || ret)
pr_warn("WARNING: Failed to read OPAL base & entry values\n");
 
+   of_node_put(dn);
+
/* Use count to keep track of the program headers */
count = 0;
 
-- 
2.25.1



[PATCH] powerpc: sysdev: Fix refcount leak bug in mpic_msgr

2022-06-17 Thread Liang He
In mpic_msgr_number_of_blocks() and mpic_msgr_block_number(),
of_find_node_by_name() will return a node pointer with refcount
incremented. We should use of_node_put() when it is not used
anymore.

Signed-off-by: Liang He 
---
 arch/powerpc/sysdev/mpic_msgr.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c
index 698fefaaa6dd..c2a235d9eb09 100644
--- a/arch/powerpc/sysdev/mpic_msgr.c
+++ b/arch/powerpc/sysdev/mpic_msgr.c
@@ -122,6 +122,7 @@ static unsigned int mpic_msgr_number_of_blocks(void)
count += 1;
}
}
+   of_node_put(aliases);
 
return count;
 }
@@ -150,6 +151,7 @@ static int mpic_msgr_block_number(struct device_node *node)
if (node == of_find_node_by_path(prop->value))
break;
}
+   of_node_put(aliases);
 
return index == number_of_blocks ? -1 : index;
 }
-- 
2.25.1



Re:Re: [PATCH] powerpc: powernv: Fix refcount leak bug in opal-powercap

2022-06-17 Thread Liang He



At 2022-06-17 13:01:27, "Christophe JAILLET"  
wrote:
>Le 17/06/2022 à 06:20, Liang He a écrit :
>> In opal_powercap_init(), of_find_compatible_node() will return
>> a node pointer with refcount incremented. We should use of_node_put()
>> in fail path or when it is not used anymore.
>> 
>> Besides, for_each_child_of_node() will automatically *inc* and *dec*
>> refcount during iteration. However, we should add the of_node_put()
>> if there is a break.
>
>Hi,
>
>I'm not sure that your patch is right here. Because of this *inc* and 
>*dec* things, do we still need to of_node_put(powercap) once we have 
>entered for_each_child_of_node?
>
>I think that this reference will be released on the first iteration of 
>the loop.
>
>
>Maybe of_node_put(powercap) should be duplicated everywhere it is 
>relevant and removed from the error handling path?
>Or an additional reference should be taken before the loop?
>Or adding a new label with "powercap = NULL" and branching there when 
>needed?
>
>CJ
>
>> 
>> Signed-off-by: Liang He 
>> ---
>>   arch/powerpc/platforms/powernv/opal-powercap.c | 5 -
>>   1 file changed, 4 insertions(+), 1 deletion(-)
>> 
>> diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c 
>> b/arch/powerpc/platforms/powernv/opal-powercap.c
>> index 64506b46e77b..b102477d3f95 100644
>> --- a/arch/powerpc/platforms/powernv/opal-powercap.c
>> +++ b/arch/powerpc/platforms/powernv/opal-powercap.c
>> @@ -153,7 +153,7 @@ void __init opal_powercap_init(void)
>>  pcaps = kcalloc(of_get_child_count(powercap), sizeof(*pcaps),
>>  GFP_KERNEL);
>>  if (!pcaps)
>> -return;
>> +goto out_powercap;
>>   
>>  powercap_kobj = kobject_create_and_add("powercap", opal_kobj);
>>  if (!powercap_kobj) {
>> @@ -236,6 +236,9 @@ void __init opal_powercap_init(void)
>>  kfree(pcaps[i].pg.name);
>>  }
>>  kobject_put(powercap_kobj);
>> +of_node_put(node);
>>   out_pcaps:
>>  kfree(pcaps);
>> +out_powercap:
>> +of_node_put(powercap);
>>   }

Hi, CJ.

I think my patch is correct based on the old commit: 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v5.19-rc2=09700c504d8e63faffd2a2235074e8c5d130cb8f

Bugs and fix solutions in this 09700c504d8e63-commit are very similar with mine.

Besides, I also find similar new bugs in other two files in the same directory 
'powernv', 
so I have merged all three files' patches into one commit.  '[PATCH v2] 
powerpc: powernv: Fix refcount leak bug'.

Thanks.

Liang

[PATCH v2] powerpc: powernv: Fix refcount leak bug

2022-06-17 Thread Liang He
In these driver init functions, there are two kinds of errors:

(1) missing of_put_node() for of_find_compatible_node()'s returned
pointer (refcount incremented)  in fail path or when it is not
used anymore.
(2) missing of_put_node() for 'for_each_xxx' loop's break

These bugs are similar with the ones reported by commit-09700c504d.

Signed-off-by: Liang He 
---
 changelog:
 
 v2: merge all powernv related bugs into one commit 
 v1: only fix bugs in opal-powercap.c


 arch/powerpc/platforms/powernv/opal-powercap.c  | 6 +-
 arch/powerpc/platforms/powernv/opal-psr.c   | 6 +-
 arch/powerpc/platforms/powernv/opal-sensor-groups.c | 6 +-
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c 
b/arch/powerpc/platforms/powernv/opal-powercap.c
index 64506b46e77b..78c359c90093 100644
--- a/arch/powerpc/platforms/powernv/opal-powercap.c
+++ b/arch/powerpc/platforms/powernv/opal-powercap.c
@@ -153,7 +153,7 @@ void __init opal_powercap_init(void)
pcaps = kcalloc(of_get_child_count(powercap), sizeof(*pcaps),
GFP_KERNEL);
if (!pcaps)
-   return;
+   goto out_powercap;
 
powercap_kobj = kobject_create_and_add("powercap", opal_kobj);
if (!powercap_kobj) {
@@ -226,6 +226,7 @@ void __init opal_powercap_init(void)
}
i++;
}
+   of_node_put(powercap);
 
return;
 
@@ -236,6 +237,9 @@ void __init opal_powercap_init(void)
kfree(pcaps[i].pg.name);
}
kobject_put(powercap_kobj);
+   of_node_put(node);
 out_pcaps:
kfree(pcaps);
+out_powercap:
+   of_node_put(powercap);
 }
diff --git a/arch/powerpc/platforms/powernv/opal-psr.c 
b/arch/powerpc/platforms/powernv/opal-psr.c
index 69d7e75950d1..ec32e0a93f08 100644
--- a/arch/powerpc/platforms/powernv/opal-psr.c
+++ b/arch/powerpc/platforms/powernv/opal-psr.c
@@ -135,7 +135,7 @@ void __init opal_psr_init(void)
psr_attrs = kcalloc(of_get_child_count(psr), sizeof(*psr_attrs),
GFP_KERNEL);
if (!psr_attrs)
-   return;
+   goto out_psr;
 
psr_kobj = kobject_create_and_add("psr", opal_kobj);
if (!psr_kobj) {
@@ -162,10 +162,14 @@ void __init opal_psr_init(void)
}
i++;
}
+   of_node_put(psr);
 
return;
 out_kobj:
+   of_node_put(node);
kobject_put(psr_kobj);
 out:
kfree(psr_attrs);
+out_psr:
+   of_node_put(psr);
 }
diff --git a/arch/powerpc/platforms/powernv/opal-sensor-groups.c 
b/arch/powerpc/platforms/powernv/opal-sensor-groups.c
index 8fba7d25ae56..9944376b115c 100644
--- a/arch/powerpc/platforms/powernv/opal-sensor-groups.c
+++ b/arch/powerpc/platforms/powernv/opal-sensor-groups.c
@@ -170,7 +170,7 @@ void __init opal_sensor_groups_init(void)
 
sgs = kcalloc(of_get_child_count(sg), sizeof(*sgs), GFP_KERNEL);
if (!sgs)
-   return;
+   goto out_sg_put;
 
sg_kobj = kobject_create_and_add("sensor_groups", opal_kobj);
if (!sg_kobj) {
@@ -222,6 +222,7 @@ void __init opal_sensor_groups_init(void)
}
i++;
}
+   of_node_put(sg);
 
return;
 
@@ -231,6 +232,9 @@ void __init opal_sensor_groups_init(void)
kfree(sgs[i].sg.attrs);
}
kobject_put(sg_kobj);
+   of_node_put(node);
 out_sgs:
kfree(sgs);
+out_sg_put:
+   of_node_put(sg);
 }
-- 
2.25.1



[PATCH] powerpc: maple: Fix refcount leak bug in time.c

2022-06-17 Thread Liang He
In maple_get_boot_time(), of_find_compatible_node() will return
a node pointer with refcount incremented. We should use of_node_put()
in fail path or when it is not used anymore.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/maple/time.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/platforms/maple/time.c 
b/arch/powerpc/platforms/maple/time.c
index 823e219ef8ee..91606411d2e0 100644
--- a/arch/powerpc/platforms/maple/time.c
+++ b/arch/powerpc/platforms/maple/time.c
@@ -153,6 +153,7 @@ time64_t __init maple_get_boot_time(void)
   maple_rtc_addr);
}
  bail:
+   of_node_put(rtcs);
if (maple_rtc_addr == 0) {
maple_rtc_addr = RTC_PORT(0); /* legacy address */
printk(KERN_INFO "Maple: No device node for RTC, assuming "
-- 
2.25.1



Re:Re: [PATCH v4] powerpc:85xx: Add missing of_node_put() in sgy_cst1000

2022-06-17 Thread Liang He



在 2022-06-17 18:57:36,"Christophe Leroy"  写道:
>
>
>Le 17/06/2022 à 12:47, Liang He a écrit :
>> 
>> 
>> 
>> At 2022-06-17 16:27:03, conor.doo...@microchip.com wrote:
>>> On 17/06/2022 09:17, Liang He wrote:
>>>>
>>>>
>>>>
>>>> At 2022-06-17 14:53:13, "Christophe Leroy"  
>>>> wrote:
>>>>>
>>>>>
>>>>> Le 17/06/2022 à 08:45, Liang He a écrit :
>>>>>>
>>>>>>
>>>>>>
>>>>>> At 2022-06-17 14:28:56, "Christophe Leroy"  
>>>>>> wrote:
>>>>>>>
>>>>>>>
>>>>>>> Le 17/06/2022 à 08:08, Liang He a écrit :
>>>>>>>> In gpio_halt_probe(), of_find_matching_node() will return a node
>>>>>>>> pointer with refcount incremented. We should use of_node_put() in
>>>>>>>> fail path or when it is not used anymore.
>>>>>>>>
>>>>>>>> Signed-off-by: Liang He 
>>>>>>>> ---
>>>>>>>>  changelog:
>>>>>>>>  v4: reuse exist 'err' and use a simple code style, advised by CJ
>>>>>>>>  v3: use local 'child_node' advised by Michael.
>>>>>>>>  v2: use goto-label patch style advised by Christophe Leroy.
>>>>>>>>  v1: add of_node_put() before each exit.
>>>>>>>>
>>>>>>>>  arch/powerpc/platforms/85xx/sgy_cts1000.c | 35 
>>>>>>>> ++-
>>>>>>>>  1 file changed, 22 insertions(+), 13 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
>>>>>>>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>>>>>> index 98ae64075193..e4588943fe7e 100644
>>>>>>>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>>>>>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>>>>>> @@ -71,6 +71,7 @@ static int gpio_halt_probe(struct platform_device 
>>>>>>>> *pdev)
>>>>>>>>  {
>>>>>>>>enum of_gpio_flags flags;
>>>>>>>>struct device_node *node = pdev->dev.of_node;
>>>>>>>> +  struct device_node *child_node;
>>>>>>>>int gpio, err, irq;
>>>>>>>>int trigger;
>>>>>>>>  
>>>>>>>> @@ -78,26 +79,29 @@ static int gpio_halt_probe(struct platform_device 
>>>>>>>> *pdev)
>>>>>>>>return -ENODEV;
>>>>>>>>  
>>>>>>>>/* If there's no matching child, this isn't really an error */
>>>>>>>> -  halt_node = of_find_matching_node(node, child_match);
>>>>>>>> -  if (!halt_node)
>>>>>>>> +  child_node = of_find_matching_node(node, child_match);
>>>>>>>> +  if (!child_node)
>>>>>>>>return 0;
>>>>>>>>  
>>>>>>>>/* Technically we could just read the first one, but punish
>>>>>>>> * DT writers for invalid form. */
>>>>>>>> -  if (of_gpio_count(halt_node) != 1)
>>>>>>>> -  return -EINVAL;
>>>>>>>> +  if (of_gpio_count(child_node) != 1) {
>>>>>>>> +  err = -EINVAL;
>>>>>>>> +  goto err_put;
>>>>>>>> +  }
>>>>>>>>  
>>>>>>>>/* Get the gpio number relative to the dynamic base. */
>>>>>>>> -  gpio = of_get_gpio_flags(halt_node, 0, );
>>>>>>>> -  if (!gpio_is_valid(gpio))
>>>>>>>> -  return -EINVAL;
>>>>>>>> +  gpio = of_get_gpio_flags(child_node, 0, );
>>>>>>>> +  if (!gpio_is_valid(gpio)) {
>>>>>>>> +  err = -EINVAL;
>>>>>>>> +  gotot err_put;
>>>>>>>
>>>>>>> Did you test the build ?
>>>>>>
>>>>>> Sorry for this fault.
>>

[PATCH] powerpc: kernel: Change the order of of_node_put()

2022-06-17 Thread Liang He
In add_pcspkr(), it is better to call of_node_put() after the
'if(!np)' check.

Signed-off-by: Liang He 
---
 arch/powerpc/kernel/setup-common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/setup-common.c 
b/arch/powerpc/kernel/setup-common.c
index eb0077b302e2..761817d1f4db 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -563,9 +563,9 @@ static __init int add_pcspkr(void)
int ret;
 
np = of_find_compatible_node(NULL, NULL, "pnpPNP,100");
-   of_node_put(np);
if (!np)
return -ENODEV;
+   of_node_put(np);
 
pd = platform_device_alloc("pcspkr", -1);
if (!pd)
-- 
2.25.1



[PATCH v5] powerpc:85xx: Add missing of_node_put() in sgy_cst1000

2022-06-17 Thread Liang He
In gpio_halt_probe(), of_find_matching_node() will return a node
pointer with refcount incremented. We should use of_node_put() in
fail path or when it is not used anymore.

Signed-off-by: Liang He 
---
 changelog:
 v5: fix 'gotot' error introduced by v4 and use cross-compiler to test 
 v4: reuse exist 'err' and use a simple code style, advised by CJ
 v3: use local 'child_node' advised by Michael.
 v2: use goto-label patch style advised by Christophe Leroy.
 v1: add of_node_put() before each exit.

 arch/powerpc/platforms/85xx/sgy_cts1000.c | 35 ++-
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
b/arch/powerpc/platforms/85xx/sgy_cts1000.c
index 98ae64075193..e14d1b74d4e4 100644
--- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
+++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
@@ -71,6 +71,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
 {
enum of_gpio_flags flags;
struct device_node *node = pdev->dev.of_node;
+   struct device_node *child_node;
int gpio, err, irq;
int trigger;
 
@@ -78,26 +79,29 @@ static int gpio_halt_probe(struct platform_device *pdev)
return -ENODEV;
 
/* If there's no matching child, this isn't really an error */
-   halt_node = of_find_matching_node(node, child_match);
-   if (!halt_node)
+   child_node = of_find_matching_node(node, child_match);
+   if (!child_node)
return 0;
 
/* Technically we could just read the first one, but punish
 * DT writers for invalid form. */
-   if (of_gpio_count(halt_node) != 1)
-   return -EINVAL;
+   if (of_gpio_count(child_node) != 1) {
+   err = -EINVAL;
+   goto err_put;
+   }
 
/* Get the gpio number relative to the dynamic base. */
-   gpio = of_get_gpio_flags(halt_node, 0, );
-   if (!gpio_is_valid(gpio))
-   return -EINVAL;
+   gpio = of_get_gpio_flags(child_node, 0, );
+   if (!gpio_is_valid(gpio)) {
+   err = -EINVAL;
+   goto err_put;
+   }
 
err = gpio_request(gpio, "gpio-halt");
if (err) {
printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n",
   gpio);
-   halt_node = NULL;
-   return err;
+   goto err_put;
}
 
trigger = (flags == OF_GPIO_ACTIVE_LOW);
@@ -105,15 +109,14 @@ static int gpio_halt_probe(struct platform_device *pdev)
gpio_direction_output(gpio, !trigger);
 
/* Now get the IRQ which tells us when the power button is hit */
-   irq = irq_of_parse_and_map(halt_node, 0);
+   irq = irq_of_parse_and_map(child_node, 0);
err = request_irq(irq, gpio_halt_irq, IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING, "gpio-halt", halt_node);
+ IRQF_TRIGGER_FALLING, "gpio-halt", child_node);
if (err) {
printk(KERN_ERR "gpio-halt: error requesting IRQ %d for "
   "GPIO %d.\n", irq, gpio);
gpio_free(gpio);
-   halt_node = NULL;
-   return err;
+   goto err_put;
}
 
/* Register our halt function */
@@ -123,7 +126,12 @@ static int gpio_halt_probe(struct platform_device *pdev)
printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
   " irq).\n", gpio, trigger, irq);
 
+   halt_node = child_node;
return 0;
+
+err_put:
+   of_node_put(child_node);
+   return err;
 }
 
 static int gpio_halt_remove(struct platform_device *pdev)
@@ -139,6 +147,7 @@ static int gpio_halt_remove(struct platform_device *pdev)
 
gpio_free(gpio);
 
+   of_node_put(halt_node);
halt_node = NULL;
}
 
-- 
2.25.1



Re:Re: [PATCH v4] powerpc:85xx: Add missing of_node_put() in sgy_cst1000

2022-06-17 Thread Liang He



At 2022-06-17 16:27:03, conor.doo...@microchip.com wrote:
>On 17/06/2022 09:17, Liang He wrote:
>> 
>> 
>> 
>> At 2022-06-17 14:53:13, "Christophe Leroy"  
>> wrote:
>>>
>>>
>>> Le 17/06/2022 à 08:45, Liang He a écrit :
>>>>
>>>>
>>>>
>>>> At 2022-06-17 14:28:56, "Christophe Leroy"  
>>>> wrote:
>>>>>
>>>>>
>>>>> Le 17/06/2022 à 08:08, Liang He a écrit :
>>>>>> In gpio_halt_probe(), of_find_matching_node() will return a node
>>>>>> pointer with refcount incremented. We should use of_node_put() in
>>>>>> fail path or when it is not used anymore.
>>>>>>
>>>>>> Signed-off-by: Liang He 
>>>>>> ---
>>>>>> changelog:
>>>>>> v4: reuse exist 'err' and use a simple code style, advised by CJ
>>>>>> v3: use local 'child_node' advised by Michael.
>>>>>> v2: use goto-label patch style advised by Christophe Leroy.
>>>>>> v1: add of_node_put() before each exit.
>>>>>>
>>>>>> arch/powerpc/platforms/85xx/sgy_cts1000.c | 35 
>>>>>> ++-
>>>>>> 1 file changed, 22 insertions(+), 13 deletions(-)
>>>>>>
>>>>>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
>>>>>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>>>> index 98ae64075193..e4588943fe7e 100644
>>>>>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>>>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>>>> @@ -71,6 +71,7 @@ static int gpio_halt_probe(struct platform_device 
>>>>>> *pdev)
>>>>>> {
>>>>>>  enum of_gpio_flags flags;
>>>>>>  struct device_node *node = pdev->dev.of_node;
>>>>>> +struct device_node *child_node;
>>>>>>  int gpio, err, irq;
>>>>>>  int trigger;
>>>>>> 
>>>>>> @@ -78,26 +79,29 @@ static int gpio_halt_probe(struct platform_device 
>>>>>> *pdev)
>>>>>>  return -ENODEV;
>>>>>> 
>>>>>>  /* If there's no matching child, this isn't really an error */
>>>>>> -halt_node = of_find_matching_node(node, child_match);
>>>>>> -if (!halt_node)
>>>>>> +child_node = of_find_matching_node(node, child_match);
>>>>>> +if (!child_node)
>>>>>>  return 0;
>>>>>> 
>>>>>>  /* Technically we could just read the first one, but punish
>>>>>>   * DT writers for invalid form. */
>>>>>> -if (of_gpio_count(halt_node) != 1)
>>>>>> -return -EINVAL;
>>>>>> +if (of_gpio_count(child_node) != 1) {
>>>>>> +err = -EINVAL;
>>>>>> +goto err_put;
>>>>>> +}
>>>>>> 
>>>>>>  /* Get the gpio number relative to the dynamic base. */
>>>>>> -gpio = of_get_gpio_flags(halt_node, 0, );
>>>>>> -if (!gpio_is_valid(gpio))
>>>>>> -return -EINVAL;
>>>>>> +gpio = of_get_gpio_flags(child_node, 0, );
>>>>>> +if (!gpio_is_valid(gpio)) {
>>>>>> +err = -EINVAL;
>>>>>> +gotot err_put;
>>>>>
>>>>> Did you test the build ?
>>>>
>>>> Sorry for this fault.
>>>>
>>>> In fact, I am still finding an efficient way to building different arch 
>>>> source code as I only have x86-64.
>>>>
>>>> Now I am try using QEMU.
>>>>
>>>> Anyway, sorry for this fault.
>>>
>>> You can find cross compilers for most architectures for x86-64 here :
>>> https://mirrors.edge.kernel.org/pub/tools/crosstool/
>>>
>>> Christophe
>> 
>> Hi, Christophe and Conor.
>> 
>> Sorry to trouble you again.
>> 
>> Now I only know how to quickly identify the refcounting bugs, but I cannot 
>> efficiently give a build test.
>> 
>> For example,

Re:Re: [PATCH v4] powerpc:85xx: Add missing of_node_put() in sgy_cst1000

2022-06-17 Thread Liang He

At 2022-06-17 16:27:03, conor.doo...@microchip.com wrote:
>On 17/06/2022 09:17, Liang He wrote:
>> 
>> 
>> 
>> At 2022-06-17 14:53:13, "Christophe Leroy"  
>> wrote:
>>>
>>>
>>> Le 17/06/2022 à 08:45, Liang He a écrit :
>>>>
>>>>
>>>>
>>>> At 2022-06-17 14:28:56, "Christophe Leroy"  
>>>> wrote:
>>>>>
>>>>>
>>>>> Le 17/06/2022 à 08:08, Liang He a écrit :
>>>>>> In gpio_halt_probe(), of_find_matching_node() will return a node
>>>>>> pointer with refcount incremented. We should use of_node_put() in
>>>>>> fail path or when it is not used anymore.
>>>>>>
>>>>>> Signed-off-by: Liang He 
>>>>>> ---
>>>>>> changelog:
>>>>>> v4: reuse exist 'err' and use a simple code style, advised by CJ
>>>>>> v3: use local 'child_node' advised by Michael.
>>>>>> v2: use goto-label patch style advised by Christophe Leroy.
>>>>>> v1: add of_node_put() before each exit.
>>>>>>
>>>>>> arch/powerpc/platforms/85xx/sgy_cts1000.c | 35 
>>>>>> ++-
>>>>>> 1 file changed, 22 insertions(+), 13 deletions(-)
>>>>>>
>>>>>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
>>>>>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>>>> index 98ae64075193..e4588943fe7e 100644
>>>>>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>>>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>>>> @@ -71,6 +71,7 @@ static int gpio_halt_probe(struct platform_device 
>>>>>> *pdev)
>>>>>> {
>>>>>>  enum of_gpio_flags flags;
>>>>>>  struct device_node *node = pdev->dev.of_node;
>>>>>> +struct device_node *child_node;
>>>>>>  int gpio, err, irq;
>>>>>>  int trigger;
>>>>>> 
>>>>>> @@ -78,26 +79,29 @@ static int gpio_halt_probe(struct platform_device 
>>>>>> *pdev)
>>>>>>  return -ENODEV;
>>>>>> 
>>>>>>  /* If there's no matching child, this isn't really an error */
>>>>>> -halt_node = of_find_matching_node(node, child_match);
>>>>>> -if (!halt_node)
>>>>>> +child_node = of_find_matching_node(node, child_match);
>>>>>> +if (!child_node)
>>>>>>  return 0;
>>>>>> 
>>>>>>  /* Technically we could just read the first one, but punish
>>>>>>   * DT writers for invalid form. */
>>>>>> -if (of_gpio_count(halt_node) != 1)
>>>>>> -return -EINVAL;
>>>>>> +if (of_gpio_count(child_node) != 1) {
>>>>>> +err = -EINVAL;
>>>>>> +goto err_put;
>>>>>> +}
>>>>>> 
>>>>>>  /* Get the gpio number relative to the dynamic base. */
>>>>>> -gpio = of_get_gpio_flags(halt_node, 0, );
>>>>>> -if (!gpio_is_valid(gpio))
>>>>>> -return -EINVAL;
>>>>>> +gpio = of_get_gpio_flags(child_node, 0, );
>>>>>> +if (!gpio_is_valid(gpio)) {
>>>>>> +err = -EINVAL;
>>>>>> +gotot err_put;
>>>>>
>>>>> Did you test the build ?
>>>>
>>>> Sorry for this fault.
>>>>
>>>> In fact, I am still finding an efficient way to building different arch 
>>>> source code as I only have x86-64.
>>>>
>>>> Now I am try using QEMU.
>>>>
>>>> Anyway, sorry for this fault.
>>>
>>> You can find cross compilers for most architectures for x86-64 here :
>>> https://mirrors.edge.kernel.org/pub/tools/crosstool/
>>>
>>> Christophe
>> 
>> Hi, Christophe and Conor.
>> 
>> Sorry to trouble you again.
>> 
>> Now I only know how to quickly identify the refcounting bugs, but I cannot 
>> efficiently give a build test.
>> 
>> For example, I use the cross compilers 'powerpc-linux-gnu-gcc' to compile 
>> 'arch/powerpc/platforms/85xx/sgy_cts1000.c' with -fsyntax-only flag.
>> But I meet too many header file missing errors. Even if I add some 'include' 
>> pathes, e.g., ./arch/powerpc/include, ./include,
>> there are still too many other errors.
>> 
>> So if there is any efficient way to check my patch code to avoid 'gotot' 
>> error again.
>
>idk anything about powerpc, but what I find is a nice way to get a compiler
>for an arch I don't use is to search on lore.kernel.org for a 0day robot
>build error since it gives instructions for building on that arch.
>For example:
>https://lore.kernel.org/linuxppc-dev/202206060910.ryntfqdi-...@intel.com/
>
>
>In this case, your bug seems obvious? You typed "gotot" instead of "goto".
>
>Hope that helps,
>Conor.
>
>> 
>> Thanks again, Christophe and Conor.
>> 
>> Liang


Thanks so much, I will try it.

Re:Re: [PATCH v4] powerpc:85xx: Add missing of_node_put() in sgy_cst1000

2022-06-17 Thread Liang He



At 2022-06-17 14:53:13, "Christophe Leroy"  wrote:
>
>
>Le 17/06/2022 à 08:45, Liang He a écrit :
>> 
>> 
>> 
>> At 2022-06-17 14:28:56, "Christophe Leroy"  
>> wrote:
>>>
>>>
>>> Le 17/06/2022 à 08:08, Liang He a écrit :
>>>> In gpio_halt_probe(), of_find_matching_node() will return a node
>>>> pointer with refcount incremented. We should use of_node_put() in
>>>> fail path or when it is not used anymore.
>>>>
>>>> Signed-off-by: Liang He 
>>>> ---
>>>>changelog:
>>>>v4: reuse exist 'err' and use a simple code style, advised by CJ
>>>>v3: use local 'child_node' advised by Michael.
>>>>v2: use goto-label patch style advised by Christophe Leroy.
>>>>v1: add of_node_put() before each exit.
>>>>
>>>>arch/powerpc/platforms/85xx/sgy_cts1000.c | 35 ++-
>>>>1 file changed, 22 insertions(+), 13 deletions(-)
>>>>
>>>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
>>>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>> index 98ae64075193..e4588943fe7e 100644
>>>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>> @@ -71,6 +71,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
>>>>{
>>>>enum of_gpio_flags flags;
>>>>struct device_node *node = pdev->dev.of_node;
>>>> +  struct device_node *child_node;
>>>>int gpio, err, irq;
>>>>int trigger;
>>>>
>>>> @@ -78,26 +79,29 @@ static int gpio_halt_probe(struct platform_device 
>>>> *pdev)
>>>>return -ENODEV;
>>>>
>>>>/* If there's no matching child, this isn't really an error */
>>>> -  halt_node = of_find_matching_node(node, child_match);
>>>> -  if (!halt_node)
>>>> +  child_node = of_find_matching_node(node, child_match);
>>>> +  if (!child_node)
>>>>return 0;
>>>>
>>>>/* Technically we could just read the first one, but punish
>>>> * DT writers for invalid form. */
>>>> -  if (of_gpio_count(halt_node) != 1)
>>>> -  return -EINVAL;
>>>> +  if (of_gpio_count(child_node) != 1) {
>>>> +  err = -EINVAL;
>>>> +  goto err_put;
>>>> +  }
>>>>
>>>>/* Get the gpio number relative to the dynamic base. */
>>>> -  gpio = of_get_gpio_flags(halt_node, 0, );
>>>> -  if (!gpio_is_valid(gpio))
>>>> -  return -EINVAL;
>>>> +  gpio = of_get_gpio_flags(child_node, 0, );
>>>> +  if (!gpio_is_valid(gpio)) {
>>>> +  err = -EINVAL;
>>>> +  gotot err_put;
>>>
>>> Did you test the build ?
>> 
>> Sorry for this fault.
>> 
>> In fact, I am still finding an efficient way to building different arch 
>> source code as I only have x86-64.
>> 
>> Now I am try using QEMU.
>> 
>> Anyway, sorry for this fault.
>
>You can find cross compilers for most architectures for x86-64 here : 
>https://mirrors.edge.kernel.org/pub/tools/crosstool/
>
>Christophe

Hi, Christophe and Conor.

Sorry to trouble you again.

Now I only know how to quickly identify the refcounting bugs, but I cannot 
efficiently give a build test.

For example, I use the cross compilers 'powerpc-linux-gnu-gcc' to compile 
'arch/powerpc/platforms/85xx/sgy_cts1000.c' with -fsyntax-only flag.
But I meet too many header file missing errors. Even if I add some 'include' 
pathes, e.g., ./arch/powerpc/include, ./include, 
there are still too many other errors.

So if there is any efficient way to check my patch code to avoid 'gotot' error 
again.

Thanks again, Christophe and Conor.

Liang

[PATCH] powerpc: powernv: Fix refcount leak in opal

2022-06-17 Thread Liang He
In opal_imc_init_dev(), of_find_compatible_node() will return a
node pointer with refcount incremented. We should use of_node_put()
when it is not used anymore.

Signed-off-by: Liang He 
--- 

 arch/powerpc/platforms/powernv/opal.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 55a8fbfdb5b2..d86cc48a10aa 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -952,6 +952,7 @@ static void __init opal_imc_init_dev(void)
np = of_find_compatible_node(NULL, NULL, IMC_DTB_COMPAT);
if (np)
of_platform_device_create(np, NULL, NULL);
+   of_node_put(np);
 }
 
 static int kopald(void *unused)
-- 
2.25.1



Re:Re: [PATCH v4] powerpc:85xx: Add missing of_node_put() in sgy_cst1000

2022-06-17 Thread Liang He



At 2022-06-17 14:28:56, "Christophe Leroy"  wrote:
>
>
>Le 17/06/2022 à 08:08, Liang He a écrit :
>> In gpio_halt_probe(), of_find_matching_node() will return a node
>> pointer with refcount incremented. We should use of_node_put() in
>> fail path or when it is not used anymore.
>> 
>> Signed-off-by: Liang He 
>> ---
>>   changelog:
>>   v4: reuse exist 'err' and use a simple code style, advised by CJ
>>   v3: use local 'child_node' advised by Michael.
>>   v2: use goto-label patch style advised by Christophe Leroy.
>>   v1: add of_node_put() before each exit.
>> 
>>   arch/powerpc/platforms/85xx/sgy_cts1000.c | 35 ++-
>>   1 file changed, 22 insertions(+), 13 deletions(-)
>> 
>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>> index 98ae64075193..e4588943fe7e 100644
>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>> @@ -71,6 +71,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
>>   {
>>  enum of_gpio_flags flags;
>>  struct device_node *node = pdev->dev.of_node;
>> +struct device_node *child_node;
>>  int gpio, err, irq;
>>  int trigger;
>>   
>> @@ -78,26 +79,29 @@ static int gpio_halt_probe(struct platform_device *pdev)
>>  return -ENODEV;
>>   
>>  /* If there's no matching child, this isn't really an error */
>> -halt_node = of_find_matching_node(node, child_match);
>> -if (!halt_node)
>> +child_node = of_find_matching_node(node, child_match);
>> +if (!child_node)
>>  return 0;
>>   
>>  /* Technically we could just read the first one, but punish
>>   * DT writers for invalid form. */
>> -if (of_gpio_count(halt_node) != 1)
>> -return -EINVAL;
>> +if (of_gpio_count(child_node) != 1) {
>> +err = -EINVAL;
>> +goto err_put;
>> +}
>>   
>>  /* Get the gpio number relative to the dynamic base. */
>> -gpio = of_get_gpio_flags(halt_node, 0, );
>> -if (!gpio_is_valid(gpio))
>> -return -EINVAL;
>> +gpio = of_get_gpio_flags(child_node, 0, );
>> +if (!gpio_is_valid(gpio)) {
>> +err = -EINVAL;
>> +gotot err_put;
>
>Did you test the build ?

Sorry for this fault. 

In fact, I am still finding an efficient way to building different arch source 
code as I only have x86-64.

Now I am try using QEMU.

Anyway, sorry for this fault.


>
>> +}
>>   
>>  err = gpio_request(gpio, "gpio-halt");
>>  if (err) {
>>  printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n",
>> gpio);
>> -halt_node = NULL;
>> -return err;
>> +goto err_put;
>>  }
>>   
>>  trigger = (flags == OF_GPIO_ACTIVE_LOW);
>> @@ -105,15 +109,14 @@ static int gpio_halt_probe(struct platform_device 
>> *pdev)
>>  gpio_direction_output(gpio, !trigger);
>>   
>>  /* Now get the IRQ which tells us when the power button is hit */
>> -irq = irq_of_parse_and_map(halt_node, 0);
>> +irq = irq_of_parse_and_map(child_node, 0);
>>  err = request_irq(irq, gpio_halt_irq, IRQF_TRIGGER_RISING |
>> -  IRQF_TRIGGER_FALLING, "gpio-halt", halt_node);
>> +  IRQF_TRIGGER_FALLING, "gpio-halt", child_node);
>>  if (err) {
>>  printk(KERN_ERR "gpio-halt: error requesting IRQ %d for "
>> "GPIO %d.\n", irq, gpio);
>>  gpio_free(gpio);
>> -halt_node = NULL;
>> -return err;
>> +goto err_put;
>>  }
>>   
>>  /* Register our halt function */
>> @@ -123,7 +126,12 @@ static int gpio_halt_probe(struct platform_device *pdev)
>>  printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
>> " irq).\n", gpio, trigger, irq);
>>   
>> +halt_node = child_node;
>>  return 0;
>> +
>> +err_put:
>> +of_node_put(child_node);
>> +return err;
>>   }
>>   
>>   static int gpio_halt_remove(struct platform_device *pdev)
>> @@ -139,6 +147,7 @@ static int gpio_halt_remove(struct platform_device *pdev)
>>   
>>  gpio_free(gpio);
>>   
>> +of_node_put(halt_node);
>>  halt_node = NULL;
>>  }
>>   


[PATCH v4] powerpc:85xx: Add missing of_node_put() in sgy_cst1000

2022-06-17 Thread Liang He
In gpio_halt_probe(), of_find_matching_node() will return a node
pointer with refcount incremented. We should use of_node_put() in
fail path or when it is not used anymore.

Signed-off-by: Liang He 
---
 changelog:
 v4: reuse exist 'err' and use a simple code style, advised by CJ
 v3: use local 'child_node' advised by Michael.
 v2: use goto-label patch style advised by Christophe Leroy.
 v1: add of_node_put() before each exit.

 arch/powerpc/platforms/85xx/sgy_cts1000.c | 35 ++-
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
b/arch/powerpc/platforms/85xx/sgy_cts1000.c
index 98ae64075193..e4588943fe7e 100644
--- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
+++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
@@ -71,6 +71,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
 {
enum of_gpio_flags flags;
struct device_node *node = pdev->dev.of_node;
+   struct device_node *child_node;
int gpio, err, irq;
int trigger;
 
@@ -78,26 +79,29 @@ static int gpio_halt_probe(struct platform_device *pdev)
return -ENODEV;
 
/* If there's no matching child, this isn't really an error */
-   halt_node = of_find_matching_node(node, child_match);
-   if (!halt_node)
+   child_node = of_find_matching_node(node, child_match);
+   if (!child_node)
return 0;
 
/* Technically we could just read the first one, but punish
 * DT writers for invalid form. */
-   if (of_gpio_count(halt_node) != 1)
-   return -EINVAL;
+   if (of_gpio_count(child_node) != 1) {
+   err = -EINVAL;
+   goto err_put;
+   }
 
/* Get the gpio number relative to the dynamic base. */
-   gpio = of_get_gpio_flags(halt_node, 0, );
-   if (!gpio_is_valid(gpio))
-   return -EINVAL;
+   gpio = of_get_gpio_flags(child_node, 0, );
+   if (!gpio_is_valid(gpio)) {
+   err = -EINVAL;
+   gotot err_put;
+   }
 
err = gpio_request(gpio, "gpio-halt");
if (err) {
printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n",
   gpio);
-   halt_node = NULL;
-   return err;
+   goto err_put;
}
 
trigger = (flags == OF_GPIO_ACTIVE_LOW);
@@ -105,15 +109,14 @@ static int gpio_halt_probe(struct platform_device *pdev)
gpio_direction_output(gpio, !trigger);
 
/* Now get the IRQ which tells us when the power button is hit */
-   irq = irq_of_parse_and_map(halt_node, 0);
+   irq = irq_of_parse_and_map(child_node, 0);
err = request_irq(irq, gpio_halt_irq, IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING, "gpio-halt", halt_node);
+ IRQF_TRIGGER_FALLING, "gpio-halt", child_node);
if (err) {
printk(KERN_ERR "gpio-halt: error requesting IRQ %d for "
   "GPIO %d.\n", irq, gpio);
gpio_free(gpio);
-   halt_node = NULL;
-   return err;
+   goto err_put;
}
 
/* Register our halt function */
@@ -123,7 +126,12 @@ static int gpio_halt_probe(struct platform_device *pdev)
printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
   " irq).\n", gpio, trigger, irq);
 
+   halt_node = child_node;
return 0;
+
+err_put:
+   of_node_put(child_node);
+   return err;
 }
 
 static int gpio_halt_remove(struct platform_device *pdev)
@@ -139,6 +147,7 @@ static int gpio_halt_remove(struct platform_device *pdev)
 
gpio_free(gpio);
 
+   of_node_put(halt_node);
halt_node = NULL;
}
 
-- 
2.25.1



Re:Re: [PATCH v3] powerpc:85xx: Add missing of_node_put() in sgy_cst1000

2022-06-16 Thread Liang He


At 2022-06-17 13:37:12, "Christophe JAILLET"  
wrote:
>Le 17/06/2022 à 07:22, Liang He a écrit :
>> In gpio_halt_probe(), of_find_matching_node() will return a node
>> pointer with refcount incremented. We should use of_node_put() in
>> fail path or when it is not used anymore.
>> 
>> Signed-off-by: Liang He 
>> ---
>>   arch/powerpc/platforms/85xx/sgy_cts1000.c | 39 +++
>>   1 file changed, 25 insertions(+), 14 deletions(-)
>> 
>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>> index 98ae64075193..a8690fc552cf 100644
>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>> @@ -71,33 +71,39 @@ static int gpio_halt_probe(struct platform_device *pdev)
>>   {
>>  enum of_gpio_flags flags;
>>  struct device_node *node = pdev->dev.of_node;
>> +struct device_node *child_node;
>>  int gpio, err, irq;
>>  int trigger;
>> +int ret;
>>   
>>  if (!node)
>>  return -ENODEV;
>>   
>>  /* If there's no matching child, this isn't really an error */
>> -halt_node = of_find_matching_node(node, child_match);
>> -if (!halt_node)
>> +child_node = of_find_matching_node(node, child_match);
>> +if (!child_node)
>>  return 0;
>>   
>>  /* Technically we could just read the first one, but punish
>>   * DT writers for invalid form. */
>> -if (of_gpio_count(halt_node) != 1)
>> -return -EINVAL;
>> +if (of_gpio_count(child_node) != 1) {
>> +ret = -EINVAL;
>> +goto err_put;
>> +}
>>   
>>  /* Get the gpio number relative to the dynamic base. */
>> -gpio = of_get_gpio_flags(halt_node, 0, );
>> -if (!gpio_is_valid(gpio))
>> -return -EINVAL;
>> +gpio = of_get_gpio_flags(child_node, 0, );
>> +if (!gpio_is_valid(gpio)) {
>> +ret = -EINVAL;
>> +gotot err_put;
>> +}
>>   
>>  err = gpio_request(gpio, "gpio-halt");
>>  if (err) {
>>  printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n",
>> gpio);
>> -halt_node = NULL;
>> -return err;
>> +ret = err;
>
>Sorry for not seeing and asking before, but why do you need 'ret'?
>Can't you use the existing 'err' in place in this whole patch?
>

Thanks, CJ.

Your advice is good and I have not noticed the 'err'.

>> +goto err_put;
>>  }
>>   
>>  trigger = (flags == OF_GPIO_ACTIVE_LOW);
>> @@ -105,15 +111,15 @@ static int gpio_halt_probe(struct platform_device 
>> *pdev)
>>  gpio_direction_output(gpio, !trigger);
>>   
>>  /* Now get the IRQ which tells us when the power button is hit */
>> -irq = irq_of_parse_and_map(halt_node, 0);
>> +irq = irq_of_parse_and_map(child_node, 0);
>>  err = request_irq(irq, gpio_halt_irq, IRQF_TRIGGER_RISING |
>> -  IRQF_TRIGGER_FALLING, "gpio-halt", halt_node);
>> +  IRQF_TRIGGER_FALLING, "gpio-halt", child_node);
>>  if (err) {
>>  printk(KERN_ERR "gpio-halt: error requesting IRQ %d for "
>> "GPIO %d.\n", irq, gpio);
>>  gpio_free(gpio);
>> -halt_node = NULL;
>> -return err;
>> +ret = err;
>> +goto err_put;
>>  }
>>   
>>  /* Register our halt function */
>> @@ -122,8 +128,12 @@ static int gpio_halt_probe(struct platform_device *pdev)
>>   
>>  printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
>> " irq).\n", gpio, trigger, irq);
>> +ret = 0;
>> +halt_node = of_node_get(child_node);
>
>LGTM, but my preferred style would be:
>   halt_node = child_node;
>   return 0;
>I'm not a maintainer, so this is just my opinion and it is mostly a 
>mater of taste.
>
>CJ

Thanks, CJ.

Now, I also prefer this style and I will use it.

>
>>   
>> -return 0;
>> +err_put:
>> +of_node_put(child_node);
>> +return ret;
>>   }
>>   
>>   static int gpio_halt_remove(struct platform_device *pdev)
>> @@ -139,6 +149,7 @@ static int gpio_halt_remove(struct platform_device *pdev)
>>   
>>  gpio_free(gpio);
>>   
>> +of_node_put(halt_node);
>>  halt_node = NULL;
>>  }
>>   


Re:Re: [PATCH] powerpc: powernv: Fix refcount leak bug in opal-powercap

2022-06-16 Thread Liang He



At 2022-06-17 13:01:27, "Christophe JAILLET"  
wrote:
>Le 17/06/2022 à 06:20, Liang He a écrit :
>> In opal_powercap_init(), of_find_compatible_node() will return
>> a node pointer with refcount incremented. We should use of_node_put()
>> in fail path or when it is not used anymore.
>> 
>> Besides, for_each_child_of_node() will automatically *inc* and *dec*
>> refcount during iteration. However, we should add the of_node_put()
>> if there is a break.
>
>Hi,
>
>I'm not sure that your patch is right here. Because of this *inc* and 
>*dec* things, do we still need to of_node_put(powercap) once we have 
>entered for_each_child_of_node?
>
>I think that this reference will be released on the first iteration of 
>the loop.
>

Hi, CJ, 

Thanks for your reply and I want have a discuss.

Based on my review on the src of 'of_get_next_child',  there is only
*inc* for next and *dec* for pre as follow. 

(|node| == powercap)
==__of_get_next_child( |node|, prev)==
 ...
next = prev? prev->sibling:|node|->child;
of_node_get(next);
of_node_put(prev);
 ...
=

However, there is no any code to release the |node| (i.e., *powercap*).

Am I right?   If I am wrong, please correct me, thanks.

>
>Maybe of_node_put(powercap) should be duplicated everywhere it is 
>relevant and removed from the error handling path?
>Or an additional reference should be taken before the loop?
>Or adding a new label with "powercap = NULL" and branching there when 
>needed?
>
>CJ

If my understanding is right, I think current patch is right.

Otherwise, I will make a new patch to handle that, Thanks.

Liang 

>
>> 
>> Signed-off-by: Liang He 
>> ---
>>   arch/powerpc/platforms/powernv/opal-powercap.c | 5 -
>>   1 file changed, 4 insertions(+), 1 deletion(-)
>> 
>> diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c 
>> b/arch/powerpc/platforms/powernv/opal-powercap.c
>> index 64506b46e77b..b102477d3f95 100644
>> --- a/arch/powerpc/platforms/powernv/opal-powercap.c
>> +++ b/arch/powerpc/platforms/powernv/opal-powercap.c
>> @@ -153,7 +153,7 @@ void __init opal_powercap_init(void)
>>  pcaps = kcalloc(of_get_child_count(powercap), sizeof(*pcaps),
>>  GFP_KERNEL);
>>  if (!pcaps)
>> -return;
>> +goto out_powercap;
>>   
>>  powercap_kobj = kobject_create_and_add("powercap", opal_kobj);
>>  if (!powercap_kobj) {
>> @@ -236,6 +236,9 @@ void __init opal_powercap_init(void)
>>  kfree(pcaps[i].pg.name);
>>  }
>>  kobject_put(powercap_kobj);
>> +of_node_put(node);
>>   out_pcaps:
>>  kfree(pcaps);
>> +out_powercap:
>> +of_node_put(powercap);
>>   }


[PATCH v3] powerpc:85xx: Add missing of_node_put() in sgy_cst1000

2022-06-16 Thread Liang He
In gpio_halt_probe(), of_find_matching_node() will return a node
pointer with refcount incremented. We should use of_node_put() in
fail path or when it is not used anymore.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/85xx/sgy_cts1000.c | 39 +++
 1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
b/arch/powerpc/platforms/85xx/sgy_cts1000.c
index 98ae64075193..a8690fc552cf 100644
--- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
+++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
@@ -71,33 +71,39 @@ static int gpio_halt_probe(struct platform_device *pdev)
 {
enum of_gpio_flags flags;
struct device_node *node = pdev->dev.of_node;
+   struct device_node *child_node;
int gpio, err, irq;
int trigger;
+   int ret;
 
if (!node)
return -ENODEV;
 
/* If there's no matching child, this isn't really an error */
-   halt_node = of_find_matching_node(node, child_match);
-   if (!halt_node)
+   child_node = of_find_matching_node(node, child_match);
+   if (!child_node)
return 0;
 
/* Technically we could just read the first one, but punish
 * DT writers for invalid form. */
-   if (of_gpio_count(halt_node) != 1)
-   return -EINVAL;
+   if (of_gpio_count(child_node) != 1) {
+   ret = -EINVAL;
+   goto err_put;
+   }
 
/* Get the gpio number relative to the dynamic base. */
-   gpio = of_get_gpio_flags(halt_node, 0, );
-   if (!gpio_is_valid(gpio))
-   return -EINVAL;
+   gpio = of_get_gpio_flags(child_node, 0, );
+   if (!gpio_is_valid(gpio)) {
+   ret = -EINVAL;
+   gotot err_put;
+   }
 
err = gpio_request(gpio, "gpio-halt");
if (err) {
printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n",
   gpio);
-   halt_node = NULL;
-   return err;
+   ret = err;
+   goto err_put;
}
 
trigger = (flags == OF_GPIO_ACTIVE_LOW);
@@ -105,15 +111,15 @@ static int gpio_halt_probe(struct platform_device *pdev)
gpio_direction_output(gpio, !trigger);
 
/* Now get the IRQ which tells us when the power button is hit */
-   irq = irq_of_parse_and_map(halt_node, 0);
+   irq = irq_of_parse_and_map(child_node, 0);
err = request_irq(irq, gpio_halt_irq, IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING, "gpio-halt", halt_node);
+ IRQF_TRIGGER_FALLING, "gpio-halt", child_node);
if (err) {
printk(KERN_ERR "gpio-halt: error requesting IRQ %d for "
   "GPIO %d.\n", irq, gpio);
gpio_free(gpio);
-   halt_node = NULL;
-   return err;
+   ret = err;
+   goto err_put;
}
 
/* Register our halt function */
@@ -122,8 +128,12 @@ static int gpio_halt_probe(struct platform_device *pdev)
 
printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
   " irq).\n", gpio, trigger, irq);
+   ret = 0;
+   halt_node = of_node_get(child_node);
 
-   return 0;
+err_put:
+   of_node_put(child_node);
+   return ret;
 }
 
 static int gpio_halt_remove(struct platform_device *pdev)
@@ -139,6 +149,7 @@ static int gpio_halt_remove(struct platform_device *pdev)
 
gpio_free(gpio);
 
+   of_node_put(halt_node);
halt_node = NULL;
}
 
-- 
2.25.1



Re:Re:Re: [PATCH v2] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c

2022-06-16 Thread Liang He


 2022-06-17 12:29:02,"Michael Ellerman"  写道:
>"Liang He"  writes:
>> At 2022-06-17 07:37:06, "Michael Ellerman"  wrote:
>>>Christophe JAILLET  writes:
>>>> Le 16/06/2022 à 17:19, Liang He a écrit :
>>>>> In gpio_halt_probe(), of_find_matching_node() will return a node pointer 
>>>>> with
>>>>> refcount incremented. We should use of_node_put() in each fail path or 
>>>>> when it
>>>>> is not used anymore.
>>>>> 
>>>>> Signed-off-by: Liang He 
>>>>> ---
>>>>>   changelog:
>>>>> 
>>>>>   v2: use goto-label patch style advised by Christophe.
>>>>>   v1: add of_node_put() before each exit.
>>>>> 
>>>>>   arch/powerpc/platforms/85xx/sgy_cts1000.c | 27 +++
>>>>>   1 file changed, 18 insertions(+), 9 deletions(-)
>>>>> 
>>>>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
>>>>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>>> index 98ae64075193..e280f963d88c 100644
>>>>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>>>> @@ -73,6 +73,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
>>>...
>>>>> @@ -122,8 +127,12 @@ static int gpio_halt_probe(struct platform_device 
>>>>> *pdev)
>>>>>   
>>>>>   printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
>>>>>  " irq).\n", gpio, trigger, irq);
>>>>> + ret = 0;
>>>>>   
>>>>> - return 0;
>>>>> +err_put:
>>>>> + of_node_put(halt_node);
>>>>> + halt_node = NULL;
>>>>
>>>> Hi,
>>>> so now we set 'halt_node' to NULL even in the normal case.
>>>> This is really spurious.
>>>>
>>>> Look at gpio_halt_cb(), but I think that this is just wrong and badly 
>>>> breaks this driver.
>>>
>>>I agree, thanks for reviewing.
>>>
>>>I think the cleanest solution is to use a local variable for the node in
>>>the body of gpio_halt_probe(), and only assign to halt_node once all the
>>>checks have passed.
>>>
>>>So something like:
>>>
>>>struct device_node *child_node;
>>>
>>> child_node = of_find_matching_node(node, child_match);
>>>...
>>>
>>> printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
>>>" irq).\n", gpio, trigger, irq);
>>>ret = 0;
>>>halt_node = of_node_get(child_node);
>>>
>>>out_put:
>>>of_node_put(child_node);
>>>
>>> return ret;
>>>}
>>>
>>>
>>>cheers
>>
>> Hi, Michael and Christophe,
>>
>> I am writing the new patch based on Michael's advice. However, I wonder if 
>> there is
>> any place to call of_node_put(halt_node)?  As I do not exactly know if 
>> gpio_halt_remove()
>> or anyother place can correctly release this global reference?
>> If not, it is correct that I add a of_node_put(halt_node) in 
>> gpio_halt_remove(), right?
>
>Yes I think so, just before it's set to NULL, eg:
>
>diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
>b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>index 98ae64075193..7beb3cd420ba 100644
>--- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
>+++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>@@ -139,6 +139,7 @@ static int gpio_halt_remove(struct platform_device *pdev)
> 
>   gpio_free(gpio);
> 
>+  of_node_put(halt_node);
>   halt_node = NULL;
>   }
> 
>
>cheers



Ok, I will make the new patch soon.

[PATCH] powerpc: powernv: Fix refcount leak bug in opal-powercap

2022-06-16 Thread Liang He
In opal_powercap_init(), of_find_compatible_node() will return
a node pointer with refcount incremented. We should use of_node_put()
in fail path or when it is not used anymore.

Besides, for_each_child_of_node() will automatically *inc* and *dec*
refcount during iteration. However, we should add the of_node_put()
if there is a break.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/powernv/opal-powercap.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c 
b/arch/powerpc/platforms/powernv/opal-powercap.c
index 64506b46e77b..b102477d3f95 100644
--- a/arch/powerpc/platforms/powernv/opal-powercap.c
+++ b/arch/powerpc/platforms/powernv/opal-powercap.c
@@ -153,7 +153,7 @@ void __init opal_powercap_init(void)
pcaps = kcalloc(of_get_child_count(powercap), sizeof(*pcaps),
GFP_KERNEL);
if (!pcaps)
-   return;
+   goto out_powercap;
 
powercap_kobj = kobject_create_and_add("powercap", opal_kobj);
if (!powercap_kobj) {
@@ -236,6 +236,9 @@ void __init opal_powercap_init(void)
kfree(pcaps[i].pg.name);
}
kobject_put(powercap_kobj);
+   of_node_put(node);
 out_pcaps:
kfree(pcaps);
+out_powercap:
+   of_node_put(powercap);
 }
-- 
2.25.1



Re:Re: [PATCH v2] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c

2022-06-16 Thread Liang He



At 2022-06-17 07:37:06, "Michael Ellerman"  wrote:
>Christophe JAILLET  writes:
>> Le 16/06/2022 à 17:19, Liang He a écrit :
>>> In gpio_halt_probe(), of_find_matching_node() will return a node pointer 
>>> with
>>> refcount incremented. We should use of_node_put() in each fail path or when 
>>> it
>>> is not used anymore.
>>> 
>>> Signed-off-by: Liang He 
>>> ---
>>>   changelog:
>>> 
>>>   v2: use goto-label patch style advised by Christophe.
>>>   v1: add of_node_put() before each exit.
>>> 
>>>   arch/powerpc/platforms/85xx/sgy_cts1000.c | 27 +++
>>>   1 file changed, 18 insertions(+), 9 deletions(-)
>>> 
>>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
>>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>> index 98ae64075193..e280f963d88c 100644
>>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>> @@ -73,6 +73,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
>...
>>> @@ -122,8 +127,12 @@ static int gpio_halt_probe(struct platform_device 
>>> *pdev)
>>>   
>>> printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
>>>" irq).\n", gpio, trigger, irq);
>>> +   ret = 0;
>>>   
>>> -   return 0;
>>> +err_put:
>>> +   of_node_put(halt_node);
>>> +   halt_node = NULL;
>>
>> Hi,
>> so now we set 'halt_node' to NULL even in the normal case.
>> This is really spurious.
>>
>> Look at gpio_halt_cb(), but I think that this is just wrong and badly 
>> breaks this driver.
>
>I agree, thanks for reviewing.
>
>I think the cleanest solution is to use a local variable for the node in
>the body of gpio_halt_probe(), and only assign to halt_node once all the
>checks have passed.
>
>So something like:
>
>struct device_node *child_node;
>
>   child_node = of_find_matching_node(node, child_match);
>...
>
>   printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
>  " irq).\n", gpio, trigger, irq);
>ret = 0;
>halt_node = of_node_get(child_node);
>
>out_put:
>of_node_put(child_node);
>
>   return ret;
>}
>
>
>cheers

Hi, Michael and Christophe,

I am writing the new patch based on Michael's advice. However, I wonder if 
there is
any place to call of_node_put(halt_node)?  As I do not exactly know if 
gpio_halt_remove()
or anyother place can correctly release this global reference?
If not, it is correct that I add a of_node_put(halt_node) in 
gpio_halt_remove(), right?

Thanks and wait for your replies.

Liang


Re:Re: [PATCH v2] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c

2022-06-16 Thread Liang He



At 2022-06-17 07:37:06, "Michael Ellerman"  wrote:
>Christophe JAILLET  writes:
>> Le 16/06/2022 à 17:19, Liang He a écrit :
>>> In gpio_halt_probe(), of_find_matching_node() will return a node pointer 
>>> with
>>> refcount incremented. We should use of_node_put() in each fail path or when 
>>> it
>>> is not used anymore.
>>> 
>>> Signed-off-by: Liang He 
>>> ---
>>>   changelog:
>>> 
>>>   v2: use goto-label patch style advised by Christophe.
>>>   v1: add of_node_put() before each exit.
>>> 
>>>   arch/powerpc/platforms/85xx/sgy_cts1000.c | 27 +++
>>>   1 file changed, 18 insertions(+), 9 deletions(-)
>>> 
>>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
>>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>> index 98ae64075193..e280f963d88c 100644
>>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>>> @@ -73,6 +73,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
>...
>>> @@ -122,8 +127,12 @@ static int gpio_halt_probe(struct platform_device 
>>> *pdev)
>>>   
>>> printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
>>>" irq).\n", gpio, trigger, irq);
>>> +   ret = 0;
>>>   
>>> -   return 0;
>>> +err_put:
>>> +   of_node_put(halt_node);
>>> +   halt_node = NULL;
>>
>> Hi,
>> so now we set 'halt_node' to NULL even in the normal case.
>> This is really spurious.
>>
>> Look at gpio_halt_cb(), but I think that this is just wrong and badly 
>> breaks this driver.
>
>I agree, thanks for reviewing.
>
>I think the cleanest solution is to use a local variable for the node in
>the body of gpio_halt_probe(), and only assign to halt_node once all the
>checks have passed.
>
>So something like:
>
>struct device_node *child_node;
>
>   child_node = of_find_matching_node(node, child_match);
>...
>
>   printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
>  " irq).\n", gpio, trigger, irq);
>ret = 0;
>halt_node = of_node_get(child_node);
>
>out_put:
>of_node_put(child_node);
>
>   return ret;
>}
>
>
>cheers

Thanks, Michael and Christophe.

I will send a patch based on your reviews.

Liang


[PATCH] powerpc: sysdev: xive: Fix refcount leak in native.c

2022-06-16 Thread Liang He
In xive_native_init(), of_find_compatible_node() will return a
node pointer with refcount incremented. We should use of_node_put()
in each fail path or when it is not used anymore.

Signed-off-by: Liang He 
---
 arch/powerpc/sysdev/xive/native.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/sysdev/xive/native.c 
b/arch/powerpc/sysdev/xive/native.c
index d25d8c692909..3925825954bc 100644
--- a/arch/powerpc/sysdev/xive/native.c
+++ b/arch/powerpc/sysdev/xive/native.c
@@ -579,12 +579,12 @@ bool __init xive_native_init(void)
/* Resource 1 is HV window */
if (of_address_to_resource(np, 1, )) {
pr_err("Failed to get thread mgmnt area resource\n");
-   return false;
+   goto err_put;
}
tima = ioremap(r.start, resource_size());
if (!tima) {
pr_err("Failed to map thread mgmnt area\n");
-   return false;
+   goto err_put;
}
 
/* Read number of priorities */
@@ -612,7 +612,7 @@ bool __init xive_native_init(void)
/* Resource 2 is OS window */
if (of_address_to_resource(np, 2, )) {
pr_err("Failed to get thread mgmnt area resource\n");
-   return false;
+   goto err_put;
}
 
xive_tima_os = r.start;
@@ -624,7 +624,7 @@ bool __init xive_native_init(void)
rc = opal_xive_reset(OPAL_XIVE_MODE_EXPL);
if (rc) {
pr_err("Switch to exploitation mode failed with error %lld\n", 
rc);
-   return false;
+   goto err_put;
}
 
/* Setup some dummy HV pool VPs */
@@ -634,10 +634,15 @@ bool __init xive_native_init(void)
if (!xive_core_init(np, _native_ops, tima, TM_QW3_HV_PHYS,
max_prio)) {
opal_xive_reset(OPAL_XIVE_MODE_EMU);
-   return false;
+   goto err_put;
}
+   of_node_put(np);
pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10));
return true;
+
+err_put:
+   of_node_put(np);
+   return false;
 }
 
 static bool xive_native_provision_pages(void)
-- 
2.25.1



[PATCH v2] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c

2022-06-16 Thread Liang He
In gpio_halt_probe(), of_find_matching_node() will return a node pointer with
refcount incremented. We should use of_node_put() in each fail path or when it
is not used anymore.

Signed-off-by: Liang He 
---
 changelog:

 v2: use goto-label patch style advised by Christophe.
 v1: add of_node_put() before each exit.

 arch/powerpc/platforms/85xx/sgy_cts1000.c | 27 +++
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
b/arch/powerpc/platforms/85xx/sgy_cts1000.c
index 98ae64075193..e280f963d88c 100644
--- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
+++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
@@ -73,6 +73,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
int gpio, err, irq;
int trigger;
+   int ret;
 
if (!node)
return -ENODEV;
@@ -84,20 +85,24 @@ static int gpio_halt_probe(struct platform_device *pdev)
 
/* Technically we could just read the first one, but punish
 * DT writers for invalid form. */
-   if (of_gpio_count(halt_node) != 1)
-   return -EINVAL;
+   if (of_gpio_count(halt_node) != 1) {
+   ret = -EINVAL;
+   goto err_put;
+   }
 
/* Get the gpio number relative to the dynamic base. */
gpio = of_get_gpio_flags(halt_node, 0, );
-   if (!gpio_is_valid(gpio))
-   return -EINVAL;
+   if (!gpio_is_valid(gpio)) {
+   ret = -EINVAL;
+   gotot err_put;
+   }
 
err = gpio_request(gpio, "gpio-halt");
if (err) {
printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n",
   gpio);
-   halt_node = NULL;
-   return err;
+   ret = err;
+   goto err_put;
}
 
trigger = (flags == OF_GPIO_ACTIVE_LOW);
@@ -112,8 +117,8 @@ static int gpio_halt_probe(struct platform_device *pdev)
printk(KERN_ERR "gpio-halt: error requesting IRQ %d for "
   "GPIO %d.\n", irq, gpio);
gpio_free(gpio);
-   halt_node = NULL;
-   return err;
+   ret = err;
+   goto err_put;
}
 
/* Register our halt function */
@@ -122,8 +127,12 @@ static int gpio_halt_probe(struct platform_device *pdev)
 
printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
   " irq).\n", gpio, trigger, irq);
+   ret = 0;
 
-   return 0;
+err_put:
+   of_node_put(halt_node);
+   halt_node = NULL;
+   return ret;
 }
 
 static int gpio_halt_remove(struct platform_device *pdev)
-- 
2.25.1



Re:Re: [PATCH] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c

2022-06-16 Thread Liang He




At 2022-06-16 22:49:36, "Christophe Leroy"  wrote:
>
>
>Le 15/06/2022 à 14:07, Liang He a écrit :
>> [You don't often get email from win...@126.com. Learn why this is important 
>> at https://aka.ms/LearnAboutSenderIdentification ]
>> 
>> Signed-off-by: Liang He 
>> ---
>>   arch/powerpc/platforms/85xx/sgy_cts1000.c | 10 ++
>>   1 file changed, 10 insertions(+)
>> 
>> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
>> b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>> index 98ae64075193..2a45b30852b2 100644
>> --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
>> +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
>> @@ -85,17 +85,24 @@ static int gpio_halt_probe(struct platform_device *pdev)
>>  /* Technically we could just read the first one, but punish
>>   * DT writers for invalid form. */
>>  if (of_gpio_count(halt_node) != 1)
>> +   {
>> +   of_node_put(halt_node);
>
>Duplicating the same code at multiple exit points is bad practice.
>
>If you can't do a simple 'return' exit, you should use 'goto' to a 
>common error path exit.

Thanks for your valuable advice, I will resend a new patch for that.


>
>>  return -EINVAL;
>> +   }
>> 
>>  /* Get the gpio number relative to the dynamic base. */
>>  gpio = of_get_gpio_flags(halt_node, 0, );
>>  if (!gpio_is_valid(gpio))
>> +   {
>> +   of_node_put(halt_node);
>>  return -EINVAL;
>> +   }
>> 
>>  err = gpio_request(gpio, "gpio-halt");
>>  if (err) {
>>  printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n",
>> gpio);
>> +   of_node_put(halt_node);
>>  halt_node = NULL;
>>  return err;
>>  }
>> @@ -112,6 +119,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
>>  printk(KERN_ERR "gpio-halt: error requesting IRQ %d for "
>> "GPIO %d.\n", irq, gpio);
>>  gpio_free(gpio);
>> +   of_node_put(halt_node);
>>  halt_node = NULL;
>>  return err;
>>  }
>> @@ -123,6 +131,8 @@ static int gpio_halt_probe(struct platform_device *pdev)
>>  printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
>> " irq).\n", gpio, trigger, irq);
>> 
>> +   of_node_put(halt_node);
>> +
>>  return 0;
>>   }
>> 
>> --
>> 2.25.1
>> 


[PATCH] powerpc: platforms: 52xx: Fix refcount leak in media5200.c

2022-06-16 Thread Liang He
In media5200_init_irq(), of_find_compatible_node() will return a
node pointer with refcount incremented. We should use of_node_put()
in fail path or when it is not used anymore.

Don't worry about 'fpga_np==NULL' as of_node_put() can correctly
handle it.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/52xx/media5200.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/platforms/52xx/media5200.c 
b/arch/powerpc/platforms/52xx/media5200.c
index ee367ff3ec8a..33a35fff11b5 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -174,6 +174,8 @@ static void __init media5200_init_irq(void)
goto out;
pr_debug("%s: allocated irqhost\n", __func__);
 
+   of_node_put(fpga_np);
+
irq_set_handler_data(cascade_virq, _irq);
irq_set_chained_handler(cascade_virq, media5200_irq_cascade);
 
@@ -181,6 +183,7 @@ static void __init media5200_init_irq(void)
 
  out:
pr_err("Could not find Media5200 FPGA; PCI interrupts will not work\n");
+   of_node_put(fpga_np);
 }
 
 /*
-- 
2.25.1



[PATCH] arch: powerpc: platforms: 85xx: Fix refcount leak bug in ksi8560.c

2022-06-16 Thread Liang He
In ksi8560_setup_arch(), of_find_compatible_node() will return a
node pointer with refcount incremented. We should use of_node_put()
when it is not used anymore.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/85xx/ksi8560.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/platforms/85xx/ksi8560.c 
b/arch/powerpc/platforms/85xx/ksi8560.c
index bdf9d42f8521..a22f02b0fc77 100644
--- a/arch/powerpc/platforms/85xx/ksi8560.c
+++ b/arch/powerpc/platforms/85xx/ksi8560.c
@@ -133,6 +133,8 @@ static void __init ksi8560_setup_arch(void)
else
printk(KERN_ERR "Can't find CPLD in device tree\n");
 
+   of_node_put(cpld);
+
if (ppc_md.progress)
ppc_md.progress("ksi8560_setup_arch()", 0);
 
-- 
2.25.1



[PATCH] arch: powerpc: platforms: 512x: Add missing of_node_put()

2022-06-15 Thread Liang He
In mpc5121_clk_init(), of_find_compatible_node() will return a
node pointer with refcount incremented. We should use of_node_put()
when it is not used anymore.

Signed-off-by: Liang He 
---
 arch/powerpc/platforms/512x/clock-commonclk.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c 
b/arch/powerpc/platforms/512x/clock-commonclk.c
index 0652c7e69225..ca475462e95b 100644
--- a/arch/powerpc/platforms/512x/clock-commonclk.c
+++ b/arch/powerpc/platforms/512x/clock-commonclk.c
@@ -1208,6 +1208,8 @@ int __init mpc5121_clk_init(void)
/* register as an OF clock provider */
mpc5121_clk_register_of_provider(clk_np);
 
+   of_node_put(clk_np);
+
/*
 * unbreak not yet adjusted peripheral drivers during migration
 * towards fully operational common clock support, and allow
-- 
2.25.1



[PATCH] arch: powerpc: platforms: 85xx: Add missing of_node_put in sgy_cts1000.c

2022-06-15 Thread Liang He
Signed-off-by: Liang He 
---
 arch/powerpc/platforms/85xx/sgy_cts1000.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c 
b/arch/powerpc/platforms/85xx/sgy_cts1000.c
index 98ae64075193..2a45b30852b2 100644
--- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
+++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
@@ -85,17 +85,24 @@ static int gpio_halt_probe(struct platform_device *pdev)
/* Technically we could just read the first one, but punish
 * DT writers for invalid form. */
if (of_gpio_count(halt_node) != 1)
+   {
+   of_node_put(halt_node);
return -EINVAL;
+   }
 
/* Get the gpio number relative to the dynamic base. */
gpio = of_get_gpio_flags(halt_node, 0, );
if (!gpio_is_valid(gpio))
+   {
+   of_node_put(halt_node);
return -EINVAL;
+   }
 
err = gpio_request(gpio, "gpio-halt");
if (err) {
printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n",
   gpio);
+   of_node_put(halt_node);
halt_node = NULL;
return err;
}
@@ -112,6 +119,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
printk(KERN_ERR "gpio-halt: error requesting IRQ %d for "
   "GPIO %d.\n", irq, gpio);
gpio_free(gpio);
+   of_node_put(halt_node);
halt_node = NULL;
return err;
}
@@ -123,6 +131,8 @@ static int gpio_halt_probe(struct platform_device *pdev)
printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
   " irq).\n", gpio, trigger, irq);
 
+   of_node_put(halt_node);
+
return 0;
 }
 
-- 
2.25.1