blob: c2573e858009bd3d32d0660f0921bc956cf18aaf [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* CPU control.
2 * (C) 2001, 2002, 2003, 2004 Rusty Russell
3 *
4 * This code is licenced under the GPL.
5 */
6#include <linux/proc_fs.h>
7#include <linux/smp.h>
8#include <linux/init.h>
9#include <linux/notifier.h>
10#include <linux/sched.h>
Thomas Gleixnera3c901b2018-11-25 19:33:39 +010011#include <linux/sched/smt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070012#include <linux/unistd.h>
13#include <linux/cpu.h>
Anton Vorontsovcb792952012-05-31 16:26:22 -070014#include <linux/oom.h>
15#include <linux/rcupdate.h>
Paul Gortmaker9984de12011-05-23 14:51:41 -040016#include <linux/export.h>
Anton Vorontsove4cc2f82012-05-31 16:26:26 -070017#include <linux/bug.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <linux/kthread.h>
19#include <linux/stop_machine.h>
Ingo Molnar81615b62006-06-26 00:24:32 -070020#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090021#include <linux/gfp.h>
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +010022#include <linux/suspend.h>
Gautham R. Shenoya19423b2014-03-11 02:04:03 +053023#include <linux/lockdep.h>
Preeti U Murthy345527b2015-03-30 14:59:19 +053024#include <linux/tick.h>
Thomas Gleixnera8994182015-07-05 17:12:30 +000025#include <linux/irq.h>
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +000026#include <linux/smpboot.h>
Richard Weinbergere6d49892016-08-18 14:57:17 +020027#include <linux/relay.h>
Sebastian Andrzej Siewior6731d4f2016-08-23 14:53:19 +020028#include <linux/slab.h>
Thomas Gleixnercff7d372016-02-26 18:43:28 +000029
Todd E Brandtbb3632c2014-06-06 05:40:17 -070030#include <trace/events/power.h>
Thomas Gleixnercff7d372016-02-26 18:43:28 +000031#define CREATE_TRACE_POINTS
32#include <trace/events/cpuhp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
Thomas Gleixner38498a62012-04-20 13:05:44 +000034#include "smpboot.h"
35
Thomas Gleixnercff7d372016-02-26 18:43:28 +000036/**
37 * cpuhp_cpu_state - Per cpu hotplug state storage
38 * @state: The current cpu state
39 * @target: The target state
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +000040 * @thread: Pointer to the hotplug thread
41 * @should_run: Thread should execute
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +020042 * @rollback: Perform a rollback
Thomas Gleixnera7246322016-08-12 19:49:38 +020043 * @single: Single callback invocation
44 * @bringup: Single callback bringup or teardown selector
45 * @cb_state: The state for a single callback (install/uninstall)
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +000046 * @result: Result of the operation
47 * @done: Signal completion to the issuer of the task
Thomas Gleixnercff7d372016-02-26 18:43:28 +000048 */
49struct cpuhp_cpu_state {
50 enum cpuhp_state state;
51 enum cpuhp_state target;
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +000052#ifdef CONFIG_SMP
53 struct task_struct *thread;
54 bool should_run;
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +020055 bool rollback;
Thomas Gleixnera7246322016-08-12 19:49:38 +020056 bool single;
57 bool bringup;
Thomas Gleixner8438e492018-06-29 16:05:48 +020058 bool booted_once;
Thomas Gleixnercf392d12016-08-12 19:49:39 +020059 struct hlist_node *node;
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +000060 enum cpuhp_state cb_state;
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +000061 int result;
62 struct completion done;
63#endif
Thomas Gleixnercff7d372016-02-26 18:43:28 +000064};
65
66static DEFINE_PER_CPU(struct cpuhp_cpu_state, cpuhp_state);
67
Thomas Gleixnerc198e222017-05-24 10:15:43 +020068#if defined(CONFIG_LOCKDEP) && defined(CONFIG_SMP)
69static struct lock_class_key cpuhp_state_key;
70static struct lockdep_map cpuhp_state_lock_map =
71 STATIC_LOCKDEP_MAP_INIT("cpuhp_state", &cpuhp_state_key);
72#endif
73
Thomas Gleixnercff7d372016-02-26 18:43:28 +000074/**
75 * cpuhp_step - Hotplug state machine step
76 * @name: Name of the step
77 * @startup: Startup function of the step
78 * @teardown: Teardown function of the step
79 * @skip_onerr: Do not invoke the functions on error rollback
80 * Will go away once the notifiers are gone
Thomas Gleixner757c9892016-02-26 18:43:32 +000081 * @cant_stop: Bringup/teardown can't be stopped at this step
Thomas Gleixnercff7d372016-02-26 18:43:28 +000082 */
83struct cpuhp_step {
Thomas Gleixnercf392d12016-08-12 19:49:39 +020084 const char *name;
85 union {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +020086 int (*single)(unsigned int cpu);
87 int (*multi)(unsigned int cpu,
88 struct hlist_node *node);
89 } startup;
Thomas Gleixnercf392d12016-08-12 19:49:39 +020090 union {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +020091 int (*single)(unsigned int cpu);
92 int (*multi)(unsigned int cpu,
93 struct hlist_node *node);
94 } teardown;
Thomas Gleixnercf392d12016-08-12 19:49:39 +020095 struct hlist_head list;
96 bool skip_onerr;
97 bool cant_stop;
98 bool multi_instance;
Thomas Gleixnercff7d372016-02-26 18:43:28 +000099};
100
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +0000101static DEFINE_MUTEX(cpuhp_state_mutex);
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000102static struct cpuhp_step cpuhp_bp_states[];
Thomas Gleixner4baa0af2016-02-26 18:43:29 +0000103static struct cpuhp_step cpuhp_ap_states[];
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000104
Thomas Gleixnera7246322016-08-12 19:49:38 +0200105static bool cpuhp_is_ap_state(enum cpuhp_state state)
106{
107 /*
108 * The extra check for CPUHP_TEARDOWN_CPU is only for documentation
109 * purposes as that state is handled explicitly in cpu_down.
110 */
111 return state > CPUHP_BRINGUP_CPU && state != CPUHP_TEARDOWN_CPU;
112}
113
114static struct cpuhp_step *cpuhp_get_step(enum cpuhp_state state)
115{
116 struct cpuhp_step *sp;
117
118 sp = cpuhp_is_ap_state(state) ? cpuhp_ap_states : cpuhp_bp_states;
119 return sp + state;
120}
121
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000122/**
123 * cpuhp_invoke_callback _ Invoke the callbacks for a given state
124 * @cpu: The cpu for which the callback should be invoked
125 * @step: The step in the state machine
Thomas Gleixnera7246322016-08-12 19:49:38 +0200126 * @bringup: True if the bringup callback should be invoked
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000127 *
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200128 * Called from cpu hotplug and from the state register machinery.
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000129 */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200130static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200131 bool bringup, struct hlist_node *node)
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000132{
133 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
Thomas Gleixnera7246322016-08-12 19:49:38 +0200134 struct cpuhp_step *step = cpuhp_get_step(state);
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200135 int (*cbm)(unsigned int cpu, struct hlist_node *node);
136 int (*cb)(unsigned int cpu);
137 int ret, cnt;
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000138
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200139 if (!step->multi_instance) {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +0200140 cb = bringup ? step->startup.single : step->teardown.single;
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200141 if (!cb)
142 return 0;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200143 trace_cpuhp_enter(cpu, st->target, state, cb);
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000144 ret = cb(cpu);
Thomas Gleixnera7246322016-08-12 19:49:38 +0200145 trace_cpuhp_exit(cpu, st->state, state, ret);
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200146 return ret;
147 }
Thomas Gleixner3c1627e2016-09-05 15:28:36 +0200148 cbm = bringup ? step->startup.multi : step->teardown.multi;
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200149 if (!cbm)
150 return 0;
151
152 /* Single invocation for instance add/remove */
153 if (node) {
154 trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node);
155 ret = cbm(cpu, node);
156 trace_cpuhp_exit(cpu, st->state, state, ret);
157 return ret;
158 }
159
160 /* State transition. Invoke on all instances */
161 cnt = 0;
162 hlist_for_each(node, &step->list) {
163 trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node);
164 ret = cbm(cpu, node);
165 trace_cpuhp_exit(cpu, st->state, state, ret);
166 if (ret)
167 goto err;
168 cnt++;
169 }
170 return 0;
171err:
172 /* Rollback the instances if one failed */
Thomas Gleixner3c1627e2016-09-05 15:28:36 +0200173 cbm = !bringup ? step->startup.multi : step->teardown.multi;
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200174 if (!cbm)
175 return ret;
176
177 hlist_for_each(node, &step->list) {
178 if (!cnt--)
179 break;
180 cbm(cpu, node);
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000181 }
182 return ret;
183}
184
Rusty Russell98a79d62008-12-13 21:19:41 +1030185#ifdef CONFIG_SMP
Rusty Russellb3199c02008-12-30 09:05:14 +1030186/* Serializes the updates to cpu_online_mask, cpu_present_mask */
Linus Torvaldsaa953872006-07-23 12:12:16 -0700187static DEFINE_MUTEX(cpu_add_remove_lock);
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000188bool cpuhp_tasks_frozen;
189EXPORT_SYMBOL_GPL(cpuhp_tasks_frozen);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700191/*
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530192 * The following two APIs (cpu_maps_update_begin/done) must be used when
193 * attempting to serialize the updates to cpu_online_mask & cpu_present_mask.
194 * The APIs cpu_notifier_register_begin/done() must be used to protect CPU
195 * hotplug callback (un)registration performed using __register_cpu_notifier()
196 * or __unregister_cpu_notifier().
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700197 */
198void cpu_maps_update_begin(void)
199{
200 mutex_lock(&cpu_add_remove_lock);
201}
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530202EXPORT_SYMBOL(cpu_notifier_register_begin);
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700203
204void cpu_maps_update_done(void)
205{
206 mutex_unlock(&cpu_add_remove_lock);
207}
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530208EXPORT_SYMBOL(cpu_notifier_register_done);
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700209
Daniel J Blueman5c113fb2010-06-01 12:15:11 +0100210static RAW_NOTIFIER_HEAD(cpu_chain);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -0700212/* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
213 * Should always be manipulated under cpu_add_remove_lock
214 */
215static int cpu_hotplug_disabled;
216
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700217#ifdef CONFIG_HOTPLUG_CPU
218
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100219static struct {
220 struct task_struct *active_writer;
David Hildenbrand87af9e72014-12-12 10:11:44 +0100221 /* wait queue to wake up the active_writer */
222 wait_queue_head_t wq;
223 /* verifies that no writer will get active while readers are active */
224 struct mutex lock;
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100225 /*
226 * Also blocks the new readers during
227 * an ongoing cpu hotplug operation.
228 */
David Hildenbrand87af9e72014-12-12 10:11:44 +0100229 atomic_t refcount;
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530230
231#ifdef CONFIG_DEBUG_LOCK_ALLOC
232 struct lockdep_map dep_map;
233#endif
Linus Torvalds31950eb2009-06-22 21:18:12 -0700234} cpu_hotplug = {
235 .active_writer = NULL,
David Hildenbrand87af9e72014-12-12 10:11:44 +0100236 .wq = __WAIT_QUEUE_HEAD_INITIALIZER(cpu_hotplug.wq),
Linus Torvalds31950eb2009-06-22 21:18:12 -0700237 .lock = __MUTEX_INITIALIZER(cpu_hotplug.lock),
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530238#ifdef CONFIG_DEBUG_LOCK_ALLOC
Joonas Lahtinena705e072016-10-12 13:18:56 +0300239 .dep_map = STATIC_LOCKDEP_MAP_INIT("cpu_hotplug.dep_map", &cpu_hotplug.dep_map),
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530240#endif
Linus Torvalds31950eb2009-06-22 21:18:12 -0700241};
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100242
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530243/* Lockdep annotations for get/put_online_cpus() and cpu_hotplug_begin/end() */
244#define cpuhp_lock_acquire_read() lock_map_acquire_read(&cpu_hotplug.dep_map)
Paul E. McKenneydd56af42014-08-25 20:25:06 -0700245#define cpuhp_lock_acquire_tryread() \
246 lock_map_acquire_tryread(&cpu_hotplug.dep_map)
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530247#define cpuhp_lock_acquire() lock_map_acquire(&cpu_hotplug.dep_map)
248#define cpuhp_lock_release() lock_map_release(&cpu_hotplug.dep_map)
249
Paul E. McKenney62db99f2014-10-22 14:51:49 -0700250
Gautham R Shenoy86ef5c92008-01-25 21:08:02 +0100251void get_online_cpus(void)
Ashok Raja9d9baa2005-11-28 13:43:46 -0800252{
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100253 might_sleep();
254 if (cpu_hotplug.active_writer == current)
Linus Torvaldsaa953872006-07-23 12:12:16 -0700255 return;
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530256 cpuhp_lock_acquire_read();
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100257 mutex_lock(&cpu_hotplug.lock);
David Hildenbrand87af9e72014-12-12 10:11:44 +0100258 atomic_inc(&cpu_hotplug.refcount);
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100259 mutex_unlock(&cpu_hotplug.lock);
Ashok Raja9d9baa2005-11-28 13:43:46 -0800260}
Gautham R Shenoy86ef5c92008-01-25 21:08:02 +0100261EXPORT_SYMBOL_GPL(get_online_cpus);
Ashok Raj90d45d12005-11-08 21:34:24 -0800262
Gautham R Shenoy86ef5c92008-01-25 21:08:02 +0100263void put_online_cpus(void)
Ashok Raja9d9baa2005-11-28 13:43:46 -0800264{
David Hildenbrand87af9e72014-12-12 10:11:44 +0100265 int refcount;
266
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100267 if (cpu_hotplug.active_writer == current)
Linus Torvaldsaa953872006-07-23 12:12:16 -0700268 return;
Srivatsa S. Bhat075663d2012-10-08 16:28:20 -0700269
David Hildenbrand87af9e72014-12-12 10:11:44 +0100270 refcount = atomic_dec_return(&cpu_hotplug.refcount);
271 if (WARN_ON(refcount < 0)) /* try to fix things up */
272 atomic_inc(&cpu_hotplug.refcount);
Srivatsa S. Bhat075663d2012-10-08 16:28:20 -0700273
David Hildenbrand87af9e72014-12-12 10:11:44 +0100274 if (refcount <= 0 && waitqueue_active(&cpu_hotplug.wq))
275 wake_up(&cpu_hotplug.wq);
276
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530277 cpuhp_lock_release();
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100278
Ashok Raja9d9baa2005-11-28 13:43:46 -0800279}
Gautham R Shenoy86ef5c92008-01-25 21:08:02 +0100280EXPORT_SYMBOL_GPL(put_online_cpus);
Ashok Raja9d9baa2005-11-28 13:43:46 -0800281
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100282/*
283 * This ensures that the hotplug operation can begin only when the
284 * refcount goes to zero.
285 *
286 * Note that during a cpu-hotplug operation, the new readers, if any,
287 * will be blocked by the cpu_hotplug.lock
288 *
Oleg Nesterovd2ba7e22008-04-29 01:00:29 -0700289 * Since cpu_hotplug_begin() is always called after invoking
290 * cpu_maps_update_begin(), we can be sure that only one writer is active.
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100291 *
292 * Note that theoretically, there is a possibility of a livelock:
293 * - Refcount goes to zero, last reader wakes up the sleeping
294 * writer.
295 * - Last reader unlocks the cpu_hotplug.lock.
296 * - A new reader arrives at this moment, bumps up the refcount.
297 * - The writer acquires the cpu_hotplug.lock finds the refcount
298 * non zero and goes to sleep again.
299 *
300 * However, this is very difficult to achieve in practice since
Gautham R Shenoy86ef5c92008-01-25 21:08:02 +0100301 * get_online_cpus() not an api which is called all that often.
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100302 *
303 */
Toshi Kanib9d10be2013-08-12 09:45:53 -0600304void cpu_hotplug_begin(void)
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100305{
David Hildenbrand87af9e72014-12-12 10:11:44 +0100306 DEFINE_WAIT(wait);
Oleg Nesterovd2ba7e22008-04-29 01:00:29 -0700307
David Hildenbrand87af9e72014-12-12 10:11:44 +0100308 cpu_hotplug.active_writer = current;
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530309 cpuhp_lock_acquire();
David Hildenbrand87af9e72014-12-12 10:11:44 +0100310
Oleg Nesterovd2ba7e22008-04-29 01:00:29 -0700311 for (;;) {
312 mutex_lock(&cpu_hotplug.lock);
David Hildenbrand87af9e72014-12-12 10:11:44 +0100313 prepare_to_wait(&cpu_hotplug.wq, &wait, TASK_UNINTERRUPTIBLE);
314 if (likely(!atomic_read(&cpu_hotplug.refcount)))
315 break;
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100316 mutex_unlock(&cpu_hotplug.lock);
317 schedule();
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100318 }
David Hildenbrand87af9e72014-12-12 10:11:44 +0100319 finish_wait(&cpu_hotplug.wq, &wait);
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100320}
321
Toshi Kanib9d10be2013-08-12 09:45:53 -0600322void cpu_hotplug_done(void)
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100323{
324 cpu_hotplug.active_writer = NULL;
325 mutex_unlock(&cpu_hotplug.lock);
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530326 cpuhp_lock_release();
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100327}
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700328
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -0700329/*
330 * Wait for currently running CPU hotplug operations to complete (if any) and
331 * disable future CPU hotplug (from sysfs). The 'cpu_add_remove_lock' protects
332 * the 'cpu_hotplug_disabled' flag. The same lock is also acquired by the
333 * hotplug path before performing hotplug operations. So acquiring that lock
334 * guarantees mutual exclusion from any currently running hotplug operations.
335 */
336void cpu_hotplug_disable(void)
337{
338 cpu_maps_update_begin();
Vitaly Kuznetsov89af7ba2015-08-05 00:52:46 -0700339 cpu_hotplug_disabled++;
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -0700340 cpu_maps_update_done();
341}
Vitaly Kuznetsov32145c42015-08-05 00:52:47 -0700342EXPORT_SYMBOL_GPL(cpu_hotplug_disable);
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -0700343
Lianwei Wang01b41152016-06-09 23:43:28 -0700344static void __cpu_hotplug_enable(void)
345{
346 if (WARN_ONCE(!cpu_hotplug_disabled, "Unbalanced cpu hotplug enable\n"))
347 return;
348 cpu_hotplug_disabled--;
349}
350
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -0700351void cpu_hotplug_enable(void)
352{
353 cpu_maps_update_begin();
Lianwei Wang01b41152016-06-09 23:43:28 -0700354 __cpu_hotplug_enable();
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -0700355 cpu_maps_update_done();
356}
Vitaly Kuznetsov32145c42015-08-05 00:52:47 -0700357EXPORT_SYMBOL_GPL(cpu_hotplug_enable);
Toshi Kanib9d10be2013-08-12 09:45:53 -0600358#endif /* CONFIG_HOTPLUG_CPU */
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700359
Thomas Gleixnera3c901b2018-11-25 19:33:39 +0100360/*
361 * Architectures that need SMT-specific errata handling during SMT hotplug
362 * should override this.
363 */
364void __weak arch_smt_update(void) { }
365
Thomas Gleixner8438e492018-06-29 16:05:48 +0200366#ifdef CONFIG_HOTPLUG_SMT
367enum cpuhp_smt_control cpu_smt_control __read_mostly = CPU_SMT_ENABLED;
Konrad Rzeszutek Wilka0695af2018-06-20 11:29:53 -0400368EXPORT_SYMBOL_GPL(cpu_smt_control);
Thomas Gleixner8438e492018-06-29 16:05:48 +0200369
Thomas Gleixnerc504b9f2018-08-07 08:19:57 +0200370static bool cpu_smt_available __read_mostly;
371
Jiri Kosinaa69c5e02018-07-13 16:23:23 +0200372void __init cpu_smt_disable(bool force)
Thomas Gleixner8438e492018-06-29 16:05:48 +0200373{
Jiri Kosinaa69c5e02018-07-13 16:23:23 +0200374 if (cpu_smt_control == CPU_SMT_FORCE_DISABLED ||
375 cpu_smt_control == CPU_SMT_NOT_SUPPORTED)
376 return;
377
378 if (force) {
Thomas Gleixner8438e492018-06-29 16:05:48 +0200379 pr_info("SMT: Force disabled\n");
380 cpu_smt_control = CPU_SMT_FORCE_DISABLED;
Jiri Kosinaa69c5e02018-07-13 16:23:23 +0200381 } else {
Borislav Petkov6270cc32018-10-04 19:22:27 +0200382 pr_info("SMT: disabled\n");
Jiri Kosinaa69c5e02018-07-13 16:23:23 +0200383 cpu_smt_control = CPU_SMT_DISABLED;
Thomas Gleixner8438e492018-06-29 16:05:48 +0200384 }
Jiri Kosinaa69c5e02018-07-13 16:23:23 +0200385}
386
Thomas Gleixner929d3b22018-07-13 16:23:24 +0200387/*
388 * The decision whether SMT is supported can only be done after the full
Thomas Gleixnerc504b9f2018-08-07 08:19:57 +0200389 * CPU identification. Called from architecture code before non boot CPUs
390 * are brought up.
391 */
392void __init cpu_smt_check_topology_early(void)
393{
394 if (!topology_smt_supported())
395 cpu_smt_control = CPU_SMT_NOT_SUPPORTED;
396}
397
398/*
399 * If SMT was disabled by BIOS, detect it here, after the CPUs have been
400 * brought online. This ensures the smt/l1tf sysfs entries are consistent
401 * with reality. cpu_smt_available is set to true during the bringup of non
402 * boot CPUs when a SMT sibling is detected. Note, this may overwrite
403 * cpu_smt_control's previous setting.
Thomas Gleixner929d3b22018-07-13 16:23:24 +0200404 */
405void __init cpu_smt_check_topology(void)
406{
Thomas Gleixnerc504b9f2018-08-07 08:19:57 +0200407 if (!cpu_smt_available)
Thomas Gleixner929d3b22018-07-13 16:23:24 +0200408 cpu_smt_control = CPU_SMT_NOT_SUPPORTED;
409}
410
Jiri Kosinaa69c5e02018-07-13 16:23:23 +0200411static int __init smt_cmdline_disable(char *str)
412{
413 cpu_smt_disable(str && !strcmp(str, "force"));
Thomas Gleixner8438e492018-06-29 16:05:48 +0200414 return 0;
415}
416early_param("nosmt", smt_cmdline_disable);
417
418static inline bool cpu_smt_allowed(unsigned int cpu)
419{
Thomas Gleixnerc504b9f2018-08-07 08:19:57 +0200420 if (topology_is_primary_thread(cpu))
Thomas Gleixner8438e492018-06-29 16:05:48 +0200421 return true;
422
Thomas Gleixnerc504b9f2018-08-07 08:19:57 +0200423 /*
424 * If the CPU is not a 'primary' thread and the booted_once bit is
425 * set then the processor has SMT support. Store this information
426 * for the late check of SMT support in cpu_smt_check_topology().
427 */
428 if (per_cpu(cpuhp_state, cpu).booted_once)
429 cpu_smt_available = true;
430
431 if (cpu_smt_control == CPU_SMT_ENABLED)
Thomas Gleixner8438e492018-06-29 16:05:48 +0200432 return true;
433
434 /*
435 * On x86 it's required to boot all logical CPUs at least once so
436 * that the init code can get a chance to set CR4.MCE on each
437 * CPU. Otherwise, a broadacasted MCE observing CR4.MCE=0b on any
438 * core will shutdown the machine.
439 */
440 return !per_cpu(cpuhp_state, cpu).booted_once;
441}
442#else
443static inline bool cpu_smt_allowed(unsigned int cpu) { return true; }
444#endif
445
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446/* Need to know about CPUs going up/down? */
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200447int register_cpu_notifier(struct notifier_block *nb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448{
Neil Brownbd5349c2006-10-17 00:10:35 -0700449 int ret;
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100450 cpu_maps_update_begin();
Neil Brownbd5349c2006-10-17 00:10:35 -0700451 ret = raw_notifier_chain_register(&cpu_chain, nb);
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100452 cpu_maps_update_done();
Neil Brownbd5349c2006-10-17 00:10:35 -0700453 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454}
Chandra Seetharaman65edc682006-06-27 02:54:08 -0700455
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200456int __register_cpu_notifier(struct notifier_block *nb)
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530457{
458 return raw_notifier_chain_register(&cpu_chain, nb);
459}
460
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000461static int __cpu_notify(unsigned long val, unsigned int cpu, int nr_to_call,
Akinobu Mitae9fb7632010-05-26 14:43:28 -0700462 int *nr_calls)
463{
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000464 unsigned long mod = cpuhp_tasks_frozen ? CPU_TASKS_FROZEN : 0;
465 void *hcpu = (void *)(long)cpu;
466
Akinobu Mitae6bde732010-05-26 14:43:29 -0700467 int ret;
468
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000469 ret = __raw_notifier_call_chain(&cpu_chain, val | mod, hcpu, nr_to_call,
Akinobu Mitae9fb7632010-05-26 14:43:28 -0700470 nr_calls);
Akinobu Mitae6bde732010-05-26 14:43:29 -0700471
472 return notifier_to_errno(ret);
Akinobu Mitae9fb7632010-05-26 14:43:28 -0700473}
474
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000475static int cpu_notify(unsigned long val, unsigned int cpu)
Akinobu Mitae9fb7632010-05-26 14:43:28 -0700476{
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000477 return __cpu_notify(val, cpu, -1, NULL);
Akinobu Mitae9fb7632010-05-26 14:43:28 -0700478}
479
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200480static void cpu_notify_nofail(unsigned long val, unsigned int cpu)
481{
482 BUG_ON(cpu_notify(val, cpu));
483}
484
Thomas Gleixnerba997462016-02-26 18:43:24 +0000485/* Notifier wrappers for transitioning to state machine */
486static int notify_prepare(unsigned int cpu)
487{
488 int nr_calls = 0;
489 int ret;
490
491 ret = __cpu_notify(CPU_UP_PREPARE, cpu, -1, &nr_calls);
492 if (ret) {
493 nr_calls--;
494 printk(KERN_WARNING "%s: attempt to bring up CPU %u failed\n",
495 __func__, cpu);
496 __cpu_notify(CPU_UP_CANCELED, cpu, nr_calls, NULL);
497 }
498 return ret;
499}
500
501static int notify_online(unsigned int cpu)
502{
503 cpu_notify(CPU_ONLINE, cpu);
504 return 0;
505}
506
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +0200507static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st);
508
Thomas Gleixner8df3e072016-02-26 18:43:41 +0000509static int bringup_wait_for_ap(unsigned int cpu)
510{
511 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
512
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +0200513 /* Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE */
Thomas Gleixner8df3e072016-02-26 18:43:41 +0000514 wait_for_completion(&st->done);
Thomas Gleixner6b3d13f2017-07-11 22:06:24 +0200515 if (WARN_ON_ONCE((!cpu_online(cpu))))
516 return -ECANCELED;
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +0200517
518 /* Unpark the stopper thread and the hotplug thread of the target cpu */
519 stop_machine_unpark(cpu);
520 kthread_unpark(st->thread);
521
Thomas Gleixner8438e492018-06-29 16:05:48 +0200522 /*
523 * SMT soft disabling on X86 requires to bring the CPU out of the
524 * BIOS 'wait for SIPI' state in order to set the CR4.MCE bit. The
525 * CPU marked itself as booted_once in cpu_notify_starting() so the
526 * cpu_smt_allowed() check will now return false if this is not the
527 * primary sibling.
528 */
529 if (!cpu_smt_allowed(cpu))
530 return -ECANCELED;
531
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +0200532 /* Should we go further up ? */
533 if (st->target > CPUHP_AP_ONLINE_IDLE) {
534 __cpuhp_kick_ap_work(st);
535 wait_for_completion(&st->done);
536 }
Thomas Gleixner8df3e072016-02-26 18:43:41 +0000537 return st->result;
538}
539
Thomas Gleixnerba997462016-02-26 18:43:24 +0000540static int bringup_cpu(unsigned int cpu)
541{
542 struct task_struct *idle = idle_thread_get(cpu);
543 int ret;
544
Boris Ostrovskyaa877172016-08-03 13:22:28 -0400545 /*
546 * Some architectures have to walk the irq descriptors to
547 * setup the vector space for the cpu which comes online.
548 * Prevent irq alloc/free across the bringup.
549 */
550 irq_lock_sparse();
551
Thomas Gleixnerba997462016-02-26 18:43:24 +0000552 /* Arch-specific enabling code. */
553 ret = __cpu_up(cpu, idle);
Boris Ostrovskyaa877172016-08-03 13:22:28 -0400554 irq_unlock_sparse();
Thomas Gleixnerba997462016-02-26 18:43:24 +0000555 if (ret) {
556 cpu_notify(CPU_UP_CANCELED, cpu);
557 return ret;
558 }
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +0200559 return bringup_wait_for_ap(cpu);
Thomas Gleixnerba997462016-02-26 18:43:24 +0000560}
561
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000562/*
563 * Hotplug state machine related functions
564 */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200565static void undo_cpu_down(unsigned int cpu, struct cpuhp_cpu_state *st)
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000566{
567 for (st->state++; st->state < st->target; st->state++) {
Thomas Gleixnera7246322016-08-12 19:49:38 +0200568 struct cpuhp_step *step = cpuhp_get_step(st->state);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000569
570 if (!step->skip_onerr)
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200571 cpuhp_invoke_callback(cpu, st->state, true, NULL);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000572 }
573}
574
575static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
Thomas Gleixnera7246322016-08-12 19:49:38 +0200576 enum cpuhp_state target)
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000577{
578 enum cpuhp_state prev_state = st->state;
579 int ret = 0;
580
581 for (; st->state > target; st->state--) {
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200582 ret = cpuhp_invoke_callback(cpu, st->state, false, NULL);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000583 if (ret) {
584 st->target = prev_state;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200585 undo_cpu_down(cpu, st);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000586 break;
587 }
588 }
589 return ret;
590}
591
Thomas Gleixnera7246322016-08-12 19:49:38 +0200592static void undo_cpu_up(unsigned int cpu, struct cpuhp_cpu_state *st)
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000593{
594 for (st->state--; st->state > st->target; st->state--) {
Thomas Gleixnera7246322016-08-12 19:49:38 +0200595 struct cpuhp_step *step = cpuhp_get_step(st->state);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000596
597 if (!step->skip_onerr)
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200598 cpuhp_invoke_callback(cpu, st->state, false, NULL);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000599 }
600}
601
Thomas Gleixnerce4fbb92019-03-26 17:36:05 +0100602static inline bool can_rollback_cpu(struct cpuhp_cpu_state *st)
603{
604 if (IS_ENABLED(CONFIG_HOTPLUG_CPU))
605 return true;
606 /*
607 * When CPU hotplug is disabled, then taking the CPU down is not
608 * possible because takedown_cpu() and the architecture and
609 * subsystem specific mechanisms are not available. So the CPU
610 * which would be completely unplugged again needs to stay around
611 * in the current state.
612 */
613 return st->state <= CPUHP_BRINGUP_CPU;
614}
615
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000616static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
Thomas Gleixnera7246322016-08-12 19:49:38 +0200617 enum cpuhp_state target)
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000618{
619 enum cpuhp_state prev_state = st->state;
620 int ret = 0;
621
622 while (st->state < target) {
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000623 st->state++;
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200624 ret = cpuhp_invoke_callback(cpu, st->state, true, NULL);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000625 if (ret) {
Thomas Gleixnerce4fbb92019-03-26 17:36:05 +0100626 if (can_rollback_cpu(st)) {
627 st->target = prev_state;
628 undo_cpu_up(cpu, st);
629 }
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000630 break;
631 }
632 }
633 return ret;
634}
635
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000636/*
637 * The cpu hotplug threads manage the bringup and teardown of the cpus
638 */
639static void cpuhp_create(unsigned int cpu)
640{
641 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
642
643 init_completion(&st->done);
644}
645
646static int cpuhp_should_run(unsigned int cpu)
647{
648 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
649
650 return st->should_run;
651}
652
653/* Execute the teardown callbacks. Used to be CPU_DOWN_PREPARE */
654static int cpuhp_ap_offline(unsigned int cpu, struct cpuhp_cpu_state *st)
655{
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000656 enum cpuhp_state target = max((int)st->target, CPUHP_TEARDOWN_CPU);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000657
Thomas Gleixnera7246322016-08-12 19:49:38 +0200658 return cpuhp_down_callbacks(cpu, st, target);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000659}
660
661/* Execute the online startup callbacks. Used to be CPU_ONLINE */
662static int cpuhp_ap_online(unsigned int cpu, struct cpuhp_cpu_state *st)
663{
Thomas Gleixnera7246322016-08-12 19:49:38 +0200664 return cpuhp_up_callbacks(cpu, st, st->target);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000665}
666
667/*
668 * Execute teardown/startup callbacks on the plugged cpu. Also used to invoke
669 * callbacks when a state gets [un]installed at runtime.
670 */
671static void cpuhp_thread_fun(unsigned int cpu)
672{
673 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
674 int ret = 0;
675
676 /*
677 * Paired with the mb() in cpuhp_kick_ap_work and
678 * cpuhp_invoke_ap_callback, so the work set is consistent visible.
679 */
680 smp_mb();
681 if (!st->should_run)
682 return;
683
684 st->should_run = false;
685
Thomas Gleixnerc198e222017-05-24 10:15:43 +0200686 lock_map_acquire(&cpuhp_state_lock_map);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000687 /* Single callback invocation for [un]install ? */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200688 if (st->single) {
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000689 if (st->cb_state < CPUHP_AP_ONLINE) {
690 local_irq_disable();
Thomas Gleixnera7246322016-08-12 19:49:38 +0200691 ret = cpuhp_invoke_callback(cpu, st->cb_state,
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200692 st->bringup, st->node);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000693 local_irq_enable();
694 } else {
Thomas Gleixnera7246322016-08-12 19:49:38 +0200695 ret = cpuhp_invoke_callback(cpu, st->cb_state,
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200696 st->bringup, st->node);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000697 }
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200698 } else if (st->rollback) {
699 BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE);
700
Thomas Gleixnera7246322016-08-12 19:49:38 +0200701 undo_cpu_down(cpu, st);
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200702 /*
703 * This is a momentary workaround to keep the notifier users
704 * happy. Will go away once we got rid of the notifiers.
705 */
706 cpu_notify_nofail(CPU_DOWN_FAILED, cpu);
707 st->rollback = false;
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000708 } else {
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000709 /* Cannot happen .... */
Thomas Gleixner8df3e072016-02-26 18:43:41 +0000710 BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000711
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000712 /* Regular hotplug work */
713 if (st->state < st->target)
714 ret = cpuhp_ap_online(cpu, st);
715 else if (st->state > st->target)
716 ret = cpuhp_ap_offline(cpu, st);
717 }
Thomas Gleixnerc198e222017-05-24 10:15:43 +0200718 lock_map_release(&cpuhp_state_lock_map);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000719 st->result = ret;
720 complete(&st->done);
721}
722
723/* Invoke a single callback on a remote cpu */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200724static int
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200725cpuhp_invoke_ap_callback(int cpu, enum cpuhp_state state, bool bringup,
726 struct hlist_node *node)
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000727{
728 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
729
730 if (!cpu_online(cpu))
731 return 0;
732
Thomas Gleixnerc198e222017-05-24 10:15:43 +0200733 lock_map_acquire(&cpuhp_state_lock_map);
734 lock_map_release(&cpuhp_state_lock_map);
735
Thomas Gleixner6a4e2452016-07-13 17:16:03 +0000736 /*
737 * If we are up and running, use the hotplug thread. For early calls
738 * we invoke the thread function directly.
739 */
740 if (!st->thread)
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200741 return cpuhp_invoke_callback(cpu, state, bringup, node);
Thomas Gleixner6a4e2452016-07-13 17:16:03 +0000742
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000743 st->cb_state = state;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200744 st->single = true;
745 st->bringup = bringup;
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200746 st->node = node;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200747
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000748 /*
749 * Make sure the above stores are visible before should_run becomes
750 * true. Paired with the mb() above in cpuhp_thread_fun()
751 */
752 smp_mb();
753 st->should_run = true;
754 wake_up_process(st->thread);
755 wait_for_completion(&st->done);
756 return st->result;
757}
758
759/* Regular hotplug invocation of the AP hotplug thread */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000760static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st)
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000761{
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000762 st->result = 0;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200763 st->single = false;
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000764 /*
765 * Make sure the above stores are visible before should_run becomes
766 * true. Paired with the mb() above in cpuhp_thread_fun()
767 */
768 smp_mb();
769 st->should_run = true;
770 wake_up_process(st->thread);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000771}
772
773static int cpuhp_kick_ap_work(unsigned int cpu)
774{
775 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
776 enum cpuhp_state state = st->state;
777
778 trace_cpuhp_enter(cpu, st->target, state, cpuhp_kick_ap_work);
Thomas Gleixnerc198e222017-05-24 10:15:43 +0200779 lock_map_acquire(&cpuhp_state_lock_map);
780 lock_map_release(&cpuhp_state_lock_map);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000781 __cpuhp_kick_ap_work(st);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000782 wait_for_completion(&st->done);
783 trace_cpuhp_exit(cpu, st->state, state, st->result);
784 return st->result;
785}
786
787static struct smp_hotplug_thread cpuhp_threads = {
788 .store = &cpuhp_state.thread,
789 .create = &cpuhp_create,
790 .thread_should_run = cpuhp_should_run,
791 .thread_fn = cpuhp_thread_fun,
792 .thread_comm = "cpuhp/%u",
793 .selfparking = true,
794};
795
796void __init cpuhp_threads_init(void)
797{
798 BUG_ON(smpboot_register_percpu_thread(&cpuhp_threads));
799 kthread_unpark(this_cpu_read(cpuhp_state.thread));
800}
801
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802EXPORT_SYMBOL(register_cpu_notifier);
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530803EXPORT_SYMBOL(__register_cpu_notifier);
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200804void unregister_cpu_notifier(struct notifier_block *nb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805{
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100806 cpu_maps_update_begin();
Neil Brownbd5349c2006-10-17 00:10:35 -0700807 raw_notifier_chain_unregister(&cpu_chain, nb);
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100808 cpu_maps_update_done();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809}
810EXPORT_SYMBOL(unregister_cpu_notifier);
811
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200812void __unregister_cpu_notifier(struct notifier_block *nb)
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530813{
814 raw_notifier_chain_unregister(&cpu_chain, nb);
815}
816EXPORT_SYMBOL(__unregister_cpu_notifier);
817
Michal Hocko56eaecc2016-12-07 14:54:38 +0100818#ifdef CONFIG_HOTPLUG_CPU
Anton Vorontsove4cc2f82012-05-31 16:26:26 -0700819/**
820 * clear_tasks_mm_cpumask - Safely clear tasks' mm_cpumask for a CPU
821 * @cpu: a CPU id
822 *
823 * This function walks all processes, finds a valid mm struct for each one and
824 * then clears a corresponding bit in mm's cpumask. While this all sounds
825 * trivial, there are various non-obvious corner cases, which this function
826 * tries to solve in a safe manner.
827 *
828 * Also note that the function uses a somewhat relaxed locking scheme, so it may
829 * be called only for an already offlined CPU.
830 */
Anton Vorontsovcb792952012-05-31 16:26:22 -0700831void clear_tasks_mm_cpumask(int cpu)
832{
833 struct task_struct *p;
834
835 /*
836 * This function is called after the cpu is taken down and marked
837 * offline, so its not like new tasks will ever get this cpu set in
838 * their mm mask. -- Peter Zijlstra
839 * Thus, we may use rcu_read_lock() here, instead of grabbing
840 * full-fledged tasklist_lock.
841 */
Anton Vorontsove4cc2f82012-05-31 16:26:26 -0700842 WARN_ON(cpu_online(cpu));
Anton Vorontsovcb792952012-05-31 16:26:22 -0700843 rcu_read_lock();
844 for_each_process(p) {
845 struct task_struct *t;
846
Anton Vorontsove4cc2f82012-05-31 16:26:26 -0700847 /*
848 * Main thread might exit, but other threads may still have
849 * a valid mm. Find one.
850 */
Anton Vorontsovcb792952012-05-31 16:26:22 -0700851 t = find_lock_task_mm(p);
852 if (!t)
853 continue;
854 cpumask_clear_cpu(cpu, mm_cpumask(t->mm));
855 task_unlock(t);
856 }
857 rcu_read_unlock();
858}
859
Kirill Tkhaib728ca02014-06-25 12:19:55 +0400860static inline void check_for_tasks(int dead_cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861{
Kirill Tkhaib728ca02014-06-25 12:19:55 +0400862 struct task_struct *g, *p;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863
Oleg Nesterova75a6062015-09-10 15:07:50 +0200864 read_lock(&tasklist_lock);
865 for_each_process_thread(g, p) {
Kirill Tkhaib728ca02014-06-25 12:19:55 +0400866 if (!p->on_rq)
867 continue;
868 /*
869 * We do the check with unlocked task_rq(p)->lock.
870 * Order the reading to do not warn about a task,
871 * which was running on this cpu in the past, and
872 * it's just been woken on another cpu.
873 */
874 rmb();
875 if (task_cpu(p) != dead_cpu)
876 continue;
877
878 pr_warn("Task %s (pid=%d) is on cpu %d (state=%ld, flags=%x)\n",
879 p->comm, task_pid_nr(p), dead_cpu, p->state, p->flags);
Oleg Nesterova75a6062015-09-10 15:07:50 +0200880 }
881 read_unlock(&tasklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882}
883
Thomas Gleixner98458172016-02-26 18:43:25 +0000884static int notify_down_prepare(unsigned int cpu)
885{
886 int err, nr_calls = 0;
887
888 err = __cpu_notify(CPU_DOWN_PREPARE, cpu, -1, &nr_calls);
889 if (err) {
890 nr_calls--;
891 __cpu_notify(CPU_DOWN_FAILED, cpu, nr_calls, NULL);
892 pr_warn("%s: attempt to take down CPU %u failed\n",
893 __func__, cpu);
894 }
895 return err;
896}
897
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898/* Take this CPU down. */
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200899static int take_cpu_down(void *_param)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900{
Thomas Gleixner4baa0af2016-02-26 18:43:29 +0000901 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
902 enum cpuhp_state target = max((int)st->target, CPUHP_AP_OFFLINE);
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000903 int err, cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 /* Ensure this CPU doesn't handle any more interrupts. */
906 err = __cpu_disable();
907 if (err < 0)
Zwane Mwaikambof3705132005-06-25 14:54:50 -0700908 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909
Thomas Gleixnera7246322016-08-12 19:49:38 +0200910 /*
911 * We get here while we are in CPUHP_TEARDOWN_CPU state and we must not
912 * do this step again.
913 */
914 WARN_ON(st->state != CPUHP_TEARDOWN_CPU);
915 st->state--;
Thomas Gleixner4baa0af2016-02-26 18:43:29 +0000916 /* Invoke the former CPU_DYING callbacks */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200917 for (; st->state > target; st->state--)
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200918 cpuhp_invoke_callback(cpu, st->state, false, NULL);
Thomas Gleixner4baa0af2016-02-26 18:43:29 +0000919
Thomas Gleixner52c063d2015-04-03 02:37:24 +0200920 /* Give up timekeeping duties */
921 tick_handover_do_timer();
Thomas Gleixner14e568e2013-01-31 12:11:14 +0000922 /* Park the stopper thread */
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000923 stop_machine_park(cpu);
Zwane Mwaikambof3705132005-06-25 14:54:50 -0700924 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925}
926
Thomas Gleixner98458172016-02-26 18:43:25 +0000927static int takedown_cpu(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928{
Thomas Gleixnere69aab12016-02-26 18:43:43 +0000929 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
Thomas Gleixner98458172016-02-26 18:43:25 +0000930 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
Thomas Gleixner2a58c522016-03-10 20:42:08 +0100932 /* Park the smpboot threads */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000933 kthread_park(per_cpu_ptr(&cpuhp_state, cpu)->thread);
934
Peter Zijlstra6acce3e2013-10-11 14:38:20 +0200935 /*
Thomas Gleixnera8994182015-07-05 17:12:30 +0000936 * Prevent irq alloc/free while the dying cpu reorganizes the
937 * interrupt affinities.
938 */
939 irq_lock_sparse();
940
941 /*
Peter Zijlstra6acce3e2013-10-11 14:38:20 +0200942 * So now all preempt/rcu users must observe !cpu_active().
943 */
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000944 err = stop_machine(take_cpu_down, NULL, cpumask_of(cpu));
Rusty Russell04321582008-07-28 12:16:29 -0500945 if (err) {
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200946 /* CPU refused to die */
Thomas Gleixnera8994182015-07-05 17:12:30 +0000947 irq_unlock_sparse();
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200948 /* Unpark the hotplug thread so we can rollback there */
949 kthread_unpark(per_cpu_ptr(&cpuhp_state, cpu)->thread);
Thomas Gleixner98458172016-02-26 18:43:25 +0000950 return err;
Satoru Takeuchi8fa1d7d2006-10-28 10:38:57 -0700951 }
Rusty Russell04321582008-07-28 12:16:29 -0500952 BUG_ON(cpu_online(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953
Peter Zijlstra48c5cca2010-11-13 19:32:29 +0100954 /*
Thomas Gleixneree1e7142016-08-18 14:57:16 +0200955 * The CPUHP_AP_SCHED_MIGRATE_DYING callback will have removed all
Peter Zijlstra48c5cca2010-11-13 19:32:29 +0100956 * runnable tasks from the cpu, there's only the idle task left now
957 * that the migration thread is done doing the stop_machine thing.
Peter Zijlstra51a96c72010-11-19 20:37:53 +0100958 *
959 * Wait for the stop thread to go away.
Peter Zijlstra48c5cca2010-11-13 19:32:29 +0100960 */
Thomas Gleixnere69aab12016-02-26 18:43:43 +0000961 wait_for_completion(&st->done);
962 BUG_ON(st->state != CPUHP_AP_IDLE_DEAD);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963
Thomas Gleixnera8994182015-07-05 17:12:30 +0000964 /* Interrupts are moved away from the dying cpu, reenable alloc/free */
965 irq_unlock_sparse();
966
Preeti U Murthy345527b2015-03-30 14:59:19 +0530967 hotplug_cpu__broadcast_tick_pull(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968 /* This actually kills the CPU. */
969 __cpu_die(cpu);
970
Thomas Gleixnera49b1162015-04-03 02:38:05 +0200971 tick_cleanup_dead_cpu(cpu);
Thomas Gleixner98458172016-02-26 18:43:25 +0000972 return 0;
973}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974
Thomas Gleixner98458172016-02-26 18:43:25 +0000975static int notify_dead(unsigned int cpu)
976{
977 cpu_notify_nofail(CPU_DEAD, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 check_for_tasks(cpu);
Thomas Gleixner98458172016-02-26 18:43:25 +0000979 return 0;
980}
981
Thomas Gleixner71f87b22016-03-03 10:52:10 +0100982static void cpuhp_complete_idle_dead(void *arg)
983{
984 struct cpuhp_cpu_state *st = arg;
985
986 complete(&st->done);
987}
988
Thomas Gleixnere69aab12016-02-26 18:43:43 +0000989void cpuhp_report_idle_dead(void)
990{
991 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
992
993 BUG_ON(st->state != CPUHP_AP_OFFLINE);
Thomas Gleixner27d50c72016-02-26 18:43:44 +0000994 rcu_report_dead(smp_processor_id());
Thomas Gleixner71f87b22016-03-03 10:52:10 +0100995 st->state = CPUHP_AP_IDLE_DEAD;
996 /*
997 * We cannot call complete after rcu_report_dead() so we delegate it
998 * to an online cpu.
999 */
1000 smp_call_function_single(cpumask_first(cpu_online_mask),
1001 cpuhp_complete_idle_dead, st, 0);
Thomas Gleixnere69aab12016-02-26 18:43:43 +00001002}
1003
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001004#else
1005#define notify_down_prepare NULL
1006#define takedown_cpu NULL
1007#define notify_dead NULL
1008#endif
1009
1010#ifdef CONFIG_HOTPLUG_CPU
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001011
Thomas Gleixner98458172016-02-26 18:43:25 +00001012/* Requires cpu_add_remove_lock to be held */
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001013static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,
1014 enum cpuhp_state target)
Thomas Gleixner98458172016-02-26 18:43:25 +00001015{
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001016 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1017 int prev_state, ret = 0;
1018 bool hasdied = false;
Thomas Gleixner98458172016-02-26 18:43:25 +00001019
1020 if (num_online_cpus() == 1)
1021 return -EBUSY;
1022
Thomas Gleixner757c9892016-02-26 18:43:32 +00001023 if (!cpu_present(cpu))
Thomas Gleixner98458172016-02-26 18:43:25 +00001024 return -EINVAL;
1025
1026 cpu_hotplug_begin();
1027
1028 cpuhp_tasks_frozen = tasks_frozen;
1029
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001030 prev_state = st->state;
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001031 st->target = target;
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001032 /*
1033 * If the current CPU state is in the range of the AP hotplug thread,
1034 * then we need to kick the thread.
1035 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001036 if (st->state > CPUHP_TEARDOWN_CPU) {
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001037 ret = cpuhp_kick_ap_work(cpu);
1038 /*
1039 * The AP side has done the error rollback already. Just
1040 * return the error code..
1041 */
1042 if (ret)
1043 goto out;
1044
1045 /*
1046 * We might have stopped still in the range of the AP hotplug
1047 * thread. Nothing to do anymore.
1048 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001049 if (st->state > CPUHP_TEARDOWN_CPU)
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001050 goto out;
1051 }
1052 /*
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001053 * The AP brought itself down to CPUHP_TEARDOWN_CPU. So we need
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001054 * to do the further cleanups.
1055 */
Thomas Gleixnera7246322016-08-12 19:49:38 +02001056 ret = cpuhp_down_callbacks(cpu, st, target);
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +02001057 if (ret && st->state > CPUHP_TEARDOWN_CPU && st->state < prev_state) {
1058 st->target = prev_state;
1059 st->rollback = true;
1060 cpuhp_kick_ap_work(cpu);
1061 }
Thomas Gleixner98458172016-02-26 18:43:25 +00001062
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001063 hasdied = prev_state != st->state && st->state == CPUHP_OFFLINE;
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001064out:
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001065 cpu_hotplug_done();
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001066 /* This post dead nonsense must die */
1067 if (!ret && hasdied)
Thomas Gleixner090e77c2016-02-26 18:43:23 +00001068 cpu_notify_nofail(CPU_POST_DEAD, cpu);
Thomas Gleixnera3c901b2018-11-25 19:33:39 +01001069 arch_smt_update();
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001070 return ret;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001071}
1072
Thomas Gleixner373b8de2018-05-29 17:49:05 +02001073static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target)
1074{
1075 if (cpu_hotplug_disabled)
1076 return -EBUSY;
1077 return _cpu_down(cpu, 0, target);
1078}
1079
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001080static int do_cpu_down(unsigned int cpu, enum cpuhp_state target)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001081{
Heiko Carstens9ea09af2008-12-22 12:36:30 +01001082 int err;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001083
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001084 cpu_maps_update_begin();
Thomas Gleixner373b8de2018-05-29 17:49:05 +02001085 err = cpu_down_maps_locked(cpu, target);
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001086 cpu_maps_update_done();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 return err;
1088}
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001089int cpu_down(unsigned int cpu)
1090{
1091 return do_cpu_down(cpu, CPUHP_OFFLINE);
1092}
Zhang Ruib62b8ef2008-04-29 02:35:56 -04001093EXPORT_SYMBOL(cpu_down);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094#endif /*CONFIG_HOTPLUG_CPU*/
1095
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001096/**
Thomas Gleixneree1e7142016-08-18 14:57:16 +02001097 * notify_cpu_starting(cpu) - Invoke the callbacks on the starting CPU
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001098 * @cpu: cpu that just started
1099 *
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001100 * It must be called by the arch code on the new cpu, before the new cpu
1101 * enables interrupts and before the "boot" cpu returns from __cpu_up().
1102 */
1103void notify_cpu_starting(unsigned int cpu)
1104{
1105 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1106 enum cpuhp_state target = min((int)st->target, CPUHP_AP_ONLINE);
1107
Sebastian Andrzej Siewior0c6d4572016-08-17 14:21:04 +02001108 rcu_cpu_starting(cpu); /* Enables RCU usage on this CPU. */
Thomas Gleixner8438e492018-06-29 16:05:48 +02001109 st->booted_once = true;
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001110 while (st->state < target) {
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001111 st->state++;
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001112 cpuhp_invoke_callback(cpu, st->state, true, NULL);
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001113 }
1114}
1115
Thomas Gleixner949338e2016-02-26 18:43:35 +00001116/*
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +02001117 * Called from the idle task. Wake up the controlling task which brings the
1118 * stopper and the hotplug thread of the upcoming CPU up and then delegates
1119 * the rest of the online bringup to the hotplug thread.
Thomas Gleixner949338e2016-02-26 18:43:35 +00001120 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001121void cpuhp_online_idle(enum cpuhp_state state)
Thomas Gleixner949338e2016-02-26 18:43:35 +00001122{
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001123 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001124
1125 /* Happens for the boot cpu */
1126 if (state != CPUHP_AP_ONLINE_IDLE)
1127 return;
1128
1129 st->state = CPUHP_AP_ONLINE_IDLE;
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +02001130 complete(&st->done);
Thomas Gleixner949338e2016-02-26 18:43:35 +00001131}
1132
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001133/* Requires cpu_add_remove_lock to be held */
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001134static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135{
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001136 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
Suresh Siddha3bb5d2e2012-04-20 17:08:50 -07001137 struct task_struct *idle;
Thomas Gleixner2e1a3482016-02-26 18:43:37 +00001138 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001140 cpu_hotplug_begin();
Thomas Gleixner38498a62012-04-20 13:05:44 +00001141
Thomas Gleixner757c9892016-02-26 18:43:32 +00001142 if (!cpu_present(cpu)) {
Yasuaki Ishimatsu5e5041f2012-10-23 01:30:54 +02001143 ret = -EINVAL;
1144 goto out;
1145 }
1146
Thomas Gleixner757c9892016-02-26 18:43:32 +00001147 /*
1148 * The caller of do_cpu_up might have raced with another
1149 * caller. Ignore it for now.
1150 */
1151 if (st->state >= target)
Thomas Gleixner38498a62012-04-20 13:05:44 +00001152 goto out;
Thomas Gleixner757c9892016-02-26 18:43:32 +00001153
1154 if (st->state == CPUHP_OFFLINE) {
1155 /* Let it fail before we try to bring the cpu up */
1156 idle = idle_thread_get(cpu);
1157 if (IS_ERR(idle)) {
1158 ret = PTR_ERR(idle);
1159 goto out;
1160 }
Suresh Siddha3bb5d2e2012-04-20 17:08:50 -07001161 }
Thomas Gleixner38498a62012-04-20 13:05:44 +00001162
Thomas Gleixnerba997462016-02-26 18:43:24 +00001163 cpuhp_tasks_frozen = tasks_frozen;
1164
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001165 st->target = target;
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001166 /*
1167 * If the current CPU state is in the range of the AP hotplug thread,
1168 * then we need to kick the thread once more.
1169 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001170 if (st->state > CPUHP_BRINGUP_CPU) {
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001171 ret = cpuhp_kick_ap_work(cpu);
1172 /*
1173 * The AP side has done the error rollback already. Just
1174 * return the error code..
1175 */
1176 if (ret)
1177 goto out;
1178 }
1179
1180 /*
1181 * Try to reach the target state. We max out on the BP at
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001182 * CPUHP_BRINGUP_CPU. After that the AP hotplug thread is
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001183 * responsible for bringing it up to the target state.
1184 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001185 target = min((int)target, CPUHP_BRINGUP_CPU);
Thomas Gleixnera7246322016-08-12 19:49:38 +02001186 ret = cpuhp_up_callbacks(cpu, st, target);
Thomas Gleixner38498a62012-04-20 13:05:44 +00001187out:
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001188 cpu_hotplug_done();
Thomas Gleixnera3c901b2018-11-25 19:33:39 +01001189 arch_smt_update();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 return ret;
1191}
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001192
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001193static int do_cpu_up(unsigned int cpu, enum cpuhp_state target)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001194{
1195 int err = 0;
minskey guocf234222010-05-24 14:32:41 -07001196
Rusty Russelle0b582e2009-01-01 10:12:28 +10301197 if (!cpu_possible(cpu)) {
Fabian Frederick84117da2014-06-04 16:11:17 -07001198 pr_err("can't online cpu %d because it is not configured as may-hotadd at boot time\n",
1199 cpu);
Chen Gong87d5e022010-03-05 13:42:38 -08001200#if defined(CONFIG_IA64)
Fabian Frederick84117da2014-06-04 16:11:17 -07001201 pr_err("please check additional_cpus= boot parameter\n");
KAMEZAWA Hiroyuki73e753a2007-10-18 23:40:47 -07001202#endif
1203 return -EINVAL;
1204 }
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001205
Toshi Kani01b0f192013-11-12 15:07:25 -08001206 err = try_online_node(cpu_to_node(cpu));
1207 if (err)
1208 return err;
minskey guocf234222010-05-24 14:32:41 -07001209
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001210 cpu_maps_update_begin();
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001211
Max Krasnyanskye761b772008-07-15 04:43:49 -07001212 if (cpu_hotplug_disabled) {
1213 err = -EBUSY;
1214 goto out;
1215 }
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02001216 if (!cpu_smt_allowed(cpu)) {
1217 err = -EPERM;
1218 goto out;
1219 }
Max Krasnyanskye761b772008-07-15 04:43:49 -07001220
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001221 err = _cpu_up(cpu, 0, target);
Max Krasnyanskye761b772008-07-15 04:43:49 -07001222out:
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001223 cpu_maps_update_done();
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001224 return err;
1225}
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001226
1227int cpu_up(unsigned int cpu)
1228{
1229 return do_cpu_up(cpu, CPUHP_ONLINE);
1230}
Paul E. McKenneya513f6b2011-12-11 21:54:45 -08001231EXPORT_SYMBOL_GPL(cpu_up);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001232
Rafael J. Wysockif3de4be2007-08-30 23:56:29 -07001233#ifdef CONFIG_PM_SLEEP_SMP
Rusty Russelle0b582e2009-01-01 10:12:28 +10301234static cpumask_var_t frozen_cpus;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001235
James Morsed391e552016-08-17 13:50:25 +01001236int freeze_secondary_cpus(int primary)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001237{
James Morsed391e552016-08-17 13:50:25 +01001238 int cpu, error = 0;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001239
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001240 cpu_maps_update_begin();
James Morsed391e552016-08-17 13:50:25 +01001241 if (!cpu_online(primary))
1242 primary = cpumask_first(cpu_online_mask);
Xiaotian Feng9ee349a2009-12-16 18:04:32 +01001243 /*
1244 * We take down all of the non-boot CPUs in one shot to avoid races
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001245 * with the userspace trying to use the CPU hotplug at the same time
1246 */
Rusty Russelle0b582e2009-01-01 10:12:28 +10301247 cpumask_clear(frozen_cpus);
Peter Zijlstra6ad4c182009-11-25 13:31:39 +01001248
Fabian Frederick84117da2014-06-04 16:11:17 -07001249 pr_info("Disabling non-boot CPUs ...\n");
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001250 for_each_online_cpu(cpu) {
James Morsed391e552016-08-17 13:50:25 +01001251 if (cpu == primary)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001252 continue;
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001253 trace_suspend_resume(TPS("CPU_OFF"), cpu, true);
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001254 error = _cpu_down(cpu, 1, CPUHP_OFFLINE);
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001255 trace_suspend_resume(TPS("CPU_OFF"), cpu, false);
Mike Travisfeae3202009-11-17 18:22:13 -06001256 if (!error)
Rusty Russelle0b582e2009-01-01 10:12:28 +10301257 cpumask_set_cpu(cpu, frozen_cpus);
Mike Travisfeae3202009-11-17 18:22:13 -06001258 else {
Fabian Frederick84117da2014-06-04 16:11:17 -07001259 pr_err("Error taking CPU%d down: %d\n", cpu, error);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001260 break;
1261 }
1262 }
Joseph Cihula86886e52009-06-30 19:31:07 -07001263
Vitaly Kuznetsov89af7ba2015-08-05 00:52:46 -07001264 if (!error)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001265 BUG_ON(num_online_cpus() > 1);
Vitaly Kuznetsov89af7ba2015-08-05 00:52:46 -07001266 else
Fabian Frederick84117da2014-06-04 16:11:17 -07001267 pr_err("Non-boot CPUs are not disabled\n");
Vitaly Kuznetsov89af7ba2015-08-05 00:52:46 -07001268
1269 /*
1270 * Make sure the CPUs won't be enabled by someone else. We need to do
1271 * this even in case of failure as all disable_nonboot_cpus() users are
1272 * supposed to do enable_nonboot_cpus() on the failure path.
1273 */
1274 cpu_hotplug_disabled++;
1275
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001276 cpu_maps_update_done();
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001277 return error;
1278}
1279
Suresh Siddhad0af9ee2009-08-19 18:05:36 -07001280void __weak arch_enable_nonboot_cpus_begin(void)
1281{
1282}
1283
1284void __weak arch_enable_nonboot_cpus_end(void)
1285{
1286}
1287
Mathias Krause71cf5ae2015-07-19 20:06:22 +02001288void enable_nonboot_cpus(void)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001289{
1290 int cpu, error;
1291
1292 /* Allow everyone to use the CPU hotplug again */
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001293 cpu_maps_update_begin();
Lianwei Wang01b41152016-06-09 23:43:28 -07001294 __cpu_hotplug_enable();
Rusty Russelle0b582e2009-01-01 10:12:28 +10301295 if (cpumask_empty(frozen_cpus))
Rafael J. Wysocki1d64b9c2007-04-01 23:49:49 -07001296 goto out;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001297
Fabian Frederick84117da2014-06-04 16:11:17 -07001298 pr_info("Enabling non-boot CPUs ...\n");
Suresh Siddhad0af9ee2009-08-19 18:05:36 -07001299
1300 arch_enable_nonboot_cpus_begin();
1301
Rusty Russelle0b582e2009-01-01 10:12:28 +10301302 for_each_cpu(cpu, frozen_cpus) {
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001303 trace_suspend_resume(TPS("CPU_ON"), cpu, true);
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001304 error = _cpu_up(cpu, 1, CPUHP_ONLINE);
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001305 trace_suspend_resume(TPS("CPU_ON"), cpu, false);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001306 if (!error) {
Fabian Frederick84117da2014-06-04 16:11:17 -07001307 pr_info("CPU%d is up\n", cpu);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001308 continue;
1309 }
Fabian Frederick84117da2014-06-04 16:11:17 -07001310 pr_warn("Error taking CPU%d up: %d\n", cpu, error);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001311 }
Suresh Siddhad0af9ee2009-08-19 18:05:36 -07001312
1313 arch_enable_nonboot_cpus_end();
1314
Rusty Russelle0b582e2009-01-01 10:12:28 +10301315 cpumask_clear(frozen_cpus);
Rafael J. Wysocki1d64b9c2007-04-01 23:49:49 -07001316out:
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001317 cpu_maps_update_done();
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001318}
Rusty Russelle0b582e2009-01-01 10:12:28 +10301319
Fenghua Yud7268a32011-11-15 21:59:31 +01001320static int __init alloc_frozen_cpus(void)
Rusty Russelle0b582e2009-01-01 10:12:28 +10301321{
1322 if (!alloc_cpumask_var(&frozen_cpus, GFP_KERNEL|__GFP_ZERO))
1323 return -ENOMEM;
1324 return 0;
1325}
1326core_initcall(alloc_frozen_cpus);
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001327
1328/*
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001329 * When callbacks for CPU hotplug notifications are being executed, we must
1330 * ensure that the state of the system with respect to the tasks being frozen
1331 * or not, as reported by the notification, remains unchanged *throughout the
1332 * duration* of the execution of the callbacks.
1333 * Hence we need to prevent the freezer from racing with regular CPU hotplug.
1334 *
1335 * This synchronization is implemented by mutually excluding regular CPU
1336 * hotplug and Suspend/Hibernate call paths by hooking onto the Suspend/
1337 * Hibernate notifications.
1338 */
1339static int
1340cpu_hotplug_pm_callback(struct notifier_block *nb,
1341 unsigned long action, void *ptr)
1342{
1343 switch (action) {
1344
1345 case PM_SUSPEND_PREPARE:
1346 case PM_HIBERNATION_PREPARE:
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -07001347 cpu_hotplug_disable();
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001348 break;
1349
1350 case PM_POST_SUSPEND:
1351 case PM_POST_HIBERNATION:
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -07001352 cpu_hotplug_enable();
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001353 break;
1354
1355 default:
1356 return NOTIFY_DONE;
1357 }
1358
1359 return NOTIFY_OK;
1360}
1361
1362
Fenghua Yud7268a32011-11-15 21:59:31 +01001363static int __init cpu_hotplug_pm_sync_init(void)
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001364{
Fenghua Yu6e32d472012-11-13 11:32:43 -08001365 /*
1366 * cpu_hotplug_pm_callback has higher priority than x86
1367 * bsp_pm_callback which depends on cpu_hotplug_pm_callback
1368 * to disable cpu hotplug to avoid cpu hotplug race.
1369 */
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001370 pm_notifier(cpu_hotplug_pm_callback, 0);
1371 return 0;
1372}
1373core_initcall(cpu_hotplug_pm_sync_init);
1374
Rafael J. Wysockif3de4be2007-08-30 23:56:29 -07001375#endif /* CONFIG_PM_SLEEP_SMP */
Max Krasnyansky68f4f1e2008-05-29 11:17:02 -07001376
1377#endif /* CONFIG_SMP */
Mike Travisb8d317d2008-07-24 18:21:29 -07001378
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001379/* Boot processor state steps */
1380static struct cpuhp_step cpuhp_bp_states[] = {
1381 [CPUHP_OFFLINE] = {
1382 .name = "offline",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001383 .startup.single = NULL,
1384 .teardown.single = NULL,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001385 },
1386#ifdef CONFIG_SMP
1387 [CPUHP_CREATE_THREADS]= {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001388 .name = "threads:prepare",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001389 .startup.single = smpboot_create_threads,
1390 .teardown.single = NULL,
Thomas Gleixner757c9892016-02-26 18:43:32 +00001391 .cant_stop = true,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001392 },
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001393 [CPUHP_PERF_PREPARE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001394 .name = "perf:prepare",
1395 .startup.single = perf_event_init_cpu,
1396 .teardown.single = perf_event_exit_cpu,
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001397 },
Thomas Gleixner7ee681b2016-07-13 17:16:29 +00001398 [CPUHP_WORKQUEUE_PREP] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001399 .name = "workqueue:prepare",
1400 .startup.single = workqueue_prepare_cpu,
1401 .teardown.single = NULL,
Thomas Gleixner7ee681b2016-07-13 17:16:29 +00001402 },
Thomas Gleixner27590dc2016-07-15 10:41:04 +02001403 [CPUHP_HRTIMERS_PREPARE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001404 .name = "hrtimers:prepare",
1405 .startup.single = hrtimers_prepare_cpu,
1406 .teardown.single = hrtimers_dead_cpu,
Thomas Gleixner27590dc2016-07-15 10:41:04 +02001407 },
Richard Weinberger31487f82016-07-13 17:17:01 +00001408 [CPUHP_SMPCFD_PREPARE] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001409 .name = "smpcfd:prepare",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001410 .startup.single = smpcfd_prepare_cpu,
1411 .teardown.single = smpcfd_dead_cpu,
Richard Weinberger31487f82016-07-13 17:17:01 +00001412 },
Richard Weinbergere6d49892016-08-18 14:57:17 +02001413 [CPUHP_RELAY_PREPARE] = {
1414 .name = "relay:prepare",
1415 .startup.single = relay_prepare_cpu,
1416 .teardown.single = NULL,
1417 },
Sebastian Andrzej Siewior6731d4f2016-08-23 14:53:19 +02001418 [CPUHP_SLAB_PREPARE] = {
1419 .name = "slab:prepare",
1420 .startup.single = slab_prepare_cpu,
1421 .teardown.single = slab_dead_cpu,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001422 },
Thomas Gleixner4df83742016-07-13 17:17:03 +00001423 [CPUHP_RCUTREE_PREP] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001424 .name = "RCU/tree:prepare",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001425 .startup.single = rcutree_prepare_cpu,
1426 .teardown.single = rcutree_dead_cpu,
Thomas Gleixner4df83742016-07-13 17:17:03 +00001427 },
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001428 /*
1429 * Preparatory and dead notifiers. Will be replaced once the notifiers
1430 * are converted to states.
1431 */
1432 [CPUHP_NOTIFY_PREPARE] = {
1433 .name = "notify:prepare",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001434 .startup.single = notify_prepare,
1435 .teardown.single = notify_dead,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001436 .skip_onerr = true,
Thomas Gleixner757c9892016-02-26 18:43:32 +00001437 .cant_stop = true,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001438 },
Richard Cochran4fae16d2016-07-27 11:08:18 +02001439 /*
1440 * On the tear-down path, timers_dead_cpu() must be invoked
1441 * before blk_mq_queue_reinit_notify() from notify_dead(),
1442 * otherwise a RCU stall occurs.
1443 */
Thomas Gleixner249d4a92017-12-27 21:37:25 +01001444 [CPUHP_TIMERS_PREPARE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001445 .name = "timers:dead",
Thomas Gleixner249d4a92017-12-27 21:37:25 +01001446 .startup.single = timers_prepare_cpu,
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001447 .teardown.single = timers_dead_cpu,
Richard Cochran4fae16d2016-07-27 11:08:18 +02001448 },
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001449 /* Kicks the plugged cpu into life */
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001450 [CPUHP_BRINGUP_CPU] = {
1451 .name = "cpu:bringup",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001452 .startup.single = bringup_cpu,
1453 .teardown.single = NULL,
Thomas Gleixner757c9892016-02-26 18:43:32 +00001454 .cant_stop = true,
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001455 },
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001456 /*
1457 * Handled on controll processor until the plugged processor manages
1458 * this itself.
1459 */
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001460 [CPUHP_TEARDOWN_CPU] = {
1461 .name = "cpu:teardown",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001462 .startup.single = NULL,
1463 .teardown.single = takedown_cpu,
Thomas Gleixner757c9892016-02-26 18:43:32 +00001464 .cant_stop = true,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001465 },
Thomas Gleixnera7c734142016-07-12 21:59:23 +02001466#else
1467 [CPUHP_BRINGUP_CPU] = { },
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001468#endif
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001469};
1470
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001471/* Application processor state steps */
1472static struct cpuhp_step cpuhp_ap_states[] = {
1473#ifdef CONFIG_SMP
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001474 /* Final state before CPU kills itself */
1475 [CPUHP_AP_IDLE_DEAD] = {
1476 .name = "idle:dead",
1477 },
1478 /*
1479 * Last state before CPU enters the idle loop to die. Transient state
1480 * for synchronization.
1481 */
1482 [CPUHP_AP_OFFLINE] = {
1483 .name = "ap:offline",
1484 .cant_stop = true,
1485 },
Thomas Gleixner9cf72432016-03-10 12:54:09 +01001486 /* First state is scheduler control. Interrupts are disabled */
1487 [CPUHP_AP_SCHED_STARTING] = {
1488 .name = "sched:starting",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001489 .startup.single = sched_cpu_starting,
1490 .teardown.single = sched_cpu_dying,
Thomas Gleixner9cf72432016-03-10 12:54:09 +01001491 },
Thomas Gleixner4df83742016-07-13 17:17:03 +00001492 [CPUHP_AP_RCUTREE_DYING] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001493 .name = "RCU/tree:dying",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001494 .startup.single = NULL,
1495 .teardown.single = rcutree_dying_cpu,
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001496 },
Lai Jiangshanff3d4fd2017-11-28 21:19:53 +08001497 [CPUHP_AP_SMPCFD_DYING] = {
1498 .name = "smpcfd:dying",
1499 .startup.single = NULL,
1500 .teardown.single = smpcfd_dying_cpu,
1501 },
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001502 /* Entry state on starting. Interrupts enabled from here on. Transient
1503 * state for synchronsization */
1504 [CPUHP_AP_ONLINE] = {
1505 .name = "ap:online",
1506 },
1507 /* Handle smpboot threads park/unpark */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001508 [CPUHP_AP_SMPBOOT_THREADS] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001509 .name = "smpboot/threads:online",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001510 .startup.single = smpboot_unpark_threads,
Thomas Gleixner93335752018-05-29 19:05:25 +02001511 .teardown.single = smpboot_park_threads,
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001512 },
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001513 [CPUHP_AP_PERF_ONLINE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001514 .name = "perf:online",
1515 .startup.single = perf_event_init_cpu,
1516 .teardown.single = perf_event_exit_cpu,
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001517 },
Thomas Gleixner7ee681b2016-07-13 17:16:29 +00001518 [CPUHP_AP_WORKQUEUE_ONLINE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001519 .name = "workqueue:online",
1520 .startup.single = workqueue_online_cpu,
1521 .teardown.single = workqueue_offline_cpu,
Thomas Gleixner7ee681b2016-07-13 17:16:29 +00001522 },
Thomas Gleixner4df83742016-07-13 17:17:03 +00001523 [CPUHP_AP_RCUTREE_ONLINE] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001524 .name = "RCU/tree:online",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001525 .startup.single = rcutree_online_cpu,
1526 .teardown.single = rcutree_offline_cpu,
Thomas Gleixner4df83742016-07-13 17:17:03 +00001527 },
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001528
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001529 /*
1530 * Online/down_prepare notifiers. Will be removed once the notifiers
1531 * are converted to states.
1532 */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001533 [CPUHP_AP_NOTIFY_ONLINE] = {
1534 .name = "notify:online",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001535 .startup.single = notify_online,
1536 .teardown.single = notify_down_prepare,
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +02001537 .skip_onerr = true,
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001538 },
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001539#endif
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001540 /*
1541 * The dynamically registered state space is here
1542 */
1543
Thomas Gleixneraaddd7d2016-03-10 12:54:19 +01001544#ifdef CONFIG_SMP
1545 /* Last state is scheduler control setting the cpu active */
1546 [CPUHP_AP_ACTIVE] = {
1547 .name = "sched:active",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001548 .startup.single = sched_cpu_activate,
1549 .teardown.single = sched_cpu_deactivate,
Thomas Gleixneraaddd7d2016-03-10 12:54:19 +01001550 },
1551#endif
1552
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001553 /* CPU is fully up and running. */
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001554 [CPUHP_ONLINE] = {
1555 .name = "online",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001556 .startup.single = NULL,
1557 .teardown.single = NULL,
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001558 },
1559};
1560
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001561/* Sanity check for callbacks */
1562static int cpuhp_cb_check(enum cpuhp_state state)
1563{
1564 if (state <= CPUHP_OFFLINE || state >= CPUHP_ONLINE)
1565 return -EINVAL;
1566 return 0;
1567}
1568
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001569static void cpuhp_store_callbacks(enum cpuhp_state state,
1570 const char *name,
1571 int (*startup)(unsigned int cpu),
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001572 int (*teardown)(unsigned int cpu),
1573 bool multi_instance)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001574{
1575 /* (Un)Install the callbacks for further cpu hotplug operations */
1576 struct cpuhp_step *sp;
1577
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001578 sp = cpuhp_get_step(state);
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001579 sp->startup.single = startup;
1580 sp->teardown.single = teardown;
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001581 sp->name = name;
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001582 sp->multi_instance = multi_instance;
1583 INIT_HLIST_HEAD(&sp->list);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001584}
1585
1586static void *cpuhp_get_teardown_cb(enum cpuhp_state state)
1587{
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001588 return cpuhp_get_step(state)->teardown.single;
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001589}
1590
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001591/*
1592 * Call the startup/teardown function for a step either on the AP or
1593 * on the current CPU.
1594 */
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001595static int cpuhp_issue_call(int cpu, enum cpuhp_state state, bool bringup,
1596 struct hlist_node *node)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001597{
Thomas Gleixnera7246322016-08-12 19:49:38 +02001598 struct cpuhp_step *sp = cpuhp_get_step(state);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001599 int ret;
1600
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001601 if ((bringup && !sp->startup.single) ||
1602 (!bringup && !sp->teardown.single))
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001603 return 0;
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001604 /*
1605 * The non AP bound callbacks can fail on bringup. On teardown
1606 * e.g. module removal we crash for now.
1607 */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001608#ifdef CONFIG_SMP
1609 if (cpuhp_is_ap_state(state))
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001610 ret = cpuhp_invoke_ap_callback(cpu, state, bringup, node);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001611 else
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001612 ret = cpuhp_invoke_callback(cpu, state, bringup, node);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001613#else
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001614 ret = cpuhp_invoke_callback(cpu, state, bringup, node);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001615#endif
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001616 BUG_ON(ret && !bringup);
1617 return ret;
1618}
1619
1620/*
1621 * Called from __cpuhp_setup_state on a recoverable failure.
1622 *
1623 * Note: The teardown callbacks for rollback are not allowed to fail!
1624 */
1625static void cpuhp_rollback_install(int failedcpu, enum cpuhp_state state,
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001626 struct hlist_node *node)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001627{
1628 int cpu;
1629
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001630 /* Roll back the already executed steps on the other cpus */
1631 for_each_present_cpu(cpu) {
1632 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1633 int cpustate = st->state;
1634
1635 if (cpu >= failedcpu)
1636 break;
1637
1638 /* Did we invoke the startup call on that cpu ? */
1639 if (cpustate >= state)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001640 cpuhp_issue_call(cpu, state, false, node);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001641 }
1642}
1643
1644/*
1645 * Returns a free for dynamic slot assignment of the Online state. The states
1646 * are protected by the cpuhp_slot_states mutex and an empty slot is identified
1647 * by having no name assigned.
1648 */
1649static int cpuhp_reserve_state(enum cpuhp_state state)
1650{
1651 enum cpuhp_state i;
1652
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001653 for (i = CPUHP_AP_ONLINE_DYN; i <= CPUHP_AP_ONLINE_DYN_END; i++) {
1654 if (cpuhp_ap_states[i].name)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001655 continue;
1656
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001657 cpuhp_ap_states[i].name = "Reserved";
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001658 return i;
1659 }
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001660 WARN(1, "No more dynamic states available for CPU hotplug\n");
1661 return -ENOSPC;
1662}
1663
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001664int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node,
1665 bool invoke)
1666{
1667 struct cpuhp_step *sp;
1668 int cpu;
1669 int ret;
1670
1671 sp = cpuhp_get_step(state);
1672 if (sp->multi_instance == false)
1673 return -EINVAL;
1674
1675 get_online_cpus();
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001676 mutex_lock(&cpuhp_state_mutex);
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001677
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001678 if (!invoke || !sp->startup.multi)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001679 goto add_node;
1680
1681 /*
1682 * Try to call the startup callback for each present cpu
1683 * depending on the hotplug state of the cpu.
1684 */
1685 for_each_present_cpu(cpu) {
1686 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1687 int cpustate = st->state;
1688
1689 if (cpustate < state)
1690 continue;
1691
1692 ret = cpuhp_issue_call(cpu, state, true, node);
1693 if (ret) {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001694 if (sp->teardown.multi)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001695 cpuhp_rollback_install(cpu, state, node);
1696 goto err;
1697 }
1698 }
1699add_node:
1700 ret = 0;
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001701 hlist_add_head(node, &sp->list);
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001702
1703err:
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001704 mutex_unlock(&cpuhp_state_mutex);
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001705 put_online_cpus();
1706 return ret;
1707}
1708EXPORT_SYMBOL_GPL(__cpuhp_state_add_instance);
1709
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001710/**
1711 * __cpuhp_setup_state - Setup the callbacks for an hotplug machine state
1712 * @state: The state to setup
1713 * @invoke: If true, the startup function is invoked for cpus where
1714 * cpu state >= @state
1715 * @startup: startup callback function
1716 * @teardown: teardown callback function
1717 *
1718 * Returns 0 if successful, otherwise a proper error code
1719 */
1720int __cpuhp_setup_state(enum cpuhp_state state,
1721 const char *name, bool invoke,
1722 int (*startup)(unsigned int cpu),
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001723 int (*teardown)(unsigned int cpu),
1724 bool multi_instance)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001725{
1726 int cpu, ret = 0;
1727 int dyn_state = 0;
1728
1729 if (cpuhp_cb_check(state) || !name)
1730 return -EINVAL;
1731
1732 get_online_cpus();
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001733 mutex_lock(&cpuhp_state_mutex);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001734
1735 /* currently assignments for the ONLINE state are possible */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001736 if (state == CPUHP_AP_ONLINE_DYN) {
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001737 dyn_state = 1;
1738 ret = cpuhp_reserve_state(state);
1739 if (ret < 0)
1740 goto out;
1741 state = ret;
1742 }
1743
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001744 cpuhp_store_callbacks(state, name, startup, teardown, multi_instance);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001745
1746 if (!invoke || !startup)
1747 goto out;
1748
1749 /*
1750 * Try to call the startup callback for each present cpu
1751 * depending on the hotplug state of the cpu.
1752 */
1753 for_each_present_cpu(cpu) {
1754 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1755 int cpustate = st->state;
1756
1757 if (cpustate < state)
1758 continue;
1759
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001760 ret = cpuhp_issue_call(cpu, state, true, NULL);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001761 if (ret) {
Thomas Gleixnera7246322016-08-12 19:49:38 +02001762 if (teardown)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001763 cpuhp_rollback_install(cpu, state, NULL);
1764 cpuhp_store_callbacks(state, NULL, NULL, NULL, false);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001765 goto out;
1766 }
1767 }
1768out:
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001769 mutex_unlock(&cpuhp_state_mutex);
1770
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001771 put_online_cpus();
1772 if (!ret && dyn_state)
1773 return state;
1774 return ret;
1775}
1776EXPORT_SYMBOL(__cpuhp_setup_state);
1777
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001778int __cpuhp_state_remove_instance(enum cpuhp_state state,
1779 struct hlist_node *node, bool invoke)
1780{
1781 struct cpuhp_step *sp = cpuhp_get_step(state);
1782 int cpu;
1783
1784 BUG_ON(cpuhp_cb_check(state));
1785
1786 if (!sp->multi_instance)
1787 return -EINVAL;
1788
1789 get_online_cpus();
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001790 mutex_lock(&cpuhp_state_mutex);
1791
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001792 if (!invoke || !cpuhp_get_teardown_cb(state))
1793 goto remove;
1794 /*
1795 * Call the teardown callback for each present cpu depending
1796 * on the hotplug state of the cpu. This function is not
1797 * allowed to fail currently!
1798 */
1799 for_each_present_cpu(cpu) {
1800 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1801 int cpustate = st->state;
1802
1803 if (cpustate >= state)
1804 cpuhp_issue_call(cpu, state, false, node);
1805 }
1806
1807remove:
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001808 hlist_del(node);
1809 mutex_unlock(&cpuhp_state_mutex);
1810 put_online_cpus();
1811
1812 return 0;
1813}
1814EXPORT_SYMBOL_GPL(__cpuhp_state_remove_instance);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001815/**
1816 * __cpuhp_remove_state - Remove the callbacks for an hotplug machine state
1817 * @state: The state to remove
1818 * @invoke: If true, the teardown function is invoked for cpus where
1819 * cpu state >= @state
1820 *
1821 * The teardown callback is currently not allowed to fail. Think
1822 * about module removal!
1823 */
1824void __cpuhp_remove_state(enum cpuhp_state state, bool invoke)
1825{
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001826 struct cpuhp_step *sp = cpuhp_get_step(state);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001827 int cpu;
1828
1829 BUG_ON(cpuhp_cb_check(state));
1830
1831 get_online_cpus();
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001832 mutex_lock(&cpuhp_state_mutex);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001833
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001834 if (sp->multi_instance) {
1835 WARN(!hlist_empty(&sp->list),
1836 "Error: Removing state %d which has instances left.\n",
1837 state);
1838 goto remove;
1839 }
1840
Thomas Gleixnera7246322016-08-12 19:49:38 +02001841 if (!invoke || !cpuhp_get_teardown_cb(state))
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001842 goto remove;
1843
1844 /*
1845 * Call the teardown callback for each present cpu depending
1846 * on the hotplug state of the cpu. This function is not
1847 * allowed to fail currently!
1848 */
1849 for_each_present_cpu(cpu) {
1850 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1851 int cpustate = st->state;
1852
1853 if (cpustate >= state)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001854 cpuhp_issue_call(cpu, state, false, NULL);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001855 }
1856remove:
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001857 cpuhp_store_callbacks(state, NULL, NULL, NULL, false);
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001858 mutex_unlock(&cpuhp_state_mutex);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001859 put_online_cpus();
1860}
1861EXPORT_SYMBOL(__cpuhp_remove_state);
1862
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00001863#if defined(CONFIG_SYSFS) && defined(CONFIG_HOTPLUG_CPU)
1864static ssize_t show_cpuhp_state(struct device *dev,
1865 struct device_attribute *attr, char *buf)
1866{
1867 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
1868
1869 return sprintf(buf, "%d\n", st->state);
1870}
1871static DEVICE_ATTR(state, 0444, show_cpuhp_state, NULL);
1872
Thomas Gleixner757c9892016-02-26 18:43:32 +00001873static ssize_t write_cpuhp_target(struct device *dev,
1874 struct device_attribute *attr,
1875 const char *buf, size_t count)
1876{
1877 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
1878 struct cpuhp_step *sp;
1879 int target, ret;
1880
1881 ret = kstrtoint(buf, 10, &target);
1882 if (ret)
1883 return ret;
1884
1885#ifdef CONFIG_CPU_HOTPLUG_STATE_CONTROL
1886 if (target < CPUHP_OFFLINE || target > CPUHP_ONLINE)
1887 return -EINVAL;
1888#else
1889 if (target != CPUHP_OFFLINE && target != CPUHP_ONLINE)
1890 return -EINVAL;
1891#endif
1892
1893 ret = lock_device_hotplug_sysfs();
1894 if (ret)
1895 return ret;
1896
1897 mutex_lock(&cpuhp_state_mutex);
1898 sp = cpuhp_get_step(target);
1899 ret = !sp->name || sp->cant_stop ? -EINVAL : 0;
1900 mutex_unlock(&cpuhp_state_mutex);
1901 if (ret)
Sebastian Andrzej Siewior106c77e2017-06-02 16:27:14 +02001902 goto out;
Thomas Gleixner757c9892016-02-26 18:43:32 +00001903
1904 if (st->state < target)
1905 ret = do_cpu_up(dev->id, target);
1906 else
1907 ret = do_cpu_down(dev->id, target);
Sebastian Andrzej Siewior106c77e2017-06-02 16:27:14 +02001908out:
Thomas Gleixner757c9892016-02-26 18:43:32 +00001909 unlock_device_hotplug();
1910 return ret ? ret : count;
1911}
1912
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00001913static ssize_t show_cpuhp_target(struct device *dev,
1914 struct device_attribute *attr, char *buf)
1915{
1916 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
1917
1918 return sprintf(buf, "%d\n", st->target);
1919}
Thomas Gleixner757c9892016-02-26 18:43:32 +00001920static DEVICE_ATTR(target, 0644, show_cpuhp_target, write_cpuhp_target);
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00001921
1922static struct attribute *cpuhp_cpu_attrs[] = {
1923 &dev_attr_state.attr,
1924 &dev_attr_target.attr,
1925 NULL
1926};
1927
1928static struct attribute_group cpuhp_cpu_attr_group = {
1929 .attrs = cpuhp_cpu_attrs,
1930 .name = "hotplug",
1931 NULL
1932};
1933
1934static ssize_t show_cpuhp_states(struct device *dev,
1935 struct device_attribute *attr, char *buf)
1936{
1937 ssize_t cur, res = 0;
1938 int i;
1939
1940 mutex_lock(&cpuhp_state_mutex);
Thomas Gleixner757c9892016-02-26 18:43:32 +00001941 for (i = CPUHP_OFFLINE; i <= CPUHP_ONLINE; i++) {
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00001942 struct cpuhp_step *sp = cpuhp_get_step(i);
1943
1944 if (sp->name) {
1945 cur = sprintf(buf, "%3d: %s\n", i, sp->name);
1946 buf += cur;
1947 res += cur;
1948 }
1949 }
1950 mutex_unlock(&cpuhp_state_mutex);
1951 return res;
1952}
1953static DEVICE_ATTR(states, 0444, show_cpuhp_states, NULL);
1954
1955static struct attribute *cpuhp_cpu_root_attrs[] = {
1956 &dev_attr_states.attr,
1957 NULL
1958};
1959
1960static struct attribute_group cpuhp_cpu_root_attr_group = {
1961 .attrs = cpuhp_cpu_root_attrs,
1962 .name = "hotplug",
1963 NULL
1964};
1965
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02001966#ifdef CONFIG_HOTPLUG_SMT
1967
1968static const char *smt_states[] = {
1969 [CPU_SMT_ENABLED] = "on",
1970 [CPU_SMT_DISABLED] = "off",
1971 [CPU_SMT_FORCE_DISABLED] = "forceoff",
1972 [CPU_SMT_NOT_SUPPORTED] = "notsupported",
1973};
1974
1975static ssize_t
1976show_smt_control(struct device *dev, struct device_attribute *attr, char *buf)
1977{
1978 return snprintf(buf, PAGE_SIZE - 2, "%s\n", smt_states[cpu_smt_control]);
1979}
1980
1981static void cpuhp_offline_cpu_device(unsigned int cpu)
1982{
1983 struct device *dev = get_cpu_device(cpu);
1984
1985 dev->offline = true;
1986 /* Tell user space about the state change */
1987 kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
1988}
1989
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02001990static void cpuhp_online_cpu_device(unsigned int cpu)
1991{
1992 struct device *dev = get_cpu_device(cpu);
1993
1994 dev->offline = false;
1995 /* Tell user space about the state change */
1996 kobject_uevent(&dev->kobj, KOBJ_ONLINE);
1997}
1998
Jiri Kosina5bdc5362019-05-30 00:09:39 +02001999int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002000{
2001 int cpu, ret = 0;
2002
2003 cpu_maps_update_begin();
2004 for_each_online_cpu(cpu) {
2005 if (topology_is_primary_thread(cpu))
2006 continue;
2007 ret = cpu_down_maps_locked(cpu, CPUHP_OFFLINE);
2008 if (ret)
2009 break;
2010 /*
2011 * As this needs to hold the cpu maps lock it's impossible
2012 * to call device_offline() because that ends up calling
2013 * cpu_down() which takes cpu maps lock. cpu maps lock
2014 * needs to be held as this might race against in kernel
2015 * abusers of the hotplug machinery (thermal management).
2016 *
2017 * So nothing would update device:offline state. That would
2018 * leave the sysfs entry stale and prevent onlining after
2019 * smt control has been changed to 'off' again. This is
2020 * called under the sysfs hotplug lock, so it is properly
2021 * serialized against the regular offline usage.
2022 */
2023 cpuhp_offline_cpu_device(cpu);
2024 }
Jiri Kosinab410c572018-09-25 14:38:55 +02002025 if (!ret) {
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002026 cpu_smt_control = ctrlval;
Jiri Kosinab410c572018-09-25 14:38:55 +02002027 arch_smt_update();
2028 }
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002029 cpu_maps_update_done();
2030 return ret;
2031}
2032
Jiri Kosina5bdc5362019-05-30 00:09:39 +02002033int cpuhp_smt_enable(void)
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002034{
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002035 int cpu, ret = 0;
2036
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002037 cpu_maps_update_begin();
2038 cpu_smt_control = CPU_SMT_ENABLED;
Jiri Kosinab410c572018-09-25 14:38:55 +02002039 arch_smt_update();
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002040 for_each_present_cpu(cpu) {
2041 /* Skip online CPUs and CPUs on offline nodes */
2042 if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
2043 continue;
2044 ret = _cpu_up(cpu, 0, CPUHP_ONLINE);
2045 if (ret)
2046 break;
2047 /* See comment in cpuhp_smt_disable() */
2048 cpuhp_online_cpu_device(cpu);
2049 }
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002050 cpu_maps_update_done();
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002051 return ret;
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002052}
2053
2054static ssize_t
2055store_smt_control(struct device *dev, struct device_attribute *attr,
2056 const char *buf, size_t count)
2057{
2058 int ctrlval, ret;
2059
2060 if (sysfs_streq(buf, "on"))
2061 ctrlval = CPU_SMT_ENABLED;
2062 else if (sysfs_streq(buf, "off"))
2063 ctrlval = CPU_SMT_DISABLED;
2064 else if (sysfs_streq(buf, "forceoff"))
2065 ctrlval = CPU_SMT_FORCE_DISABLED;
2066 else
2067 return -EINVAL;
2068
2069 if (cpu_smt_control == CPU_SMT_FORCE_DISABLED)
2070 return -EPERM;
2071
2072 if (cpu_smt_control == CPU_SMT_NOT_SUPPORTED)
2073 return -ENODEV;
2074
2075 ret = lock_device_hotplug_sysfs();
2076 if (ret)
2077 return ret;
2078
2079 if (ctrlval != cpu_smt_control) {
2080 switch (ctrlval) {
2081 case CPU_SMT_ENABLED:
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002082 ret = cpuhp_smt_enable();
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002083 break;
2084 case CPU_SMT_DISABLED:
2085 case CPU_SMT_FORCE_DISABLED:
2086 ret = cpuhp_smt_disable(ctrlval);
2087 break;
2088 }
2089 }
2090
2091 unlock_device_hotplug();
2092 return ret ? ret : count;
2093}
2094static DEVICE_ATTR(control, 0644, show_smt_control, store_smt_control);
2095
2096static ssize_t
2097show_smt_active(struct device *dev, struct device_attribute *attr, char *buf)
2098{
2099 bool active = topology_max_smt_threads() > 1;
2100
2101 return snprintf(buf, PAGE_SIZE - 2, "%d\n", active);
2102}
2103static DEVICE_ATTR(active, 0444, show_smt_active, NULL);
2104
2105static struct attribute *cpuhp_smt_attrs[] = {
2106 &dev_attr_control.attr,
2107 &dev_attr_active.attr,
2108 NULL
2109};
2110
2111static const struct attribute_group cpuhp_smt_attr_group = {
2112 .attrs = cpuhp_smt_attrs,
2113 .name = "smt",
2114 NULL
2115};
2116
2117static int __init cpu_smt_state_init(void)
2118{
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002119 return sysfs_create_group(&cpu_subsys.dev_root->kobj,
2120 &cpuhp_smt_attr_group);
2121}
2122
2123#else
2124static inline int cpu_smt_state_init(void) { return 0; }
2125#endif
2126
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00002127static int __init cpuhp_sysfs_init(void)
2128{
2129 int cpu, ret;
2130
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002131 ret = cpu_smt_state_init();
2132 if (ret)
2133 return ret;
2134
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00002135 ret = sysfs_create_group(&cpu_subsys.dev_root->kobj,
2136 &cpuhp_cpu_root_attr_group);
2137 if (ret)
2138 return ret;
2139
2140 for_each_possible_cpu(cpu) {
2141 struct device *dev = get_cpu_device(cpu);
2142
2143 if (!dev)
2144 continue;
2145 ret = sysfs_create_group(&dev->kobj, &cpuhp_cpu_attr_group);
2146 if (ret)
2147 return ret;
2148 }
2149 return 0;
2150}
2151device_initcall(cpuhp_sysfs_init);
2152#endif
2153
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002154/*
2155 * cpu_bit_bitmap[] is a special, "compressed" data structure that
2156 * represents all NR_CPUS bits binary values of 1<<nr.
2157 *
Rusty Russelle0b582e2009-01-01 10:12:28 +10302158 * It is used by cpumask_of() to get a constant address to a CPU
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002159 * mask value that has a single bit set only.
2160 */
Mike Travisb8d317d2008-07-24 18:21:29 -07002161
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002162/* cpu_bit_bitmap[0] is empty - so we can back into it */
Michael Rodriguez4d519852011-03-22 16:34:07 -07002163#define MASK_DECLARE_1(x) [x+1][0] = (1UL << (x))
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002164#define MASK_DECLARE_2(x) MASK_DECLARE_1(x), MASK_DECLARE_1(x+1)
2165#define MASK_DECLARE_4(x) MASK_DECLARE_2(x), MASK_DECLARE_2(x+2)
2166#define MASK_DECLARE_8(x) MASK_DECLARE_4(x), MASK_DECLARE_4(x+4)
Mike Travisb8d317d2008-07-24 18:21:29 -07002167
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002168const unsigned long cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)] = {
Mike Travisb8d317d2008-07-24 18:21:29 -07002169
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002170 MASK_DECLARE_8(0), MASK_DECLARE_8(8),
2171 MASK_DECLARE_8(16), MASK_DECLARE_8(24),
2172#if BITS_PER_LONG > 32
2173 MASK_DECLARE_8(32), MASK_DECLARE_8(40),
2174 MASK_DECLARE_8(48), MASK_DECLARE_8(56),
Mike Travisb8d317d2008-07-24 18:21:29 -07002175#endif
2176};
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002177EXPORT_SYMBOL_GPL(cpu_bit_bitmap);
Rusty Russell2d3854a2008-11-05 13:39:10 +11002178
2179const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL;
2180EXPORT_SYMBOL(cpu_all_bits);
Rusty Russellb3199c02008-12-30 09:05:14 +10302181
2182#ifdef CONFIG_INIT_ALL_POSSIBLE
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002183struct cpumask __cpu_possible_mask __read_mostly
Rasmus Villemoesc4c54dd2016-01-20 15:00:16 -08002184 = {CPU_BITS_ALL};
Rusty Russellb3199c02008-12-30 09:05:14 +10302185#else
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002186struct cpumask __cpu_possible_mask __read_mostly;
Rusty Russellb3199c02008-12-30 09:05:14 +10302187#endif
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002188EXPORT_SYMBOL(__cpu_possible_mask);
Rusty Russellb3199c02008-12-30 09:05:14 +10302189
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002190struct cpumask __cpu_online_mask __read_mostly;
2191EXPORT_SYMBOL(__cpu_online_mask);
Rusty Russellb3199c02008-12-30 09:05:14 +10302192
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002193struct cpumask __cpu_present_mask __read_mostly;
2194EXPORT_SYMBOL(__cpu_present_mask);
Rusty Russellb3199c02008-12-30 09:05:14 +10302195
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002196struct cpumask __cpu_active_mask __read_mostly;
2197EXPORT_SYMBOL(__cpu_active_mask);
Rusty Russell3fa41522008-12-30 09:05:16 +10302198
Rusty Russell3fa41522008-12-30 09:05:16 +10302199void init_cpu_present(const struct cpumask *src)
2200{
Rasmus Villemoesc4c54dd2016-01-20 15:00:16 -08002201 cpumask_copy(&__cpu_present_mask, src);
Rusty Russell3fa41522008-12-30 09:05:16 +10302202}
2203
2204void init_cpu_possible(const struct cpumask *src)
2205{
Rasmus Villemoesc4c54dd2016-01-20 15:00:16 -08002206 cpumask_copy(&__cpu_possible_mask, src);
Rusty Russell3fa41522008-12-30 09:05:16 +10302207}
2208
2209void init_cpu_online(const struct cpumask *src)
2210{
Rasmus Villemoesc4c54dd2016-01-20 15:00:16 -08002211 cpumask_copy(&__cpu_online_mask, src);
Rusty Russell3fa41522008-12-30 09:05:16 +10302212}
Thomas Gleixnercff7d372016-02-26 18:43:28 +00002213
2214/*
2215 * Activate the first processor.
2216 */
2217void __init boot_cpu_init(void)
2218{
2219 int cpu = smp_processor_id();
2220
2221 /* Mark the boot cpu "present", "online" etc for SMP and UP case */
2222 set_cpu_online(cpu, true);
2223 set_cpu_active(cpu, true);
2224 set_cpu_present(cpu, true);
2225 set_cpu_possible(cpu, true);
2226}
2227
2228/*
2229 * Must be called _AFTER_ setting up the per_cpu areas
2230 */
Linus Torvalds6bb53ee2018-08-12 12:19:42 -07002231void __init boot_cpu_hotplug_init(void)
Thomas Gleixnercff7d372016-02-26 18:43:28 +00002232{
Abel Vesaaee08612018-08-15 00:26:00 +03002233#ifdef CONFIG_SMP
Thomas Gleixner8438e492018-06-29 16:05:48 +02002234 this_cpu_write(cpuhp_state.booted_once, true);
Abel Vesaaee08612018-08-15 00:26:00 +03002235#endif
Thomas Gleixner8438e492018-06-29 16:05:48 +02002236 this_cpu_write(cpuhp_state.state, CPUHP_ONLINE);
Thomas Gleixnercff7d372016-02-26 18:43:28 +00002237}
Josh Poimboeufedda9c32019-04-12 15:39:28 -05002238
Tyler Hickse2bd0772019-11-04 12:22:02 +01002239/*
2240 * These are used for a global "mitigations=" cmdline option for toggling
2241 * optional CPU mitigations.
2242 */
2243enum cpu_mitigations {
2244 CPU_MITIGATIONS_OFF,
2245 CPU_MITIGATIONS_AUTO,
2246 CPU_MITIGATIONS_AUTO_NOSMT,
2247};
2248
2249static enum cpu_mitigations cpu_mitigations __ro_after_init =
2250 CPU_MITIGATIONS_AUTO;
Josh Poimboeufedda9c32019-04-12 15:39:28 -05002251
2252static int __init mitigations_parse_cmdline(char *arg)
2253{
2254 if (!strcmp(arg, "off"))
2255 cpu_mitigations = CPU_MITIGATIONS_OFF;
2256 else if (!strcmp(arg, "auto"))
2257 cpu_mitigations = CPU_MITIGATIONS_AUTO;
2258 else if (!strcmp(arg, "auto,nosmt"))
2259 cpu_mitigations = CPU_MITIGATIONS_AUTO_NOSMT;
Geert Uytterhoeven0cbb0ae2019-05-16 09:09:35 +02002260 else
2261 pr_crit("Unsupported mitigations=%s, system may still be vulnerable\n",
2262 arg);
Josh Poimboeufedda9c32019-04-12 15:39:28 -05002263
2264 return 0;
2265}
2266early_param("mitigations", mitigations_parse_cmdline);
Tyler Hickse2bd0772019-11-04 12:22:02 +01002267
2268/* mitigations=off */
2269bool cpu_mitigations_off(void)
2270{
2271 return cpu_mitigations == CPU_MITIGATIONS_OFF;
2272}
2273EXPORT_SYMBOL_GPL(cpu_mitigations_off);
2274
2275/* mitigations=auto,nosmt */
2276bool cpu_mitigations_auto_nosmt(void)
2277{
2278 return cpu_mitigations == CPU_MITIGATIONS_AUTO_NOSMT;
2279}
2280EXPORT_SYMBOL_GPL(cpu_mitigations_auto_nosmt);