]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
arm64: Introduce get_cpu_ops() helper function
authorGavin Shan <gshan@redhat.com>
Wed, 18 Mar 2020 23:01:44 +0000 (10:01 +1100)
committerCatalin Marinas <catalin.marinas@arm.com>
Tue, 24 Mar 2020 17:24:19 +0000 (17:24 +0000)
This introduces get_cpu_ops() to return the CPU operations according to
the given CPU index. For now, it simply returns the @cpu_ops[cpu] as
before. Also, helper function __cpu_try_die() is introduced to be shared
by cpu_die() and ipi_cpu_crash_stop(). So it shouldn't introduce any
functional changes.

Signed-off-by: Gavin Shan <gshan@redhat.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
arch/arm64/include/asm/cpu_ops.h
arch/arm64/kernel/cpu_ops.c
arch/arm64/kernel/cpuidle.c
arch/arm64/kernel/setup.c
arch/arm64/kernel/smp.c

index baa13b5db2caa27f73babf4dc574332d85caacb2..d28e8f37d3b402ca52121bf9b6189818388760c4 100644 (file)
@@ -55,8 +55,8 @@ struct cpu_operations {
 #endif
 };
 
-extern const struct cpu_operations *cpu_ops[NR_CPUS];
 int __init init_cpu_ops(int cpu);
+extern const struct cpu_operations *get_cpu_ops(int cpu);
 
 static inline void __init init_bootcpu_ops(void)
 {
index a6c3c816b61858643a8df083c05513237aa01448..e133011f64b5bf661bd9aaa37013652d0a481e6d 100644 (file)
@@ -20,7 +20,7 @@ extern const struct cpu_operations acpi_parking_protocol_ops;
 #endif
 extern const struct cpu_operations cpu_psci_ops;
 
-const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init;
+static const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init;
 
 static const struct cpu_operations *const dt_supported_cpu_ops[] __initconst = {
        &smp_spin_table_ops,
@@ -111,3 +111,8 @@ int __init init_cpu_ops(int cpu)
 
        return 0;
 }
+
+const struct cpu_operations *get_cpu_ops(int cpu)
+{
+       return cpu_ops[cpu];
+}
index e4d6af2fdec716ae36028f8e060dda92fb5127d2..b512b5503f6e676d7bdb370b854e0bf5177bb84c 100644 (file)
 
 int arm_cpuidle_init(unsigned int cpu)
 {
+       const struct cpu_operations *ops = get_cpu_ops(cpu);
        int ret = -EOPNOTSUPP;
 
-       if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_suspend &&
-                       cpu_ops[cpu]->cpu_init_idle)
-               ret = cpu_ops[cpu]->cpu_init_idle(cpu);
+       if (ops && ops->cpu_suspend && ops->cpu_init_idle)
+               ret = ops->cpu_init_idle(cpu);
 
        return ret;
 }
@@ -37,8 +37,9 @@ int arm_cpuidle_init(unsigned int cpu)
 int arm_cpuidle_suspend(int index)
 {
        int cpu = smp_processor_id();
+       const struct cpu_operations *ops = get_cpu_ops(cpu);
 
-       return cpu_ops[cpu]->cpu_suspend(index);
+       return ops->cpu_suspend(index);
 }
 
 #ifdef CONFIG_ACPI
index f66bd260cce87676c67ebc74ef43f889e1bf17ad..3fd2c11c09fc5d27bd8995c35d88e6a0ef4cfe7e 100644 (file)
@@ -371,8 +371,10 @@ void __init setup_arch(char **cmdline_p)
 static inline bool cpu_can_disable(unsigned int cpu)
 {
 #ifdef CONFIG_HOTPLUG_CPU
-       if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_can_disable)
-               return cpu_ops[cpu]->cpu_can_disable(cpu);
+       const struct cpu_operations *ops = get_cpu_ops(cpu);
+
+       if (ops && ops->cpu_can_disable)
+               return ops->cpu_can_disable(cpu);
 #endif
        return false;
 }
index 6f8477d7f3beb8d595b0e71b073f4eedb7955388..e5c9862c271b86d572683c311f2d1b8ad7c8fc88 100644 (file)
@@ -93,8 +93,10 @@ static inline int op_cpu_kill(unsigned int cpu)
  */
 static int boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       if (cpu_ops[cpu]->cpu_boot)
-               return cpu_ops[cpu]->cpu_boot(cpu);
+       const struct cpu_operations *ops = get_cpu_ops(cpu);
+
+       if (ops->cpu_boot)
+               return ops->cpu_boot(cpu);
 
        return -EOPNOTSUPP;
 }
@@ -196,6 +198,7 @@ asmlinkage notrace void secondary_start_kernel(void)
 {
        u64 mpidr = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
        struct mm_struct *mm = &init_mm;
+       const struct cpu_operations *ops;
        unsigned int cpu;
 
        cpu = task_cpu(current);
@@ -227,8 +230,9 @@ asmlinkage notrace void secondary_start_kernel(void)
         */
        check_local_cpu_capabilities();
 
-       if (cpu_ops[cpu]->cpu_postboot)
-               cpu_ops[cpu]->cpu_postboot();
+       ops = get_cpu_ops(cpu);
+       if (ops->cpu_postboot)
+               ops->cpu_postboot();
 
        /*
         * Log the CPU info before it is marked online and might get read.
@@ -266,19 +270,21 @@ asmlinkage notrace void secondary_start_kernel(void)
 #ifdef CONFIG_HOTPLUG_CPU
 static int op_cpu_disable(unsigned int cpu)
 {
+       const struct cpu_operations *ops = get_cpu_ops(cpu);
+
        /*
         * If we don't have a cpu_die method, abort before we reach the point
         * of no return. CPU0 may not have an cpu_ops, so test for it.
         */
-       if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_die)
+       if (!ops || !ops->cpu_die)
                return -EOPNOTSUPP;
 
        /*
         * We may need to abort a hot unplug for some other mechanism-specific
         * reason.
         */
-       if (cpu_ops[cpu]->cpu_disable)
-               return cpu_ops[cpu]->cpu_disable(cpu);
+       if (ops->cpu_disable)
+               return ops->cpu_disable(cpu);
 
        return 0;
 }
@@ -314,15 +320,17 @@ int __cpu_disable(void)
 
 static int op_cpu_kill(unsigned int cpu)
 {
+       const struct cpu_operations *ops = get_cpu_ops(cpu);
+
        /*
         * If we have no means of synchronising with the dying CPU, then assume
         * that it is really dead. We can only wait for an arbitrary length of
         * time and hope that it's dead, so let's skip the wait and just hope.
         */
-       if (!cpu_ops[cpu]->cpu_kill)
+       if (!ops->cpu_kill)
                return 0;
 
-       return cpu_ops[cpu]->cpu_kill(cpu);
+       return ops->cpu_kill(cpu);
 }
 
 /*
@@ -357,6 +365,7 @@ void __cpu_die(unsigned int cpu)
 void cpu_die(void)
 {
        unsigned int cpu = smp_processor_id();
+       const struct cpu_operations *ops = get_cpu_ops(cpu);
 
        idle_task_exit();
 
@@ -370,12 +379,22 @@ void cpu_die(void)
         * mechanism must perform all required cache maintenance to ensure that
         * no dirty lines are lost in the process of shutting down the CPU.
         */
-       cpu_ops[cpu]->cpu_die(cpu);
+       ops->cpu_die(cpu);
 
        BUG();
 }
 #endif
 
+static void __cpu_try_die(int cpu)
+{
+#ifdef CONFIG_HOTPLUG_CPU
+       const struct cpu_operations *ops = get_cpu_ops(cpu);
+
+       if (ops && ops->cpu_die)
+               ops->cpu_die(cpu);
+#endif
+}
+
 /*
  * Kill the calling secondary CPU, early in bringup before it is turned
  * online.
@@ -389,12 +408,11 @@ void cpu_die_early(void)
        /* Mark this CPU absent */
        set_cpu_present(cpu, 0);
 
-#ifdef CONFIG_HOTPLUG_CPU
-       update_cpu_boot_status(CPU_KILL_ME);
-       /* Check if we can park ourselves */
-       if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_die)
-               cpu_ops[cpu]->cpu_die(cpu);
-#endif
+       if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) {
+               update_cpu_boot_status(CPU_KILL_ME);
+               __cpu_try_die(cpu);
+       }
+
        update_cpu_boot_status(CPU_STUCK_IN_KERNEL);
 
        cpu_park_loop();
@@ -488,10 +506,13 @@ static bool __init is_mpidr_duplicate(unsigned int cpu, u64 hwid)
  */
 static int __init smp_cpu_setup(int cpu)
 {
+       const struct cpu_operations *ops;
+
        if (init_cpu_ops(cpu))
                return -ENODEV;
 
-       if (cpu_ops[cpu]->cpu_init(cpu))
+       ops = get_cpu_ops(cpu);
+       if (ops->cpu_init(cpu))
                return -ENODEV;
 
        set_cpu_possible(cpu, true);
@@ -714,6 +735,7 @@ void __init smp_init_cpus(void)
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
+       const struct cpu_operations *ops;
        int err;
        unsigned int cpu;
        unsigned int this_cpu;
@@ -744,10 +766,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
                if (cpu == smp_processor_id())
                        continue;
 
-               if (!cpu_ops[cpu])
+               ops = get_cpu_ops(cpu);
+               if (!ops)
                        continue;
 
-               err = cpu_ops[cpu]->cpu_prepare(cpu);
+               err = ops->cpu_prepare(cpu);
                if (err)
                        continue;
 
@@ -863,10 +886,8 @@ static void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
        local_irq_disable();
        sdei_mask_local_cpu();
 
-#ifdef CONFIG_HOTPLUG_CPU
-       if (cpu_ops[cpu]->cpu_die)
-               cpu_ops[cpu]->cpu_die(cpu);
-#endif
+       if (IS_ENABLED(CONFIG_HOTPLUG_CPU))
+               __cpu_try_die(cpu);
 
        /* just in case */
        cpu_park_loop();
@@ -1044,8 +1065,9 @@ static bool have_cpu_die(void)
 {
 #ifdef CONFIG_HOTPLUG_CPU
        int any_cpu = raw_smp_processor_id();
+       const struct cpu_operations *ops = get_cpu_ops(any_cpu);
 
-       if (cpu_ops[any_cpu] && cpu_ops[any_cpu]->cpu_die)
+       if (ops && ops->cpu_die)
                return true;
 #endif
        return false;