]> git.baikalelectronics.ru Git - kernel.git/commitdiff
cpufreq: powernv: Fix init_chip_info initialization in numa=off
authorPratik R. Sampat <psampat@linux.ibm.com>
Wed, 28 Jul 2021 12:05:00 +0000 (17:35 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Sep 2021 10:26:37 +0000 (12:26 +0200)
commit f34ee9cb2c5ac5af426fee6fa4591a34d187e696 upstream.

In the numa=off kernel command-line configuration init_chip_info() loops
around the number of chips and attempts to copy the cpumask of that node
which is NULL for all iterations after the first chip.

Hence, store the cpu mask for each chip instead of derving cpumask from
node while populating the "chips" struct array and copy that to the
chips[i].mask

Fixes: 5c3ec2d14064 ("cpufreq: powernv: Handle throttling due to Pmax capping at chip level")
Cc: stable@vger.kernel.org # v4.3+
Reported-by: Shirisha Ganta <shirisha.ganta1@ibm.com>
Signed-off-by: Pratik R. Sampat <psampat@linux.ibm.com>
Reviewed-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
[mpe: Rename goto label to out_free_chip_cpu_mask]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210728120500.87549-2-psampat@linux.ibm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/cpufreq/powernv-cpufreq.c

index bc6ccf2c7aae0ce8f1e95291edd4b7ac13aecfeb..c636c9ba0100896c80452759602b999b530cef0d 100644 (file)
@@ -36,6 +36,7 @@
 #define MAX_PSTATE_SHIFT       32
 #define LPSTATE_SHIFT          48
 #define GPSTATE_SHIFT          56
+#define MAX_NR_CHIPS           32
 
 #define MAX_RAMP_DOWN_TIME                             5120
 /*
@@ -1050,12 +1051,20 @@ static int init_chip_info(void)
        unsigned int *chip;
        unsigned int cpu, i;
        unsigned int prev_chip_id = UINT_MAX;
+       cpumask_t *chip_cpu_mask;
        int ret = 0;
 
        chip = kcalloc(num_possible_cpus(), sizeof(*chip), GFP_KERNEL);
        if (!chip)
                return -ENOMEM;
 
+       /* Allocate a chip cpu mask large enough to fit mask for all chips */
+       chip_cpu_mask = kcalloc(MAX_NR_CHIPS, sizeof(cpumask_t), GFP_KERNEL);
+       if (!chip_cpu_mask) {
+               ret = -ENOMEM;
+               goto free_and_return;
+       }
+
        for_each_possible_cpu(cpu) {
                unsigned int id = cpu_to_chip_id(cpu);
 
@@ -1063,22 +1072,25 @@ static int init_chip_info(void)
                        prev_chip_id = id;
                        chip[nr_chips++] = id;
                }
+               cpumask_set_cpu(cpu, &chip_cpu_mask[nr_chips-1]);
        }
 
        chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL);
        if (!chips) {
                ret = -ENOMEM;
-               goto free_and_return;
+               goto out_free_chip_cpu_mask;
        }
 
        for (i = 0; i < nr_chips; i++) {
                chips[i].id = chip[i];
-               cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i]));
+               cpumask_copy(&chips[i].mask, &chip_cpu_mask[i]);
                INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn);
                for_each_cpu(cpu, &chips[i].mask)
                        per_cpu(chip_info, cpu) =  &chips[i];
        }
 
+out_free_chip_cpu_mask:
+       kfree(chip_cpu_mask);
 free_and_return:
        kfree(chip);
        return ret;