]> git.itanic.dy.fi Git - linux-stable/commitdiff
powerpc/pseries: Add missing of_node_put()s in hotplug-cpu.c
authorLiang He <windhl@126.com>
Tue, 21 Jun 2022 11:17:01 +0000 (19:17 +0800)
committerMichael Ellerman <mpe@ellerman.id.au>
Mon, 5 Sep 2022 07:30:24 +0000 (17:30 +1000)
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 <windhl@126.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220621111701.4082889-1-windhl@126.com
arch/powerpc/platforms/pseries/hotplug-cpu.c

index 0f8cd8b06432d21a02bd0ddae4a0b8677de962ae..e0a7ac5db15d9fa22684b61ce6737c0d31efd80a 100644 (file)
@@ -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(&cs, dn);
+               of_node_put(dn);
                if (ret)
                        goto out;
        }