blob: b0beef398ce16cb24ef330c25cd30d40402aee13 [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
Peter Zijlstraa594a9e2019-12-10 09:34:54 +0100518 /* Unpark the hotplug thread of the target cpu */
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +0200519 kthread_unpark(st->thread);
520
Thomas Gleixner8438e492018-06-29 16:05:48 +0200521 /*
522 * SMT soft disabling on X86 requires to bring the CPU out of the
523 * BIOS 'wait for SIPI' state in order to set the CR4.MCE bit. The
524 * CPU marked itself as booted_once in cpu_notify_starting() so the
525 * cpu_smt_allowed() check will now return false if this is not the
526 * primary sibling.
527 */
528 if (!cpu_smt_allowed(cpu))
529 return -ECANCELED;
530
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +0200531 /* Should we go further up ? */
532 if (st->target > CPUHP_AP_ONLINE_IDLE) {
533 __cpuhp_kick_ap_work(st);
534 wait_for_completion(&st->done);
535 }
Thomas Gleixner8df3e072016-02-26 18:43:41 +0000536 return st->result;
537}
538
Thomas Gleixnerba997462016-02-26 18:43:24 +0000539static int bringup_cpu(unsigned int cpu)
540{
541 struct task_struct *idle = idle_thread_get(cpu);
542 int ret;
543
Boris Ostrovskyaa877172016-08-03 13:22:28 -0400544 /*
545 * Some architectures have to walk the irq descriptors to
546 * setup the vector space for the cpu which comes online.
547 * Prevent irq alloc/free across the bringup.
548 */
549 irq_lock_sparse();
550
Thomas Gleixnerba997462016-02-26 18:43:24 +0000551 /* Arch-specific enabling code. */
552 ret = __cpu_up(cpu, idle);
Boris Ostrovskyaa877172016-08-03 13:22:28 -0400553 irq_unlock_sparse();
Thomas Gleixnerba997462016-02-26 18:43:24 +0000554 if (ret) {
555 cpu_notify(CPU_UP_CANCELED, cpu);
556 return ret;
557 }
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +0200558 return bringup_wait_for_ap(cpu);
Thomas Gleixnerba997462016-02-26 18:43:24 +0000559}
560
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000561/*
562 * Hotplug state machine related functions
563 */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200564static void undo_cpu_down(unsigned int cpu, struct cpuhp_cpu_state *st)
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000565{
566 for (st->state++; st->state < st->target; st->state++) {
Thomas Gleixnera7246322016-08-12 19:49:38 +0200567 struct cpuhp_step *step = cpuhp_get_step(st->state);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000568
569 if (!step->skip_onerr)
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200570 cpuhp_invoke_callback(cpu, st->state, true, NULL);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000571 }
572}
573
574static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
Thomas Gleixnera7246322016-08-12 19:49:38 +0200575 enum cpuhp_state target)
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000576{
577 enum cpuhp_state prev_state = st->state;
578 int ret = 0;
579
580 for (; st->state > target; st->state--) {
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200581 ret = cpuhp_invoke_callback(cpu, st->state, false, NULL);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000582 if (ret) {
583 st->target = prev_state;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200584 undo_cpu_down(cpu, st);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000585 break;
586 }
587 }
588 return ret;
589}
590
Thomas Gleixnera7246322016-08-12 19:49:38 +0200591static void undo_cpu_up(unsigned int cpu, struct cpuhp_cpu_state *st)
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000592{
593 for (st->state--; st->state > st->target; st->state--) {
Thomas Gleixnera7246322016-08-12 19:49:38 +0200594 struct cpuhp_step *step = cpuhp_get_step(st->state);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000595
596 if (!step->skip_onerr)
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200597 cpuhp_invoke_callback(cpu, st->state, false, NULL);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000598 }
599}
600
Thomas Gleixnerce4fbb92019-03-26 17:36:05 +0100601static inline bool can_rollback_cpu(struct cpuhp_cpu_state *st)
602{
603 if (IS_ENABLED(CONFIG_HOTPLUG_CPU))
604 return true;
605 /*
606 * When CPU hotplug is disabled, then taking the CPU down is not
607 * possible because takedown_cpu() and the architecture and
608 * subsystem specific mechanisms are not available. So the CPU
609 * which would be completely unplugged again needs to stay around
610 * in the current state.
611 */
612 return st->state <= CPUHP_BRINGUP_CPU;
613}
614
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000615static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
Thomas Gleixnera7246322016-08-12 19:49:38 +0200616 enum cpuhp_state target)
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000617{
618 enum cpuhp_state prev_state = st->state;
619 int ret = 0;
620
621 while (st->state < target) {
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000622 st->state++;
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200623 ret = cpuhp_invoke_callback(cpu, st->state, true, NULL);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000624 if (ret) {
Thomas Gleixnerce4fbb92019-03-26 17:36:05 +0100625 if (can_rollback_cpu(st)) {
626 st->target = prev_state;
627 undo_cpu_up(cpu, st);
628 }
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000629 break;
630 }
631 }
632 return ret;
633}
634
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000635/*
636 * The cpu hotplug threads manage the bringup and teardown of the cpus
637 */
638static void cpuhp_create(unsigned int cpu)
639{
640 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
641
642 init_completion(&st->done);
643}
644
645static int cpuhp_should_run(unsigned int cpu)
646{
647 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
648
649 return st->should_run;
650}
651
652/* Execute the teardown callbacks. Used to be CPU_DOWN_PREPARE */
653static int cpuhp_ap_offline(unsigned int cpu, struct cpuhp_cpu_state *st)
654{
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000655 enum cpuhp_state target = max((int)st->target, CPUHP_TEARDOWN_CPU);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000656
Thomas Gleixnera7246322016-08-12 19:49:38 +0200657 return cpuhp_down_callbacks(cpu, st, target);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000658}
659
660/* Execute the online startup callbacks. Used to be CPU_ONLINE */
661static int cpuhp_ap_online(unsigned int cpu, struct cpuhp_cpu_state *st)
662{
Thomas Gleixnera7246322016-08-12 19:49:38 +0200663 return cpuhp_up_callbacks(cpu, st, st->target);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000664}
665
666/*
667 * Execute teardown/startup callbacks on the plugged cpu. Also used to invoke
668 * callbacks when a state gets [un]installed at runtime.
669 */
670static void cpuhp_thread_fun(unsigned int cpu)
671{
672 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
673 int ret = 0;
674
675 /*
676 * Paired with the mb() in cpuhp_kick_ap_work and
677 * cpuhp_invoke_ap_callback, so the work set is consistent visible.
678 */
679 smp_mb();
680 if (!st->should_run)
681 return;
682
683 st->should_run = false;
684
Thomas Gleixnerc198e222017-05-24 10:15:43 +0200685 lock_map_acquire(&cpuhp_state_lock_map);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000686 /* Single callback invocation for [un]install ? */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200687 if (st->single) {
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000688 if (st->cb_state < CPUHP_AP_ONLINE) {
689 local_irq_disable();
Thomas Gleixnera7246322016-08-12 19:49:38 +0200690 ret = cpuhp_invoke_callback(cpu, st->cb_state,
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200691 st->bringup, st->node);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000692 local_irq_enable();
693 } else {
Thomas Gleixnera7246322016-08-12 19:49:38 +0200694 ret = cpuhp_invoke_callback(cpu, st->cb_state,
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200695 st->bringup, st->node);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000696 }
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200697 } else if (st->rollback) {
698 BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE);
699
Thomas Gleixnera7246322016-08-12 19:49:38 +0200700 undo_cpu_down(cpu, st);
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200701 /*
702 * This is a momentary workaround to keep the notifier users
703 * happy. Will go away once we got rid of the notifiers.
704 */
705 cpu_notify_nofail(CPU_DOWN_FAILED, cpu);
706 st->rollback = false;
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000707 } else {
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000708 /* Cannot happen .... */
Thomas Gleixner8df3e072016-02-26 18:43:41 +0000709 BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000710
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000711 /* Regular hotplug work */
712 if (st->state < st->target)
713 ret = cpuhp_ap_online(cpu, st);
714 else if (st->state > st->target)
715 ret = cpuhp_ap_offline(cpu, st);
716 }
Thomas Gleixnerc198e222017-05-24 10:15:43 +0200717 lock_map_release(&cpuhp_state_lock_map);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000718 st->result = ret;
719 complete(&st->done);
720}
721
722/* Invoke a single callback on a remote cpu */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200723static int
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200724cpuhp_invoke_ap_callback(int cpu, enum cpuhp_state state, bool bringup,
725 struct hlist_node *node)
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000726{
727 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
728
729 if (!cpu_online(cpu))
730 return 0;
731
Thomas Gleixnerc198e222017-05-24 10:15:43 +0200732 lock_map_acquire(&cpuhp_state_lock_map);
733 lock_map_release(&cpuhp_state_lock_map);
734
Thomas Gleixner6a4e2452016-07-13 17:16:03 +0000735 /*
736 * If we are up and running, use the hotplug thread. For early calls
737 * we invoke the thread function directly.
738 */
739 if (!st->thread)
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200740 return cpuhp_invoke_callback(cpu, state, bringup, node);
Thomas Gleixner6a4e2452016-07-13 17:16:03 +0000741
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000742 st->cb_state = state;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200743 st->single = true;
744 st->bringup = bringup;
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200745 st->node = node;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200746
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000747 /*
748 * Make sure the above stores are visible before should_run becomes
749 * true. Paired with the mb() above in cpuhp_thread_fun()
750 */
751 smp_mb();
752 st->should_run = true;
753 wake_up_process(st->thread);
754 wait_for_completion(&st->done);
755 return st->result;
756}
757
758/* Regular hotplug invocation of the AP hotplug thread */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000759static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st)
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000760{
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000761 st->result = 0;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200762 st->single = false;
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000763 /*
764 * Make sure the above stores are visible before should_run becomes
765 * true. Paired with the mb() above in cpuhp_thread_fun()
766 */
767 smp_mb();
768 st->should_run = true;
769 wake_up_process(st->thread);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000770}
771
772static int cpuhp_kick_ap_work(unsigned int cpu)
773{
774 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
775 enum cpuhp_state state = st->state;
776
777 trace_cpuhp_enter(cpu, st->target, state, cpuhp_kick_ap_work);
Thomas Gleixnerc198e222017-05-24 10:15:43 +0200778 lock_map_acquire(&cpuhp_state_lock_map);
779 lock_map_release(&cpuhp_state_lock_map);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000780 __cpuhp_kick_ap_work(st);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000781 wait_for_completion(&st->done);
782 trace_cpuhp_exit(cpu, st->state, state, st->result);
783 return st->result;
784}
785
786static struct smp_hotplug_thread cpuhp_threads = {
787 .store = &cpuhp_state.thread,
788 .create = &cpuhp_create,
789 .thread_should_run = cpuhp_should_run,
790 .thread_fn = cpuhp_thread_fun,
791 .thread_comm = "cpuhp/%u",
792 .selfparking = true,
793};
794
795void __init cpuhp_threads_init(void)
796{
797 BUG_ON(smpboot_register_percpu_thread(&cpuhp_threads));
798 kthread_unpark(this_cpu_read(cpuhp_state.thread));
799}
800
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801EXPORT_SYMBOL(register_cpu_notifier);
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530802EXPORT_SYMBOL(__register_cpu_notifier);
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200803void unregister_cpu_notifier(struct notifier_block *nb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804{
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100805 cpu_maps_update_begin();
Neil Brownbd5349c2006-10-17 00:10:35 -0700806 raw_notifier_chain_unregister(&cpu_chain, nb);
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100807 cpu_maps_update_done();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808}
809EXPORT_SYMBOL(unregister_cpu_notifier);
810
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200811void __unregister_cpu_notifier(struct notifier_block *nb)
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530812{
813 raw_notifier_chain_unregister(&cpu_chain, nb);
814}
815EXPORT_SYMBOL(__unregister_cpu_notifier);
816
Michal Hocko56eaecc2016-12-07 14:54:38 +0100817#ifdef CONFIG_HOTPLUG_CPU
Nicholas Pigginfe348032020-11-26 20:25:29 +1000818#ifndef arch_clear_mm_cpumask_cpu
819#define arch_clear_mm_cpumask_cpu(cpu, mm) cpumask_clear_cpu(cpu, mm_cpumask(mm))
820#endif
821
Anton Vorontsove4cc2f82012-05-31 16:26:26 -0700822/**
823 * clear_tasks_mm_cpumask - Safely clear tasks' mm_cpumask for a CPU
824 * @cpu: a CPU id
825 *
826 * This function walks all processes, finds a valid mm struct for each one and
827 * then clears a corresponding bit in mm's cpumask. While this all sounds
828 * trivial, there are various non-obvious corner cases, which this function
829 * tries to solve in a safe manner.
830 *
831 * Also note that the function uses a somewhat relaxed locking scheme, so it may
832 * be called only for an already offlined CPU.
833 */
Anton Vorontsovcb792952012-05-31 16:26:22 -0700834void clear_tasks_mm_cpumask(int cpu)
835{
836 struct task_struct *p;
837
838 /*
839 * This function is called after the cpu is taken down and marked
840 * offline, so its not like new tasks will ever get this cpu set in
841 * their mm mask. -- Peter Zijlstra
842 * Thus, we may use rcu_read_lock() here, instead of grabbing
843 * full-fledged tasklist_lock.
844 */
Anton Vorontsove4cc2f82012-05-31 16:26:26 -0700845 WARN_ON(cpu_online(cpu));
Anton Vorontsovcb792952012-05-31 16:26:22 -0700846 rcu_read_lock();
847 for_each_process(p) {
848 struct task_struct *t;
849
Anton Vorontsove4cc2f82012-05-31 16:26:26 -0700850 /*
851 * Main thread might exit, but other threads may still have
852 * a valid mm. Find one.
853 */
Anton Vorontsovcb792952012-05-31 16:26:22 -0700854 t = find_lock_task_mm(p);
855 if (!t)
856 continue;
Nicholas Pigginfe348032020-11-26 20:25:29 +1000857 arch_clear_mm_cpumask_cpu(cpu, t->mm);
Anton Vorontsovcb792952012-05-31 16:26:22 -0700858 task_unlock(t);
859 }
860 rcu_read_unlock();
861}
862
Kirill Tkhaib728ca02014-06-25 12:19:55 +0400863static inline void check_for_tasks(int dead_cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864{
Kirill Tkhaib728ca02014-06-25 12:19:55 +0400865 struct task_struct *g, *p;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866
Oleg Nesterova75a6062015-09-10 15:07:50 +0200867 read_lock(&tasklist_lock);
868 for_each_process_thread(g, p) {
Kirill Tkhaib728ca02014-06-25 12:19:55 +0400869 if (!p->on_rq)
870 continue;
871 /*
872 * We do the check with unlocked task_rq(p)->lock.
873 * Order the reading to do not warn about a task,
874 * which was running on this cpu in the past, and
875 * it's just been woken on another cpu.
876 */
877 rmb();
878 if (task_cpu(p) != dead_cpu)
879 continue;
880
881 pr_warn("Task %s (pid=%d) is on cpu %d (state=%ld, flags=%x)\n",
882 p->comm, task_pid_nr(p), dead_cpu, p->state, p->flags);
Oleg Nesterova75a6062015-09-10 15:07:50 +0200883 }
884 read_unlock(&tasklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885}
886
Thomas Gleixner98458172016-02-26 18:43:25 +0000887static int notify_down_prepare(unsigned int cpu)
888{
889 int err, nr_calls = 0;
890
891 err = __cpu_notify(CPU_DOWN_PREPARE, cpu, -1, &nr_calls);
892 if (err) {
893 nr_calls--;
894 __cpu_notify(CPU_DOWN_FAILED, cpu, nr_calls, NULL);
895 pr_warn("%s: attempt to take down CPU %u failed\n",
896 __func__, cpu);
897 }
898 return err;
899}
900
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901/* Take this CPU down. */
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200902static int take_cpu_down(void *_param)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903{
Thomas Gleixner4baa0af2016-02-26 18:43:29 +0000904 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
905 enum cpuhp_state target = max((int)st->target, CPUHP_AP_OFFLINE);
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000906 int err, cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 /* Ensure this CPU doesn't handle any more interrupts. */
909 err = __cpu_disable();
910 if (err < 0)
Zwane Mwaikambof3705132005-06-25 14:54:50 -0700911 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912
Thomas Gleixnera7246322016-08-12 19:49:38 +0200913 /*
914 * We get here while we are in CPUHP_TEARDOWN_CPU state and we must not
915 * do this step again.
916 */
917 WARN_ON(st->state != CPUHP_TEARDOWN_CPU);
918 st->state--;
Thomas Gleixner4baa0af2016-02-26 18:43:29 +0000919 /* Invoke the former CPU_DYING callbacks */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200920 for (; st->state > target; st->state--)
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200921 cpuhp_invoke_callback(cpu, st->state, false, NULL);
Thomas Gleixner4baa0af2016-02-26 18:43:29 +0000922
Thomas Gleixner52c063d2015-04-03 02:37:24 +0200923 /* Give up timekeeping duties */
924 tick_handover_do_timer();
Thomas Gleixner14e568e2013-01-31 12:11:14 +0000925 /* Park the stopper thread */
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000926 stop_machine_park(cpu);
Zwane Mwaikambof3705132005-06-25 14:54:50 -0700927 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928}
929
Thomas Gleixner98458172016-02-26 18:43:25 +0000930static int takedown_cpu(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931{
Thomas Gleixnere69aab12016-02-26 18:43:43 +0000932 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
Thomas Gleixner98458172016-02-26 18:43:25 +0000933 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934
Thomas Gleixner2a58c522016-03-10 20:42:08 +0100935 /* Park the smpboot threads */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000936 kthread_park(per_cpu_ptr(&cpuhp_state, cpu)->thread);
937
Peter Zijlstra6acce3e2013-10-11 14:38:20 +0200938 /*
Thomas Gleixnera8994182015-07-05 17:12:30 +0000939 * Prevent irq alloc/free while the dying cpu reorganizes the
940 * interrupt affinities.
941 */
942 irq_lock_sparse();
943
944 /*
Peter Zijlstra6acce3e2013-10-11 14:38:20 +0200945 * So now all preempt/rcu users must observe !cpu_active().
946 */
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000947 err = stop_machine(take_cpu_down, NULL, cpumask_of(cpu));
Rusty Russell04321582008-07-28 12:16:29 -0500948 if (err) {
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200949 /* CPU refused to die */
Thomas Gleixnera8994182015-07-05 17:12:30 +0000950 irq_unlock_sparse();
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200951 /* Unpark the hotplug thread so we can rollback there */
952 kthread_unpark(per_cpu_ptr(&cpuhp_state, cpu)->thread);
Thomas Gleixner98458172016-02-26 18:43:25 +0000953 return err;
Satoru Takeuchi8fa1d7d2006-10-28 10:38:57 -0700954 }
Rusty Russell04321582008-07-28 12:16:29 -0500955 BUG_ON(cpu_online(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956
Peter Zijlstra48c5cca2010-11-13 19:32:29 +0100957 /*
Thomas Gleixneree1e7142016-08-18 14:57:16 +0200958 * The CPUHP_AP_SCHED_MIGRATE_DYING callback will have removed all
Peter Zijlstra48c5cca2010-11-13 19:32:29 +0100959 * runnable tasks from the cpu, there's only the idle task left now
960 * that the migration thread is done doing the stop_machine thing.
Peter Zijlstra51a96c72010-11-19 20:37:53 +0100961 *
962 * Wait for the stop thread to go away.
Peter Zijlstra48c5cca2010-11-13 19:32:29 +0100963 */
Thomas Gleixnere69aab12016-02-26 18:43:43 +0000964 wait_for_completion(&st->done);
965 BUG_ON(st->state != CPUHP_AP_IDLE_DEAD);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966
Thomas Gleixnera8994182015-07-05 17:12:30 +0000967 /* Interrupts are moved away from the dying cpu, reenable alloc/free */
968 irq_unlock_sparse();
969
Preeti U Murthy345527b2015-03-30 14:59:19 +0530970 hotplug_cpu__broadcast_tick_pull(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 /* This actually kills the CPU. */
972 __cpu_die(cpu);
973
Thomas Gleixnera49b1162015-04-03 02:38:05 +0200974 tick_cleanup_dead_cpu(cpu);
Thomas Gleixner98458172016-02-26 18:43:25 +0000975 return 0;
976}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977
Thomas Gleixner98458172016-02-26 18:43:25 +0000978static int notify_dead(unsigned int cpu)
979{
980 cpu_notify_nofail(CPU_DEAD, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 check_for_tasks(cpu);
Thomas Gleixner98458172016-02-26 18:43:25 +0000982 return 0;
983}
984
Thomas Gleixner71f87b22016-03-03 10:52:10 +0100985static void cpuhp_complete_idle_dead(void *arg)
986{
987 struct cpuhp_cpu_state *st = arg;
988
989 complete(&st->done);
990}
991
Thomas Gleixnere69aab12016-02-26 18:43:43 +0000992void cpuhp_report_idle_dead(void)
993{
994 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
995
996 BUG_ON(st->state != CPUHP_AP_OFFLINE);
Thomas Gleixner27d50c72016-02-26 18:43:44 +0000997 rcu_report_dead(smp_processor_id());
Thomas Gleixner71f87b22016-03-03 10:52:10 +0100998 st->state = CPUHP_AP_IDLE_DEAD;
999 /*
1000 * We cannot call complete after rcu_report_dead() so we delegate it
1001 * to an online cpu.
1002 */
1003 smp_call_function_single(cpumask_first(cpu_online_mask),
1004 cpuhp_complete_idle_dead, st, 0);
Thomas Gleixnere69aab12016-02-26 18:43:43 +00001005}
1006
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001007#else
1008#define notify_down_prepare NULL
1009#define takedown_cpu NULL
1010#define notify_dead NULL
1011#endif
1012
1013#ifdef CONFIG_HOTPLUG_CPU
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001014
Thomas Gleixner98458172016-02-26 18:43:25 +00001015/* Requires cpu_add_remove_lock to be held */
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001016static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,
1017 enum cpuhp_state target)
Thomas Gleixner98458172016-02-26 18:43:25 +00001018{
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001019 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1020 int prev_state, ret = 0;
1021 bool hasdied = false;
Thomas Gleixner98458172016-02-26 18:43:25 +00001022
1023 if (num_online_cpus() == 1)
1024 return -EBUSY;
1025
Thomas Gleixner757c9892016-02-26 18:43:32 +00001026 if (!cpu_present(cpu))
Thomas Gleixner98458172016-02-26 18:43:25 +00001027 return -EINVAL;
1028
1029 cpu_hotplug_begin();
1030
1031 cpuhp_tasks_frozen = tasks_frozen;
1032
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001033 prev_state = st->state;
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001034 st->target = target;
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001035 /*
1036 * If the current CPU state is in the range of the AP hotplug thread,
1037 * then we need to kick the thread.
1038 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001039 if (st->state > CPUHP_TEARDOWN_CPU) {
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001040 ret = cpuhp_kick_ap_work(cpu);
1041 /*
1042 * The AP side has done the error rollback already. Just
1043 * return the error code..
1044 */
1045 if (ret)
1046 goto out;
1047
1048 /*
1049 * We might have stopped still in the range of the AP hotplug
1050 * thread. Nothing to do anymore.
1051 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001052 if (st->state > CPUHP_TEARDOWN_CPU)
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001053 goto out;
1054 }
1055 /*
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001056 * The AP brought itself down to CPUHP_TEARDOWN_CPU. So we need
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001057 * to do the further cleanups.
1058 */
Thomas Gleixnera7246322016-08-12 19:49:38 +02001059 ret = cpuhp_down_callbacks(cpu, st, target);
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +02001060 if (ret && st->state > CPUHP_TEARDOWN_CPU && st->state < prev_state) {
1061 st->target = prev_state;
1062 st->rollback = true;
1063 cpuhp_kick_ap_work(cpu);
1064 }
Thomas Gleixner98458172016-02-26 18:43:25 +00001065
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001066 hasdied = prev_state != st->state && st->state == CPUHP_OFFLINE;
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001067out:
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001068 cpu_hotplug_done();
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001069 /* This post dead nonsense must die */
1070 if (!ret && hasdied)
Thomas Gleixner090e77c2016-02-26 18:43:23 +00001071 cpu_notify_nofail(CPU_POST_DEAD, cpu);
Thomas Gleixnera3c901b2018-11-25 19:33:39 +01001072 arch_smt_update();
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001073 return ret;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001074}
1075
Thomas Gleixner373b8de2018-05-29 17:49:05 +02001076static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target)
1077{
1078 if (cpu_hotplug_disabled)
1079 return -EBUSY;
1080 return _cpu_down(cpu, 0, target);
1081}
1082
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001083static int do_cpu_down(unsigned int cpu, enum cpuhp_state target)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001084{
Heiko Carstens9ea09af2008-12-22 12:36:30 +01001085 int err;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001086
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001087 cpu_maps_update_begin();
Thomas Gleixner373b8de2018-05-29 17:49:05 +02001088 err = cpu_down_maps_locked(cpu, target);
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001089 cpu_maps_update_done();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 return err;
1091}
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001092int cpu_down(unsigned int cpu)
1093{
1094 return do_cpu_down(cpu, CPUHP_OFFLINE);
1095}
Zhang Ruib62b8ef2008-04-29 02:35:56 -04001096EXPORT_SYMBOL(cpu_down);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097#endif /*CONFIG_HOTPLUG_CPU*/
1098
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001099/**
Thomas Gleixneree1e7142016-08-18 14:57:16 +02001100 * notify_cpu_starting(cpu) - Invoke the callbacks on the starting CPU
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001101 * @cpu: cpu that just started
1102 *
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001103 * It must be called by the arch code on the new cpu, before the new cpu
1104 * enables interrupts and before the "boot" cpu returns from __cpu_up().
1105 */
1106void notify_cpu_starting(unsigned int cpu)
1107{
1108 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1109 enum cpuhp_state target = min((int)st->target, CPUHP_AP_ONLINE);
1110
Sebastian Andrzej Siewior0c6d4572016-08-17 14:21:04 +02001111 rcu_cpu_starting(cpu); /* Enables RCU usage on this CPU. */
Thomas Gleixner8438e492018-06-29 16:05:48 +02001112 st->booted_once = true;
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001113 while (st->state < target) {
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001114 st->state++;
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001115 cpuhp_invoke_callback(cpu, st->state, true, NULL);
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001116 }
1117}
1118
Thomas Gleixner949338e2016-02-26 18:43:35 +00001119/*
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +02001120 * Called from the idle task. Wake up the controlling task which brings the
Peter Zijlstraa594a9e2019-12-10 09:34:54 +01001121 * hotplug thread of the upcoming CPU up and then delegates the rest of the
1122 * online bringup to the hotplug thread.
Thomas Gleixner949338e2016-02-26 18:43:35 +00001123 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001124void cpuhp_online_idle(enum cpuhp_state state)
Thomas Gleixner949338e2016-02-26 18:43:35 +00001125{
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001126 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001127
1128 /* Happens for the boot cpu */
1129 if (state != CPUHP_AP_ONLINE_IDLE)
1130 return;
1131
Peter Zijlstraa594a9e2019-12-10 09:34:54 +01001132 /*
1133 * Unpart the stopper thread before we start the idle loop (and start
1134 * scheduling); this ensures the stopper task is always available.
1135 */
1136 stop_machine_unpark(smp_processor_id());
1137
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001138 st->state = CPUHP_AP_ONLINE_IDLE;
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +02001139 complete(&st->done);
Thomas Gleixner949338e2016-02-26 18:43:35 +00001140}
1141
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001142/* Requires cpu_add_remove_lock to be held */
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001143static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144{
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001145 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
Suresh Siddha3bb5d2e2012-04-20 17:08:50 -07001146 struct task_struct *idle;
Thomas Gleixner2e1a3482016-02-26 18:43:37 +00001147 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001149 cpu_hotplug_begin();
Thomas Gleixner38498a62012-04-20 13:05:44 +00001150
Thomas Gleixner757c9892016-02-26 18:43:32 +00001151 if (!cpu_present(cpu)) {
Yasuaki Ishimatsu5e5041f2012-10-23 01:30:54 +02001152 ret = -EINVAL;
1153 goto out;
1154 }
1155
Thomas Gleixner757c9892016-02-26 18:43:32 +00001156 /*
1157 * The caller of do_cpu_up might have raced with another
1158 * caller. Ignore it for now.
1159 */
1160 if (st->state >= target)
Thomas Gleixner38498a62012-04-20 13:05:44 +00001161 goto out;
Thomas Gleixner757c9892016-02-26 18:43:32 +00001162
1163 if (st->state == CPUHP_OFFLINE) {
1164 /* Let it fail before we try to bring the cpu up */
1165 idle = idle_thread_get(cpu);
1166 if (IS_ERR(idle)) {
1167 ret = PTR_ERR(idle);
1168 goto out;
1169 }
Suresh Siddha3bb5d2e2012-04-20 17:08:50 -07001170 }
Thomas Gleixner38498a62012-04-20 13:05:44 +00001171
Thomas Gleixnerba997462016-02-26 18:43:24 +00001172 cpuhp_tasks_frozen = tasks_frozen;
1173
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001174 st->target = target;
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001175 /*
1176 * If the current CPU state is in the range of the AP hotplug thread,
1177 * then we need to kick the thread once more.
1178 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001179 if (st->state > CPUHP_BRINGUP_CPU) {
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001180 ret = cpuhp_kick_ap_work(cpu);
1181 /*
1182 * The AP side has done the error rollback already. Just
1183 * return the error code..
1184 */
1185 if (ret)
1186 goto out;
1187 }
1188
1189 /*
1190 * Try to reach the target state. We max out on the BP at
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001191 * CPUHP_BRINGUP_CPU. After that the AP hotplug thread is
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001192 * responsible for bringing it up to the target state.
1193 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001194 target = min((int)target, CPUHP_BRINGUP_CPU);
Thomas Gleixnera7246322016-08-12 19:49:38 +02001195 ret = cpuhp_up_callbacks(cpu, st, target);
Thomas Gleixner38498a62012-04-20 13:05:44 +00001196out:
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001197 cpu_hotplug_done();
Thomas Gleixnera3c901b2018-11-25 19:33:39 +01001198 arch_smt_update();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199 return ret;
1200}
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001201
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001202static int do_cpu_up(unsigned int cpu, enum cpuhp_state target)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001203{
1204 int err = 0;
minskey guocf234222010-05-24 14:32:41 -07001205
Rusty Russelle0b582e2009-01-01 10:12:28 +10301206 if (!cpu_possible(cpu)) {
Fabian Frederick84117da2014-06-04 16:11:17 -07001207 pr_err("can't online cpu %d because it is not configured as may-hotadd at boot time\n",
1208 cpu);
Chen Gong87d5e022010-03-05 13:42:38 -08001209#if defined(CONFIG_IA64)
Fabian Frederick84117da2014-06-04 16:11:17 -07001210 pr_err("please check additional_cpus= boot parameter\n");
KAMEZAWA Hiroyuki73e753a2007-10-18 23:40:47 -07001211#endif
1212 return -EINVAL;
1213 }
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001214
Toshi Kani01b0f192013-11-12 15:07:25 -08001215 err = try_online_node(cpu_to_node(cpu));
1216 if (err)
1217 return err;
minskey guocf234222010-05-24 14:32:41 -07001218
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001219 cpu_maps_update_begin();
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001220
Max Krasnyanskye761b772008-07-15 04:43:49 -07001221 if (cpu_hotplug_disabled) {
1222 err = -EBUSY;
1223 goto out;
1224 }
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02001225 if (!cpu_smt_allowed(cpu)) {
1226 err = -EPERM;
1227 goto out;
1228 }
Max Krasnyanskye761b772008-07-15 04:43:49 -07001229
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001230 err = _cpu_up(cpu, 0, target);
Max Krasnyanskye761b772008-07-15 04:43:49 -07001231out:
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001232 cpu_maps_update_done();
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001233 return err;
1234}
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001235
1236int cpu_up(unsigned int cpu)
1237{
1238 return do_cpu_up(cpu, CPUHP_ONLINE);
1239}
Paul E. McKenneya513f6b2011-12-11 21:54:45 -08001240EXPORT_SYMBOL_GPL(cpu_up);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001241
Rafael J. Wysockif3de4be2007-08-30 23:56:29 -07001242#ifdef CONFIG_PM_SLEEP_SMP
Rusty Russelle0b582e2009-01-01 10:12:28 +10301243static cpumask_var_t frozen_cpus;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001244
James Morsed391e552016-08-17 13:50:25 +01001245int freeze_secondary_cpus(int primary)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001246{
James Morsed391e552016-08-17 13:50:25 +01001247 int cpu, error = 0;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001248
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001249 cpu_maps_update_begin();
James Morsed391e552016-08-17 13:50:25 +01001250 if (!cpu_online(primary))
1251 primary = cpumask_first(cpu_online_mask);
Xiaotian Feng9ee349a2009-12-16 18:04:32 +01001252 /*
1253 * We take down all of the non-boot CPUs in one shot to avoid races
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001254 * with the userspace trying to use the CPU hotplug at the same time
1255 */
Rusty Russelle0b582e2009-01-01 10:12:28 +10301256 cpumask_clear(frozen_cpus);
Peter Zijlstra6ad4c182009-11-25 13:31:39 +01001257
Fabian Frederick84117da2014-06-04 16:11:17 -07001258 pr_info("Disabling non-boot CPUs ...\n");
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001259 for_each_online_cpu(cpu) {
James Morsed391e552016-08-17 13:50:25 +01001260 if (cpu == primary)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001261 continue;
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001262 trace_suspend_resume(TPS("CPU_OFF"), cpu, true);
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001263 error = _cpu_down(cpu, 1, CPUHP_OFFLINE);
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001264 trace_suspend_resume(TPS("CPU_OFF"), cpu, false);
Mike Travisfeae3202009-11-17 18:22:13 -06001265 if (!error)
Rusty Russelle0b582e2009-01-01 10:12:28 +10301266 cpumask_set_cpu(cpu, frozen_cpus);
Mike Travisfeae3202009-11-17 18:22:13 -06001267 else {
Fabian Frederick84117da2014-06-04 16:11:17 -07001268 pr_err("Error taking CPU%d down: %d\n", cpu, error);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001269 break;
1270 }
1271 }
Joseph Cihula86886e52009-06-30 19:31:07 -07001272
Vitaly Kuznetsov89af7ba2015-08-05 00:52:46 -07001273 if (!error)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001274 BUG_ON(num_online_cpus() > 1);
Vitaly Kuznetsov89af7ba2015-08-05 00:52:46 -07001275 else
Fabian Frederick84117da2014-06-04 16:11:17 -07001276 pr_err("Non-boot CPUs are not disabled\n");
Vitaly Kuznetsov89af7ba2015-08-05 00:52:46 -07001277
1278 /*
1279 * Make sure the CPUs won't be enabled by someone else. We need to do
1280 * this even in case of failure as all disable_nonboot_cpus() users are
1281 * supposed to do enable_nonboot_cpus() on the failure path.
1282 */
1283 cpu_hotplug_disabled++;
1284
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001285 cpu_maps_update_done();
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001286 return error;
1287}
1288
Suresh Siddhad0af9ee2009-08-19 18:05:36 -07001289void __weak arch_enable_nonboot_cpus_begin(void)
1290{
1291}
1292
1293void __weak arch_enable_nonboot_cpus_end(void)
1294{
1295}
1296
Mathias Krause71cf5ae2015-07-19 20:06:22 +02001297void enable_nonboot_cpus(void)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001298{
1299 int cpu, error;
Thierry Strudel49d0e062016-06-14 17:46:44 -07001300 struct device *cpu_device;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001301
1302 /* Allow everyone to use the CPU hotplug again */
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001303 cpu_maps_update_begin();
Lianwei Wang01b41152016-06-09 23:43:28 -07001304 __cpu_hotplug_enable();
Rusty Russelle0b582e2009-01-01 10:12:28 +10301305 if (cpumask_empty(frozen_cpus))
Rafael J. Wysocki1d64b9c2007-04-01 23:49:49 -07001306 goto out;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001307
Fabian Frederick84117da2014-06-04 16:11:17 -07001308 pr_info("Enabling non-boot CPUs ...\n");
Suresh Siddhad0af9ee2009-08-19 18:05:36 -07001309
1310 arch_enable_nonboot_cpus_begin();
1311
Rusty Russelle0b582e2009-01-01 10:12:28 +10301312 for_each_cpu(cpu, frozen_cpus) {
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001313 trace_suspend_resume(TPS("CPU_ON"), cpu, true);
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001314 error = _cpu_up(cpu, 1, CPUHP_ONLINE);
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001315 trace_suspend_resume(TPS("CPU_ON"), cpu, false);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001316 if (!error) {
Fabian Frederick84117da2014-06-04 16:11:17 -07001317 pr_info("CPU%d is up\n", cpu);
Thierry Strudel49d0e062016-06-14 17:46:44 -07001318 cpu_device = get_cpu_device(cpu);
1319 if (!cpu_device)
1320 pr_err("%s: failed to get cpu%d device\n",
1321 __func__, cpu);
1322 else
1323 kobject_uevent(&cpu_device->kobj, KOBJ_ONLINE);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001324 continue;
1325 }
Fabian Frederick84117da2014-06-04 16:11:17 -07001326 pr_warn("Error taking CPU%d up: %d\n", cpu, error);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001327 }
Suresh Siddhad0af9ee2009-08-19 18:05:36 -07001328
1329 arch_enable_nonboot_cpus_end();
1330
Rusty Russelle0b582e2009-01-01 10:12:28 +10301331 cpumask_clear(frozen_cpus);
Rafael J. Wysocki1d64b9c2007-04-01 23:49:49 -07001332out:
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001333 cpu_maps_update_done();
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001334}
Rusty Russelle0b582e2009-01-01 10:12:28 +10301335
Fenghua Yud7268a32011-11-15 21:59:31 +01001336static int __init alloc_frozen_cpus(void)
Rusty Russelle0b582e2009-01-01 10:12:28 +10301337{
1338 if (!alloc_cpumask_var(&frozen_cpus, GFP_KERNEL|__GFP_ZERO))
1339 return -ENOMEM;
1340 return 0;
1341}
1342core_initcall(alloc_frozen_cpus);
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001343
1344/*
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001345 * When callbacks for CPU hotplug notifications are being executed, we must
1346 * ensure that the state of the system with respect to the tasks being frozen
1347 * or not, as reported by the notification, remains unchanged *throughout the
1348 * duration* of the execution of the callbacks.
1349 * Hence we need to prevent the freezer from racing with regular CPU hotplug.
1350 *
1351 * This synchronization is implemented by mutually excluding regular CPU
1352 * hotplug and Suspend/Hibernate call paths by hooking onto the Suspend/
1353 * Hibernate notifications.
1354 */
1355static int
1356cpu_hotplug_pm_callback(struct notifier_block *nb,
1357 unsigned long action, void *ptr)
1358{
1359 switch (action) {
1360
1361 case PM_SUSPEND_PREPARE:
1362 case PM_HIBERNATION_PREPARE:
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -07001363 cpu_hotplug_disable();
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001364 break;
1365
1366 case PM_POST_SUSPEND:
1367 case PM_POST_HIBERNATION:
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -07001368 cpu_hotplug_enable();
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001369 break;
1370
1371 default:
1372 return NOTIFY_DONE;
1373 }
1374
1375 return NOTIFY_OK;
1376}
1377
1378
Fenghua Yud7268a32011-11-15 21:59:31 +01001379static int __init cpu_hotplug_pm_sync_init(void)
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001380{
Fenghua Yu6e32d472012-11-13 11:32:43 -08001381 /*
1382 * cpu_hotplug_pm_callback has higher priority than x86
1383 * bsp_pm_callback which depends on cpu_hotplug_pm_callback
1384 * to disable cpu hotplug to avoid cpu hotplug race.
1385 */
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001386 pm_notifier(cpu_hotplug_pm_callback, 0);
1387 return 0;
1388}
1389core_initcall(cpu_hotplug_pm_sync_init);
1390
Rafael J. Wysockif3de4be2007-08-30 23:56:29 -07001391#endif /* CONFIG_PM_SLEEP_SMP */
Max Krasnyansky68f4f1e2008-05-29 11:17:02 -07001392
1393#endif /* CONFIG_SMP */
Mike Travisb8d317d2008-07-24 18:21:29 -07001394
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001395/* Boot processor state steps */
1396static struct cpuhp_step cpuhp_bp_states[] = {
1397 [CPUHP_OFFLINE] = {
1398 .name = "offline",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001399 .startup.single = NULL,
1400 .teardown.single = NULL,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001401 },
1402#ifdef CONFIG_SMP
1403 [CPUHP_CREATE_THREADS]= {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001404 .name = "threads:prepare",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001405 .startup.single = smpboot_create_threads,
1406 .teardown.single = NULL,
Thomas Gleixner757c9892016-02-26 18:43:32 +00001407 .cant_stop = true,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001408 },
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001409 [CPUHP_PERF_PREPARE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001410 .name = "perf:prepare",
1411 .startup.single = perf_event_init_cpu,
1412 .teardown.single = perf_event_exit_cpu,
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001413 },
Thomas Gleixner7ee681b2016-07-13 17:16:29 +00001414 [CPUHP_WORKQUEUE_PREP] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001415 .name = "workqueue:prepare",
1416 .startup.single = workqueue_prepare_cpu,
1417 .teardown.single = NULL,
Thomas Gleixner7ee681b2016-07-13 17:16:29 +00001418 },
Thomas Gleixner27590dc2016-07-15 10:41:04 +02001419 [CPUHP_HRTIMERS_PREPARE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001420 .name = "hrtimers:prepare",
1421 .startup.single = hrtimers_prepare_cpu,
1422 .teardown.single = hrtimers_dead_cpu,
Thomas Gleixner27590dc2016-07-15 10:41:04 +02001423 },
Richard Weinberger31487f82016-07-13 17:17:01 +00001424 [CPUHP_SMPCFD_PREPARE] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001425 .name = "smpcfd:prepare",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001426 .startup.single = smpcfd_prepare_cpu,
1427 .teardown.single = smpcfd_dead_cpu,
Richard Weinberger31487f82016-07-13 17:17:01 +00001428 },
Richard Weinbergere6d49892016-08-18 14:57:17 +02001429 [CPUHP_RELAY_PREPARE] = {
1430 .name = "relay:prepare",
1431 .startup.single = relay_prepare_cpu,
1432 .teardown.single = NULL,
1433 },
Sebastian Andrzej Siewior6731d4f2016-08-23 14:53:19 +02001434 [CPUHP_SLAB_PREPARE] = {
1435 .name = "slab:prepare",
1436 .startup.single = slab_prepare_cpu,
1437 .teardown.single = slab_dead_cpu,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001438 },
Thomas Gleixner4df83742016-07-13 17:17:03 +00001439 [CPUHP_RCUTREE_PREP] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001440 .name = "RCU/tree:prepare",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001441 .startup.single = rcutree_prepare_cpu,
1442 .teardown.single = rcutree_dead_cpu,
Thomas Gleixner4df83742016-07-13 17:17:03 +00001443 },
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001444 /*
1445 * Preparatory and dead notifiers. Will be replaced once the notifiers
1446 * are converted to states.
1447 */
1448 [CPUHP_NOTIFY_PREPARE] = {
1449 .name = "notify:prepare",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001450 .startup.single = notify_prepare,
1451 .teardown.single = notify_dead,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001452 .skip_onerr = true,
Thomas Gleixner757c9892016-02-26 18:43:32 +00001453 .cant_stop = true,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001454 },
Richard Cochran4fae16d2016-07-27 11:08:18 +02001455 /*
1456 * On the tear-down path, timers_dead_cpu() must be invoked
1457 * before blk_mq_queue_reinit_notify() from notify_dead(),
1458 * otherwise a RCU stall occurs.
1459 */
Thomas Gleixner249d4a92017-12-27 21:37:25 +01001460 [CPUHP_TIMERS_PREPARE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001461 .name = "timers:dead",
Thomas Gleixner249d4a92017-12-27 21:37:25 +01001462 .startup.single = timers_prepare_cpu,
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001463 .teardown.single = timers_dead_cpu,
Richard Cochran4fae16d2016-07-27 11:08:18 +02001464 },
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001465 /* Kicks the plugged cpu into life */
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001466 [CPUHP_BRINGUP_CPU] = {
1467 .name = "cpu:bringup",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001468 .startup.single = bringup_cpu,
1469 .teardown.single = NULL,
Thomas Gleixner757c9892016-02-26 18:43:32 +00001470 .cant_stop = true,
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001471 },
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001472 /*
1473 * Handled on controll processor until the plugged processor manages
1474 * this itself.
1475 */
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001476 [CPUHP_TEARDOWN_CPU] = {
1477 .name = "cpu:teardown",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001478 .startup.single = NULL,
1479 .teardown.single = takedown_cpu,
Thomas Gleixner757c9892016-02-26 18:43:32 +00001480 .cant_stop = true,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001481 },
Thomas Gleixnera7c734142016-07-12 21:59:23 +02001482#else
1483 [CPUHP_BRINGUP_CPU] = { },
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001484#endif
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001485};
1486
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001487/* Application processor state steps */
1488static struct cpuhp_step cpuhp_ap_states[] = {
1489#ifdef CONFIG_SMP
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001490 /* Final state before CPU kills itself */
1491 [CPUHP_AP_IDLE_DEAD] = {
1492 .name = "idle:dead",
1493 },
1494 /*
1495 * Last state before CPU enters the idle loop to die. Transient state
1496 * for synchronization.
1497 */
1498 [CPUHP_AP_OFFLINE] = {
1499 .name = "ap:offline",
1500 .cant_stop = true,
1501 },
Thomas Gleixner9cf72432016-03-10 12:54:09 +01001502 /* First state is scheduler control. Interrupts are disabled */
1503 [CPUHP_AP_SCHED_STARTING] = {
1504 .name = "sched:starting",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001505 .startup.single = sched_cpu_starting,
1506 .teardown.single = sched_cpu_dying,
Thomas Gleixner9cf72432016-03-10 12:54:09 +01001507 },
Thomas Gleixner4df83742016-07-13 17:17:03 +00001508 [CPUHP_AP_RCUTREE_DYING] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001509 .name = "RCU/tree:dying",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001510 .startup.single = NULL,
1511 .teardown.single = rcutree_dying_cpu,
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001512 },
Lai Jiangshanff3d4fd2017-11-28 21:19:53 +08001513 [CPUHP_AP_SMPCFD_DYING] = {
1514 .name = "smpcfd:dying",
1515 .startup.single = NULL,
1516 .teardown.single = smpcfd_dying_cpu,
1517 },
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001518 /* Entry state on starting. Interrupts enabled from here on. Transient
1519 * state for synchronsization */
1520 [CPUHP_AP_ONLINE] = {
1521 .name = "ap:online",
1522 },
1523 /* Handle smpboot threads park/unpark */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001524 [CPUHP_AP_SMPBOOT_THREADS] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001525 .name = "smpboot/threads:online",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001526 .startup.single = smpboot_unpark_threads,
Thomas Gleixner93335752018-05-29 19:05:25 +02001527 .teardown.single = smpboot_park_threads,
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001528 },
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001529 [CPUHP_AP_PERF_ONLINE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001530 .name = "perf:online",
1531 .startup.single = perf_event_init_cpu,
1532 .teardown.single = perf_event_exit_cpu,
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001533 },
Thomas Gleixner7ee681b2016-07-13 17:16:29 +00001534 [CPUHP_AP_WORKQUEUE_ONLINE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001535 .name = "workqueue:online",
1536 .startup.single = workqueue_online_cpu,
1537 .teardown.single = workqueue_offline_cpu,
Thomas Gleixner7ee681b2016-07-13 17:16:29 +00001538 },
Thomas Gleixner4df83742016-07-13 17:17:03 +00001539 [CPUHP_AP_RCUTREE_ONLINE] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001540 .name = "RCU/tree:online",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001541 .startup.single = rcutree_online_cpu,
1542 .teardown.single = rcutree_offline_cpu,
Thomas Gleixner4df83742016-07-13 17:17:03 +00001543 },
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001544
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001545 /*
1546 * Online/down_prepare notifiers. Will be removed once the notifiers
1547 * are converted to states.
1548 */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001549 [CPUHP_AP_NOTIFY_ONLINE] = {
1550 .name = "notify:online",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001551 .startup.single = notify_online,
1552 .teardown.single = notify_down_prepare,
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +02001553 .skip_onerr = true,
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001554 },
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001555#endif
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001556 /*
1557 * The dynamically registered state space is here
1558 */
1559
Thomas Gleixneraaddd7d2016-03-10 12:54:19 +01001560#ifdef CONFIG_SMP
1561 /* Last state is scheduler control setting the cpu active */
1562 [CPUHP_AP_ACTIVE] = {
1563 .name = "sched:active",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001564 .startup.single = sched_cpu_activate,
1565 .teardown.single = sched_cpu_deactivate,
Thomas Gleixneraaddd7d2016-03-10 12:54:19 +01001566 },
1567#endif
1568
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001569 /* CPU is fully up and running. */
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001570 [CPUHP_ONLINE] = {
1571 .name = "online",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001572 .startup.single = NULL,
1573 .teardown.single = NULL,
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001574 },
1575};
1576
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001577/* Sanity check for callbacks */
1578static int cpuhp_cb_check(enum cpuhp_state state)
1579{
1580 if (state <= CPUHP_OFFLINE || state >= CPUHP_ONLINE)
1581 return -EINVAL;
1582 return 0;
1583}
1584
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001585static void cpuhp_store_callbacks(enum cpuhp_state state,
1586 const char *name,
1587 int (*startup)(unsigned int cpu),
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001588 int (*teardown)(unsigned int cpu),
1589 bool multi_instance)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001590{
1591 /* (Un)Install the callbacks for further cpu hotplug operations */
1592 struct cpuhp_step *sp;
1593
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001594 sp = cpuhp_get_step(state);
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001595 sp->startup.single = startup;
1596 sp->teardown.single = teardown;
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001597 sp->name = name;
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001598 sp->multi_instance = multi_instance;
1599 INIT_HLIST_HEAD(&sp->list);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001600}
1601
1602static void *cpuhp_get_teardown_cb(enum cpuhp_state state)
1603{
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001604 return cpuhp_get_step(state)->teardown.single;
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001605}
1606
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001607/*
1608 * Call the startup/teardown function for a step either on the AP or
1609 * on the current CPU.
1610 */
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001611static int cpuhp_issue_call(int cpu, enum cpuhp_state state, bool bringup,
1612 struct hlist_node *node)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001613{
Thomas Gleixnera7246322016-08-12 19:49:38 +02001614 struct cpuhp_step *sp = cpuhp_get_step(state);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001615 int ret;
1616
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001617 if ((bringup && !sp->startup.single) ||
1618 (!bringup && !sp->teardown.single))
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001619 return 0;
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001620 /*
1621 * The non AP bound callbacks can fail on bringup. On teardown
1622 * e.g. module removal we crash for now.
1623 */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001624#ifdef CONFIG_SMP
1625 if (cpuhp_is_ap_state(state))
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001626 ret = cpuhp_invoke_ap_callback(cpu, state, bringup, node);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001627 else
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001628 ret = cpuhp_invoke_callback(cpu, state, bringup, node);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001629#else
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001630 ret = cpuhp_invoke_callback(cpu, state, bringup, node);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001631#endif
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001632 BUG_ON(ret && !bringup);
1633 return ret;
1634}
1635
1636/*
1637 * Called from __cpuhp_setup_state on a recoverable failure.
1638 *
1639 * Note: The teardown callbacks for rollback are not allowed to fail!
1640 */
1641static void cpuhp_rollback_install(int failedcpu, enum cpuhp_state state,
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001642 struct hlist_node *node)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001643{
1644 int cpu;
1645
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001646 /* Roll back the already executed steps on the other cpus */
1647 for_each_present_cpu(cpu) {
1648 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1649 int cpustate = st->state;
1650
1651 if (cpu >= failedcpu)
1652 break;
1653
1654 /* Did we invoke the startup call on that cpu ? */
1655 if (cpustate >= state)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001656 cpuhp_issue_call(cpu, state, false, node);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001657 }
1658}
1659
1660/*
1661 * Returns a free for dynamic slot assignment of the Online state. The states
1662 * are protected by the cpuhp_slot_states mutex and an empty slot is identified
1663 * by having no name assigned.
1664 */
1665static int cpuhp_reserve_state(enum cpuhp_state state)
1666{
1667 enum cpuhp_state i;
1668
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001669 for (i = CPUHP_AP_ONLINE_DYN; i <= CPUHP_AP_ONLINE_DYN_END; i++) {
1670 if (cpuhp_ap_states[i].name)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001671 continue;
1672
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001673 cpuhp_ap_states[i].name = "Reserved";
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001674 return i;
1675 }
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001676 WARN(1, "No more dynamic states available for CPU hotplug\n");
1677 return -ENOSPC;
1678}
1679
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001680int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node,
1681 bool invoke)
1682{
1683 struct cpuhp_step *sp;
1684 int cpu;
1685 int ret;
1686
1687 sp = cpuhp_get_step(state);
1688 if (sp->multi_instance == false)
1689 return -EINVAL;
1690
1691 get_online_cpus();
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001692 mutex_lock(&cpuhp_state_mutex);
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001693
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001694 if (!invoke || !sp->startup.multi)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001695 goto add_node;
1696
1697 /*
1698 * Try to call the startup callback for each present cpu
1699 * depending on the hotplug state of the cpu.
1700 */
1701 for_each_present_cpu(cpu) {
1702 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1703 int cpustate = st->state;
1704
1705 if (cpustate < state)
1706 continue;
1707
1708 ret = cpuhp_issue_call(cpu, state, true, node);
1709 if (ret) {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001710 if (sp->teardown.multi)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001711 cpuhp_rollback_install(cpu, state, node);
1712 goto err;
1713 }
1714 }
1715add_node:
1716 ret = 0;
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001717 hlist_add_head(node, &sp->list);
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001718
1719err:
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001720 mutex_unlock(&cpuhp_state_mutex);
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001721 put_online_cpus();
1722 return ret;
1723}
1724EXPORT_SYMBOL_GPL(__cpuhp_state_add_instance);
1725
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001726/**
1727 * __cpuhp_setup_state - Setup the callbacks for an hotplug machine state
1728 * @state: The state to setup
1729 * @invoke: If true, the startup function is invoked for cpus where
1730 * cpu state >= @state
1731 * @startup: startup callback function
1732 * @teardown: teardown callback function
1733 *
1734 * Returns 0 if successful, otherwise a proper error code
1735 */
1736int __cpuhp_setup_state(enum cpuhp_state state,
1737 const char *name, bool invoke,
1738 int (*startup)(unsigned int cpu),
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001739 int (*teardown)(unsigned int cpu),
1740 bool multi_instance)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001741{
1742 int cpu, ret = 0;
1743 int dyn_state = 0;
1744
1745 if (cpuhp_cb_check(state) || !name)
1746 return -EINVAL;
1747
1748 get_online_cpus();
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001749 mutex_lock(&cpuhp_state_mutex);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001750
1751 /* currently assignments for the ONLINE state are possible */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001752 if (state == CPUHP_AP_ONLINE_DYN) {
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001753 dyn_state = 1;
1754 ret = cpuhp_reserve_state(state);
1755 if (ret < 0)
1756 goto out;
1757 state = ret;
1758 }
1759
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001760 cpuhp_store_callbacks(state, name, startup, teardown, multi_instance);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001761
1762 if (!invoke || !startup)
1763 goto out;
1764
1765 /*
1766 * Try to call the startup callback for each present cpu
1767 * depending on the hotplug state of the cpu.
1768 */
1769 for_each_present_cpu(cpu) {
1770 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1771 int cpustate = st->state;
1772
1773 if (cpustate < state)
1774 continue;
1775
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001776 ret = cpuhp_issue_call(cpu, state, true, NULL);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001777 if (ret) {
Thomas Gleixnera7246322016-08-12 19:49:38 +02001778 if (teardown)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001779 cpuhp_rollback_install(cpu, state, NULL);
1780 cpuhp_store_callbacks(state, NULL, NULL, NULL, false);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001781 goto out;
1782 }
1783 }
1784out:
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001785 mutex_unlock(&cpuhp_state_mutex);
1786
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001787 put_online_cpus();
1788 if (!ret && dyn_state)
1789 return state;
1790 return ret;
1791}
1792EXPORT_SYMBOL(__cpuhp_setup_state);
1793
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001794int __cpuhp_state_remove_instance(enum cpuhp_state state,
1795 struct hlist_node *node, bool invoke)
1796{
1797 struct cpuhp_step *sp = cpuhp_get_step(state);
1798 int cpu;
1799
1800 BUG_ON(cpuhp_cb_check(state));
1801
1802 if (!sp->multi_instance)
1803 return -EINVAL;
1804
1805 get_online_cpus();
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001806 mutex_lock(&cpuhp_state_mutex);
1807
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001808 if (!invoke || !cpuhp_get_teardown_cb(state))
1809 goto remove;
1810 /*
1811 * Call the teardown callback for each present cpu depending
1812 * on the hotplug state of the cpu. This function is not
1813 * allowed to fail currently!
1814 */
1815 for_each_present_cpu(cpu) {
1816 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1817 int cpustate = st->state;
1818
1819 if (cpustate >= state)
1820 cpuhp_issue_call(cpu, state, false, node);
1821 }
1822
1823remove:
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001824 hlist_del(node);
1825 mutex_unlock(&cpuhp_state_mutex);
1826 put_online_cpus();
1827
1828 return 0;
1829}
1830EXPORT_SYMBOL_GPL(__cpuhp_state_remove_instance);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001831/**
1832 * __cpuhp_remove_state - Remove the callbacks for an hotplug machine state
1833 * @state: The state to remove
1834 * @invoke: If true, the teardown function is invoked for cpus where
1835 * cpu state >= @state
1836 *
1837 * The teardown callback is currently not allowed to fail. Think
1838 * about module removal!
1839 */
1840void __cpuhp_remove_state(enum cpuhp_state state, bool invoke)
1841{
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001842 struct cpuhp_step *sp = cpuhp_get_step(state);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001843 int cpu;
1844
1845 BUG_ON(cpuhp_cb_check(state));
1846
1847 get_online_cpus();
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001848 mutex_lock(&cpuhp_state_mutex);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001849
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001850 if (sp->multi_instance) {
1851 WARN(!hlist_empty(&sp->list),
1852 "Error: Removing state %d which has instances left.\n",
1853 state);
1854 goto remove;
1855 }
1856
Thomas Gleixnera7246322016-08-12 19:49:38 +02001857 if (!invoke || !cpuhp_get_teardown_cb(state))
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001858 goto remove;
1859
1860 /*
1861 * Call the teardown callback for each present cpu depending
1862 * on the hotplug state of the cpu. This function is not
1863 * allowed to fail currently!
1864 */
1865 for_each_present_cpu(cpu) {
1866 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1867 int cpustate = st->state;
1868
1869 if (cpustate >= state)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001870 cpuhp_issue_call(cpu, state, false, NULL);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001871 }
1872remove:
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001873 cpuhp_store_callbacks(state, NULL, NULL, NULL, false);
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001874 mutex_unlock(&cpuhp_state_mutex);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001875 put_online_cpus();
1876}
1877EXPORT_SYMBOL(__cpuhp_remove_state);
1878
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00001879#if defined(CONFIG_SYSFS) && defined(CONFIG_HOTPLUG_CPU)
1880static ssize_t show_cpuhp_state(struct device *dev,
1881 struct device_attribute *attr, char *buf)
1882{
1883 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
1884
1885 return sprintf(buf, "%d\n", st->state);
1886}
1887static DEVICE_ATTR(state, 0444, show_cpuhp_state, NULL);
1888
Thomas Gleixner757c9892016-02-26 18:43:32 +00001889static ssize_t write_cpuhp_target(struct device *dev,
1890 struct device_attribute *attr,
1891 const char *buf, size_t count)
1892{
1893 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
1894 struct cpuhp_step *sp;
1895 int target, ret;
1896
1897 ret = kstrtoint(buf, 10, &target);
1898 if (ret)
1899 return ret;
1900
1901#ifdef CONFIG_CPU_HOTPLUG_STATE_CONTROL
1902 if (target < CPUHP_OFFLINE || target > CPUHP_ONLINE)
1903 return -EINVAL;
1904#else
1905 if (target != CPUHP_OFFLINE && target != CPUHP_ONLINE)
1906 return -EINVAL;
1907#endif
1908
1909 ret = lock_device_hotplug_sysfs();
1910 if (ret)
1911 return ret;
1912
1913 mutex_lock(&cpuhp_state_mutex);
1914 sp = cpuhp_get_step(target);
1915 ret = !sp->name || sp->cant_stop ? -EINVAL : 0;
1916 mutex_unlock(&cpuhp_state_mutex);
1917 if (ret)
Sebastian Andrzej Siewior106c77e2017-06-02 16:27:14 +02001918 goto out;
Thomas Gleixner757c9892016-02-26 18:43:32 +00001919
1920 if (st->state < target)
1921 ret = do_cpu_up(dev->id, target);
1922 else
1923 ret = do_cpu_down(dev->id, target);
Sebastian Andrzej Siewior106c77e2017-06-02 16:27:14 +02001924out:
Thomas Gleixner757c9892016-02-26 18:43:32 +00001925 unlock_device_hotplug();
1926 return ret ? ret : count;
1927}
1928
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00001929static ssize_t show_cpuhp_target(struct device *dev,
1930 struct device_attribute *attr, char *buf)
1931{
1932 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
1933
1934 return sprintf(buf, "%d\n", st->target);
1935}
Thomas Gleixner757c9892016-02-26 18:43:32 +00001936static DEVICE_ATTR(target, 0644, show_cpuhp_target, write_cpuhp_target);
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00001937
1938static struct attribute *cpuhp_cpu_attrs[] = {
1939 &dev_attr_state.attr,
1940 &dev_attr_target.attr,
1941 NULL
1942};
1943
1944static struct attribute_group cpuhp_cpu_attr_group = {
1945 .attrs = cpuhp_cpu_attrs,
1946 .name = "hotplug",
1947 NULL
1948};
1949
1950static ssize_t show_cpuhp_states(struct device *dev,
1951 struct device_attribute *attr, char *buf)
1952{
1953 ssize_t cur, res = 0;
1954 int i;
1955
1956 mutex_lock(&cpuhp_state_mutex);
Thomas Gleixner757c9892016-02-26 18:43:32 +00001957 for (i = CPUHP_OFFLINE; i <= CPUHP_ONLINE; i++) {
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00001958 struct cpuhp_step *sp = cpuhp_get_step(i);
1959
1960 if (sp->name) {
1961 cur = sprintf(buf, "%3d: %s\n", i, sp->name);
1962 buf += cur;
1963 res += cur;
1964 }
1965 }
1966 mutex_unlock(&cpuhp_state_mutex);
1967 return res;
1968}
1969static DEVICE_ATTR(states, 0444, show_cpuhp_states, NULL);
1970
1971static struct attribute *cpuhp_cpu_root_attrs[] = {
1972 &dev_attr_states.attr,
1973 NULL
1974};
1975
1976static struct attribute_group cpuhp_cpu_root_attr_group = {
1977 .attrs = cpuhp_cpu_root_attrs,
1978 .name = "hotplug",
1979 NULL
1980};
1981
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02001982#ifdef CONFIG_HOTPLUG_SMT
1983
1984static const char *smt_states[] = {
1985 [CPU_SMT_ENABLED] = "on",
1986 [CPU_SMT_DISABLED] = "off",
1987 [CPU_SMT_FORCE_DISABLED] = "forceoff",
1988 [CPU_SMT_NOT_SUPPORTED] = "notsupported",
1989};
1990
1991static ssize_t
1992show_smt_control(struct device *dev, struct device_attribute *attr, char *buf)
1993{
1994 return snprintf(buf, PAGE_SIZE - 2, "%s\n", smt_states[cpu_smt_control]);
1995}
1996
1997static void cpuhp_offline_cpu_device(unsigned int cpu)
1998{
1999 struct device *dev = get_cpu_device(cpu);
2000
2001 dev->offline = true;
2002 /* Tell user space about the state change */
2003 kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
2004}
2005
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002006static void cpuhp_online_cpu_device(unsigned int cpu)
2007{
2008 struct device *dev = get_cpu_device(cpu);
2009
2010 dev->offline = false;
2011 /* Tell user space about the state change */
2012 kobject_uevent(&dev->kobj, KOBJ_ONLINE);
2013}
2014
Jiri Kosina5bdc5362019-05-30 00:09:39 +02002015int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002016{
2017 int cpu, ret = 0;
2018
2019 cpu_maps_update_begin();
2020 for_each_online_cpu(cpu) {
2021 if (topology_is_primary_thread(cpu))
2022 continue;
2023 ret = cpu_down_maps_locked(cpu, CPUHP_OFFLINE);
2024 if (ret)
2025 break;
2026 /*
2027 * As this needs to hold the cpu maps lock it's impossible
2028 * to call device_offline() because that ends up calling
2029 * cpu_down() which takes cpu maps lock. cpu maps lock
2030 * needs to be held as this might race against in kernel
2031 * abusers of the hotplug machinery (thermal management).
2032 *
2033 * So nothing would update device:offline state. That would
2034 * leave the sysfs entry stale and prevent onlining after
2035 * smt control has been changed to 'off' again. This is
2036 * called under the sysfs hotplug lock, so it is properly
2037 * serialized against the regular offline usage.
2038 */
2039 cpuhp_offline_cpu_device(cpu);
2040 }
Zhenzhong Duanf2a02af2019-01-17 02:10:59 -08002041 if (!ret)
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002042 cpu_smt_control = ctrlval;
2043 cpu_maps_update_done();
2044 return ret;
2045}
2046
Jiri Kosina5bdc5362019-05-30 00:09:39 +02002047int cpuhp_smt_enable(void)
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002048{
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002049 int cpu, ret = 0;
2050
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002051 cpu_maps_update_begin();
2052 cpu_smt_control = CPU_SMT_ENABLED;
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002053 for_each_present_cpu(cpu) {
2054 /* Skip online CPUs and CPUs on offline nodes */
2055 if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
2056 continue;
2057 ret = _cpu_up(cpu, 0, CPUHP_ONLINE);
2058 if (ret)
2059 break;
2060 /* See comment in cpuhp_smt_disable() */
2061 cpuhp_online_cpu_device(cpu);
2062 }
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002063 cpu_maps_update_done();
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002064 return ret;
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002065}
2066
2067static ssize_t
2068store_smt_control(struct device *dev, struct device_attribute *attr,
2069 const char *buf, size_t count)
2070{
2071 int ctrlval, ret;
2072
2073 if (sysfs_streq(buf, "on"))
2074 ctrlval = CPU_SMT_ENABLED;
2075 else if (sysfs_streq(buf, "off"))
2076 ctrlval = CPU_SMT_DISABLED;
2077 else if (sysfs_streq(buf, "forceoff"))
2078 ctrlval = CPU_SMT_FORCE_DISABLED;
2079 else
2080 return -EINVAL;
2081
2082 if (cpu_smt_control == CPU_SMT_FORCE_DISABLED)
2083 return -EPERM;
2084
2085 if (cpu_smt_control == CPU_SMT_NOT_SUPPORTED)
2086 return -ENODEV;
2087
2088 ret = lock_device_hotplug_sysfs();
2089 if (ret)
2090 return ret;
2091
2092 if (ctrlval != cpu_smt_control) {
2093 switch (ctrlval) {
2094 case CPU_SMT_ENABLED:
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002095 ret = cpuhp_smt_enable();
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002096 break;
2097 case CPU_SMT_DISABLED:
2098 case CPU_SMT_FORCE_DISABLED:
2099 ret = cpuhp_smt_disable(ctrlval);
2100 break;
2101 }
2102 }
2103
2104 unlock_device_hotplug();
2105 return ret ? ret : count;
2106}
2107static DEVICE_ATTR(control, 0644, show_smt_control, store_smt_control);
2108
2109static ssize_t
2110show_smt_active(struct device *dev, struct device_attribute *attr, char *buf)
2111{
2112 bool active = topology_max_smt_threads() > 1;
2113
2114 return snprintf(buf, PAGE_SIZE - 2, "%d\n", active);
2115}
2116static DEVICE_ATTR(active, 0444, show_smt_active, NULL);
2117
2118static struct attribute *cpuhp_smt_attrs[] = {
2119 &dev_attr_control.attr,
2120 &dev_attr_active.attr,
2121 NULL
2122};
2123
2124static const struct attribute_group cpuhp_smt_attr_group = {
2125 .attrs = cpuhp_smt_attrs,
2126 .name = "smt",
2127 NULL
2128};
2129
2130static int __init cpu_smt_state_init(void)
2131{
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002132 return sysfs_create_group(&cpu_subsys.dev_root->kobj,
2133 &cpuhp_smt_attr_group);
2134}
2135
2136#else
2137static inline int cpu_smt_state_init(void) { return 0; }
2138#endif
2139
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00002140static int __init cpuhp_sysfs_init(void)
2141{
2142 int cpu, ret;
2143
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002144 ret = cpu_smt_state_init();
2145 if (ret)
2146 return ret;
2147
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00002148 ret = sysfs_create_group(&cpu_subsys.dev_root->kobj,
2149 &cpuhp_cpu_root_attr_group);
2150 if (ret)
2151 return ret;
2152
2153 for_each_possible_cpu(cpu) {
2154 struct device *dev = get_cpu_device(cpu);
2155
2156 if (!dev)
2157 continue;
2158 ret = sysfs_create_group(&dev->kobj, &cpuhp_cpu_attr_group);
2159 if (ret)
2160 return ret;
2161 }
2162 return 0;
2163}
2164device_initcall(cpuhp_sysfs_init);
2165#endif
2166
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002167/*
2168 * cpu_bit_bitmap[] is a special, "compressed" data structure that
2169 * represents all NR_CPUS bits binary values of 1<<nr.
2170 *
Rusty Russelle0b582e2009-01-01 10:12:28 +10302171 * It is used by cpumask_of() to get a constant address to a CPU
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002172 * mask value that has a single bit set only.
2173 */
Mike Travisb8d317d2008-07-24 18:21:29 -07002174
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002175/* cpu_bit_bitmap[0] is empty - so we can back into it */
Michael Rodriguez4d519852011-03-22 16:34:07 -07002176#define MASK_DECLARE_1(x) [x+1][0] = (1UL << (x))
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002177#define MASK_DECLARE_2(x) MASK_DECLARE_1(x), MASK_DECLARE_1(x+1)
2178#define MASK_DECLARE_4(x) MASK_DECLARE_2(x), MASK_DECLARE_2(x+2)
2179#define MASK_DECLARE_8(x) MASK_DECLARE_4(x), MASK_DECLARE_4(x+4)
Mike Travisb8d317d2008-07-24 18:21:29 -07002180
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002181const unsigned long cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)] = {
Mike Travisb8d317d2008-07-24 18:21:29 -07002182
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002183 MASK_DECLARE_8(0), MASK_DECLARE_8(8),
2184 MASK_DECLARE_8(16), MASK_DECLARE_8(24),
2185#if BITS_PER_LONG > 32
2186 MASK_DECLARE_8(32), MASK_DECLARE_8(40),
2187 MASK_DECLARE_8(48), MASK_DECLARE_8(56),
Mike Travisb8d317d2008-07-24 18:21:29 -07002188#endif
2189};
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002190EXPORT_SYMBOL_GPL(cpu_bit_bitmap);
Rusty Russell2d3854a2008-11-05 13:39:10 +11002191
2192const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL;
2193EXPORT_SYMBOL(cpu_all_bits);
Rusty Russellb3199c02008-12-30 09:05:14 +10302194
2195#ifdef CONFIG_INIT_ALL_POSSIBLE
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002196struct cpumask __cpu_possible_mask __read_mostly
Rasmus Villemoesc4c54dd2016-01-20 15:00:16 -08002197 = {CPU_BITS_ALL};
Rusty Russellb3199c02008-12-30 09:05:14 +10302198#else
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002199struct cpumask __cpu_possible_mask __read_mostly;
Rusty Russellb3199c02008-12-30 09:05:14 +10302200#endif
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002201EXPORT_SYMBOL(__cpu_possible_mask);
Rusty Russellb3199c02008-12-30 09:05:14 +10302202
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002203struct cpumask __cpu_online_mask __read_mostly;
2204EXPORT_SYMBOL(__cpu_online_mask);
Rusty Russellb3199c02008-12-30 09:05:14 +10302205
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002206struct cpumask __cpu_present_mask __read_mostly;
2207EXPORT_SYMBOL(__cpu_present_mask);
Rusty Russellb3199c02008-12-30 09:05:14 +10302208
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002209struct cpumask __cpu_active_mask __read_mostly;
2210EXPORT_SYMBOL(__cpu_active_mask);
Rusty Russell3fa41522008-12-30 09:05:16 +10302211
Rusty Russell3fa41522008-12-30 09:05:16 +10302212void init_cpu_present(const struct cpumask *src)
2213{
Rasmus Villemoesc4c54dd2016-01-20 15:00:16 -08002214 cpumask_copy(&__cpu_present_mask, src);
Rusty Russell3fa41522008-12-30 09:05:16 +10302215}
2216
2217void init_cpu_possible(const struct cpumask *src)
2218{
Rasmus Villemoesc4c54dd2016-01-20 15:00:16 -08002219 cpumask_copy(&__cpu_possible_mask, src);
Rusty Russell3fa41522008-12-30 09:05:16 +10302220}
2221
2222void init_cpu_online(const struct cpumask *src)
2223{
Rasmus Villemoesc4c54dd2016-01-20 15:00:16 -08002224 cpumask_copy(&__cpu_online_mask, src);
Rusty Russell3fa41522008-12-30 09:05:16 +10302225}
Thomas Gleixnercff7d372016-02-26 18:43:28 +00002226
2227/*
2228 * Activate the first processor.
2229 */
2230void __init boot_cpu_init(void)
2231{
2232 int cpu = smp_processor_id();
2233
2234 /* Mark the boot cpu "present", "online" etc for SMP and UP case */
2235 set_cpu_online(cpu, true);
2236 set_cpu_active(cpu, true);
2237 set_cpu_present(cpu, true);
2238 set_cpu_possible(cpu, true);
2239}
2240
2241/*
2242 * Must be called _AFTER_ setting up the per_cpu areas
2243 */
Linus Torvalds6bb53ee2018-08-12 12:19:42 -07002244void __init boot_cpu_hotplug_init(void)
Thomas Gleixnercff7d372016-02-26 18:43:28 +00002245{
Abel Vesaaee08612018-08-15 00:26:00 +03002246#ifdef CONFIG_SMP
Thomas Gleixner8438e492018-06-29 16:05:48 +02002247 this_cpu_write(cpuhp_state.booted_once, true);
Abel Vesaaee08612018-08-15 00:26:00 +03002248#endif
Thomas Gleixner8438e492018-06-29 16:05:48 +02002249 this_cpu_write(cpuhp_state.state, CPUHP_ONLINE);
Thomas Gleixnercff7d372016-02-26 18:43:28 +00002250}
Todd Poynor5ee34122011-06-15 17:21:57 -07002251
Tyler Hickse2bd0772019-11-04 12:22:02 +01002252/*
2253 * These are used for a global "mitigations=" cmdline option for toggling
2254 * optional CPU mitigations.
2255 */
2256enum cpu_mitigations {
2257 CPU_MITIGATIONS_OFF,
2258 CPU_MITIGATIONS_AUTO,
2259 CPU_MITIGATIONS_AUTO_NOSMT,
2260};
2261
2262static enum cpu_mitigations cpu_mitigations __ro_after_init =
2263 CPU_MITIGATIONS_AUTO;
Josh Poimboeufedda9c32019-04-12 15:39:28 -05002264
2265static int __init mitigations_parse_cmdline(char *arg)
2266{
2267 if (!strcmp(arg, "off"))
2268 cpu_mitigations = CPU_MITIGATIONS_OFF;
2269 else if (!strcmp(arg, "auto"))
2270 cpu_mitigations = CPU_MITIGATIONS_AUTO;
2271 else if (!strcmp(arg, "auto,nosmt"))
2272 cpu_mitigations = CPU_MITIGATIONS_AUTO_NOSMT;
Geert Uytterhoeven0cbb0ae2019-05-16 09:09:35 +02002273 else
2274 pr_crit("Unsupported mitigations=%s, system may still be vulnerable\n",
2275 arg);
Josh Poimboeufedda9c32019-04-12 15:39:28 -05002276
2277 return 0;
2278}
2279early_param("mitigations", mitigations_parse_cmdline);
Greg Kroah-Hartmanef4a5762019-05-14 21:04:42 +02002280
Tyler Hickse2bd0772019-11-04 12:22:02 +01002281/* mitigations=off */
2282bool cpu_mitigations_off(void)
2283{
2284 return cpu_mitigations == CPU_MITIGATIONS_OFF;
2285}
2286EXPORT_SYMBOL_GPL(cpu_mitigations_off);
2287
2288/* mitigations=auto,nosmt */
2289bool cpu_mitigations_auto_nosmt(void)
2290{
2291 return cpu_mitigations == CPU_MITIGATIONS_AUTO_NOSMT;
2292}
2293EXPORT_SYMBOL_GPL(cpu_mitigations_auto_nosmt);
Greg Kroah-Hartman258971b2019-11-16 11:05:12 +01002294
Todd Poynor5ee34122011-06-15 17:21:57 -07002295static ATOMIC_NOTIFIER_HEAD(idle_notifier);
2296
2297void idle_notifier_register(struct notifier_block *n)
2298{
2299 atomic_notifier_chain_register(&idle_notifier, n);
2300}
2301EXPORT_SYMBOL_GPL(idle_notifier_register);
2302
2303void idle_notifier_unregister(struct notifier_block *n)
2304{
2305 atomic_notifier_chain_unregister(&idle_notifier, n);
2306}
2307EXPORT_SYMBOL_GPL(idle_notifier_unregister);
2308
2309void idle_notifier_call_chain(unsigned long val)
2310{
2311 atomic_notifier_call_chain(&idle_notifier, val, NULL);
2312}
2313EXPORT_SYMBOL_GPL(idle_notifier_call_chain);