blob: 91956a9fdc9a4ea105cc6f585079fef081712d49 [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>
Jason A. Donenfelded20ec42022-02-13 22:48:04 +010029#include <linux/random.h>
Maria Yue90f8e12017-09-21 11:30:53 +080030#include <linux/highmem.h>
Thomas Gleixnercff7d372016-02-26 18:43:28 +000031
Todd E Brandtbb3632c2014-06-06 05:40:17 -070032#include <trace/events/power.h>
Thomas Gleixnercff7d372016-02-26 18:43:28 +000033#define CREATE_TRACE_POINTS
34#include <trace/events/cpuhp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
Thomas Gleixner38498a62012-04-20 13:05:44 +000036#include "smpboot.h"
37
Thomas Gleixnercff7d372016-02-26 18:43:28 +000038/**
39 * cpuhp_cpu_state - Per cpu hotplug state storage
40 * @state: The current cpu state
41 * @target: The target state
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +000042 * @thread: Pointer to the hotplug thread
43 * @should_run: Thread should execute
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +020044 * @rollback: Perform a rollback
Thomas Gleixnera7246322016-08-12 19:49:38 +020045 * @single: Single callback invocation
46 * @bringup: Single callback bringup or teardown selector
47 * @cb_state: The state for a single callback (install/uninstall)
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +000048 * @result: Result of the operation
49 * @done: Signal completion to the issuer of the task
Thomas Gleixnercff7d372016-02-26 18:43:28 +000050 */
51struct cpuhp_cpu_state {
52 enum cpuhp_state state;
53 enum cpuhp_state target;
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +000054#ifdef CONFIG_SMP
55 struct task_struct *thread;
56 bool should_run;
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +020057 bool rollback;
Thomas Gleixnera7246322016-08-12 19:49:38 +020058 bool single;
59 bool bringup;
Thomas Gleixner8438e492018-06-29 16:05:48 +020060 bool booted_once;
Thomas Gleixnercf392d12016-08-12 19:49:39 +020061 struct hlist_node *node;
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +000062 enum cpuhp_state cb_state;
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +000063 int result;
64 struct completion done;
65#endif
Thomas Gleixnercff7d372016-02-26 18:43:28 +000066};
67
68static DEFINE_PER_CPU(struct cpuhp_cpu_state, cpuhp_state);
69
Thomas Gleixnerc198e222017-05-24 10:15:43 +020070#if defined(CONFIG_LOCKDEP) && defined(CONFIG_SMP)
71static struct lock_class_key cpuhp_state_key;
72static struct lockdep_map cpuhp_state_lock_map =
73 STATIC_LOCKDEP_MAP_INIT("cpuhp_state", &cpuhp_state_key);
74#endif
75
Thomas Gleixnercff7d372016-02-26 18:43:28 +000076/**
77 * cpuhp_step - Hotplug state machine step
78 * @name: Name of the step
79 * @startup: Startup function of the step
80 * @teardown: Teardown function of the step
81 * @skip_onerr: Do not invoke the functions on error rollback
82 * Will go away once the notifiers are gone
Thomas Gleixner757c9892016-02-26 18:43:32 +000083 * @cant_stop: Bringup/teardown can't be stopped at this step
Thomas Gleixnercff7d372016-02-26 18:43:28 +000084 */
85struct cpuhp_step {
Thomas Gleixnercf392d12016-08-12 19:49:39 +020086 const char *name;
87 union {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +020088 int (*single)(unsigned int cpu);
89 int (*multi)(unsigned int cpu,
90 struct hlist_node *node);
91 } startup;
Thomas Gleixnercf392d12016-08-12 19:49:39 +020092 union {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +020093 int (*single)(unsigned int cpu);
94 int (*multi)(unsigned int cpu,
95 struct hlist_node *node);
96 } teardown;
Thomas Gleixnercf392d12016-08-12 19:49:39 +020097 struct hlist_head list;
98 bool skip_onerr;
99 bool cant_stop;
100 bool multi_instance;
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000101};
102
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +0000103static DEFINE_MUTEX(cpuhp_state_mutex);
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000104static struct cpuhp_step cpuhp_bp_states[];
Thomas Gleixner4baa0af2016-02-26 18:43:29 +0000105static struct cpuhp_step cpuhp_ap_states[];
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000106
Thomas Gleixnera7246322016-08-12 19:49:38 +0200107static bool cpuhp_is_ap_state(enum cpuhp_state state)
108{
109 /*
110 * The extra check for CPUHP_TEARDOWN_CPU is only for documentation
111 * purposes as that state is handled explicitly in cpu_down.
112 */
113 return state > CPUHP_BRINGUP_CPU && state != CPUHP_TEARDOWN_CPU;
114}
115
116static struct cpuhp_step *cpuhp_get_step(enum cpuhp_state state)
117{
118 struct cpuhp_step *sp;
119
120 sp = cpuhp_is_ap_state(state) ? cpuhp_ap_states : cpuhp_bp_states;
121 return sp + state;
122}
123
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000124/**
125 * cpuhp_invoke_callback _ Invoke the callbacks for a given state
126 * @cpu: The cpu for which the callback should be invoked
127 * @step: The step in the state machine
Thomas Gleixnera7246322016-08-12 19:49:38 +0200128 * @bringup: True if the bringup callback should be invoked
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000129 *
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200130 * Called from cpu hotplug and from the state register machinery.
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000131 */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200132static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200133 bool bringup, struct hlist_node *node)
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000134{
135 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
Thomas Gleixnera7246322016-08-12 19:49:38 +0200136 struct cpuhp_step *step = cpuhp_get_step(state);
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200137 int (*cbm)(unsigned int cpu, struct hlist_node *node);
138 int (*cb)(unsigned int cpu);
139 int ret, cnt;
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000140
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200141 if (!step->multi_instance) {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +0200142 cb = bringup ? step->startup.single : step->teardown.single;
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200143 if (!cb)
144 return 0;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200145 trace_cpuhp_enter(cpu, st->target, state, cb);
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000146 ret = cb(cpu);
Thomas Gleixnera7246322016-08-12 19:49:38 +0200147 trace_cpuhp_exit(cpu, st->state, state, ret);
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200148 return ret;
149 }
Thomas Gleixner3c1627e2016-09-05 15:28:36 +0200150 cbm = bringup ? step->startup.multi : step->teardown.multi;
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200151 if (!cbm)
152 return 0;
153
154 /* Single invocation for instance add/remove */
155 if (node) {
156 trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node);
157 ret = cbm(cpu, node);
158 trace_cpuhp_exit(cpu, st->state, state, ret);
159 return ret;
160 }
161
162 /* State transition. Invoke on all instances */
163 cnt = 0;
164 hlist_for_each(node, &step->list) {
165 trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node);
166 ret = cbm(cpu, node);
167 trace_cpuhp_exit(cpu, st->state, state, ret);
168 if (ret)
169 goto err;
170 cnt++;
171 }
172 return 0;
173err:
174 /* Rollback the instances if one failed */
Thomas Gleixner3c1627e2016-09-05 15:28:36 +0200175 cbm = !bringup ? step->startup.multi : step->teardown.multi;
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200176 if (!cbm)
177 return ret;
178
179 hlist_for_each(node, &step->list) {
180 if (!cnt--)
181 break;
182 cbm(cpu, node);
Thomas Gleixnercff7d372016-02-26 18:43:28 +0000183 }
184 return ret;
185}
186
Rusty Russell98a79d62008-12-13 21:19:41 +1030187#ifdef CONFIG_SMP
Rusty Russellb3199c02008-12-30 09:05:14 +1030188/* Serializes the updates to cpu_online_mask, cpu_present_mask */
Linus Torvaldsaa953872006-07-23 12:12:16 -0700189static DEFINE_MUTEX(cpu_add_remove_lock);
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000190bool cpuhp_tasks_frozen;
191EXPORT_SYMBOL_GPL(cpuhp_tasks_frozen);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700193/*
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530194 * The following two APIs (cpu_maps_update_begin/done) must be used when
195 * attempting to serialize the updates to cpu_online_mask & cpu_present_mask.
196 * The APIs cpu_notifier_register_begin/done() must be used to protect CPU
197 * hotplug callback (un)registration performed using __register_cpu_notifier()
198 * or __unregister_cpu_notifier().
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700199 */
200void cpu_maps_update_begin(void)
201{
202 mutex_lock(&cpu_add_remove_lock);
203}
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530204EXPORT_SYMBOL(cpu_notifier_register_begin);
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700205
206void cpu_maps_update_done(void)
207{
208 mutex_unlock(&cpu_add_remove_lock);
209}
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530210EXPORT_SYMBOL(cpu_notifier_register_done);
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700211
Daniel J Blueman5c113fb2010-06-01 12:15:11 +0100212static RAW_NOTIFIER_HEAD(cpu_chain);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -0700214/* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
215 * Should always be manipulated under cpu_add_remove_lock
216 */
217static int cpu_hotplug_disabled;
218
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700219#ifdef CONFIG_HOTPLUG_CPU
220
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100221static struct {
222 struct task_struct *active_writer;
David Hildenbrand87af9e72014-12-12 10:11:44 +0100223 /* wait queue to wake up the active_writer */
224 wait_queue_head_t wq;
225 /* verifies that no writer will get active while readers are active */
226 struct mutex lock;
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100227 /*
228 * Also blocks the new readers during
229 * an ongoing cpu hotplug operation.
230 */
David Hildenbrand87af9e72014-12-12 10:11:44 +0100231 atomic_t refcount;
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530232
233#ifdef CONFIG_DEBUG_LOCK_ALLOC
234 struct lockdep_map dep_map;
235#endif
Linus Torvalds31950eb2009-06-22 21:18:12 -0700236} cpu_hotplug = {
237 .active_writer = NULL,
David Hildenbrand87af9e72014-12-12 10:11:44 +0100238 .wq = __WAIT_QUEUE_HEAD_INITIALIZER(cpu_hotplug.wq),
Linus Torvalds31950eb2009-06-22 21:18:12 -0700239 .lock = __MUTEX_INITIALIZER(cpu_hotplug.lock),
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530240#ifdef CONFIG_DEBUG_LOCK_ALLOC
Joonas Lahtinena705e072016-10-12 13:18:56 +0300241 .dep_map = STATIC_LOCKDEP_MAP_INIT("cpu_hotplug.dep_map", &cpu_hotplug.dep_map),
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530242#endif
Linus Torvalds31950eb2009-06-22 21:18:12 -0700243};
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100244
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530245/* Lockdep annotations for get/put_online_cpus() and cpu_hotplug_begin/end() */
246#define cpuhp_lock_acquire_read() lock_map_acquire_read(&cpu_hotplug.dep_map)
Paul E. McKenneydd56af42014-08-25 20:25:06 -0700247#define cpuhp_lock_acquire_tryread() \
248 lock_map_acquire_tryread(&cpu_hotplug.dep_map)
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530249#define cpuhp_lock_acquire() lock_map_acquire(&cpu_hotplug.dep_map)
250#define cpuhp_lock_release() lock_map_release(&cpu_hotplug.dep_map)
251
Prateek Soode9e7b752017-09-08 13:10:55 +0530252void cpu_hotplug_mutex_held(void)
253{
254 lockdep_assert_held(&cpu_hotplug.lock);
255}
256EXPORT_SYMBOL(cpu_hotplug_mutex_held);
Paul E. McKenney62db99f2014-10-22 14:51:49 -0700257
Gautham R Shenoy86ef5c92008-01-25 21:08:02 +0100258void get_online_cpus(void)
Ashok Raja9d9baa2005-11-28 13:43:46 -0800259{
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100260 might_sleep();
261 if (cpu_hotplug.active_writer == current)
Linus Torvaldsaa953872006-07-23 12:12:16 -0700262 return;
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530263 cpuhp_lock_acquire_read();
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100264 mutex_lock(&cpu_hotplug.lock);
David Hildenbrand87af9e72014-12-12 10:11:44 +0100265 atomic_inc(&cpu_hotplug.refcount);
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100266 mutex_unlock(&cpu_hotplug.lock);
Ashok Raja9d9baa2005-11-28 13:43:46 -0800267}
Gautham R Shenoy86ef5c92008-01-25 21:08:02 +0100268EXPORT_SYMBOL_GPL(get_online_cpus);
Ashok Raj90d45d12005-11-08 21:34:24 -0800269
Gautham R Shenoy86ef5c92008-01-25 21:08:02 +0100270void put_online_cpus(void)
Ashok Raja9d9baa2005-11-28 13:43:46 -0800271{
David Hildenbrand87af9e72014-12-12 10:11:44 +0100272 int refcount;
273
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100274 if (cpu_hotplug.active_writer == current)
Linus Torvaldsaa953872006-07-23 12:12:16 -0700275 return;
Srivatsa S. Bhat075663d2012-10-08 16:28:20 -0700276
David Hildenbrand87af9e72014-12-12 10:11:44 +0100277 refcount = atomic_dec_return(&cpu_hotplug.refcount);
278 if (WARN_ON(refcount < 0)) /* try to fix things up */
279 atomic_inc(&cpu_hotplug.refcount);
Srivatsa S. Bhat075663d2012-10-08 16:28:20 -0700280
David Hildenbrand87af9e72014-12-12 10:11:44 +0100281 if (refcount <= 0 && waitqueue_active(&cpu_hotplug.wq))
282 wake_up(&cpu_hotplug.wq);
283
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530284 cpuhp_lock_release();
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100285
Ashok Raja9d9baa2005-11-28 13:43:46 -0800286}
Gautham R Shenoy86ef5c92008-01-25 21:08:02 +0100287EXPORT_SYMBOL_GPL(put_online_cpus);
Ashok Raja9d9baa2005-11-28 13:43:46 -0800288
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100289/*
290 * This ensures that the hotplug operation can begin only when the
291 * refcount goes to zero.
292 *
293 * Note that during a cpu-hotplug operation, the new readers, if any,
294 * will be blocked by the cpu_hotplug.lock
295 *
Oleg Nesterovd2ba7e22008-04-29 01:00:29 -0700296 * Since cpu_hotplug_begin() is always called after invoking
297 * cpu_maps_update_begin(), we can be sure that only one writer is active.
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100298 *
299 * Note that theoretically, there is a possibility of a livelock:
300 * - Refcount goes to zero, last reader wakes up the sleeping
301 * writer.
302 * - Last reader unlocks the cpu_hotplug.lock.
303 * - A new reader arrives at this moment, bumps up the refcount.
304 * - The writer acquires the cpu_hotplug.lock finds the refcount
305 * non zero and goes to sleep again.
306 *
307 * However, this is very difficult to achieve in practice since
Gautham R Shenoy86ef5c92008-01-25 21:08:02 +0100308 * get_online_cpus() not an api which is called all that often.
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100309 *
310 */
Toshi Kanib9d10be2013-08-12 09:45:53 -0600311void cpu_hotplug_begin(void)
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100312{
David Hildenbrand87af9e72014-12-12 10:11:44 +0100313 DEFINE_WAIT(wait);
Oleg Nesterovd2ba7e22008-04-29 01:00:29 -0700314
David Hildenbrand87af9e72014-12-12 10:11:44 +0100315 cpu_hotplug.active_writer = current;
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530316 cpuhp_lock_acquire();
David Hildenbrand87af9e72014-12-12 10:11:44 +0100317
Oleg Nesterovd2ba7e22008-04-29 01:00:29 -0700318 for (;;) {
319 mutex_lock(&cpu_hotplug.lock);
David Hildenbrand87af9e72014-12-12 10:11:44 +0100320 prepare_to_wait(&cpu_hotplug.wq, &wait, TASK_UNINTERRUPTIBLE);
321 if (likely(!atomic_read(&cpu_hotplug.refcount)))
322 break;
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100323 mutex_unlock(&cpu_hotplug.lock);
324 schedule();
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100325 }
David Hildenbrand87af9e72014-12-12 10:11:44 +0100326 finish_wait(&cpu_hotplug.wq, &wait);
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100327}
328
Toshi Kanib9d10be2013-08-12 09:45:53 -0600329void cpu_hotplug_done(void)
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100330{
331 cpu_hotplug.active_writer = NULL;
332 mutex_unlock(&cpu_hotplug.lock);
Gautham R. Shenoya19423b2014-03-11 02:04:03 +0530333 cpuhp_lock_release();
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100334}
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700335
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -0700336/*
337 * Wait for currently running CPU hotplug operations to complete (if any) and
338 * disable future CPU hotplug (from sysfs). The 'cpu_add_remove_lock' protects
339 * the 'cpu_hotplug_disabled' flag. The same lock is also acquired by the
340 * hotplug path before performing hotplug operations. So acquiring that lock
341 * guarantees mutual exclusion from any currently running hotplug operations.
342 */
343void cpu_hotplug_disable(void)
344{
345 cpu_maps_update_begin();
Vitaly Kuznetsov89af7ba2015-08-05 00:52:46 -0700346 cpu_hotplug_disabled++;
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -0700347 cpu_maps_update_done();
348}
Vitaly Kuznetsov32145c42015-08-05 00:52:47 -0700349EXPORT_SYMBOL_GPL(cpu_hotplug_disable);
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -0700350
Lianwei Wang01b41152016-06-09 23:43:28 -0700351static void __cpu_hotplug_enable(void)
352{
353 if (WARN_ONCE(!cpu_hotplug_disabled, "Unbalanced cpu hotplug enable\n"))
354 return;
355 cpu_hotplug_disabled--;
356}
357
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -0700358void cpu_hotplug_enable(void)
359{
360 cpu_maps_update_begin();
Lianwei Wang01b41152016-06-09 23:43:28 -0700361 __cpu_hotplug_enable();
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -0700362 cpu_maps_update_done();
363}
Vitaly Kuznetsov32145c42015-08-05 00:52:47 -0700364EXPORT_SYMBOL_GPL(cpu_hotplug_enable);
Toshi Kanib9d10be2013-08-12 09:45:53 -0600365#endif /* CONFIG_HOTPLUG_CPU */
Lai Jiangshan79a6cde2010-05-26 14:43:36 -0700366
Thomas Gleixnera3c901b2018-11-25 19:33:39 +0100367/*
368 * Architectures that need SMT-specific errata handling during SMT hotplug
369 * should override this.
370 */
371void __weak arch_smt_update(void) { }
372
Thomas Gleixner8438e492018-06-29 16:05:48 +0200373#ifdef CONFIG_HOTPLUG_SMT
374enum cpuhp_smt_control cpu_smt_control __read_mostly = CPU_SMT_ENABLED;
Konrad Rzeszutek Wilka0695af2018-06-20 11:29:53 -0400375EXPORT_SYMBOL_GPL(cpu_smt_control);
Thomas Gleixner8438e492018-06-29 16:05:48 +0200376
Thomas Gleixnerc504b9f2018-08-07 08:19:57 +0200377static bool cpu_smt_available __read_mostly;
378
Jiri Kosinaa69c5e02018-07-13 16:23:23 +0200379void __init cpu_smt_disable(bool force)
Thomas Gleixner8438e492018-06-29 16:05:48 +0200380{
Jiri Kosinaa69c5e02018-07-13 16:23:23 +0200381 if (cpu_smt_control == CPU_SMT_FORCE_DISABLED ||
382 cpu_smt_control == CPU_SMT_NOT_SUPPORTED)
383 return;
384
385 if (force) {
Thomas Gleixner8438e492018-06-29 16:05:48 +0200386 pr_info("SMT: Force disabled\n");
387 cpu_smt_control = CPU_SMT_FORCE_DISABLED;
Jiri Kosinaa69c5e02018-07-13 16:23:23 +0200388 } else {
Borislav Petkov6270cc32018-10-04 19:22:27 +0200389 pr_info("SMT: disabled\n");
Jiri Kosinaa69c5e02018-07-13 16:23:23 +0200390 cpu_smt_control = CPU_SMT_DISABLED;
Thomas Gleixner8438e492018-06-29 16:05:48 +0200391 }
Jiri Kosinaa69c5e02018-07-13 16:23:23 +0200392}
393
Thomas Gleixner929d3b22018-07-13 16:23:24 +0200394/*
395 * The decision whether SMT is supported can only be done after the full
Thomas Gleixnerc504b9f2018-08-07 08:19:57 +0200396 * CPU identification. Called from architecture code before non boot CPUs
397 * are brought up.
398 */
399void __init cpu_smt_check_topology_early(void)
400{
401 if (!topology_smt_supported())
402 cpu_smt_control = CPU_SMT_NOT_SUPPORTED;
403}
404
405/*
406 * If SMT was disabled by BIOS, detect it here, after the CPUs have been
407 * brought online. This ensures the smt/l1tf sysfs entries are consistent
408 * with reality. cpu_smt_available is set to true during the bringup of non
409 * boot CPUs when a SMT sibling is detected. Note, this may overwrite
410 * cpu_smt_control's previous setting.
Thomas Gleixner929d3b22018-07-13 16:23:24 +0200411 */
412void __init cpu_smt_check_topology(void)
413{
Thomas Gleixnerc504b9f2018-08-07 08:19:57 +0200414 if (!cpu_smt_available)
Thomas Gleixner929d3b22018-07-13 16:23:24 +0200415 cpu_smt_control = CPU_SMT_NOT_SUPPORTED;
416}
417
Jiri Kosinaa69c5e02018-07-13 16:23:23 +0200418static int __init smt_cmdline_disable(char *str)
419{
420 cpu_smt_disable(str && !strcmp(str, "force"));
Thomas Gleixner8438e492018-06-29 16:05:48 +0200421 return 0;
422}
423early_param("nosmt", smt_cmdline_disable);
424
425static inline bool cpu_smt_allowed(unsigned int cpu)
426{
Thomas Gleixnerc504b9f2018-08-07 08:19:57 +0200427 if (topology_is_primary_thread(cpu))
Thomas Gleixner8438e492018-06-29 16:05:48 +0200428 return true;
429
Thomas Gleixnerc504b9f2018-08-07 08:19:57 +0200430 /*
431 * If the CPU is not a 'primary' thread and the booted_once bit is
432 * set then the processor has SMT support. Store this information
433 * for the late check of SMT support in cpu_smt_check_topology().
434 */
435 if (per_cpu(cpuhp_state, cpu).booted_once)
436 cpu_smt_available = true;
437
438 if (cpu_smt_control == CPU_SMT_ENABLED)
Thomas Gleixner8438e492018-06-29 16:05:48 +0200439 return true;
440
441 /*
442 * On x86 it's required to boot all logical CPUs at least once so
443 * that the init code can get a chance to set CR4.MCE on each
444 * CPU. Otherwise, a broadacasted MCE observing CR4.MCE=0b on any
445 * core will shutdown the machine.
446 */
447 return !per_cpu(cpuhp_state, cpu).booted_once;
448}
449#else
450static inline bool cpu_smt_allowed(unsigned int cpu) { return true; }
451#endif
452
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453/* Need to know about CPUs going up/down? */
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200454int register_cpu_notifier(struct notifier_block *nb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455{
Neil Brownbd5349c2006-10-17 00:10:35 -0700456 int ret;
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100457 cpu_maps_update_begin();
Neil Brownbd5349c2006-10-17 00:10:35 -0700458 ret = raw_notifier_chain_register(&cpu_chain, nb);
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100459 cpu_maps_update_done();
Neil Brownbd5349c2006-10-17 00:10:35 -0700460 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461}
Chandra Seetharaman65edc682006-06-27 02:54:08 -0700462
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200463int __register_cpu_notifier(struct notifier_block *nb)
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530464{
465 return raw_notifier_chain_register(&cpu_chain, nb);
466}
467
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000468static int __cpu_notify(unsigned long val, unsigned int cpu, int nr_to_call,
Akinobu Mitae9fb7632010-05-26 14:43:28 -0700469 int *nr_calls)
470{
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000471 unsigned long mod = cpuhp_tasks_frozen ? CPU_TASKS_FROZEN : 0;
472 void *hcpu = (void *)(long)cpu;
473
Akinobu Mitae6bde732010-05-26 14:43:29 -0700474 int ret;
475
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000476 ret = __raw_notifier_call_chain(&cpu_chain, val | mod, hcpu, nr_to_call,
Akinobu Mitae9fb7632010-05-26 14:43:28 -0700477 nr_calls);
Akinobu Mitae6bde732010-05-26 14:43:29 -0700478
479 return notifier_to_errno(ret);
Akinobu Mitae9fb7632010-05-26 14:43:28 -0700480}
481
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000482static int cpu_notify(unsigned long val, unsigned int cpu)
Akinobu Mitae9fb7632010-05-26 14:43:28 -0700483{
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000484 return __cpu_notify(val, cpu, -1, NULL);
Akinobu Mitae9fb7632010-05-26 14:43:28 -0700485}
486
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200487static void cpu_notify_nofail(unsigned long val, unsigned int cpu)
488{
489 BUG_ON(cpu_notify(val, cpu));
490}
491
Thomas Gleixnerba997462016-02-26 18:43:24 +0000492/* Notifier wrappers for transitioning to state machine */
493static int notify_prepare(unsigned int cpu)
494{
495 int nr_calls = 0;
496 int ret;
497
498 ret = __cpu_notify(CPU_UP_PREPARE, cpu, -1, &nr_calls);
499 if (ret) {
500 nr_calls--;
501 printk(KERN_WARNING "%s: attempt to bring up CPU %u failed\n",
502 __func__, cpu);
503 __cpu_notify(CPU_UP_CANCELED, cpu, nr_calls, NULL);
504 }
505 return ret;
506}
507
508static int notify_online(unsigned int cpu)
509{
510 cpu_notify(CPU_ONLINE, cpu);
511 return 0;
512}
Thomas Gleixnerceb354b2017-07-04 22:20:23 +0200513static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st);
Thomas Gleixnerba997462016-02-26 18:43:24 +0000514
Thomas Gleixner7b4e4b12017-07-04 22:20:23 +0200515static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st);
516
Thomas Gleixner8df3e072016-02-26 18:43:41 +0000517static int bringup_wait_for_ap(unsigned int cpu)
518{
519 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
520
Thomas Gleixnerceb354b2017-07-04 22:20:23 +0200521 /* Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE */
Thomas Gleixner8df3e072016-02-26 18:43:41 +0000522 wait_for_completion(&st->done);
Thomas Gleixner6b3d13f2017-07-11 22:06:24 +0200523 if (WARN_ON_ONCE((!cpu_online(cpu))))
524 return -ECANCELED;
Thomas Gleixnerceb354b2017-07-04 22:20:23 +0200525
Peter Zijlstraa594a9e2019-12-10 09:34:54 +0100526 /* Unpark the hotplug thread of the target cpu */
Thomas Gleixnerceb354b2017-07-04 22:20:23 +0200527 kthread_unpark(st->thread);
528
Thomas Gleixner8438e492018-06-29 16:05:48 +0200529 /*
530 * SMT soft disabling on X86 requires to bring the CPU out of the
531 * BIOS 'wait for SIPI' state in order to set the CR4.MCE bit. The
532 * CPU marked itself as booted_once in cpu_notify_starting() so the
533 * cpu_smt_allowed() check will now return false if this is not the
534 * primary sibling.
535 */
536 if (!cpu_smt_allowed(cpu))
537 return -ECANCELED;
538
Thomas Gleixnerceb354b2017-07-04 22:20:23 +0200539 /* Should we go further up ? */
540 if (st->target > CPUHP_AP_ONLINE_IDLE) {
541 __cpuhp_kick_ap_work(st);
542 wait_for_completion(&st->done);
543 }
Thomas Gleixner8df3e072016-02-26 18:43:41 +0000544 return st->result;
545}
546
Thomas Gleixnerba997462016-02-26 18:43:24 +0000547static int bringup_cpu(unsigned int cpu)
548{
549 struct task_struct *idle = idle_thread_get(cpu);
550 int ret;
551
Boris Ostrovskyaa877172016-08-03 13:22:28 -0400552 /*
553 * Some architectures have to walk the irq descriptors to
554 * setup the vector space for the cpu which comes online.
555 * Prevent irq alloc/free across the bringup.
556 */
557 irq_lock_sparse();
558
Thomas Gleixnerba997462016-02-26 18:43:24 +0000559 /* Arch-specific enabling code. */
560 ret = __cpu_up(cpu, idle);
Boris Ostrovskyaa877172016-08-03 13:22:28 -0400561 irq_unlock_sparse();
Thomas Gleixnerba997462016-02-26 18:43:24 +0000562 if (ret) {
563 cpu_notify(CPU_UP_CANCELED, cpu);
564 return ret;
565 }
Thomas Gleixnerceb354b2017-07-04 22:20:23 +0200566 return bringup_wait_for_ap(cpu);
Thomas Gleixnerba997462016-02-26 18:43:24 +0000567}
568
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000569/*
570 * Hotplug state machine related functions
571 */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200572static void undo_cpu_down(unsigned int cpu, struct cpuhp_cpu_state *st)
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000573{
574 for (st->state++; st->state < st->target; st->state++) {
Thomas Gleixnera7246322016-08-12 19:49:38 +0200575 struct cpuhp_step *step = cpuhp_get_step(st->state);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000576
577 if (!step->skip_onerr)
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200578 cpuhp_invoke_callback(cpu, st->state, true, NULL);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000579 }
580}
581
582static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
Thomas Gleixnera7246322016-08-12 19:49:38 +0200583 enum cpuhp_state target)
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000584{
585 enum cpuhp_state prev_state = st->state;
586 int ret = 0;
587
588 for (; st->state > target; st->state--) {
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200589 ret = cpuhp_invoke_callback(cpu, st->state, false, NULL);
Channagoud Kadabibd019ce2017-06-19 17:14:52 -0700590 BUG_ON(ret && st->state < CPUHP_AP_IDLE_DEAD);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000591 if (ret) {
592 st->target = prev_state;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200593 undo_cpu_down(cpu, st);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000594 break;
595 }
596 }
597 return ret;
598}
599
Thomas Gleixnera7246322016-08-12 19:49:38 +0200600static void undo_cpu_up(unsigned int cpu, struct cpuhp_cpu_state *st)
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000601{
602 for (st->state--; st->state > st->target; st->state--) {
Thomas Gleixnera7246322016-08-12 19:49:38 +0200603 struct cpuhp_step *step = cpuhp_get_step(st->state);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000604
605 if (!step->skip_onerr)
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200606 cpuhp_invoke_callback(cpu, st->state, false, NULL);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000607 }
608}
609
Thomas Gleixnerce4fbb92019-03-26 17:36:05 +0100610static inline bool can_rollback_cpu(struct cpuhp_cpu_state *st)
611{
612 if (IS_ENABLED(CONFIG_HOTPLUG_CPU))
613 return true;
614 /*
615 * When CPU hotplug is disabled, then taking the CPU down is not
616 * possible because takedown_cpu() and the architecture and
617 * subsystem specific mechanisms are not available. So the CPU
618 * which would be completely unplugged again needs to stay around
619 * in the current state.
620 */
621 return st->state <= CPUHP_BRINGUP_CPU;
622}
623
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000624static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
Thomas Gleixnera7246322016-08-12 19:49:38 +0200625 enum cpuhp_state target)
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000626{
627 enum cpuhp_state prev_state = st->state;
628 int ret = 0;
629
630 while (st->state < target) {
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000631 st->state++;
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200632 ret = cpuhp_invoke_callback(cpu, st->state, true, NULL);
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000633 if (ret) {
Thomas Gleixnerce4fbb92019-03-26 17:36:05 +0100634 if (can_rollback_cpu(st)) {
635 st->target = prev_state;
636 undo_cpu_up(cpu, st);
637 }
Thomas Gleixner2e1a3482016-02-26 18:43:37 +0000638 break;
639 }
640 }
641 return ret;
642}
643
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000644/*
645 * The cpu hotplug threads manage the bringup and teardown of the cpus
646 */
647static void cpuhp_create(unsigned int cpu)
648{
649 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
650
651 init_completion(&st->done);
652}
653
654static int cpuhp_should_run(unsigned int cpu)
655{
656 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
657
658 return st->should_run;
659}
660
661/* Execute the teardown callbacks. Used to be CPU_DOWN_PREPARE */
662static int cpuhp_ap_offline(unsigned int cpu, struct cpuhp_cpu_state *st)
663{
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000664 enum cpuhp_state target = max((int)st->target, CPUHP_TEARDOWN_CPU);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000665
Thomas Gleixnera7246322016-08-12 19:49:38 +0200666 return cpuhp_down_callbacks(cpu, st, target);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000667}
668
669/* Execute the online startup callbacks. Used to be CPU_ONLINE */
670static int cpuhp_ap_online(unsigned int cpu, struct cpuhp_cpu_state *st)
671{
Thomas Gleixnera7246322016-08-12 19:49:38 +0200672 return cpuhp_up_callbacks(cpu, st, st->target);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000673}
674
675/*
676 * Execute teardown/startup callbacks on the plugged cpu. Also used to invoke
677 * callbacks when a state gets [un]installed at runtime.
678 */
679static void cpuhp_thread_fun(unsigned int cpu)
680{
681 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
682 int ret = 0;
683
684 /*
685 * Paired with the mb() in cpuhp_kick_ap_work and
686 * cpuhp_invoke_ap_callback, so the work set is consistent visible.
687 */
688 smp_mb();
689 if (!st->should_run)
690 return;
691
692 st->should_run = false;
693
Thomas Gleixnerc198e222017-05-24 10:15:43 +0200694 lock_map_acquire(&cpuhp_state_lock_map);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000695 /* Single callback invocation for [un]install ? */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200696 if (st->single) {
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000697 if (st->cb_state < CPUHP_AP_ONLINE) {
698 local_irq_disable();
Thomas Gleixnera7246322016-08-12 19:49:38 +0200699 ret = cpuhp_invoke_callback(cpu, st->cb_state,
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200700 st->bringup, st->node);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000701 local_irq_enable();
702 } else {
Thomas Gleixnera7246322016-08-12 19:49:38 +0200703 ret = cpuhp_invoke_callback(cpu, st->cb_state,
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200704 st->bringup, st->node);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000705 }
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200706 } else if (st->rollback) {
707 BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE);
708
Thomas Gleixnera7246322016-08-12 19:49:38 +0200709 undo_cpu_down(cpu, st);
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200710 /*
711 * This is a momentary workaround to keep the notifier users
712 * happy. Will go away once we got rid of the notifiers.
713 */
714 cpu_notify_nofail(CPU_DOWN_FAILED, cpu);
715 st->rollback = false;
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000716 } else {
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000717 /* Cannot happen .... */
Thomas Gleixner8df3e072016-02-26 18:43:41 +0000718 BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000719
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000720 /* Regular hotplug work */
721 if (st->state < st->target)
722 ret = cpuhp_ap_online(cpu, st);
723 else if (st->state > st->target)
724 ret = cpuhp_ap_offline(cpu, st);
725 }
Thomas Gleixnerc198e222017-05-24 10:15:43 +0200726 lock_map_release(&cpuhp_state_lock_map);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000727 st->result = ret;
728 complete(&st->done);
729}
730
731/* Invoke a single callback on a remote cpu */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200732static int
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200733cpuhp_invoke_ap_callback(int cpu, enum cpuhp_state state, bool bringup,
734 struct hlist_node *node)
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000735{
736 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
737
738 if (!cpu_online(cpu))
739 return 0;
740
Thomas Gleixnerc198e222017-05-24 10:15:43 +0200741 lock_map_acquire(&cpuhp_state_lock_map);
742 lock_map_release(&cpuhp_state_lock_map);
743
Thomas Gleixner6a4e2452016-07-13 17:16:03 +0000744 /*
745 * If we are up and running, use the hotplug thread. For early calls
746 * we invoke the thread function directly.
747 */
748 if (!st->thread)
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200749 return cpuhp_invoke_callback(cpu, state, bringup, node);
Thomas Gleixner6a4e2452016-07-13 17:16:03 +0000750
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000751 st->cb_state = state;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200752 st->single = true;
753 st->bringup = bringup;
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200754 st->node = node;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200755
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000756 /*
757 * Make sure the above stores are visible before should_run becomes
758 * true. Paired with the mb() above in cpuhp_thread_fun()
759 */
760 smp_mb();
761 st->should_run = true;
762 wake_up_process(st->thread);
763 wait_for_completion(&st->done);
764 return st->result;
765}
766
767/* Regular hotplug invocation of the AP hotplug thread */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000768static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st)
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000769{
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000770 st->result = 0;
Thomas Gleixnera7246322016-08-12 19:49:38 +0200771 st->single = false;
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000772 /*
773 * Make sure the above stores are visible before should_run becomes
774 * true. Paired with the mb() above in cpuhp_thread_fun()
775 */
776 smp_mb();
777 st->should_run = true;
778 wake_up_process(st->thread);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000779}
780
781static int cpuhp_kick_ap_work(unsigned int cpu)
782{
783 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
784 enum cpuhp_state state = st->state;
785
786 trace_cpuhp_enter(cpu, st->target, state, cpuhp_kick_ap_work);
Thomas Gleixnerc198e222017-05-24 10:15:43 +0200787 lock_map_acquire(&cpuhp_state_lock_map);
788 lock_map_release(&cpuhp_state_lock_map);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000789 __cpuhp_kick_ap_work(st);
Thomas Gleixner4cb28ce2016-02-26 18:43:38 +0000790 wait_for_completion(&st->done);
791 trace_cpuhp_exit(cpu, st->state, state, st->result);
792 return st->result;
793}
794
795static struct smp_hotplug_thread cpuhp_threads = {
796 .store = &cpuhp_state.thread,
797 .create = &cpuhp_create,
798 .thread_should_run = cpuhp_should_run,
799 .thread_fn = cpuhp_thread_fun,
800 .thread_comm = "cpuhp/%u",
801 .selfparking = true,
802};
803
804void __init cpuhp_threads_init(void)
805{
806 BUG_ON(smpboot_register_percpu_thread(&cpuhp_threads));
807 kthread_unpark(this_cpu_read(cpuhp_state.thread));
808}
809
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810EXPORT_SYMBOL(register_cpu_notifier);
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530811EXPORT_SYMBOL(__register_cpu_notifier);
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200812void unregister_cpu_notifier(struct notifier_block *nb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813{
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100814 cpu_maps_update_begin();
Neil Brownbd5349c2006-10-17 00:10:35 -0700815 raw_notifier_chain_unregister(&cpu_chain, nb);
Gautham R Shenoyd2219382008-01-25 21:08:01 +0100816 cpu_maps_update_done();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817}
818EXPORT_SYMBOL(unregister_cpu_notifier);
819
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200820void __unregister_cpu_notifier(struct notifier_block *nb)
Srivatsa S. Bhat93ae4f92014-03-11 02:04:14 +0530821{
822 raw_notifier_chain_unregister(&cpu_chain, nb);
823}
824EXPORT_SYMBOL(__unregister_cpu_notifier);
825
Michal Hocko56eaecc2016-12-07 14:54:38 +0100826#ifdef CONFIG_HOTPLUG_CPU
Nicholas Pigginfe348032020-11-26 20:25:29 +1000827#ifndef arch_clear_mm_cpumask_cpu
828#define arch_clear_mm_cpumask_cpu(cpu, mm) cpumask_clear_cpu(cpu, mm_cpumask(mm))
829#endif
830
Anton Vorontsove4cc2f82012-05-31 16:26:26 -0700831/**
832 * clear_tasks_mm_cpumask - Safely clear tasks' mm_cpumask for a CPU
833 * @cpu: a CPU id
834 *
835 * This function walks all processes, finds a valid mm struct for each one and
836 * then clears a corresponding bit in mm's cpumask. While this all sounds
837 * trivial, there are various non-obvious corner cases, which this function
838 * tries to solve in a safe manner.
839 *
840 * Also note that the function uses a somewhat relaxed locking scheme, so it may
841 * be called only for an already offlined CPU.
842 */
Anton Vorontsovcb792952012-05-31 16:26:22 -0700843void clear_tasks_mm_cpumask(int cpu)
844{
845 struct task_struct *p;
846
847 /*
848 * This function is called after the cpu is taken down and marked
849 * offline, so its not like new tasks will ever get this cpu set in
850 * their mm mask. -- Peter Zijlstra
851 * Thus, we may use rcu_read_lock() here, instead of grabbing
852 * full-fledged tasklist_lock.
853 */
Anton Vorontsove4cc2f82012-05-31 16:26:26 -0700854 WARN_ON(cpu_online(cpu));
Anton Vorontsovcb792952012-05-31 16:26:22 -0700855 rcu_read_lock();
856 for_each_process(p) {
857 struct task_struct *t;
858
Anton Vorontsove4cc2f82012-05-31 16:26:26 -0700859 /*
860 * Main thread might exit, but other threads may still have
861 * a valid mm. Find one.
862 */
Anton Vorontsovcb792952012-05-31 16:26:22 -0700863 t = find_lock_task_mm(p);
864 if (!t)
865 continue;
Nicholas Pigginfe348032020-11-26 20:25:29 +1000866 arch_clear_mm_cpumask_cpu(cpu, t->mm);
Anton Vorontsovcb792952012-05-31 16:26:22 -0700867 task_unlock(t);
868 }
869 rcu_read_unlock();
870}
871
Kirill Tkhaib728ca02014-06-25 12:19:55 +0400872static inline void check_for_tasks(int dead_cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873{
Kirill Tkhaib728ca02014-06-25 12:19:55 +0400874 struct task_struct *g, *p;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
Oleg Nesterova75a6062015-09-10 15:07:50 +0200876 read_lock(&tasklist_lock);
877 for_each_process_thread(g, p) {
Kirill Tkhaib728ca02014-06-25 12:19:55 +0400878 if (!p->on_rq)
879 continue;
880 /*
881 * We do the check with unlocked task_rq(p)->lock.
882 * Order the reading to do not warn about a task,
883 * which was running on this cpu in the past, and
884 * it's just been woken on another cpu.
885 */
886 rmb();
887 if (task_cpu(p) != dead_cpu)
888 continue;
889
890 pr_warn("Task %s (pid=%d) is on cpu %d (state=%ld, flags=%x)\n",
891 p->comm, task_pid_nr(p), dead_cpu, p->state, p->flags);
Oleg Nesterova75a6062015-09-10 15:07:50 +0200892 }
893 read_unlock(&tasklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894}
895
Thomas Gleixner98458172016-02-26 18:43:25 +0000896static int notify_down_prepare(unsigned int cpu)
897{
898 int err, nr_calls = 0;
899
900 err = __cpu_notify(CPU_DOWN_PREPARE, cpu, -1, &nr_calls);
901 if (err) {
902 nr_calls--;
903 __cpu_notify(CPU_DOWN_FAILED, cpu, nr_calls, NULL);
904 pr_warn("%s: attempt to take down CPU %u failed\n",
905 __func__, cpu);
906 }
907 return err;
908}
909
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910/* Take this CPU down. */
Mathias Krause71cf5ae2015-07-19 20:06:22 +0200911static int take_cpu_down(void *_param)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912{
Thomas Gleixner4baa0af2016-02-26 18:43:29 +0000913 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
914 enum cpuhp_state target = max((int)st->target, CPUHP_AP_OFFLINE);
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000915 int err, cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 /* Ensure this CPU doesn't handle any more interrupts. */
918 err = __cpu_disable();
919 if (err < 0)
Zwane Mwaikambof3705132005-06-25 14:54:50 -0700920 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921
Thomas Gleixnera7246322016-08-12 19:49:38 +0200922 /*
923 * We get here while we are in CPUHP_TEARDOWN_CPU state and we must not
924 * do this step again.
925 */
926 WARN_ON(st->state != CPUHP_TEARDOWN_CPU);
927 st->state--;
Thomas Gleixner4baa0af2016-02-26 18:43:29 +0000928 /* Invoke the former CPU_DYING callbacks */
Thomas Gleixnera7246322016-08-12 19:49:38 +0200929 for (; st->state > target; st->state--)
Thomas Gleixnercf392d12016-08-12 19:49:39 +0200930 cpuhp_invoke_callback(cpu, st->state, false, NULL);
Thomas Gleixner4baa0af2016-02-26 18:43:29 +0000931
Thomas Gleixner52c063d2015-04-03 02:37:24 +0200932 /* Give up timekeeping duties */
933 tick_handover_do_timer();
Thomas Gleixner14e568e2013-01-31 12:11:14 +0000934 /* Park the stopper thread */
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000935 stop_machine_park(cpu);
Zwane Mwaikambof3705132005-06-25 14:54:50 -0700936 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937}
938
Thomas Gleixner98458172016-02-26 18:43:25 +0000939static int takedown_cpu(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940{
Thomas Gleixnere69aab12016-02-26 18:43:43 +0000941 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
Thomas Gleixner98458172016-02-26 18:43:25 +0000942 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943
Thomas Gleixner2a58c522016-03-10 20:42:08 +0100944 /* Park the smpboot threads */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +0000945 kthread_park(per_cpu_ptr(&cpuhp_state, cpu)->thread);
946
Peter Zijlstra6acce3e2013-10-11 14:38:20 +0200947 /*
Thomas Gleixnera8994182015-07-05 17:12:30 +0000948 * Prevent irq alloc/free while the dying cpu reorganizes the
949 * interrupt affinities.
950 */
951 irq_lock_sparse();
952
953 /*
Peter Zijlstra6acce3e2013-10-11 14:38:20 +0200954 * So now all preempt/rcu users must observe !cpu_active().
955 */
Thomas Gleixner090e77c2016-02-26 18:43:23 +0000956 err = stop_machine(take_cpu_down, NULL, cpumask_of(cpu));
Rusty Russell04321582008-07-28 12:16:29 -0500957 if (err) {
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200958 /* CPU refused to die */
Thomas Gleixnera8994182015-07-05 17:12:30 +0000959 irq_unlock_sparse();
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +0200960 /* Unpark the hotplug thread so we can rollback there */
961 kthread_unpark(per_cpu_ptr(&cpuhp_state, cpu)->thread);
Thomas Gleixner98458172016-02-26 18:43:25 +0000962 return err;
Satoru Takeuchi8fa1d7d2006-10-28 10:38:57 -0700963 }
Rusty Russell04321582008-07-28 12:16:29 -0500964 BUG_ON(cpu_online(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965
Peter Zijlstra48c5cca2010-11-13 19:32:29 +0100966 /*
Thomas Gleixneree1e7142016-08-18 14:57:16 +0200967 * The CPUHP_AP_SCHED_MIGRATE_DYING callback will have removed all
Peter Zijlstra48c5cca2010-11-13 19:32:29 +0100968 * runnable tasks from the cpu, there's only the idle task left now
969 * that the migration thread is done doing the stop_machine thing.
Peter Zijlstra51a96c72010-11-19 20:37:53 +0100970 *
971 * Wait for the stop thread to go away.
Peter Zijlstra48c5cca2010-11-13 19:32:29 +0100972 */
Thomas Gleixnere69aab12016-02-26 18:43:43 +0000973 wait_for_completion(&st->done);
974 BUG_ON(st->state != CPUHP_AP_IDLE_DEAD);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975
Thomas Gleixnera8994182015-07-05 17:12:30 +0000976 /* Interrupts are moved away from the dying cpu, reenable alloc/free */
977 irq_unlock_sparse();
978
Preeti U Murthy345527b2015-03-30 14:59:19 +0530979 hotplug_cpu__broadcast_tick_pull(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980 /* This actually kills the CPU. */
981 __cpu_die(cpu);
982
Thomas Gleixnera49b1162015-04-03 02:38:05 +0200983 tick_cleanup_dead_cpu(cpu);
Thomas Gleixner98458172016-02-26 18:43:25 +0000984 return 0;
985}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986
Thomas Gleixner98458172016-02-26 18:43:25 +0000987static int notify_dead(unsigned int cpu)
988{
989 cpu_notify_nofail(CPU_DEAD, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 check_for_tasks(cpu);
Thomas Gleixner98458172016-02-26 18:43:25 +0000991 return 0;
992}
993
Thomas Gleixner71f87b22016-03-03 10:52:10 +0100994static void cpuhp_complete_idle_dead(void *arg)
995{
996 struct cpuhp_cpu_state *st = arg;
997
998 complete(&st->done);
999}
1000
Thomas Gleixnere69aab12016-02-26 18:43:43 +00001001void cpuhp_report_idle_dead(void)
1002{
1003 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
1004
1005 BUG_ON(st->state != CPUHP_AP_OFFLINE);
Thomas Gleixner27d50c72016-02-26 18:43:44 +00001006 rcu_report_dead(smp_processor_id());
Thomas Gleixner71f87b22016-03-03 10:52:10 +01001007 st->state = CPUHP_AP_IDLE_DEAD;
1008 /*
1009 * We cannot call complete after rcu_report_dead() so we delegate it
1010 * to an online cpu.
1011 */
1012 smp_call_function_single(cpumask_first(cpu_online_mask),
1013 cpuhp_complete_idle_dead, st, 0);
Thomas Gleixnere69aab12016-02-26 18:43:43 +00001014}
1015
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001016#else
1017#define notify_down_prepare NULL
1018#define takedown_cpu NULL
1019#define notify_dead NULL
1020#endif
1021
1022#ifdef CONFIG_HOTPLUG_CPU
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001023
Thomas Gleixner98458172016-02-26 18:43:25 +00001024/* Requires cpu_add_remove_lock to be held */
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001025static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,
1026 enum cpuhp_state target)
Thomas Gleixner98458172016-02-26 18:43:25 +00001027{
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001028 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1029 int prev_state, ret = 0;
1030 bool hasdied = false;
Prasad Sodagudi0a293432017-10-13 15:28:58 -07001031 u64 start_time = 0;
Thomas Gleixner98458172016-02-26 18:43:25 +00001032
1033 if (num_online_cpus() == 1)
1034 return -EBUSY;
1035
Thomas Gleixner757c9892016-02-26 18:43:32 +00001036 if (!cpu_present(cpu))
Thomas Gleixner98458172016-02-26 18:43:25 +00001037 return -EINVAL;
1038
Pavankumar Kondeti68435b02017-06-29 16:17:55 +05301039 if (!tasks_frozen && !cpu_isolated(cpu) && num_online_uniso_cpus() == 1)
1040 return -EBUSY;
1041
Thomas Gleixner98458172016-02-26 18:43:25 +00001042 cpu_hotplug_begin();
Prasad Sodagudi0a293432017-10-13 15:28:58 -07001043 if (trace_cpuhp_latency_enabled())
1044 start_time = sched_clock();
Thomas Gleixner98458172016-02-26 18:43:25 +00001045
1046 cpuhp_tasks_frozen = tasks_frozen;
1047
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001048 prev_state = st->state;
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001049 st->target = target;
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001050 /*
1051 * If the current CPU state is in the range of the AP hotplug thread,
1052 * then we need to kick the thread.
1053 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001054 if (st->state > CPUHP_TEARDOWN_CPU) {
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001055 ret = cpuhp_kick_ap_work(cpu);
1056 /*
1057 * The AP side has done the error rollback already. Just
1058 * return the error code..
1059 */
1060 if (ret)
1061 goto out;
1062
1063 /*
1064 * We might have stopped still in the range of the AP hotplug
1065 * thread. Nothing to do anymore.
1066 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001067 if (st->state > CPUHP_TEARDOWN_CPU)
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001068 goto out;
1069 }
1070 /*
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001071 * The AP brought itself down to CPUHP_TEARDOWN_CPU. So we need
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001072 * to do the further cleanups.
1073 */
Thomas Gleixnera7246322016-08-12 19:49:38 +02001074 ret = cpuhp_down_callbacks(cpu, st, target);
Sebastian Andrzej Siewior3b9d6da2016-04-08 14:40:15 +02001075 if (ret && st->state > CPUHP_TEARDOWN_CPU && st->state < prev_state) {
1076 st->target = prev_state;
1077 st->rollback = true;
1078 cpuhp_kick_ap_work(cpu);
1079 }
Thomas Gleixner98458172016-02-26 18:43:25 +00001080
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001081 hasdied = prev_state != st->state && st->state == CPUHP_OFFLINE;
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001082out:
Prasad Sodagudi0a293432017-10-13 15:28:58 -07001083 trace_cpuhp_latency(cpu, 0, start_time, ret);
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001084 cpu_hotplug_done();
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001085 /* This post dead nonsense must die */
1086 if (!ret && hasdied)
Thomas Gleixner090e77c2016-02-26 18:43:23 +00001087 cpu_notify_nofail(CPU_POST_DEAD, cpu);
Thomas Gleixnera3c901b2018-11-25 19:33:39 +01001088 arch_smt_update();
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001089 return ret;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001090}
1091
Thomas Gleixner373b8de2018-05-29 17:49:05 +02001092static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target)
1093{
1094 if (cpu_hotplug_disabled)
1095 return -EBUSY;
1096 return _cpu_down(cpu, 0, target);
1097}
1098
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001099static int do_cpu_down(unsigned int cpu, enum cpuhp_state target)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001100{
Heiko Carstens9ea09af2008-12-22 12:36:30 +01001101 int err;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001102
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001103 cpu_maps_update_begin();
Thomas Gleixner373b8de2018-05-29 17:49:05 +02001104 err = cpu_down_maps_locked(cpu, target);
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001105 cpu_maps_update_done();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106 return err;
1107}
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001108int cpu_down(unsigned int cpu)
1109{
1110 return do_cpu_down(cpu, CPUHP_OFFLINE);
1111}
Zhang Ruib62b8ef2008-04-29 02:35:56 -04001112EXPORT_SYMBOL(cpu_down);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113#endif /*CONFIG_HOTPLUG_CPU*/
1114
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001115/**
Thomas Gleixneree1e7142016-08-18 14:57:16 +02001116 * notify_cpu_starting(cpu) - Invoke the callbacks on the starting CPU
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001117 * @cpu: cpu that just started
1118 *
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001119 * It must be called by the arch code on the new cpu, before the new cpu
1120 * enables interrupts and before the "boot" cpu returns from __cpu_up().
1121 */
1122void notify_cpu_starting(unsigned int cpu)
1123{
1124 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1125 enum cpuhp_state target = min((int)st->target, CPUHP_AP_ONLINE);
1126
Sebastian Andrzej Siewior0c6d4572016-08-17 14:21:04 +02001127 rcu_cpu_starting(cpu); /* Enables RCU usage on this CPU. */
Thomas Gleixner8438e492018-06-29 16:05:48 +02001128 st->booted_once = true;
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001129 while (st->state < target) {
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001130 st->state++;
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001131 cpuhp_invoke_callback(cpu, st->state, true, NULL);
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001132 }
1133}
1134
Thomas Gleixner949338e2016-02-26 18:43:35 +00001135/*
Thomas Gleixnerceb354b2017-07-04 22:20:23 +02001136 * Called from the idle task. Wake up the controlling task which brings the
Peter Zijlstraa594a9e2019-12-10 09:34:54 +01001137 * hotplug thread of the upcoming CPU up and then delegates the rest of the
1138 * online bringup to the hotplug thread.
Thomas Gleixner949338e2016-02-26 18:43:35 +00001139 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001140void cpuhp_online_idle(enum cpuhp_state state)
Thomas Gleixner949338e2016-02-26 18:43:35 +00001141{
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001142 struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001143
1144 /* Happens for the boot cpu */
1145 if (state != CPUHP_AP_ONLINE_IDLE)
1146 return;
1147
Peter Zijlstraa594a9e2019-12-10 09:34:54 +01001148 /*
1149 * Unpart the stopper thread before we start the idle loop (and start
1150 * scheduling); this ensures the stopper task is always available.
1151 */
1152 stop_machine_unpark(smp_processor_id());
1153
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001154 st->state = CPUHP_AP_ONLINE_IDLE;
Thomas Gleixnerceb354b2017-07-04 22:20:23 +02001155 complete(&st->done);
Thomas Gleixner949338e2016-02-26 18:43:35 +00001156}
1157
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001158/* Requires cpu_add_remove_lock to be held */
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001159static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160{
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001161 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
Suresh Siddha3bb5d2e2012-04-20 17:08:50 -07001162 struct task_struct *idle;
Thomas Gleixner2e1a3482016-02-26 18:43:37 +00001163 int ret = 0;
Prasad Sodagudi0a293432017-10-13 15:28:58 -07001164 u64 start_time = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001166 cpu_hotplug_begin();
Prasad Sodagudi0a293432017-10-13 15:28:58 -07001167 if (trace_cpuhp_latency_enabled())
1168 start_time = sched_clock();
Thomas Gleixner38498a62012-04-20 13:05:44 +00001169
Thomas Gleixner757c9892016-02-26 18:43:32 +00001170 if (!cpu_present(cpu)) {
Yasuaki Ishimatsu5e5041f2012-10-23 01:30:54 +02001171 ret = -EINVAL;
1172 goto out;
1173 }
1174
Thomas Gleixner757c9892016-02-26 18:43:32 +00001175 /*
1176 * The caller of do_cpu_up might have raced with another
1177 * caller. Ignore it for now.
1178 */
1179 if (st->state >= target)
Thomas Gleixner38498a62012-04-20 13:05:44 +00001180 goto out;
Thomas Gleixner757c9892016-02-26 18:43:32 +00001181
1182 if (st->state == CPUHP_OFFLINE) {
1183 /* Let it fail before we try to bring the cpu up */
1184 idle = idle_thread_get(cpu);
1185 if (IS_ERR(idle)) {
1186 ret = PTR_ERR(idle);
1187 goto out;
1188 }
Suresh Siddha3bb5d2e2012-04-20 17:08:50 -07001189 }
Thomas Gleixner38498a62012-04-20 13:05:44 +00001190
Thomas Gleixnerba997462016-02-26 18:43:24 +00001191 cpuhp_tasks_frozen = tasks_frozen;
1192
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001193 st->target = target;
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001194 /*
1195 * If the current CPU state is in the range of the AP hotplug thread,
1196 * then we need to kick the thread once more.
1197 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001198 if (st->state > CPUHP_BRINGUP_CPU) {
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001199 ret = cpuhp_kick_ap_work(cpu);
1200 /*
1201 * The AP side has done the error rollback already. Just
1202 * return the error code..
1203 */
1204 if (ret)
1205 goto out;
1206 }
1207
1208 /*
1209 * Try to reach the target state. We max out on the BP at
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001210 * CPUHP_BRINGUP_CPU. After that the AP hotplug thread is
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001211 * responsible for bringing it up to the target state.
1212 */
Thomas Gleixner8df3e072016-02-26 18:43:41 +00001213 target = min((int)target, CPUHP_BRINGUP_CPU);
Thomas Gleixnera7246322016-08-12 19:49:38 +02001214 ret = cpuhp_up_callbacks(cpu, st, target);
Thomas Gleixner38498a62012-04-20 13:05:44 +00001215out:
Prasad Sodagudi0a293432017-10-13 15:28:58 -07001216 trace_cpuhp_latency(cpu, 1, start_time, ret);
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001217 cpu_hotplug_done();
Thomas Gleixnera3c901b2018-11-25 19:33:39 +01001218 arch_smt_update();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 return ret;
1220}
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001221
Syed Rameez Mustafab3058802016-12-16 11:59:05 -08001222static int switch_to_rt_policy(void)
1223{
1224 struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
1225 unsigned int policy = current->policy;
1226 int err;
1227
1228 /* Nobody should be attempting hotplug from these policy contexts. */
1229 if (policy == SCHED_BATCH || policy == SCHED_IDLE ||
1230 policy == SCHED_DEADLINE)
1231 return -EPERM;
1232
1233 if (policy == SCHED_FIFO || policy == SCHED_RR)
1234 return 1;
1235
1236 /* Only SCHED_NORMAL left. */
1237 err = sched_setscheduler_nocheck(current, SCHED_FIFO, &param);
1238 return err;
1239
1240}
1241
1242static int switch_to_fair_policy(void)
1243{
1244 struct sched_param param = { .sched_priority = 0 };
1245
1246 return sched_setscheduler_nocheck(current, SCHED_NORMAL, &param);
1247}
1248
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001249static int do_cpu_up(unsigned int cpu, enum cpuhp_state target)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001250{
1251 int err = 0;
Syed Rameez Mustafab3058802016-12-16 11:59:05 -08001252 int switch_err = 0;
minskey guocf234222010-05-24 14:32:41 -07001253
Rusty Russelle0b582e2009-01-01 10:12:28 +10301254 if (!cpu_possible(cpu)) {
Fabian Frederick84117da2014-06-04 16:11:17 -07001255 pr_err("can't online cpu %d because it is not configured as may-hotadd at boot time\n",
1256 cpu);
Chen Gong87d5e022010-03-05 13:42:38 -08001257#if defined(CONFIG_IA64)
Fabian Frederick84117da2014-06-04 16:11:17 -07001258 pr_err("please check additional_cpus= boot parameter\n");
KAMEZAWA Hiroyuki73e753a2007-10-18 23:40:47 -07001259#endif
1260 return -EINVAL;
1261 }
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001262
Syed Rameez Mustafab3058802016-12-16 11:59:05 -08001263 switch_err = switch_to_rt_policy();
1264 if (switch_err < 0)
1265 return switch_err;
1266
Toshi Kani01b0f192013-11-12 15:07:25 -08001267 err = try_online_node(cpu_to_node(cpu));
1268 if (err)
1269 return err;
minskey guocf234222010-05-24 14:32:41 -07001270
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001271 cpu_maps_update_begin();
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001272
Max Krasnyanskye761b772008-07-15 04:43:49 -07001273 if (cpu_hotplug_disabled) {
1274 err = -EBUSY;
1275 goto out;
1276 }
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02001277 if (!cpu_smt_allowed(cpu)) {
1278 err = -EPERM;
1279 goto out;
1280 }
Max Krasnyanskye761b772008-07-15 04:43:49 -07001281
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001282 err = _cpu_up(cpu, 0, target);
Max Krasnyanskye761b772008-07-15 04:43:49 -07001283out:
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001284 cpu_maps_update_done();
Syed Rameez Mustafab3058802016-12-16 11:59:05 -08001285
1286 if (!switch_err) {
1287 switch_err = switch_to_fair_policy();
Pavankumar Kondeti657ad052017-04-14 14:59:40 +05301288 if (switch_err)
1289 pr_err("Hotplug policy switch err=%d Task %s pid=%d\n",
1290 switch_err, current->comm, current->pid);
Syed Rameez Mustafab3058802016-12-16 11:59:05 -08001291 }
1292
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001293 return err;
1294}
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001295
1296int cpu_up(unsigned int cpu)
1297{
1298 return do_cpu_up(cpu, CPUHP_ONLINE);
1299}
Paul E. McKenneya513f6b2011-12-11 21:54:45 -08001300EXPORT_SYMBOL_GPL(cpu_up);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001301
Rafael J. Wysockif3de4be2007-08-30 23:56:29 -07001302#ifdef CONFIG_PM_SLEEP_SMP
Rusty Russelle0b582e2009-01-01 10:12:28 +10301303static cpumask_var_t frozen_cpus;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001304
James Morsed391e552016-08-17 13:50:25 +01001305int freeze_secondary_cpus(int primary)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001306{
James Morsed391e552016-08-17 13:50:25 +01001307 int cpu, error = 0;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001308
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001309 cpu_maps_update_begin();
James Morsed391e552016-08-17 13:50:25 +01001310 if (!cpu_online(primary))
1311 primary = cpumask_first(cpu_online_mask);
Xiaotian Feng9ee349a2009-12-16 18:04:32 +01001312 /*
1313 * We take down all of the non-boot CPUs in one shot to avoid races
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001314 * with the userspace trying to use the CPU hotplug at the same time
1315 */
Rusty Russelle0b582e2009-01-01 10:12:28 +10301316 cpumask_clear(frozen_cpus);
Peter Zijlstra6ad4c182009-11-25 13:31:39 +01001317
Fabian Frederick84117da2014-06-04 16:11:17 -07001318 pr_info("Disabling non-boot CPUs ...\n");
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001319 for_each_online_cpu(cpu) {
James Morsed391e552016-08-17 13:50:25 +01001320 if (cpu == primary)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001321 continue;
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001322 trace_suspend_resume(TPS("CPU_OFF"), cpu, true);
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001323 error = _cpu_down(cpu, 1, CPUHP_OFFLINE);
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001324 trace_suspend_resume(TPS("CPU_OFF"), cpu, false);
Mike Travisfeae3202009-11-17 18:22:13 -06001325 if (!error)
Rusty Russelle0b582e2009-01-01 10:12:28 +10301326 cpumask_set_cpu(cpu, frozen_cpus);
Mike Travisfeae3202009-11-17 18:22:13 -06001327 else {
Fabian Frederick84117da2014-06-04 16:11:17 -07001328 pr_err("Error taking CPU%d down: %d\n", cpu, error);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001329 break;
1330 }
1331 }
Joseph Cihula86886e52009-06-30 19:31:07 -07001332
Vitaly Kuznetsov89af7ba2015-08-05 00:52:46 -07001333 if (!error)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001334 BUG_ON(num_online_cpus() > 1);
Vitaly Kuznetsov89af7ba2015-08-05 00:52:46 -07001335 else
Fabian Frederick84117da2014-06-04 16:11:17 -07001336 pr_err("Non-boot CPUs are not disabled\n");
Vitaly Kuznetsov89af7ba2015-08-05 00:52:46 -07001337
1338 /*
1339 * Make sure the CPUs won't be enabled by someone else. We need to do
1340 * this even in case of failure as all disable_nonboot_cpus() users are
1341 * supposed to do enable_nonboot_cpus() on the failure path.
1342 */
1343 cpu_hotplug_disabled++;
1344
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001345 cpu_maps_update_done();
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001346 return error;
1347}
1348
Suresh Siddhad0af9ee2009-08-19 18:05:36 -07001349void __weak arch_enable_nonboot_cpus_begin(void)
1350{
1351}
1352
1353void __weak arch_enable_nonboot_cpus_end(void)
1354{
1355}
1356
Mathias Krause71cf5ae2015-07-19 20:06:22 +02001357void enable_nonboot_cpus(void)
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001358{
1359 int cpu, error;
Thierry Strudel0c3610e2016-06-14 17:46:44 -07001360 struct device *cpu_device;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001361
1362 /* Allow everyone to use the CPU hotplug again */
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001363 cpu_maps_update_begin();
Lianwei Wang01b41152016-06-09 23:43:28 -07001364 __cpu_hotplug_enable();
Rusty Russelle0b582e2009-01-01 10:12:28 +10301365 if (cpumask_empty(frozen_cpus))
Rafael J. Wysocki1d64b9c2007-04-01 23:49:49 -07001366 goto out;
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001367
Fabian Frederick84117da2014-06-04 16:11:17 -07001368 pr_info("Enabling non-boot CPUs ...\n");
Suresh Siddhad0af9ee2009-08-19 18:05:36 -07001369
1370 arch_enable_nonboot_cpus_begin();
1371
Rusty Russelle0b582e2009-01-01 10:12:28 +10301372 for_each_cpu(cpu, frozen_cpus) {
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001373 trace_suspend_resume(TPS("CPU_ON"), cpu, true);
Thomas Gleixneraf1f4042016-02-26 18:43:30 +00001374 error = _cpu_up(cpu, 1, CPUHP_ONLINE);
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001375 trace_suspend_resume(TPS("CPU_ON"), cpu, false);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001376 if (!error) {
Fabian Frederick84117da2014-06-04 16:11:17 -07001377 pr_info("CPU%d is up\n", cpu);
Thierry Strudel0c3610e2016-06-14 17:46:44 -07001378 cpu_device = get_cpu_device(cpu);
1379 if (!cpu_device)
1380 pr_err("%s: failed to get cpu%d device\n",
1381 __func__, cpu);
1382 else
1383 kobject_uevent(&cpu_device->kobj, KOBJ_ONLINE);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001384 continue;
1385 }
Fabian Frederick84117da2014-06-04 16:11:17 -07001386 pr_warn("Error taking CPU%d up: %d\n", cpu, error);
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001387 }
Suresh Siddhad0af9ee2009-08-19 18:05:36 -07001388
1389 arch_enable_nonboot_cpus_end();
1390
Rusty Russelle0b582e2009-01-01 10:12:28 +10301391 cpumask_clear(frozen_cpus);
Rafael J. Wysocki1d64b9c2007-04-01 23:49:49 -07001392out:
Gautham R Shenoyd2219382008-01-25 21:08:01 +01001393 cpu_maps_update_done();
Rafael J. Wysockie3920fb2006-09-25 23:32:48 -07001394}
Rusty Russelle0b582e2009-01-01 10:12:28 +10301395
Fenghua Yud7268a32011-11-15 21:59:31 +01001396static int __init alloc_frozen_cpus(void)
Rusty Russelle0b582e2009-01-01 10:12:28 +10301397{
1398 if (!alloc_cpumask_var(&frozen_cpus, GFP_KERNEL|__GFP_ZERO))
1399 return -ENOMEM;
1400 return 0;
1401}
1402core_initcall(alloc_frozen_cpus);
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001403
1404/*
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001405 * When callbacks for CPU hotplug notifications are being executed, we must
1406 * ensure that the state of the system with respect to the tasks being frozen
1407 * or not, as reported by the notification, remains unchanged *throughout the
1408 * duration* of the execution of the callbacks.
1409 * Hence we need to prevent the freezer from racing with regular CPU hotplug.
1410 *
1411 * This synchronization is implemented by mutually excluding regular CPU
1412 * hotplug and Suspend/Hibernate call paths by hooking onto the Suspend/
1413 * Hibernate notifications.
1414 */
1415static int
1416cpu_hotplug_pm_callback(struct notifier_block *nb,
1417 unsigned long action, void *ptr)
1418{
1419 switch (action) {
1420
1421 case PM_SUSPEND_PREPARE:
1422 case PM_HIBERNATION_PREPARE:
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -07001423 cpu_hotplug_disable();
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001424 break;
1425
1426 case PM_POST_SUSPEND:
1427 case PM_POST_HIBERNATION:
Srivatsa S. Bhat16e53db2013-06-12 14:04:36 -07001428 cpu_hotplug_enable();
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001429 break;
1430
1431 default:
1432 return NOTIFY_DONE;
1433 }
1434
1435 return NOTIFY_OK;
1436}
1437
1438
Fenghua Yud7268a32011-11-15 21:59:31 +01001439static int __init cpu_hotplug_pm_sync_init(void)
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001440{
Fenghua Yu6e32d472012-11-13 11:32:43 -08001441 /*
1442 * cpu_hotplug_pm_callback has higher priority than x86
1443 * bsp_pm_callback which depends on cpu_hotplug_pm_callback
1444 * to disable cpu hotplug to avoid cpu hotplug race.
1445 */
Srivatsa S. Bhat79cfbdf2011-11-03 00:59:25 +01001446 pm_notifier(cpu_hotplug_pm_callback, 0);
1447 return 0;
1448}
1449core_initcall(cpu_hotplug_pm_sync_init);
1450
Rafael J. Wysockif3de4be2007-08-30 23:56:29 -07001451#endif /* CONFIG_PM_SLEEP_SMP */
Max Krasnyansky68f4f1e2008-05-29 11:17:02 -07001452
1453#endif /* CONFIG_SMP */
Mike Travisb8d317d2008-07-24 18:21:29 -07001454
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001455/* Boot processor state steps */
1456static struct cpuhp_step cpuhp_bp_states[] = {
1457 [CPUHP_OFFLINE] = {
1458 .name = "offline",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001459 .startup.single = NULL,
1460 .teardown.single = NULL,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001461 },
1462#ifdef CONFIG_SMP
1463 [CPUHP_CREATE_THREADS]= {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001464 .name = "threads:prepare",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001465 .startup.single = smpboot_create_threads,
1466 .teardown.single = NULL,
Thomas Gleixner757c9892016-02-26 18:43:32 +00001467 .cant_stop = true,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001468 },
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001469 [CPUHP_PERF_PREPARE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001470 .name = "perf:prepare",
1471 .startup.single = perf_event_init_cpu,
1472 .teardown.single = perf_event_exit_cpu,
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001473 },
Jason A. Donenfelded20ec42022-02-13 22:48:04 +01001474 [CPUHP_RANDOM_PREPARE] = {
1475 .name = "random:prepare",
1476 .startup.single = random_prepare_cpu,
1477 .teardown.single = NULL,
1478 },
Thomas Gleixner7ee681b2016-07-13 17:16:29 +00001479 [CPUHP_WORKQUEUE_PREP] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001480 .name = "workqueue:prepare",
1481 .startup.single = workqueue_prepare_cpu,
1482 .teardown.single = NULL,
Thomas Gleixner7ee681b2016-07-13 17:16:29 +00001483 },
Thomas Gleixner27590dc2016-07-15 10:41:04 +02001484 [CPUHP_HRTIMERS_PREPARE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001485 .name = "hrtimers:prepare",
1486 .startup.single = hrtimers_prepare_cpu,
1487 .teardown.single = hrtimers_dead_cpu,
Thomas Gleixner27590dc2016-07-15 10:41:04 +02001488 },
Richard Weinberger31487f82016-07-13 17:17:01 +00001489 [CPUHP_SMPCFD_PREPARE] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001490 .name = "smpcfd:prepare",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001491 .startup.single = smpcfd_prepare_cpu,
1492 .teardown.single = smpcfd_dead_cpu,
Richard Weinberger31487f82016-07-13 17:17:01 +00001493 },
Richard Weinbergere6d49892016-08-18 14:57:17 +02001494 [CPUHP_RELAY_PREPARE] = {
1495 .name = "relay:prepare",
1496 .startup.single = relay_prepare_cpu,
1497 .teardown.single = NULL,
1498 },
Sebastian Andrzej Siewior6731d4f2016-08-23 14:53:19 +02001499 [CPUHP_SLAB_PREPARE] = {
1500 .name = "slab:prepare",
1501 .startup.single = slab_prepare_cpu,
1502 .teardown.single = slab_dead_cpu,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001503 },
Thomas Gleixner4df83742016-07-13 17:17:03 +00001504 [CPUHP_RCUTREE_PREP] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001505 .name = "RCU/tree:prepare",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001506 .startup.single = rcutree_prepare_cpu,
1507 .teardown.single = rcutree_dead_cpu,
Thomas Gleixner4df83742016-07-13 17:17:03 +00001508 },
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001509 /*
1510 * Preparatory and dead notifiers. Will be replaced once the notifiers
1511 * are converted to states.
1512 */
1513 [CPUHP_NOTIFY_PREPARE] = {
1514 .name = "notify:prepare",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001515 .startup.single = notify_prepare,
1516 .teardown.single = notify_dead,
Thomas Gleixner757c9892016-02-26 18:43:32 +00001517 .cant_stop = true,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001518 },
Richard Cochran4fae16d2016-07-27 11:08:18 +02001519 /*
1520 * On the tear-down path, timers_dead_cpu() must be invoked
1521 * before blk_mq_queue_reinit_notify() from notify_dead(),
1522 * otherwise a RCU stall occurs.
1523 */
Thomas Gleixner249d4a92017-12-27 21:37:25 +01001524 [CPUHP_TIMERS_PREPARE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001525 .name = "timers:dead",
Thomas Gleixner249d4a92017-12-27 21:37:25 +01001526 .startup.single = timers_prepare_cpu,
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001527 .teardown.single = timers_dead_cpu,
Richard Cochran4fae16d2016-07-27 11:08:18 +02001528 },
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001529 /* Kicks the plugged cpu into life */
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001530 [CPUHP_BRINGUP_CPU] = {
1531 .name = "cpu:bringup",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001532 .startup.single = bringup_cpu,
1533 .teardown.single = NULL,
Thomas Gleixner757c9892016-02-26 18:43:32 +00001534 .cant_stop = true,
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001535 },
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001536 /*
1537 * Handled on controll processor until the plugged processor manages
1538 * this itself.
1539 */
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001540 [CPUHP_TEARDOWN_CPU] = {
1541 .name = "cpu:teardown",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001542 .startup.single = NULL,
1543 .teardown.single = takedown_cpu,
Thomas Gleixner757c9892016-02-26 18:43:32 +00001544 .cant_stop = true,
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001545 },
Thomas Gleixnera7c734142016-07-12 21:59:23 +02001546#else
1547 [CPUHP_BRINGUP_CPU] = { },
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001548#endif
Thomas Gleixnercff7d372016-02-26 18:43:28 +00001549};
1550
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001551/* Application processor state steps */
1552static struct cpuhp_step cpuhp_ap_states[] = {
1553#ifdef CONFIG_SMP
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001554 /* Final state before CPU kills itself */
1555 [CPUHP_AP_IDLE_DEAD] = {
1556 .name = "idle:dead",
1557 },
1558 /*
1559 * Last state before CPU enters the idle loop to die. Transient state
1560 * for synchronization.
1561 */
1562 [CPUHP_AP_OFFLINE] = {
1563 .name = "ap:offline",
1564 .cant_stop = true,
1565 },
Thomas Gleixner9cf72432016-03-10 12:54:09 +01001566 /* First state is scheduler control. Interrupts are disabled */
1567 [CPUHP_AP_SCHED_STARTING] = {
1568 .name = "sched:starting",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001569 .startup.single = sched_cpu_starting,
1570 .teardown.single = sched_cpu_dying,
Thomas Gleixner9cf72432016-03-10 12:54:09 +01001571 },
Thomas Gleixner4df83742016-07-13 17:17:03 +00001572 [CPUHP_AP_RCUTREE_DYING] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001573 .name = "RCU/tree:dying",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001574 .startup.single = NULL,
1575 .teardown.single = rcutree_dying_cpu,
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001576 },
Maria Yue90f8e12017-09-21 11:30:53 +08001577 [CPUHP_AP_KMAP_DYING] = {
1578 .name = "KMAP:dying",
1579 .startup.single = NULL,
1580 .teardown.single = kmap_remove_unused_cpu,
1581 },
Lai Jiangshanff3d4fd2017-11-28 21:19:53 +08001582 [CPUHP_AP_SMPCFD_DYING] = {
1583 .name = "smpcfd:dying",
1584 .startup.single = NULL,
1585 .teardown.single = smpcfd_dying_cpu,
1586 },
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001587 /* Entry state on starting. Interrupts enabled from here on. Transient
1588 * state for synchronsization */
1589 [CPUHP_AP_ONLINE] = {
1590 .name = "ap:online",
1591 },
1592 /* Handle smpboot threads park/unpark */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001593 [CPUHP_AP_SMPBOOT_THREADS] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001594 .name = "smpboot/threads:online",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001595 .startup.single = smpboot_unpark_threads,
Thomas Gleixner93335752018-05-29 19:05:25 +02001596 .teardown.single = smpboot_park_threads,
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001597 },
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001598 [CPUHP_AP_PERF_ONLINE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001599 .name = "perf:online",
Raghavendra Rao Ananta595428c2018-10-16 12:13:22 -07001600 .startup.single = perf_event_restart_events,
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001601 .teardown.single = perf_event_exit_cpu,
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001602 },
Thomas Gleixner7ee681b2016-07-13 17:16:29 +00001603 [CPUHP_AP_WORKQUEUE_ONLINE] = {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001604 .name = "workqueue:online",
1605 .startup.single = workqueue_online_cpu,
1606 .teardown.single = workqueue_offline_cpu,
Thomas Gleixner7ee681b2016-07-13 17:16:29 +00001607 },
Jason A. Donenfelded20ec42022-02-13 22:48:04 +01001608 [CPUHP_AP_RANDOM_ONLINE] = {
1609 .name = "random:online",
1610 .startup.single = random_online_cpu,
1611 .teardown.single = NULL,
1612 },
Thomas Gleixner4df83742016-07-13 17:17:03 +00001613 [CPUHP_AP_RCUTREE_ONLINE] = {
Thomas Gleixner677f6642016-09-06 16:13:48 +02001614 .name = "RCU/tree:online",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001615 .startup.single = rcutree_online_cpu,
1616 .teardown.single = rcutree_offline_cpu,
Thomas Gleixner4df83742016-07-13 17:17:03 +00001617 },
Thomas Gleixner00e16c32016-07-13 17:16:09 +00001618
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001619 /*
1620 * Online/down_prepare notifiers. Will be removed once the notifiers
1621 * are converted to states.
1622 */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001623 [CPUHP_AP_NOTIFY_ONLINE] = {
1624 .name = "notify:online",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001625 .startup.single = notify_online,
1626 .teardown.single = notify_down_prepare,
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001627 },
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001628#endif
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001629 /*
1630 * The dynamically registered state space is here
1631 */
1632
Thomas Gleixneraaddd7d2016-03-10 12:54:19 +01001633#ifdef CONFIG_SMP
1634 /* Last state is scheduler control setting the cpu active */
1635 [CPUHP_AP_ACTIVE] = {
1636 .name = "sched:active",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001637 .startup.single = sched_cpu_activate,
1638 .teardown.single = sched_cpu_deactivate,
Thomas Gleixneraaddd7d2016-03-10 12:54:19 +01001639 },
1640#endif
1641
Thomas Gleixnerd10ef6f2016-03-08 10:36:13 +01001642 /* CPU is fully up and running. */
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001643 [CPUHP_ONLINE] = {
1644 .name = "online",
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001645 .startup.single = NULL,
1646 .teardown.single = NULL,
Thomas Gleixner4baa0af2016-02-26 18:43:29 +00001647 },
1648};
1649
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001650/* Sanity check for callbacks */
1651static int cpuhp_cb_check(enum cpuhp_state state)
1652{
1653 if (state <= CPUHP_OFFLINE || state >= CPUHP_ONLINE)
1654 return -EINVAL;
1655 return 0;
1656}
1657
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001658static void cpuhp_store_callbacks(enum cpuhp_state state,
1659 const char *name,
1660 int (*startup)(unsigned int cpu),
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001661 int (*teardown)(unsigned int cpu),
1662 bool multi_instance)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001663{
1664 /* (Un)Install the callbacks for further cpu hotplug operations */
1665 struct cpuhp_step *sp;
1666
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001667 sp = cpuhp_get_step(state);
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001668 sp->startup.single = startup;
1669 sp->teardown.single = teardown;
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001670 sp->name = name;
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001671 sp->multi_instance = multi_instance;
1672 INIT_HLIST_HEAD(&sp->list);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001673}
1674
1675static void *cpuhp_get_teardown_cb(enum cpuhp_state state)
1676{
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001677 return cpuhp_get_step(state)->teardown.single;
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001678}
1679
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001680/*
1681 * Call the startup/teardown function for a step either on the AP or
1682 * on the current CPU.
1683 */
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001684static int cpuhp_issue_call(int cpu, enum cpuhp_state state, bool bringup,
1685 struct hlist_node *node)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001686{
Thomas Gleixnera7246322016-08-12 19:49:38 +02001687 struct cpuhp_step *sp = cpuhp_get_step(state);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001688 int ret;
1689
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001690 if ((bringup && !sp->startup.single) ||
1691 (!bringup && !sp->teardown.single))
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001692 return 0;
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001693 /*
1694 * The non AP bound callbacks can fail on bringup. On teardown
1695 * e.g. module removal we crash for now.
1696 */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001697#ifdef CONFIG_SMP
1698 if (cpuhp_is_ap_state(state))
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001699 ret = cpuhp_invoke_ap_callback(cpu, state, bringup, node);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001700 else
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001701 ret = cpuhp_invoke_callback(cpu, state, bringup, node);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001702#else
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001703 ret = cpuhp_invoke_callback(cpu, state, bringup, node);
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001704#endif
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001705 BUG_ON(ret && !bringup);
1706 return ret;
1707}
1708
1709/*
1710 * Called from __cpuhp_setup_state on a recoverable failure.
1711 *
1712 * Note: The teardown callbacks for rollback are not allowed to fail!
1713 */
1714static void cpuhp_rollback_install(int failedcpu, enum cpuhp_state state,
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001715 struct hlist_node *node)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001716{
1717 int cpu;
1718
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001719 /* Roll back the already executed steps on the other cpus */
1720 for_each_present_cpu(cpu) {
1721 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1722 int cpustate = st->state;
1723
1724 if (cpu >= failedcpu)
1725 break;
1726
1727 /* Did we invoke the startup call on that cpu ? */
1728 if (cpustate >= state)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001729 cpuhp_issue_call(cpu, state, false, node);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001730 }
1731}
1732
1733/*
1734 * Returns a free for dynamic slot assignment of the Online state. The states
1735 * are protected by the cpuhp_slot_states mutex and an empty slot is identified
1736 * by having no name assigned.
1737 */
1738static int cpuhp_reserve_state(enum cpuhp_state state)
1739{
1740 enum cpuhp_state i;
1741
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001742 for (i = CPUHP_AP_ONLINE_DYN; i <= CPUHP_AP_ONLINE_DYN_END; i++) {
1743 if (cpuhp_ap_states[i].name)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001744 continue;
1745
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001746 cpuhp_ap_states[i].name = "Reserved";
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001747 return i;
1748 }
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001749 WARN(1, "No more dynamic states available for CPU hotplug\n");
1750 return -ENOSPC;
1751}
1752
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001753int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node,
1754 bool invoke)
1755{
1756 struct cpuhp_step *sp;
1757 int cpu;
1758 int ret;
1759
1760 sp = cpuhp_get_step(state);
1761 if (sp->multi_instance == false)
1762 return -EINVAL;
1763
1764 get_online_cpus();
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001765 mutex_lock(&cpuhp_state_mutex);
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001766
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001767 if (!invoke || !sp->startup.multi)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001768 goto add_node;
1769
1770 /*
1771 * Try to call the startup callback for each present cpu
1772 * depending on the hotplug state of the cpu.
1773 */
1774 for_each_present_cpu(cpu) {
1775 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1776 int cpustate = st->state;
1777
1778 if (cpustate < state)
1779 continue;
1780
1781 ret = cpuhp_issue_call(cpu, state, true, node);
1782 if (ret) {
Thomas Gleixner3c1627e2016-09-05 15:28:36 +02001783 if (sp->teardown.multi)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001784 cpuhp_rollback_install(cpu, state, node);
1785 goto err;
1786 }
1787 }
1788add_node:
1789 ret = 0;
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001790 hlist_add_head(node, &sp->list);
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001791
1792err:
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001793 mutex_unlock(&cpuhp_state_mutex);
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001794 put_online_cpus();
1795 return ret;
1796}
1797EXPORT_SYMBOL_GPL(__cpuhp_state_add_instance);
1798
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001799/**
1800 * __cpuhp_setup_state - Setup the callbacks for an hotplug machine state
1801 * @state: The state to setup
1802 * @invoke: If true, the startup function is invoked for cpus where
1803 * cpu state >= @state
1804 * @startup: startup callback function
1805 * @teardown: teardown callback function
1806 *
1807 * Returns 0 if successful, otherwise a proper error code
1808 */
1809int __cpuhp_setup_state(enum cpuhp_state state,
1810 const char *name, bool invoke,
1811 int (*startup)(unsigned int cpu),
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001812 int (*teardown)(unsigned int cpu),
1813 bool multi_instance)
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001814{
1815 int cpu, ret = 0;
1816 int dyn_state = 0;
1817
1818 if (cpuhp_cb_check(state) || !name)
1819 return -EINVAL;
1820
1821 get_online_cpus();
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001822 mutex_lock(&cpuhp_state_mutex);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001823
1824 /* currently assignments for the ONLINE state are possible */
Thomas Gleixner1cf4f622016-02-26 18:43:39 +00001825 if (state == CPUHP_AP_ONLINE_DYN) {
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001826 dyn_state = 1;
1827 ret = cpuhp_reserve_state(state);
1828 if (ret < 0)
1829 goto out;
1830 state = ret;
1831 }
1832
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001833 cpuhp_store_callbacks(state, name, startup, teardown, multi_instance);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001834
1835 if (!invoke || !startup)
1836 goto out;
1837
1838 /*
1839 * Try to call the startup callback for each present cpu
1840 * depending on the hotplug state of the cpu.
1841 */
1842 for_each_present_cpu(cpu) {
1843 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1844 int cpustate = st->state;
1845
1846 if (cpustate < state)
1847 continue;
1848
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001849 ret = cpuhp_issue_call(cpu, state, true, NULL);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001850 if (ret) {
Thomas Gleixnera7246322016-08-12 19:49:38 +02001851 if (teardown)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001852 cpuhp_rollback_install(cpu, state, NULL);
1853 cpuhp_store_callbacks(state, NULL, NULL, NULL, false);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001854 goto out;
1855 }
1856 }
1857out:
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001858 mutex_unlock(&cpuhp_state_mutex);
1859
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001860 put_online_cpus();
1861 if (!ret && dyn_state)
1862 return state;
1863 return ret;
1864}
1865EXPORT_SYMBOL(__cpuhp_setup_state);
1866
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001867int __cpuhp_state_remove_instance(enum cpuhp_state state,
1868 struct hlist_node *node, bool invoke)
1869{
1870 struct cpuhp_step *sp = cpuhp_get_step(state);
1871 int cpu;
1872
1873 BUG_ON(cpuhp_cb_check(state));
1874
1875 if (!sp->multi_instance)
1876 return -EINVAL;
1877
1878 get_online_cpus();
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001879 mutex_lock(&cpuhp_state_mutex);
1880
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001881 if (!invoke || !cpuhp_get_teardown_cb(state))
1882 goto remove;
1883 /*
1884 * Call the teardown callback for each present cpu depending
1885 * on the hotplug state of the cpu. This function is not
1886 * allowed to fail currently!
1887 */
1888 for_each_present_cpu(cpu) {
1889 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1890 int cpustate = st->state;
1891
1892 if (cpustate >= state)
1893 cpuhp_issue_call(cpu, state, false, node);
1894 }
1895
1896remove:
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001897 hlist_del(node);
1898 mutex_unlock(&cpuhp_state_mutex);
1899 put_online_cpus();
1900
1901 return 0;
1902}
1903EXPORT_SYMBOL_GPL(__cpuhp_state_remove_instance);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001904/**
1905 * __cpuhp_remove_state - Remove the callbacks for an hotplug machine state
1906 * @state: The state to remove
1907 * @invoke: If true, the teardown function is invoked for cpus where
1908 * cpu state >= @state
1909 *
1910 * The teardown callback is currently not allowed to fail. Think
1911 * about module removal!
1912 */
1913void __cpuhp_remove_state(enum cpuhp_state state, bool invoke)
1914{
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001915 struct cpuhp_step *sp = cpuhp_get_step(state);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001916 int cpu;
1917
1918 BUG_ON(cpuhp_cb_check(state));
1919
1920 get_online_cpus();
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001921 mutex_lock(&cpuhp_state_mutex);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001922
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001923 if (sp->multi_instance) {
1924 WARN(!hlist_empty(&sp->list),
1925 "Error: Removing state %d which has instances left.\n",
1926 state);
1927 goto remove;
1928 }
1929
Thomas Gleixnera7246322016-08-12 19:49:38 +02001930 if (!invoke || !cpuhp_get_teardown_cb(state))
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001931 goto remove;
1932
1933 /*
1934 * Call the teardown callback for each present cpu depending
1935 * on the hotplug state of the cpu. This function is not
1936 * allowed to fail currently!
1937 */
1938 for_each_present_cpu(cpu) {
1939 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
1940 int cpustate = st->state;
1941
1942 if (cpustate >= state)
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001943 cpuhp_issue_call(cpu, state, false, NULL);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001944 }
1945remove:
Thomas Gleixnercf392d12016-08-12 19:49:39 +02001946 cpuhp_store_callbacks(state, NULL, NULL, NULL, false);
Sebastian Andrzej Siewior7ad6de42017-03-14 16:06:45 +01001947 mutex_unlock(&cpuhp_state_mutex);
Thomas Gleixner5b7aa872016-02-26 18:43:33 +00001948 put_online_cpus();
1949}
1950EXPORT_SYMBOL(__cpuhp_remove_state);
1951
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00001952#if defined(CONFIG_SYSFS) && defined(CONFIG_HOTPLUG_CPU)
1953static ssize_t show_cpuhp_state(struct device *dev,
1954 struct device_attribute *attr, char *buf)
1955{
1956 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
1957
1958 return sprintf(buf, "%d\n", st->state);
1959}
1960static DEVICE_ATTR(state, 0444, show_cpuhp_state, NULL);
1961
Thomas Gleixner757c9892016-02-26 18:43:32 +00001962static ssize_t write_cpuhp_target(struct device *dev,
1963 struct device_attribute *attr,
1964 const char *buf, size_t count)
1965{
1966 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
1967 struct cpuhp_step *sp;
1968 int target, ret;
1969
1970 ret = kstrtoint(buf, 10, &target);
1971 if (ret)
1972 return ret;
1973
1974#ifdef CONFIG_CPU_HOTPLUG_STATE_CONTROL
1975 if (target < CPUHP_OFFLINE || target > CPUHP_ONLINE)
1976 return -EINVAL;
1977#else
1978 if (target != CPUHP_OFFLINE && target != CPUHP_ONLINE)
1979 return -EINVAL;
1980#endif
1981
1982 ret = lock_device_hotplug_sysfs();
1983 if (ret)
1984 return ret;
1985
1986 mutex_lock(&cpuhp_state_mutex);
1987 sp = cpuhp_get_step(target);
1988 ret = !sp->name || sp->cant_stop ? -EINVAL : 0;
1989 mutex_unlock(&cpuhp_state_mutex);
1990 if (ret)
Sebastian Andrzej Siewior106c77e2017-06-02 16:27:14 +02001991 goto out;
Thomas Gleixner757c9892016-02-26 18:43:32 +00001992
1993 if (st->state < target)
1994 ret = do_cpu_up(dev->id, target);
1995 else
1996 ret = do_cpu_down(dev->id, target);
Sebastian Andrzej Siewior106c77e2017-06-02 16:27:14 +02001997out:
Thomas Gleixner757c9892016-02-26 18:43:32 +00001998 unlock_device_hotplug();
1999 return ret ? ret : count;
2000}
2001
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00002002static ssize_t show_cpuhp_target(struct device *dev,
2003 struct device_attribute *attr, char *buf)
2004{
2005 struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id);
2006
2007 return sprintf(buf, "%d\n", st->target);
2008}
Thomas Gleixner757c9892016-02-26 18:43:32 +00002009static DEVICE_ATTR(target, 0644, show_cpuhp_target, write_cpuhp_target);
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00002010
2011static struct attribute *cpuhp_cpu_attrs[] = {
2012 &dev_attr_state.attr,
2013 &dev_attr_target.attr,
2014 NULL
2015};
2016
2017static struct attribute_group cpuhp_cpu_attr_group = {
2018 .attrs = cpuhp_cpu_attrs,
2019 .name = "hotplug",
2020 NULL
2021};
2022
2023static ssize_t show_cpuhp_states(struct device *dev,
2024 struct device_attribute *attr, char *buf)
2025{
2026 ssize_t cur, res = 0;
2027 int i;
2028
2029 mutex_lock(&cpuhp_state_mutex);
Thomas Gleixner757c9892016-02-26 18:43:32 +00002030 for (i = CPUHP_OFFLINE; i <= CPUHP_ONLINE; i++) {
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00002031 struct cpuhp_step *sp = cpuhp_get_step(i);
2032
2033 if (sp->name) {
2034 cur = sprintf(buf, "%3d: %s\n", i, sp->name);
2035 buf += cur;
2036 res += cur;
2037 }
2038 }
2039 mutex_unlock(&cpuhp_state_mutex);
2040 return res;
2041}
2042static DEVICE_ATTR(states, 0444, show_cpuhp_states, NULL);
2043
2044static struct attribute *cpuhp_cpu_root_attrs[] = {
2045 &dev_attr_states.attr,
2046 NULL
2047};
2048
2049static struct attribute_group cpuhp_cpu_root_attr_group = {
2050 .attrs = cpuhp_cpu_root_attrs,
2051 .name = "hotplug",
2052 NULL
2053};
2054
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002055#ifdef CONFIG_HOTPLUG_SMT
2056
2057static const char *smt_states[] = {
2058 [CPU_SMT_ENABLED] = "on",
2059 [CPU_SMT_DISABLED] = "off",
2060 [CPU_SMT_FORCE_DISABLED] = "forceoff",
2061 [CPU_SMT_NOT_SUPPORTED] = "notsupported",
2062};
2063
2064static ssize_t
2065show_smt_control(struct device *dev, struct device_attribute *attr, char *buf)
2066{
2067 return snprintf(buf, PAGE_SIZE - 2, "%s\n", smt_states[cpu_smt_control]);
2068}
2069
2070static void cpuhp_offline_cpu_device(unsigned int cpu)
2071{
2072 struct device *dev = get_cpu_device(cpu);
2073
2074 dev->offline = true;
2075 /* Tell user space about the state change */
2076 kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
2077}
2078
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002079static void cpuhp_online_cpu_device(unsigned int cpu)
2080{
2081 struct device *dev = get_cpu_device(cpu);
2082
2083 dev->offline = false;
2084 /* Tell user space about the state change */
2085 kobject_uevent(&dev->kobj, KOBJ_ONLINE);
2086}
2087
Jiri Kosina5bdc5362019-05-30 00:09:39 +02002088int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002089{
2090 int cpu, ret = 0;
2091
2092 cpu_maps_update_begin();
2093 for_each_online_cpu(cpu) {
2094 if (topology_is_primary_thread(cpu))
2095 continue;
2096 ret = cpu_down_maps_locked(cpu, CPUHP_OFFLINE);
2097 if (ret)
2098 break;
2099 /*
2100 * As this needs to hold the cpu maps lock it's impossible
2101 * to call device_offline() because that ends up calling
2102 * cpu_down() which takes cpu maps lock. cpu maps lock
2103 * needs to be held as this might race against in kernel
2104 * abusers of the hotplug machinery (thermal management).
2105 *
2106 * So nothing would update device:offline state. That would
2107 * leave the sysfs entry stale and prevent onlining after
2108 * smt control has been changed to 'off' again. This is
2109 * called under the sysfs hotplug lock, so it is properly
2110 * serialized against the regular offline usage.
2111 */
2112 cpuhp_offline_cpu_device(cpu);
2113 }
Zhenzhong Duanf2a02af2019-01-17 02:10:59 -08002114 if (!ret)
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002115 cpu_smt_control = ctrlval;
2116 cpu_maps_update_done();
2117 return ret;
2118}
2119
Jiri Kosina5bdc5362019-05-30 00:09:39 +02002120int cpuhp_smt_enable(void)
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002121{
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002122 int cpu, ret = 0;
2123
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002124 cpu_maps_update_begin();
2125 cpu_smt_control = CPU_SMT_ENABLED;
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002126 for_each_present_cpu(cpu) {
2127 /* Skip online CPUs and CPUs on offline nodes */
2128 if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
2129 continue;
2130 ret = _cpu_up(cpu, 0, CPUHP_ONLINE);
2131 if (ret)
2132 break;
2133 /* See comment in cpuhp_smt_disable() */
2134 cpuhp_online_cpu_device(cpu);
2135 }
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002136 cpu_maps_update_done();
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002137 return ret;
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002138}
2139
2140static ssize_t
2141store_smt_control(struct device *dev, struct device_attribute *attr,
2142 const char *buf, size_t count)
2143{
2144 int ctrlval, ret;
2145
2146 if (sysfs_streq(buf, "on"))
2147 ctrlval = CPU_SMT_ENABLED;
2148 else if (sysfs_streq(buf, "off"))
2149 ctrlval = CPU_SMT_DISABLED;
2150 else if (sysfs_streq(buf, "forceoff"))
2151 ctrlval = CPU_SMT_FORCE_DISABLED;
2152 else
2153 return -EINVAL;
2154
2155 if (cpu_smt_control == CPU_SMT_FORCE_DISABLED)
2156 return -EPERM;
2157
2158 if (cpu_smt_control == CPU_SMT_NOT_SUPPORTED)
2159 return -ENODEV;
2160
2161 ret = lock_device_hotplug_sysfs();
2162 if (ret)
2163 return ret;
2164
2165 if (ctrlval != cpu_smt_control) {
2166 switch (ctrlval) {
2167 case CPU_SMT_ENABLED:
Thomas Gleixnere7cda2f2018-07-07 11:40:18 +02002168 ret = cpuhp_smt_enable();
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002169 break;
2170 case CPU_SMT_DISABLED:
2171 case CPU_SMT_FORCE_DISABLED:
2172 ret = cpuhp_smt_disable(ctrlval);
2173 break;
2174 }
2175 }
2176
2177 unlock_device_hotplug();
2178 return ret ? ret : count;
2179}
2180static DEVICE_ATTR(control, 0644, show_smt_control, store_smt_control);
2181
2182static ssize_t
2183show_smt_active(struct device *dev, struct device_attribute *attr, char *buf)
2184{
2185 bool active = topology_max_smt_threads() > 1;
2186
2187 return snprintf(buf, PAGE_SIZE - 2, "%d\n", active);
2188}
2189static DEVICE_ATTR(active, 0444, show_smt_active, NULL);
2190
2191static struct attribute *cpuhp_smt_attrs[] = {
2192 &dev_attr_control.attr,
2193 &dev_attr_active.attr,
2194 NULL
2195};
2196
2197static const struct attribute_group cpuhp_smt_attr_group = {
2198 .attrs = cpuhp_smt_attrs,
2199 .name = "smt",
2200 NULL
2201};
2202
2203static int __init cpu_smt_state_init(void)
2204{
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002205 return sysfs_create_group(&cpu_subsys.dev_root->kobj,
2206 &cpuhp_smt_attr_group);
2207}
2208
2209#else
2210static inline int cpu_smt_state_init(void) { return 0; }
2211#endif
2212
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00002213static int __init cpuhp_sysfs_init(void)
2214{
2215 int cpu, ret;
2216
Thomas Gleixnerf37486c2018-05-29 17:48:27 +02002217 ret = cpu_smt_state_init();
2218 if (ret)
2219 return ret;
2220
Thomas Gleixner98f8cdc2016-02-26 18:43:31 +00002221 ret = sysfs_create_group(&cpu_subsys.dev_root->kobj,
2222 &cpuhp_cpu_root_attr_group);
2223 if (ret)
2224 return ret;
2225
2226 for_each_possible_cpu(cpu) {
2227 struct device *dev = get_cpu_device(cpu);
2228
2229 if (!dev)
2230 continue;
2231 ret = sysfs_create_group(&dev->kobj, &cpuhp_cpu_attr_group);
2232 if (ret)
2233 return ret;
2234 }
2235 return 0;
2236}
2237device_initcall(cpuhp_sysfs_init);
2238#endif
2239
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002240/*
2241 * cpu_bit_bitmap[] is a special, "compressed" data structure that
2242 * represents all NR_CPUS bits binary values of 1<<nr.
2243 *
Rusty Russelle0b582e2009-01-01 10:12:28 +10302244 * It is used by cpumask_of() to get a constant address to a CPU
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002245 * mask value that has a single bit set only.
2246 */
Mike Travisb8d317d2008-07-24 18:21:29 -07002247
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002248/* cpu_bit_bitmap[0] is empty - so we can back into it */
Michael Rodriguez4d519852011-03-22 16:34:07 -07002249#define MASK_DECLARE_1(x) [x+1][0] = (1UL << (x))
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002250#define MASK_DECLARE_2(x) MASK_DECLARE_1(x), MASK_DECLARE_1(x+1)
2251#define MASK_DECLARE_4(x) MASK_DECLARE_2(x), MASK_DECLARE_2(x+2)
2252#define MASK_DECLARE_8(x) MASK_DECLARE_4(x), MASK_DECLARE_4(x+4)
Mike Travisb8d317d2008-07-24 18:21:29 -07002253
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002254const unsigned long cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)] = {
Mike Travisb8d317d2008-07-24 18:21:29 -07002255
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002256 MASK_DECLARE_8(0), MASK_DECLARE_8(8),
2257 MASK_DECLARE_8(16), MASK_DECLARE_8(24),
2258#if BITS_PER_LONG > 32
2259 MASK_DECLARE_8(32), MASK_DECLARE_8(40),
2260 MASK_DECLARE_8(48), MASK_DECLARE_8(56),
Mike Travisb8d317d2008-07-24 18:21:29 -07002261#endif
2262};
Linus Torvaldse56b3bc2008-07-28 11:32:33 -07002263EXPORT_SYMBOL_GPL(cpu_bit_bitmap);
Rusty Russell2d3854a2008-11-05 13:39:10 +11002264
2265const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL;
2266EXPORT_SYMBOL(cpu_all_bits);
Rusty Russellb3199c02008-12-30 09:05:14 +10302267
2268#ifdef CONFIG_INIT_ALL_POSSIBLE
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002269struct cpumask __cpu_possible_mask __read_mostly
Rasmus Villemoesc4c54dd2016-01-20 15:00:16 -08002270 = {CPU_BITS_ALL};
Rusty Russellb3199c02008-12-30 09:05:14 +10302271#else
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002272struct cpumask __cpu_possible_mask __read_mostly;
Rusty Russellb3199c02008-12-30 09:05:14 +10302273#endif
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002274EXPORT_SYMBOL(__cpu_possible_mask);
Rusty Russellb3199c02008-12-30 09:05:14 +10302275
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002276struct cpumask __cpu_online_mask __read_mostly;
2277EXPORT_SYMBOL(__cpu_online_mask);
Rusty Russellb3199c02008-12-30 09:05:14 +10302278
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002279struct cpumask __cpu_present_mask __read_mostly;
2280EXPORT_SYMBOL(__cpu_present_mask);
Rusty Russellb3199c02008-12-30 09:05:14 +10302281
Rasmus Villemoes4b804c82016-01-20 15:00:19 -08002282struct cpumask __cpu_active_mask __read_mostly;
2283EXPORT_SYMBOL(__cpu_active_mask);
Rusty Russell3fa41522008-12-30 09:05:16 +10302284
Olav Haugan99cd46a2016-05-29 19:56:37 -07002285struct cpumask __cpu_isolated_mask __read_mostly;
2286EXPORT_SYMBOL(__cpu_isolated_mask);
2287
Rusty Russell3fa41522008-12-30 09:05:16 +10302288void init_cpu_present(const struct cpumask *src)
2289{
Rasmus Villemoesc4c54dd2016-01-20 15:00:16 -08002290 cpumask_copy(&__cpu_present_mask, src);
Rusty Russell3fa41522008-12-30 09:05:16 +10302291}
2292
2293void init_cpu_possible(const struct cpumask *src)
2294{
Rasmus Villemoesc4c54dd2016-01-20 15:00:16 -08002295 cpumask_copy(&__cpu_possible_mask, src);
Rusty Russell3fa41522008-12-30 09:05:16 +10302296}
2297
2298void init_cpu_online(const struct cpumask *src)
2299{
Rasmus Villemoesc4c54dd2016-01-20 15:00:16 -08002300 cpumask_copy(&__cpu_online_mask, src);
Rusty Russell3fa41522008-12-30 09:05:16 +10302301}
Thomas Gleixnercff7d372016-02-26 18:43:28 +00002302
Olav Haugan99cd46a2016-05-29 19:56:37 -07002303void init_cpu_isolated(const struct cpumask *src)
2304{
2305 cpumask_copy(&__cpu_isolated_mask, src);
2306}
2307
Thomas Gleixnercff7d372016-02-26 18:43:28 +00002308/*
2309 * Activate the first processor.
2310 */
2311void __init boot_cpu_init(void)
2312{
2313 int cpu = smp_processor_id();
2314
2315 /* Mark the boot cpu "present", "online" etc for SMP and UP case */
2316 set_cpu_online(cpu, true);
2317 set_cpu_active(cpu, true);
2318 set_cpu_present(cpu, true);
2319 set_cpu_possible(cpu, true);
2320}
2321
2322/*
2323 * Must be called _AFTER_ setting up the per_cpu areas
2324 */
Linus Torvalds6bb53ee2018-08-12 12:19:42 -07002325void __init boot_cpu_hotplug_init(void)
Thomas Gleixnercff7d372016-02-26 18:43:28 +00002326{
Abel Vesaaee08612018-08-15 00:26:00 +03002327#ifdef CONFIG_SMP
Thomas Gleixner8438e492018-06-29 16:05:48 +02002328 this_cpu_write(cpuhp_state.booted_once, true);
Abel Vesaaee08612018-08-15 00:26:00 +03002329#endif
Thomas Gleixner8438e492018-06-29 16:05:48 +02002330 this_cpu_write(cpuhp_state.state, CPUHP_ONLINE);
Thomas Gleixnercff7d372016-02-26 18:43:28 +00002331}
Todd Poynoref07e9e42011-06-15 17:21:57 -07002332
Tyler Hickse2bd0772019-11-04 12:22:02 +01002333/*
2334 * These are used for a global "mitigations=" cmdline option for toggling
2335 * optional CPU mitigations.
2336 */
2337enum cpu_mitigations {
2338 CPU_MITIGATIONS_OFF,
2339 CPU_MITIGATIONS_AUTO,
2340 CPU_MITIGATIONS_AUTO_NOSMT,
2341};
2342
2343static enum cpu_mitigations cpu_mitigations __ro_after_init =
2344 CPU_MITIGATIONS_AUTO;
Josh Poimboeufedda9c32019-04-12 15:39:28 -05002345
2346static int __init mitigations_parse_cmdline(char *arg)
2347{
2348 if (!strcmp(arg, "off"))
2349 cpu_mitigations = CPU_MITIGATIONS_OFF;
2350 else if (!strcmp(arg, "auto"))
2351 cpu_mitigations = CPU_MITIGATIONS_AUTO;
2352 else if (!strcmp(arg, "auto,nosmt"))
2353 cpu_mitigations = CPU_MITIGATIONS_AUTO_NOSMT;
Geert Uytterhoeven0cbb0ae2019-05-16 09:09:35 +02002354 else
2355 pr_crit("Unsupported mitigations=%s, system may still be vulnerable\n",
2356 arg);
Josh Poimboeufedda9c32019-04-12 15:39:28 -05002357
2358 return 0;
2359}
2360early_param("mitigations", mitigations_parse_cmdline);
Greg Kroah-Hartmane0625b32019-05-14 20:43:04 +02002361
Tyler Hickse2bd0772019-11-04 12:22:02 +01002362/* mitigations=off */
2363bool cpu_mitigations_off(void)
2364{
2365 return cpu_mitigations == CPU_MITIGATIONS_OFF;
2366}
2367EXPORT_SYMBOL_GPL(cpu_mitigations_off);
2368
2369/* mitigations=auto,nosmt */
2370bool cpu_mitigations_auto_nosmt(void)
2371{
2372 return cpu_mitigations == CPU_MITIGATIONS_AUTO_NOSMT;
2373}
2374EXPORT_SYMBOL_GPL(cpu_mitigations_auto_nosmt);
Greg Kroah-Hartman258971b2019-11-16 11:05:12 +01002375
Todd Poynoref07e9e42011-06-15 17:21:57 -07002376static ATOMIC_NOTIFIER_HEAD(idle_notifier);
2377
2378void idle_notifier_register(struct notifier_block *n)
2379{
2380 atomic_notifier_chain_register(&idle_notifier, n);
2381}
2382EXPORT_SYMBOL_GPL(idle_notifier_register);
2383
2384void idle_notifier_unregister(struct notifier_block *n)
2385{
2386 atomic_notifier_chain_unregister(&idle_notifier, n);
2387}
2388EXPORT_SYMBOL_GPL(idle_notifier_unregister);
2389
2390void idle_notifier_call_chain(unsigned long val)
2391{
2392 atomic_notifier_call_chain(&idle_notifier, val, NULL);
2393}
2394EXPORT_SYMBOL_GPL(idle_notifier_call_chain);