Blame view
kernel/cpu.c
15.7 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 |
/* CPU control. * (C) 2001, 2002, 2003, 2004 Rusty Russell * * This code is licenced under the GPL. */ #include <linux/proc_fs.h> #include <linux/smp.h> #include <linux/init.h> #include <linux/notifier.h> #include <linux/sched.h> #include <linux/unistd.h> #include <linux/cpu.h> |
9984de1a5 kernel: Map most ... |
13 |
#include <linux/export.h> |
1da177e4c Linux-2.6.12-rc2 |
14 15 |
#include <linux/kthread.h> #include <linux/stop_machine.h> |
81615b624 [PATCH] Convert k... |
16 |
#include <linux/mutex.h> |
5a0e3ad6a include cleanup: ... |
17 |
#include <linux/gfp.h> |
79cfbdfa8 PM / Sleep: Fix r... |
18 |
#include <linux/suspend.h> |
1da177e4c Linux-2.6.12-rc2 |
19 |
|
98a79d6a5 cpumask: centrali... |
20 |
#ifdef CONFIG_SMP |
b3199c025 cpumask: switch o... |
21 |
/* Serializes the updates to cpu_online_mask, cpu_present_mask */ |
aa9538777 cpu hotplug: simp... |
22 |
static DEFINE_MUTEX(cpu_add_remove_lock); |
1da177e4c Linux-2.6.12-rc2 |
23 |
|
79a6cdeb7 cpuhotplug: do no... |
24 25 26 27 28 29 30 31 32 33 34 35 36 |
/* * The following two API's must be used when attempting * to serialize the updates to cpu_online_mask, cpu_present_mask. */ void cpu_maps_update_begin(void) { mutex_lock(&cpu_add_remove_lock); } void cpu_maps_update_done(void) { mutex_unlock(&cpu_add_remove_lock); } |
5c113fbee fix cpu_chain sec... |
37 |
static RAW_NOTIFIER_HEAD(cpu_chain); |
1da177e4c Linux-2.6.12-rc2 |
38 |
|
e3920fb42 [PATCH] Disable C... |
39 40 41 42 |
/* If set, cpu_up and cpu_down will return -EBUSY and do nothing. * Should always be manipulated under cpu_add_remove_lock */ static int cpu_hotplug_disabled; |
79a6cdeb7 cpuhotplug: do no... |
43 |
#ifdef CONFIG_HOTPLUG_CPU |
d221938c0 cpu-hotplug: refc... |
44 45 46 47 48 49 50 51 |
static struct { struct task_struct *active_writer; struct mutex lock; /* Synchronizes accesses to refcount, */ /* * Also blocks the new readers during * an ongoing cpu hotplug operation. */ int refcount; |
31950eb66 mm/init: cpu_hotp... |
52 53 54 55 56 |
} cpu_hotplug = { .active_writer = NULL, .lock = __MUTEX_INITIALIZER(cpu_hotplug.lock), .refcount = 0, }; |
d221938c0 cpu-hotplug: refc... |
57 |
|
86ef5c9a8 cpu-hotplug: repl... |
58 |
void get_online_cpus(void) |
a9d9baa1e [PATCH] clean up ... |
59 |
{ |
d221938c0 cpu-hotplug: refc... |
60 61 |
might_sleep(); if (cpu_hotplug.active_writer == current) |
aa9538777 cpu hotplug: simp... |
62 |
return; |
d221938c0 cpu-hotplug: refc... |
63 64 65 |
mutex_lock(&cpu_hotplug.lock); cpu_hotplug.refcount++; mutex_unlock(&cpu_hotplug.lock); |
a9d9baa1e [PATCH] clean up ... |
66 |
} |
86ef5c9a8 cpu-hotplug: repl... |
67 |
EXPORT_SYMBOL_GPL(get_online_cpus); |
90d45d17f [PATCH] cpu hotpl... |
68 |
|
86ef5c9a8 cpu-hotplug: repl... |
69 |
void put_online_cpus(void) |
a9d9baa1e [PATCH] clean up ... |
70 |
{ |
d221938c0 cpu-hotplug: refc... |
71 |
if (cpu_hotplug.active_writer == current) |
aa9538777 cpu hotplug: simp... |
72 |
return; |
d221938c0 cpu-hotplug: refc... |
73 |
mutex_lock(&cpu_hotplug.lock); |
d2ba7e2ae simplify cpu_hotp... |
74 75 |
if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer)) wake_up_process(cpu_hotplug.active_writer); |
d221938c0 cpu-hotplug: refc... |
76 |
mutex_unlock(&cpu_hotplug.lock); |
a9d9baa1e [PATCH] clean up ... |
77 |
} |
86ef5c9a8 cpu-hotplug: repl... |
78 |
EXPORT_SYMBOL_GPL(put_online_cpus); |
a9d9baa1e [PATCH] clean up ... |
79 |
|
d221938c0 cpu-hotplug: refc... |
80 81 82 83 84 85 86 |
/* * This ensures that the hotplug operation can begin only when the * refcount goes to zero. * * Note that during a cpu-hotplug operation, the new readers, if any, * will be blocked by the cpu_hotplug.lock * |
d2ba7e2ae simplify cpu_hotp... |
87 88 |
* Since cpu_hotplug_begin() is always called after invoking * cpu_maps_update_begin(), we can be sure that only one writer is active. |
d221938c0 cpu-hotplug: refc... |
89 90 91 92 93 94 95 96 97 98 |
* * Note that theoretically, there is a possibility of a livelock: * - Refcount goes to zero, last reader wakes up the sleeping * writer. * - Last reader unlocks the cpu_hotplug.lock. * - A new reader arrives at this moment, bumps up the refcount. * - The writer acquires the cpu_hotplug.lock finds the refcount * non zero and goes to sleep again. * * However, this is very difficult to achieve in practice since |
86ef5c9a8 cpu-hotplug: repl... |
99 |
* get_online_cpus() not an api which is called all that often. |
d221938c0 cpu-hotplug: refc... |
100 101 102 103 |
* */ static void cpu_hotplug_begin(void) { |
d221938c0 cpu-hotplug: refc... |
104 |
cpu_hotplug.active_writer = current; |
d2ba7e2ae simplify cpu_hotp... |
105 106 107 108 109 110 |
for (;;) { mutex_lock(&cpu_hotplug.lock); if (likely(!cpu_hotplug.refcount)) break; __set_current_state(TASK_UNINTERRUPTIBLE); |
d221938c0 cpu-hotplug: refc... |
111 112 |
mutex_unlock(&cpu_hotplug.lock); schedule(); |
d221938c0 cpu-hotplug: refc... |
113 |
} |
d221938c0 cpu-hotplug: refc... |
114 115 116 117 118 119 120 |
} static void cpu_hotplug_done(void) { cpu_hotplug.active_writer = NULL; mutex_unlock(&cpu_hotplug.lock); } |
79a6cdeb7 cpuhotplug: do no... |
121 122 123 124 |
#else /* #if CONFIG_HOTPLUG_CPU */ static void cpu_hotplug_begin(void) {} static void cpu_hotplug_done(void) {} |
25985edce Fix common misspe... |
125 |
#endif /* #else #if CONFIG_HOTPLUG_CPU */ |
79a6cdeb7 cpuhotplug: do no... |
126 |
|
1da177e4c Linux-2.6.12-rc2 |
127 |
/* Need to know about CPUs going up/down? */ |
f7b16c108 cpu: fix section ... |
128 |
int __ref register_cpu_notifier(struct notifier_block *nb) |
1da177e4c Linux-2.6.12-rc2 |
129 |
{ |
bd5349cfd [PATCH] Convert c... |
130 |
int ret; |
d221938c0 cpu-hotplug: refc... |
131 |
cpu_maps_update_begin(); |
bd5349cfd [PATCH] Convert c... |
132 |
ret = raw_notifier_chain_register(&cpu_chain, nb); |
d221938c0 cpu-hotplug: refc... |
133 |
cpu_maps_update_done(); |
bd5349cfd [PATCH] Convert c... |
134 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
135 |
} |
65edc68c3 [PATCH] cpu hotpl... |
136 |
|
e9fb7631e cpu-hotplug: intr... |
137 138 139 |
static int __cpu_notify(unsigned long val, void *v, int nr_to_call, int *nr_calls) { |
e6bde73b0 cpu-hotplug: retu... |
140 141 142 |
int ret; ret = __raw_notifier_call_chain(&cpu_chain, val, v, nr_to_call, |
e9fb7631e cpu-hotplug: intr... |
143 |
nr_calls); |
e6bde73b0 cpu-hotplug: retu... |
144 145 |
return notifier_to_errno(ret); |
e9fb7631e cpu-hotplug: intr... |
146 147 148 149 150 151 |
} static int cpu_notify(unsigned long val, void *v) { return __cpu_notify(val, v, -1, NULL); } |
00b9b0af5 Avoid warning whe... |
152 |
#ifdef CONFIG_HOTPLUG_CPU |
e9fb7631e cpu-hotplug: intr... |
153 154 |
static void cpu_notify_nofail(unsigned long val, void *v) { |
00b9b0af5 Avoid warning whe... |
155 |
BUG_ON(cpu_notify(val, v)); |
e9fb7631e cpu-hotplug: intr... |
156 |
} |
1da177e4c Linux-2.6.12-rc2 |
157 |
EXPORT_SYMBOL(register_cpu_notifier); |
9647155ff cpu: fix section ... |
158 |
void __ref unregister_cpu_notifier(struct notifier_block *nb) |
1da177e4c Linux-2.6.12-rc2 |
159 |
{ |
d221938c0 cpu-hotplug: refc... |
160 |
cpu_maps_update_begin(); |
bd5349cfd [PATCH] Convert c... |
161 |
raw_notifier_chain_unregister(&cpu_chain, nb); |
d221938c0 cpu-hotplug: refc... |
162 |
cpu_maps_update_done(); |
1da177e4c Linux-2.6.12-rc2 |
163 164 |
} EXPORT_SYMBOL(unregister_cpu_notifier); |
1da177e4c Linux-2.6.12-rc2 |
165 166 167 168 169 170 |
static inline void check_for_tasks(int cpu) { struct task_struct *p; write_lock_irq(&tasklist_lock); for_each_process(p) { |
11854247e sched: Fix incorr... |
171 |
if (task_cpu(p) == cpu && p->state == TASK_RUNNING && |
648616343 [S390] cputime: a... |
172 |
(p->utime || p->stime)) |
9d3cfc4c1 sched: Correct pr... |
173 174 175 176 177 |
printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d " "(state = %ld, flags = %x) ", p->comm, task_pid_nr(p), cpu, p->state, p->flags); |
1da177e4c Linux-2.6.12-rc2 |
178 179 180 |
} write_unlock_irq(&tasklist_lock); } |
db912f963 HOTPLUG: Add CPU_... |
181 182 183 184 |
struct take_cpu_down_param { unsigned long mod; void *hcpu; }; |
1da177e4c Linux-2.6.12-rc2 |
185 |
/* Take this CPU down. */ |
514a20a5d cpu: fix section ... |
186 |
static int __ref take_cpu_down(void *_param) |
1da177e4c Linux-2.6.12-rc2 |
187 |
{ |
db912f963 HOTPLUG: Add CPU_... |
188 |
struct take_cpu_down_param *param = _param; |
1da177e4c Linux-2.6.12-rc2 |
189 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
190 191 192 |
/* Ensure this CPU doesn't handle any more interrupts. */ err = __cpu_disable(); if (err < 0) |
f37051364 [PATCH] i386 CPU ... |
193 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
194 |
|
e9fb7631e cpu-hotplug: intr... |
195 |
cpu_notify(CPU_DYING | param->mod, param->hcpu); |
f37051364 [PATCH] i386 CPU ... |
196 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
197 |
} |
e3920fb42 [PATCH] Disable C... |
198 |
/* Requires cpu_add_remove_lock to be held */ |
514a20a5d cpu: fix section ... |
199 |
static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) |
1da177e4c Linux-2.6.12-rc2 |
200 |
{ |
e7407dcc6 call cpu_chain wi... |
201 |
int err, nr_calls = 0; |
e7407dcc6 call cpu_chain wi... |
202 |
void *hcpu = (void *)(long)cpu; |
8bb784428 Add suspend-relat... |
203 |
unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; |
db912f963 HOTPLUG: Add CPU_... |
204 205 206 207 |
struct take_cpu_down_param tcd_param = { .mod = mod, .hcpu = hcpu, }; |
1da177e4c Linux-2.6.12-rc2 |
208 |
|
e3920fb42 [PATCH] Disable C... |
209 210 |
if (num_online_cpus() == 1) return -EBUSY; |
1da177e4c Linux-2.6.12-rc2 |
211 |
|
e3920fb42 [PATCH] Disable C... |
212 213 |
if (!cpu_online(cpu)) return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
214 |
|
d221938c0 cpu-hotplug: refc... |
215 |
cpu_hotplug_begin(); |
4d51985e4 kernel/cpu.c: fix... |
216 |
|
e9fb7631e cpu-hotplug: intr... |
217 |
err = __cpu_notify(CPU_DOWN_PREPARE | mod, hcpu, -1, &nr_calls); |
e6bde73b0 cpu-hotplug: retu... |
218 |
if (err) { |
a0d8cdb65 cpu hotplug: cpu:... |
219 |
nr_calls--; |
e9fb7631e cpu-hotplug: intr... |
220 |
__cpu_notify(CPU_DOWN_FAILED | mod, hcpu, nr_calls, NULL); |
1da177e4c Linux-2.6.12-rc2 |
221 222 |
printk("%s: attempt to take down CPU %u failed ", |
af1f16d08 kernel: replace r... |
223 |
__func__, cpu); |
baaca49f4 Define and use ne... |
224 |
goto out_release; |
1da177e4c Linux-2.6.12-rc2 |
225 |
} |
e0b582ec5 cpumask: convert ... |
226 |
err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu)); |
043215875 Hotplug CPU: don'... |
227 |
if (err) { |
1da177e4c Linux-2.6.12-rc2 |
228 |
/* CPU didn't die: tell everyone. Can't complain. */ |
e9fb7631e cpu-hotplug: intr... |
229 |
cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu); |
1da177e4c Linux-2.6.12-rc2 |
230 |
|
6a1bdc1b5 sched: _cpu_down(... |
231 |
goto out_release; |
8fa1d7d3b [PATCH] cpu-hotpl... |
232 |
} |
043215875 Hotplug CPU: don'... |
233 |
BUG_ON(cpu_online(cpu)); |
1da177e4c Linux-2.6.12-rc2 |
234 |
|
48c5ccae8 sched: Simplify c... |
235 236 237 238 |
/* * The migration_call() CPU_DYING callback will have removed all * runnable tasks from the cpu, there's only the idle task left now * that the migration thread is done doing the stop_machine thing. |
51a96c778 cpu: Remove incor... |
239 240 |
* * Wait for the stop thread to go away. |
48c5ccae8 sched: Simplify c... |
241 |
*/ |
51a96c778 cpu: Remove incor... |
242 243 |
while (!idle_cpu(cpu)) cpu_relax(); |
1da177e4c Linux-2.6.12-rc2 |
244 245 246 |
/* This actually kills the CPU. */ __cpu_die(cpu); |
1da177e4c Linux-2.6.12-rc2 |
247 |
/* CPU is completely dead: tell everyone. Too late to complain. */ |
e9fb7631e cpu-hotplug: intr... |
248 |
cpu_notify_nofail(CPU_DEAD | mod, hcpu); |
1da177e4c Linux-2.6.12-rc2 |
249 250 |
check_for_tasks(cpu); |
baaca49f4 Define and use ne... |
251 |
out_release: |
d221938c0 cpu-hotplug: refc... |
252 |
cpu_hotplug_done(); |
e9fb7631e cpu-hotplug: intr... |
253 254 |
if (!err) cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu); |
e3920fb42 [PATCH] Disable C... |
255 256 |
return err; } |
514a20a5d cpu: fix section ... |
257 |
int __ref cpu_down(unsigned int cpu) |
e3920fb42 [PATCH] Disable C... |
258 |
{ |
9ea09af3b stop_machine: int... |
259 |
int err; |
e3920fb42 [PATCH] Disable C... |
260 |
|
d221938c0 cpu-hotplug: refc... |
261 |
cpu_maps_update_begin(); |
e761b7725 cpu hotplug, sche... |
262 263 |
if (cpu_hotplug_disabled) { |
e3920fb42 [PATCH] Disable C... |
264 |
err = -EBUSY; |
e761b7725 cpu hotplug, sche... |
265 266 |
goto out; } |
e761b7725 cpu hotplug, sche... |
267 |
err = _cpu_down(cpu, 0); |
e3920fb42 [PATCH] Disable C... |
268 |
|
e761b7725 cpu hotplug, sche... |
269 |
out: |
d221938c0 cpu-hotplug: refc... |
270 |
cpu_maps_update_done(); |
1da177e4c Linux-2.6.12-rc2 |
271 272 |
return err; } |
b62b8ef90 force offline the... |
273 |
EXPORT_SYMBOL(cpu_down); |
1da177e4c Linux-2.6.12-rc2 |
274 |
#endif /*CONFIG_HOTPLUG_CPU*/ |
e3920fb42 [PATCH] Disable C... |
275 |
/* Requires cpu_add_remove_lock to be held */ |
8bb784428 Add suspend-relat... |
276 |
static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen) |
1da177e4c Linux-2.6.12-rc2 |
277 |
{ |
baaca49f4 Define and use ne... |
278 |
int ret, nr_calls = 0; |
1da177e4c Linux-2.6.12-rc2 |
279 |
void *hcpu = (void *)(long)cpu; |
8bb784428 Add suspend-relat... |
280 |
unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; |
1da177e4c Linux-2.6.12-rc2 |
281 |
|
e3920fb42 [PATCH] Disable C... |
282 283 |
if (cpu_online(cpu) || !cpu_present(cpu)) return -EINVAL; |
90d45d17f [PATCH] cpu hotpl... |
284 |
|
d221938c0 cpu-hotplug: refc... |
285 |
cpu_hotplug_begin(); |
e9fb7631e cpu-hotplug: intr... |
286 |
ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls); |
e6bde73b0 cpu-hotplug: retu... |
287 |
if (ret) { |
a0d8cdb65 cpu hotplug: cpu:... |
288 |
nr_calls--; |
4d51985e4 kernel/cpu.c: fix... |
289 290 |
printk(KERN_WARNING "%s: attempt to bring up CPU %u failed ", |
af1f16d08 kernel: replace r... |
291 |
__func__, cpu); |
1da177e4c Linux-2.6.12-rc2 |
292 293 294 295 296 297 298 |
goto out_notify; } /* Arch-specific enabling code. */ ret = __cpu_up(cpu); if (ret != 0) goto out_notify; |
6978c7052 BUG_ON() Conversi... |
299 |
BUG_ON(!cpu_online(cpu)); |
1da177e4c Linux-2.6.12-rc2 |
300 301 |
/* Now call notifier in preparation. */ |
e9fb7631e cpu-hotplug: intr... |
302 |
cpu_notify(CPU_ONLINE | mod, hcpu); |
1da177e4c Linux-2.6.12-rc2 |
303 304 305 |
out_notify: if (ret != 0) |
e9fb7631e cpu-hotplug: intr... |
306 |
__cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL); |
d221938c0 cpu-hotplug: refc... |
307 |
cpu_hotplug_done(); |
e3920fb42 [PATCH] Disable C... |
308 309 310 |
return ret; } |
b282b6f8a [PATCH] Change cp... |
311 |
int __cpuinit cpu_up(unsigned int cpu) |
e3920fb42 [PATCH] Disable C... |
312 313 |
{ int err = 0; |
cf23422b9 cpu/mem hotplug: ... |
314 315 316 317 318 |
#ifdef CONFIG_MEMORY_HOTPLUG int nid; pg_data_t *pgdat; #endif |
e0b582ec5 cpumask: convert ... |
319 |
if (!cpu_possible(cpu)) { |
73e753a50 CPU HOTPLUG: avoi... |
320 321 322 |
printk(KERN_ERR "can't online cpu %d because it is not " "configured as may-hotadd at boot time ", cpu); |
87d5e0236 kernel/cpu.c: del... |
323 |
#if defined(CONFIG_IA64) |
73e753a50 CPU HOTPLUG: avoi... |
324 325 326 327 328 329 |
printk(KERN_ERR "please check additional_cpus= boot " "parameter "); #endif return -EINVAL; } |
e3920fb42 [PATCH] Disable C... |
330 |
|
cf23422b9 cpu/mem hotplug: ... |
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
#ifdef CONFIG_MEMORY_HOTPLUG nid = cpu_to_node(cpu); if (!node_online(nid)) { err = mem_online_node(nid); if (err) return err; } pgdat = NODE_DATA(nid); if (!pgdat) { printk(KERN_ERR "Can't online cpu %d due to NULL pgdat ", cpu); return -ENOMEM; } |
4eaf3f643 mem-hotplug: fix ... |
346 347 |
if (pgdat->node_zonelists->_zonerefs->zone == NULL) { mutex_lock(&zonelists_mutex); |
1f522509c mem-hotplug: avoi... |
348 |
build_all_zonelists(NULL); |
4eaf3f643 mem-hotplug: fix ... |
349 350 |
mutex_unlock(&zonelists_mutex); } |
cf23422b9 cpu/mem hotplug: ... |
351 |
#endif |
d221938c0 cpu-hotplug: refc... |
352 |
cpu_maps_update_begin(); |
e761b7725 cpu hotplug, sche... |
353 354 |
if (cpu_hotplug_disabled) { |
e3920fb42 [PATCH] Disable C... |
355 |
err = -EBUSY; |
e761b7725 cpu hotplug, sche... |
356 357 358 359 |
goto out; } err = _cpu_up(cpu, 0); |
e761b7725 cpu hotplug, sche... |
360 |
out: |
d221938c0 cpu-hotplug: refc... |
361 |
cpu_maps_update_done(); |
e3920fb42 [PATCH] Disable C... |
362 363 |
return err; } |
a513f6bab cpu: Export cpu_up() |
364 |
EXPORT_SYMBOL_GPL(cpu_up); |
e3920fb42 [PATCH] Disable C... |
365 |
|
f3de4be9d PM: Fix dependenc... |
366 |
#ifdef CONFIG_PM_SLEEP_SMP |
e0b582ec5 cpumask: convert ... |
367 |
static cpumask_var_t frozen_cpus; |
e3920fb42 [PATCH] Disable C... |
368 |
|
3fb82d56a x86, suspend: Avo... |
369 370 371 372 373 374 375 |
void __weak arch_disable_nonboot_cpus_begin(void) { } void __weak arch_disable_nonboot_cpus_end(void) { } |
e3920fb42 [PATCH] Disable C... |
376 377 |
int disable_nonboot_cpus(void) { |
e9a5f426b CPU: Avoid using ... |
378 |
int cpu, first_cpu, error = 0; |
e3920fb42 [PATCH] Disable C... |
379 |
|
d221938c0 cpu-hotplug: refc... |
380 |
cpu_maps_update_begin(); |
e0b582ec5 cpumask: convert ... |
381 |
first_cpu = cpumask_first(cpu_online_mask); |
9ee349ad6 sched: Fix set_cp... |
382 383 |
/* * We take down all of the non-boot CPUs in one shot to avoid races |
e3920fb42 [PATCH] Disable C... |
384 385 |
* with the userspace trying to use the CPU hotplug at the same time */ |
e0b582ec5 cpumask: convert ... |
386 |
cpumask_clear(frozen_cpus); |
3fb82d56a x86, suspend: Avo... |
387 |
arch_disable_nonboot_cpus_begin(); |
6ad4c1888 sched: Fix balanc... |
388 |
|
e3920fb42 [PATCH] Disable C... |
389 390 391 392 393 |
printk("Disabling non-boot CPUs ... "); for_each_online_cpu(cpu) { if (cpu == first_cpu) continue; |
8bb784428 Add suspend-relat... |
394 |
error = _cpu_down(cpu, 1); |
feae3203d timers, init: Lim... |
395 |
if (!error) |
e0b582ec5 cpumask: convert ... |
396 |
cpumask_set_cpu(cpu, frozen_cpus); |
feae3203d timers, init: Lim... |
397 |
else { |
e3920fb42 [PATCH] Disable C... |
398 399 400 401 402 403 |
printk(KERN_ERR "Error taking CPU%d down: %d ", cpu, error); break; } } |
86886e55b x86, intel_txt: I... |
404 |
|
3fb82d56a x86, suspend: Avo... |
405 |
arch_disable_nonboot_cpus_end(); |
e3920fb42 [PATCH] Disable C... |
406 407 408 409 410 |
if (!error) { BUG_ON(num_online_cpus() > 1); /* Make sure the CPUs won't be enabled by someone else */ cpu_hotplug_disabled = 1; } else { |
e1d9fd2e3 [PATCH] suspend: ... |
411 412 |
printk(KERN_ERR "Non-boot CPUs are not disabled "); |
e3920fb42 [PATCH] Disable C... |
413 |
} |
d221938c0 cpu-hotplug: refc... |
414 |
cpu_maps_update_done(); |
e3920fb42 [PATCH] Disable C... |
415 416 |
return error; } |
d0af9eed5 x86, pat/mtrr: Re... |
417 418 419 420 421 422 423 |
void __weak arch_enable_nonboot_cpus_begin(void) { } void __weak arch_enable_nonboot_cpus_end(void) { } |
fa7303e22 cpu: fix section ... |
424 |
void __ref enable_nonboot_cpus(void) |
e3920fb42 [PATCH] Disable C... |
425 426 427 428 |
{ int cpu, error; /* Allow everyone to use the CPU hotplug again */ |
d221938c0 cpu-hotplug: refc... |
429 |
cpu_maps_update_begin(); |
e3920fb42 [PATCH] Disable C... |
430 |
cpu_hotplug_disabled = 0; |
e0b582ec5 cpumask: convert ... |
431 |
if (cpumask_empty(frozen_cpus)) |
1d64b9cb1 [PATCH] Fix micro... |
432 |
goto out; |
e3920fb42 [PATCH] Disable C... |
433 |
|
4d51985e4 kernel/cpu.c: fix... |
434 435 |
printk(KERN_INFO "Enabling non-boot CPUs ... "); |
d0af9eed5 x86, pat/mtrr: Re... |
436 437 |
arch_enable_nonboot_cpus_begin(); |
e0b582ec5 cpumask: convert ... |
438 |
for_each_cpu(cpu, frozen_cpus) { |
8bb784428 Add suspend-relat... |
439 |
error = _cpu_up(cpu, 1); |
e3920fb42 [PATCH] Disable C... |
440 |
if (!error) { |
4d51985e4 kernel/cpu.c: fix... |
441 442 |
printk(KERN_INFO "CPU%d is up ", cpu); |
e3920fb42 [PATCH] Disable C... |
443 444 |
continue; } |
1d64b9cb1 [PATCH] Fix micro... |
445 446 |
printk(KERN_WARNING "Error taking CPU%d up: %d ", cpu, error); |
e3920fb42 [PATCH] Disable C... |
447 |
} |
d0af9eed5 x86, pat/mtrr: Re... |
448 449 |
arch_enable_nonboot_cpus_end(); |
e0b582ec5 cpumask: convert ... |
450 |
cpumask_clear(frozen_cpus); |
1d64b9cb1 [PATCH] Fix micro... |
451 |
out: |
d221938c0 cpu-hotplug: refc... |
452 |
cpu_maps_update_done(); |
1da177e4c Linux-2.6.12-rc2 |
453 |
} |
e0b582ec5 cpumask: convert ... |
454 |
|
d7268a31c CPU: Add right qu... |
455 |
static int __init alloc_frozen_cpus(void) |
e0b582ec5 cpumask: convert ... |
456 457 458 459 460 461 |
{ if (!alloc_cpumask_var(&frozen_cpus, GFP_KERNEL|__GFP_ZERO)) return -ENOMEM; return 0; } core_initcall(alloc_frozen_cpus); |
79cfbdfa8 PM / Sleep: Fix r... |
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
/* * Prevent regular CPU hotplug from racing with the freezer, by disabling CPU * hotplug when tasks are about to be frozen. Also, don't allow the freezer * to continue until any currently running CPU hotplug operation gets * completed. * To modify the 'cpu_hotplug_disabled' flag, we need to acquire the * 'cpu_add_remove_lock'. And this same lock is also taken by the regular * CPU hotplug path and released only after it is complete. Thus, we * (and hence the freezer) will block here until any currently running CPU * hotplug operation gets completed. */ void cpu_hotplug_disable_before_freeze(void) { cpu_maps_update_begin(); cpu_hotplug_disabled = 1; cpu_maps_update_done(); } /* * When tasks have been thawed, re-enable regular CPU hotplug (which had been * disabled while beginning to freeze tasks). */ void cpu_hotplug_enable_after_thaw(void) { cpu_maps_update_begin(); cpu_hotplug_disabled = 0; cpu_maps_update_done(); } /* * When callbacks for CPU hotplug notifications are being executed, we must * ensure that the state of the system with respect to the tasks being frozen * or not, as reported by the notification, remains unchanged *throughout the * duration* of the execution of the callbacks. * Hence we need to prevent the freezer from racing with regular CPU hotplug. * * This synchronization is implemented by mutually excluding regular CPU * hotplug and Suspend/Hibernate call paths by hooking onto the Suspend/ * Hibernate notifications. */ static int cpu_hotplug_pm_callback(struct notifier_block *nb, unsigned long action, void *ptr) { switch (action) { case PM_SUSPEND_PREPARE: case PM_HIBERNATION_PREPARE: cpu_hotplug_disable_before_freeze(); break; case PM_POST_SUSPEND: case PM_POST_HIBERNATION: cpu_hotplug_enable_after_thaw(); break; default: return NOTIFY_DONE; } return NOTIFY_OK; } |
d7268a31c CPU: Add right qu... |
526 |
static int __init cpu_hotplug_pm_sync_init(void) |
79cfbdfa8 PM / Sleep: Fix r... |
527 528 529 530 531 |
{ pm_notifier(cpu_hotplug_pm_callback, 0); return 0; } core_initcall(cpu_hotplug_pm_sync_init); |
f3de4be9d PM: Fix dependenc... |
532 |
#endif /* CONFIG_PM_SLEEP_SMP */ |
68f4f1ec0 sched: Move cpu m... |
533 |
|
e545a6140 kernel/cpu.c: cre... |
534 535 536 537 538 539 540 541 |
/** * notify_cpu_starting(cpu) - call the CPU_STARTING notifiers * @cpu: cpu that just started * * This function calls the cpu_chain notifiers with CPU_STARTING. * It must be called by the arch code on the new cpu, before the new cpu * enables interrupts and before the "boot" cpu returns from __cpu_up(). */ |
841964145 cpuinit fixes in ... |
542 |
void __cpuinit notify_cpu_starting(unsigned int cpu) |
e545a6140 kernel/cpu.c: cre... |
543 544 545 546 |
{ unsigned long val = CPU_STARTING; #ifdef CONFIG_PM_SLEEP_SMP |
e0b582ec5 cpumask: convert ... |
547 |
if (frozen_cpus != NULL && cpumask_test_cpu(cpu, frozen_cpus)) |
e545a6140 kernel/cpu.c: cre... |
548 549 |
val = CPU_STARTING_FROZEN; #endif /* CONFIG_PM_SLEEP_SMP */ |
e9fb7631e cpu-hotplug: intr... |
550 |
cpu_notify(val, (void *)(long)cpu); |
e545a6140 kernel/cpu.c: cre... |
551 |
} |
68f4f1ec0 sched: Move cpu m... |
552 |
#endif /* CONFIG_SMP */ |
b8d317d10 cpumask: make cpu... |
553 |
|
e56b3bc79 cpu masks: optimi... |
554 555 556 557 |
/* * cpu_bit_bitmap[] is a special, "compressed" data structure that * represents all NR_CPUS bits binary values of 1<<nr. * |
e0b582ec5 cpumask: convert ... |
558 |
* It is used by cpumask_of() to get a constant address to a CPU |
e56b3bc79 cpu masks: optimi... |
559 560 |
* mask value that has a single bit set only. */ |
b8d317d10 cpumask: make cpu... |
561 |
|
e56b3bc79 cpu masks: optimi... |
562 |
/* cpu_bit_bitmap[0] is empty - so we can back into it */ |
4d51985e4 kernel/cpu.c: fix... |
563 |
#define MASK_DECLARE_1(x) [x+1][0] = (1UL << (x)) |
e56b3bc79 cpu masks: optimi... |
564 565 566 |
#define MASK_DECLARE_2(x) MASK_DECLARE_1(x), MASK_DECLARE_1(x+1) #define MASK_DECLARE_4(x) MASK_DECLARE_2(x), MASK_DECLARE_2(x+2) #define MASK_DECLARE_8(x) MASK_DECLARE_4(x), MASK_DECLARE_4(x+4) |
b8d317d10 cpumask: make cpu... |
567 |
|
e56b3bc79 cpu masks: optimi... |
568 569 570 571 572 573 574 |
const unsigned long cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)] = { MASK_DECLARE_8(0), MASK_DECLARE_8(8), MASK_DECLARE_8(16), MASK_DECLARE_8(24), #if BITS_PER_LONG > 32 MASK_DECLARE_8(32), MASK_DECLARE_8(40), MASK_DECLARE_8(48), MASK_DECLARE_8(56), |
b8d317d10 cpumask: make cpu... |
575 576 |
#endif }; |
e56b3bc79 cpu masks: optimi... |
577 |
EXPORT_SYMBOL_GPL(cpu_bit_bitmap); |
2d3854a37 cpumask: introduc... |
578 579 580 |
const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL; EXPORT_SYMBOL(cpu_all_bits); |
b3199c025 cpumask: switch o... |
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 |
#ifdef CONFIG_INIT_ALL_POSSIBLE static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly = CPU_BITS_ALL; #else static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly; #endif const struct cpumask *const cpu_possible_mask = to_cpumask(cpu_possible_bits); EXPORT_SYMBOL(cpu_possible_mask); static DECLARE_BITMAP(cpu_online_bits, CONFIG_NR_CPUS) __read_mostly; const struct cpumask *const cpu_online_mask = to_cpumask(cpu_online_bits); EXPORT_SYMBOL(cpu_online_mask); static DECLARE_BITMAP(cpu_present_bits, CONFIG_NR_CPUS) __read_mostly; const struct cpumask *const cpu_present_mask = to_cpumask(cpu_present_bits); EXPORT_SYMBOL(cpu_present_mask); static DECLARE_BITMAP(cpu_active_bits, CONFIG_NR_CPUS) __read_mostly; const struct cpumask *const cpu_active_mask = to_cpumask(cpu_active_bits); EXPORT_SYMBOL(cpu_active_mask); |
3fa415206 cpumask: make set... |
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 |
void set_cpu_possible(unsigned int cpu, bool possible) { if (possible) cpumask_set_cpu(cpu, to_cpumask(cpu_possible_bits)); else cpumask_clear_cpu(cpu, to_cpumask(cpu_possible_bits)); } void set_cpu_present(unsigned int cpu, bool present) { if (present) cpumask_set_cpu(cpu, to_cpumask(cpu_present_bits)); else cpumask_clear_cpu(cpu, to_cpumask(cpu_present_bits)); } void set_cpu_online(unsigned int cpu, bool online) { if (online) cpumask_set_cpu(cpu, to_cpumask(cpu_online_bits)); else cpumask_clear_cpu(cpu, to_cpumask(cpu_online_bits)); } void set_cpu_active(unsigned int cpu, bool active) { if (active) cpumask_set_cpu(cpu, to_cpumask(cpu_active_bits)); else cpumask_clear_cpu(cpu, to_cpumask(cpu_active_bits)); } void init_cpu_present(const struct cpumask *src) { cpumask_copy(to_cpumask(cpu_present_bits), src); } void init_cpu_possible(const struct cpumask *src) { cpumask_copy(to_cpumask(cpu_possible_bits), src); } void init_cpu_online(const struct cpumask *src) { cpumask_copy(to_cpumask(cpu_online_bits), src); } |