Merge tag 'smp-core-2020-03-30' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 31 Mar 2020 01:06:39 +0000 (18:06 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 31 Mar 2020 01:06:39 +0000 (18:06 -0700)
Pull core SMP updates from Thomas Gleixner:
 "CPU (hotplug) updates:

   - Support for locked CSD objects in smp_call_function_single_async()
     which allows to simplify callsites in the scheduler core and MIPS

   - Treewide consolidation of CPU hotplug functions which ensures the
     consistency between the sysfs interface and kernel state. The low
     level functions cpu_up/down() are now confined to the core code and
     not longer accessible from random code"

* tag 'smp-core-2020-03-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (22 commits)
  cpu/hotplug: Ignore pm_wakeup_pending() for disable_nonboot_cpus()
  cpu/hotplug: Hide cpu_up/down()
  cpu/hotplug: Move bringup of secondary CPUs out of smp_init()
  torture: Replace cpu_up/down() with add/remove_cpu()
  firmware: psci: Replace cpu_up/down() with add/remove_cpu()
  xen/cpuhotplug: Replace cpu_up/down() with device_online/offline()
  parisc: Replace cpu_up/down() with add/remove_cpu()
  sparc: Replace cpu_up/down() with add/remove_cpu()
  powerpc: Replace cpu_up/down() with add/remove_cpu()
  x86/smp: Replace cpu_up/down() with add/remove_cpu()
  arm64: hibernate: Use bringup_hibernate_cpu()
  cpu/hotplug: Provide bringup_hibernate_cpu()
  arm64: Use reboot_cpu instead of hardconding it to 0
  arm64: Don't use disable_nonboot_cpus()
  ARM: Use reboot_cpu instead of hardcoding it to 0
  ARM: Don't use disable_nonboot_cpus()
  ia64: Replace cpu_down() with smp_shutdown_nonboot_cpus()
  cpu/hotplug: Create a new function to shutdown nonboot cpus
  cpu/hotplug: Add new {add,remove}_cpu() functions
  sched/core: Remove rq.hrtick_csd_pending
  ...

20 files changed:
arch/arm/kernel/reboot.c
arch/arm64/kernel/hibernate.c
arch/arm64/kernel/process.c
arch/ia64/kernel/process.c
arch/mips/kernel/smp.c
arch/parisc/kernel/processor.c
arch/powerpc/kexec/core_64.c
arch/sparc/kernel/ds.c
arch/x86/kernel/topology.c
arch/x86/mm/mmio-mod.c
arch/x86/xen/smp.c
drivers/base/cpu.c
drivers/firmware/psci/psci_checker.c
drivers/xen/cpu_hotplug.c
include/linux/cpu.h
kernel/cpu.c
kernel/sched/core.c
kernel/sched/sched.h
kernel/smp.c
kernel/torture.c

index bb18ed0..0ce388f 100644 (file)
@@ -88,11 +88,11 @@ void soft_restart(unsigned long addr)
  * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
  * kexec'd kernel to use any and all RAM as it sees fit, without having to
  * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
- * functionality embodied in disable_nonboot_cpus() to achieve this.
+ * functionality embodied in smp_shutdown_nonboot_cpus() to achieve this.
  */
 void machine_shutdown(void)
 {
-       disable_nonboot_cpus();
+       smp_shutdown_nonboot_cpus(reboot_cpu);
 }
 
 /*
index 590963c..5b73e92 100644 (file)
@@ -166,14 +166,11 @@ int arch_hibernation_header_restore(void *addr)
                sleep_cpu = -EINVAL;
                return -EINVAL;
        }
-       if (!cpu_online(sleep_cpu)) {
-               pr_info("Hibernated on a CPU that is offline! Bringing CPU up.\n");
-               ret = cpu_up(sleep_cpu);
-               if (ret) {
-                       pr_err("Failed to bring hibernate-CPU up!\n");
-                       sleep_cpu = -EINVAL;
-                       return ret;
-               }
+
+       ret = bringup_hibernate_cpu(sleep_cpu);
+       if (ret) {
+               sleep_cpu = -EINVAL;
+               return ret;
        }
 
        resume_hdr = *hdr;
index 0062605..3e5a6ad 100644 (file)
@@ -141,11 +141,11 @@ void arch_cpu_idle_dead(void)
  * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
  * kexec'd kernel to use any and all RAM as it sees fit, without having to
  * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
- * functionality embodied in disable_nonboot_cpus() to achieve this.
+ * functionality embodied in smpt_shutdown_nonboot_cpus() to achieve this.
  */
 void machine_shutdown(void)
 {
-       disable_nonboot_cpus();
+       smp_shutdown_nonboot_cpus(reboot_cpu);
 }
 
 /*
index 743aaf5..10cb938 100644 (file)
@@ -646,14 +646,8 @@ cpu_halt (void)
 
 void machine_shutdown(void)
 {
-#ifdef CONFIG_HOTPLUG_CPU
-       int cpu;
+       smp_shutdown_nonboot_cpus(reboot_cpu);
 
-       for_each_online_cpu(cpu) {
-               if (cpu != smp_processor_id())
-                       cpu_down(cpu);
-       }
-#endif
 #ifdef CONFIG_KEXEC
        kexec_disable_iosapic();
 #endif
index f510c00..0def624 100644 (file)
@@ -696,29 +696,22 @@ EXPORT_SYMBOL(flush_tlb_one);
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 
-static DEFINE_PER_CPU(atomic_t, tick_broadcast_count);
 static DEFINE_PER_CPU(call_single_data_t, tick_broadcast_csd);
 
 void tick_broadcast(const struct cpumask *mask)
 {
-       atomic_t *count;
        call_single_data_t *csd;
        int cpu;
 
        for_each_cpu(cpu, mask) {
-               count = &per_cpu(tick_broadcast_count, cpu);
                csd = &per_cpu(tick_broadcast_csd, cpu);
-
-               if (atomic_inc_return(count) == 1)
-                       smp_call_function_single_async(cpu, csd);
+               smp_call_function_single_async(cpu, csd);
        }
 }
 
 static void tick_broadcast_callee(void *info)
 {
-       int cpu = smp_processor_id();
        tick_receive_broadcast();
-       atomic_set(&per_cpu(tick_broadcast_count, cpu), 0);
 }
 
 static int __init tick_broadcast_init(void)
index 13f771f..7f2d0c0 100644 (file)
@@ -212,7 +212,7 @@ static int __init processor_probe(struct parisc_device *dev)
 #ifdef CONFIG_SMP
        if (cpuid) {
                set_cpu_present(cpuid, true);
-               cpu_up(cpuid);
+               add_cpu(cpuid);
        }
 #endif
 
index 04a7cba..b418409 100644 (file)
@@ -212,7 +212,7 @@ static void wake_offline_cpus(void)
                if (!cpu_online(cpu)) {
                        printk(KERN_INFO "kexec: Waking offline cpu %d.\n",
                               cpu);
-                       WARN_ON(cpu_up(cpu));
+                       WARN_ON(add_cpu(cpu));
                }
        }
 }
index bbf59b3..75232cb 100644 (file)
@@ -555,7 +555,7 @@ static int dr_cpu_configure(struct ds_info *dp, struct ds_cap_state *cp,
 
                printk(KERN_INFO "ds-%llu: Starting cpu %d...\n",
                       dp->id, cpu);
-               err = cpu_up(cpu);
+               err = add_cpu(cpu);
                if (err) {
                        __u32 res = DR_CPU_RES_FAILURE;
                        __u32 stat = DR_CPU_STAT_UNCONFIGURED;
@@ -611,7 +611,7 @@ static int dr_cpu_unconfigure(struct ds_info *dp,
 
                printk(KERN_INFO "ds-%llu: Shutting down cpu %d...\n",
                       dp->id, cpu);
-               err = cpu_down(cpu);
+               err = remove_cpu(cpu);
                if (err)
                        dr_cpu_mark(resp, cpu, ncpus,
                                    DR_CPU_RES_FAILURE,
index be5bc2e..b8810eb 100644 (file)
@@ -59,39 +59,29 @@ __setup("cpu0_hotplug", enable_cpu0_hotplug);
  */
 int _debug_hotplug_cpu(int cpu, int action)
 {
-       struct device *dev = get_cpu_device(cpu);
        int ret;
 
        if (!cpu_is_hotpluggable(cpu))
                return -EINVAL;
 
-       lock_device_hotplug();
-
        switch (action) {
        case 0:
-               ret = cpu_down(cpu);
-               if (!ret) {
+               ret = remove_cpu(cpu);
+               if (!ret)
                        pr_info("DEBUG_HOTPLUG_CPU0: CPU %u is now offline\n", cpu);
-                       dev->offline = true;
-                       kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
-               } else
+               else
                        pr_debug("Can't offline CPU%d.\n", cpu);
                break;
        case 1:
-               ret = cpu_up(cpu);
-               if (!ret) {
-                       dev->offline = false;
-                       kobject_uevent(&dev->kobj, KOBJ_ONLINE);
-               } else {
+               ret = add_cpu(cpu);
+               if (ret)
                        pr_debug("Can't online CPU%d.\n", cpu);
-               }
+
                break;
        default:
                ret = -EINVAL;
        }
 
-       unlock_device_hotplug();
-
        return ret;
 }
 
index 673de60..109325d 100644 (file)
@@ -386,7 +386,7 @@ static void enter_uniprocessor(void)
        put_online_cpus();
 
        for_each_cpu(cpu, downed_cpus) {
-               err = cpu_down(cpu);
+               err = remove_cpu(cpu);
                if (!err)
                        pr_info("CPU%d is down.\n", cpu);
                else
@@ -406,7 +406,7 @@ static void leave_uniprocessor(void)
                return;
        pr_notice("Re-enabling CPUs...\n");
        for_each_cpu(cpu, downed_cpus) {
-               err = cpu_up(cpu);
+               err = add_cpu(cpu);
                if (!err)
                        pr_info("enabled CPU%d.\n", cpu);
                else
index 7a43b2a..2097fa0 100644 (file)
@@ -132,7 +132,7 @@ void __init xen_smp_cpus_done(unsigned int max_cpus)
                if (xen_vcpu_nr(cpu) < MAX_VIRT_CPUS)
                        continue;
 
-               rc = cpu_down(cpu);
+               rc = remove_cpu(cpu);
 
                if (rc == 0) {
                        /*
index df19c00..9a1c00f 100644 (file)
@@ -55,7 +55,7 @@ static int cpu_subsys_online(struct device *dev)
        if (from_nid == NUMA_NO_NODE)
                return -ENODEV;
 
-       ret = cpu_up(cpuid);
+       ret = cpu_device_up(dev);
        /*
         * When hot adding memory to memoryless node and enabling a cpu
         * on the node, node number of the cpu may internally change.
@@ -69,7 +69,7 @@ static int cpu_subsys_online(struct device *dev)
 
 static int cpu_subsys_offline(struct device *dev)
 {
-       return cpu_down(dev->id);
+       return cpu_device_down(dev);
 }
 
 void unregister_cpu(struct cpu *cpu)
index 6a44539..873841a 100644 (file)
@@ -84,7 +84,7 @@ static unsigned int down_and_up_cpus(const struct cpumask *cpus,
 
        /* Try to power down all CPUs in the mask. */
        for_each_cpu(cpu, cpus) {
-               int ret = cpu_down(cpu);
+               int ret = remove_cpu(cpu);
 
                /*
                 * cpu_down() checks the number of online CPUs before the TOS
@@ -116,7 +116,7 @@ static unsigned int down_and_up_cpus(const struct cpumask *cpus,
 
        /* Try to power up all the CPUs that have been offlined. */
        for_each_cpu(cpu, offlined_cpus) {
-               int ret = cpu_up(cpu);
+               int ret = add_cpu(cpu);
 
                if (ret != 0) {
                        pr_err("Error occurred (%d) while trying "
index f192b6f..ec975de 100644 (file)
@@ -94,7 +94,7 @@ static int setup_cpu_watcher(struct notifier_block *notifier,
 
        for_each_possible_cpu(cpu) {
                if (vcpu_online(cpu) == 0) {
-                       (void)cpu_down(cpu);
+                       device_offline(get_cpu_device(cpu));
                        set_cpu_present(cpu, false);
                }
        }
index 1ca2baf..beaed2d 100644 (file)
@@ -88,10 +88,13 @@ extern ssize_t arch_cpu_release(const char *, size_t);
 
 #ifdef CONFIG_SMP
 extern bool cpuhp_tasks_frozen;
-int cpu_up(unsigned int cpu);
+int add_cpu(unsigned int cpu);
+int cpu_device_up(struct device *dev);
 void notify_cpu_starting(unsigned int cpu);
 extern void cpu_maps_update_begin(void);
 extern void cpu_maps_update_done(void);
+int bringup_hibernate_cpu(unsigned int sleep_cpu);
+void bringup_nonboot_cpus(unsigned int setup_max_cpus);
 
 #else  /* CONFIG_SMP */
 #define cpuhp_tasks_frozen     0
@@ -117,7 +120,9 @@ extern void lockdep_assert_cpus_held(void);
 extern void cpu_hotplug_disable(void);
 extern void cpu_hotplug_enable(void);
 void clear_tasks_mm_cpumask(int cpu);
-int cpu_down(unsigned int cpu);
+int remove_cpu(unsigned int cpu);
+int cpu_device_down(struct device *dev);
+extern void smp_shutdown_nonboot_cpus(unsigned int primary_cpu);
 
 #else /* CONFIG_HOTPLUG_CPU */
 
@@ -129,6 +134,7 @@ static inline int  cpus_read_trylock(void) { return true; }
 static inline void lockdep_assert_cpus_held(void) { }
 static inline void cpu_hotplug_disable(void) { }
 static inline void cpu_hotplug_enable(void) { }
+static inline void smp_shutdown_nonboot_cpus(unsigned int primary_cpu) { }
 #endif /* !CONFIG_HOTPLUG_CPU */
 
 /* Wrappers which go away once all code is converted */
@@ -138,12 +144,18 @@ static inline void get_online_cpus(void) { cpus_read_lock(); }
 static inline void put_online_cpus(void) { cpus_read_unlock(); }
 
 #ifdef CONFIG_PM_SLEEP_SMP
-extern int freeze_secondary_cpus(int primary);
+int __freeze_secondary_cpus(int primary, bool suspend);
+static inline int freeze_secondary_cpus(int primary)
+{
+       return __freeze_secondary_cpus(primary, true);
+}
+
 static inline int disable_nonboot_cpus(void)
 {
-       return freeze_secondary_cpus(0);
+       return __freeze_secondary_cpus(0, false);
 }
-extern void enable_nonboot_cpus(void);
+
+void enable_nonboot_cpus(void);
 
 static inline int suspend_disable_secondary_cpus(void)
 {
index 221bf6a..2371292 100644 (file)
@@ -1041,7 +1041,7 @@ static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target)
        return _cpu_down(cpu, 0, target);
 }
 
-static int do_cpu_down(unsigned int cpu, enum cpuhp_state target)
+static int cpu_down(unsigned int cpu, enum cpuhp_state target)
 {
        int err;
 
@@ -1051,11 +1051,72 @@ static int do_cpu_down(unsigned int cpu, enum cpuhp_state target)
        return err;
 }
 
-int cpu_down(unsigned int cpu)
+/**
+ * cpu_device_down - Bring down a cpu device
+ * @dev: Pointer to the cpu device to offline
+ *
+ * This function is meant to be used by device core cpu subsystem only.
+ *
+ * Other subsystems should use remove_cpu() instead.
+ */
+int cpu_device_down(struct device *dev)
 {
-       return do_cpu_down(cpu, CPUHP_OFFLINE);
+       return cpu_down(dev->id, CPUHP_OFFLINE);
+}
+
+int remove_cpu(unsigned int cpu)
+{
+       int ret;
+
+       lock_device_hotplug();
+       ret = device_offline(get_cpu_device(cpu));
+       unlock_device_hotplug();
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(remove_cpu);
+
+void smp_shutdown_nonboot_cpus(unsigned int primary_cpu)
+{
+       unsigned int cpu;
+       int error;
+
+       cpu_maps_update_begin();
+
+       /*
+        * Make certain the cpu I'm about to reboot on is online.
+        *
+        * This is inline to what migrate_to_reboot_cpu() already do.
+        */
+       if (!cpu_online(primary_cpu))
+               primary_cpu = cpumask_first(cpu_online_mask);
+
+       for_each_online_cpu(cpu) {
+               if (cpu == primary_cpu)
+                       continue;
+
+               error = cpu_down_maps_locked(cpu, CPUHP_OFFLINE);
+               if (error) {
+                       pr_err("Failed to offline CPU%d - error=%d",
+                               cpu, error);
+                       break;
+               }
+       }
+
+       /*
+        * Ensure all but the reboot CPU are offline.
+        */
+       BUG_ON(num_online_cpus() > 1);
+
+       /*
+        * Make sure the CPUs won't be enabled by someone else after this
+        * point. Kexec will reboot to a new kernel shortly resetting
+        * everything along the way.
+        */
+       cpu_hotplug_disabled++;
+
+       cpu_maps_update_done();
 }
-EXPORT_SYMBOL(cpu_down);
 
 #else
 #define takedown_cpu           NULL
@@ -1124,8 +1185,8 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
        }
 
        /*
-        * The caller of do_cpu_up might have raced with another
-        * caller. Ignore it for now.
+        * The caller of cpu_up() might have raced with another
+        * caller. Nothing to do.
         */
        if (st->state >= target)
                goto out;
@@ -1169,7 +1230,7 @@ out:
        return ret;
 }
 
-static int do_cpu_up(unsigned int cpu, enum cpuhp_state target)
+static int cpu_up(unsigned int cpu, enum cpuhp_state target)
 {
        int err = 0;
 
@@ -1203,16 +1264,70 @@ out:
        return err;
 }
 
-int cpu_up(unsigned int cpu)
+/**
+ * cpu_device_up - Bring up a cpu device
+ * @dev: Pointer to the cpu device to online
+ *
+ * This function is meant to be used by device core cpu subsystem only.
+ *
+ * Other subsystems should use add_cpu() instead.
+ */
+int cpu_device_up(struct device *dev)
+{
+       return cpu_up(dev->id, CPUHP_ONLINE);
+}
+
+int add_cpu(unsigned int cpu)
+{
+       int ret;
+
+       lock_device_hotplug();
+       ret = device_online(get_cpu_device(cpu));
+       unlock_device_hotplug();
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(add_cpu);
+
+/**
+ * bringup_hibernate_cpu - Bring up the CPU that we hibernated on
+ * @sleep_cpu: The cpu we hibernated on and should be brought up.
+ *
+ * On some architectures like arm64, we can hibernate on any CPU, but on
+ * wake up the CPU we hibernated on might be offline as a side effect of
+ * using maxcpus= for example.
+ */
+int bringup_hibernate_cpu(unsigned int sleep_cpu)
 {
-       return do_cpu_up(cpu, CPUHP_ONLINE);
+       int ret;
+
+       if (!cpu_online(sleep_cpu)) {
+               pr_info("Hibernated on a CPU that is offline! Bringing CPU up.\n");
+               ret = cpu_up(sleep_cpu, CPUHP_ONLINE);
+               if (ret) {
+                       pr_err("Failed to bring hibernate-CPU up!\n");
+                       return ret;
+               }
+       }
+       return 0;
+}
+
+void bringup_nonboot_cpus(unsigned int setup_max_cpus)
+{
+       unsigned int cpu;
+
+       for_each_present_cpu(cpu) {
+               if (num_online_cpus() >= setup_max_cpus)
+                       break;
+               if (!cpu_online(cpu))
+                       cpu_up(cpu, CPUHP_ONLINE);
+       }
 }
-EXPORT_SYMBOL_GPL(cpu_up);
 
 #ifdef CONFIG_PM_SLEEP_SMP
 static cpumask_var_t frozen_cpus;
 
-int freeze_secondary_cpus(int primary)
+int __freeze_secondary_cpus(int primary, bool suspend)
 {
        int cpu, error = 0;
 
@@ -1237,7 +1352,7 @@ int freeze_secondary_cpus(int primary)
                if (cpu == primary)
                        continue;
 
-               if (pm_wakeup_pending()) {
+               if (suspend && pm_wakeup_pending()) {
                        pr_info("Wakeup pending. Abort CPU freeze\n");
                        error = -EBUSY;
                        break;
@@ -2028,9 +2143,9 @@ static ssize_t write_cpuhp_target(struct device *dev,
                goto out;
 
        if (st->state < target)
-               ret = do_cpu_up(dev->id, target);
+               ret = cpu_up(dev->id, target);
        else
-               ret = do_cpu_down(dev->id, target);
+               ret = cpu_down(dev->id, target);
 out:
        unlock_device_hotplug();
        return ret ? ret : count;
index c1f923d..a2694ba 100644 (file)
@@ -269,7 +269,6 @@ static void __hrtick_start(void *arg)
 
        rq_lock(rq, &rf);
        __hrtick_restart(rq);
-       rq->hrtick_csd_pending = 0;
        rq_unlock(rq, &rf);
 }
 
@@ -293,12 +292,10 @@ void hrtick_start(struct rq *rq, u64 delay)
 
        hrtimer_set_expires(timer, time);
 
-       if (rq == this_rq()) {
+       if (rq == this_rq())
                __hrtick_restart(rq);
-       } else if (!rq->hrtick_csd_pending) {
+       else
                smp_call_function_single_async(cpu_of(rq), &rq->hrtick_csd);
-               rq->hrtick_csd_pending = 1;
-       }
 }
 
 #else
@@ -322,8 +319,6 @@ void hrtick_start(struct rq *rq, u64 delay)
 static void hrtick_rq_init(struct rq *rq)
 {
 #ifdef CONFIG_SMP
-       rq->hrtick_csd_pending = 0;
-
        rq->hrtick_csd.flags = 0;
        rq->hrtick_csd.func = __hrtick_start;
        rq->hrtick_csd.info = rq;
index 4647428..0f616bf 100644 (file)
@@ -992,7 +992,6 @@ struct rq {
 
 #ifdef CONFIG_SCHED_HRTICK
 #ifdef CONFIG_SMP
-       int                     hrtick_csd_pending;
        call_single_data_t      hrtick_csd;
 #endif
        struct hrtimer          hrtick_timer;
index d0ada39..786092a 100644 (file)
@@ -329,6 +329,11 @@ EXPORT_SYMBOL(smp_call_function_single);
  * (ie: embedded in an object) and is responsible for synchronizing it
  * such that the IPIs performed on the @csd are strictly serialized.
  *
+ * If the function is called with one csd which has not yet been
+ * processed by previous call to smp_call_function_single_async(), the
+ * function will return immediately with -EBUSY showing that the csd
+ * object is still in progress.
+ *
  * NOTE: Be careful, there is unfortunately no current debugging facility to
  * validate the correctness of this serialization.
  */
@@ -338,14 +343,17 @@ int smp_call_function_single_async(int cpu, call_single_data_t *csd)
 
        preempt_disable();
 
-       /* We could deadlock if we have to wait here with interrupts disabled! */
-       if (WARN_ON_ONCE(csd->flags & CSD_FLAG_LOCK))
-               csd_lock_wait(csd);
+       if (csd->flags & CSD_FLAG_LOCK) {
+               err = -EBUSY;
+               goto out;
+       }
 
        csd->flags = CSD_FLAG_LOCK;
        smp_wmb();
 
        err = generic_exec_single(cpu, csd, csd->func, csd->info);
+
+out:
        preempt_enable();
 
        return err;
@@ -589,20 +597,13 @@ void __init setup_nr_cpu_ids(void)
 void __init smp_init(void)
 {
        int num_nodes, num_cpus;
-       unsigned int cpu;
 
        idle_threads_init();
        cpuhp_threads_init();
 
        pr_info("Bringing up secondary CPUs ...\n");
 
-       /* FIXME: This should be done in userspace --RR */
-       for_each_present_cpu(cpu) {
-               if (num_online_cpus() >= setup_max_cpus)
-                       break;
-               if (!cpu_online(cpu))
-                       cpu_up(cpu);
-       }
+       bringup_nonboot_cpus(setup_max_cpus);
 
        num_nodes = num_online_nodes();
        num_cpus  = num_online_cpus();
index 8683375..a1a4148 100644 (file)
@@ -101,7 +101,7 @@ bool torture_offline(int cpu, long *n_offl_attempts, long *n_offl_successes,
                         torture_type, cpu);
        starttime = jiffies;
        (*n_offl_attempts)++;
-       ret = cpu_down(cpu);
+       ret = remove_cpu(cpu);
        if (ret) {
                s = "";
                if (!rcu_inkernel_boot_has_ended() && ret == -EBUSY) {
@@ -159,7 +159,7 @@ bool torture_online(int cpu, long *n_onl_attempts, long *n_onl_successes,
                         torture_type, cpu);
        starttime = jiffies;
        (*n_onl_attempts)++;
-       ret = cpu_up(cpu);
+       ret = add_cpu(cpu);
        if (ret) {
                s = "";
                if (!rcu_inkernel_boot_has_ended() && ret == -EBUSY) {
@@ -209,17 +209,18 @@ torture_onoff(void *arg)
        for_each_online_cpu(cpu)
                maxcpu = cpu;
        WARN_ON(maxcpu < 0);
-       if (!IS_MODULE(CONFIG_TORTURE_TEST))
+       if (!IS_MODULE(CONFIG_TORTURE_TEST)) {
                for_each_possible_cpu(cpu) {
                        if (cpu_online(cpu))
                                continue;
-                       ret = cpu_up(cpu);
+                       ret = add_cpu(cpu);
                        if (ret && verbose) {
                                pr_alert("%s" TORTURE_FLAG
                                         "%s: Initial online %d: errno %d\n",
                                         __func__, torture_type, cpu, ret);
                        }
                }
+       }
 
        if (maxcpu == 0) {
                VERBOSE_TOROUT_STRING("Only one CPU, so CPU-hotplug testing is disabled");