Blame view
kernel/cpu.c
13.8 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* 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> #include <linux/module.h> #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> |
1da177e4c Linux-2.6.12-rc2 |
18 |
|
98a79d6a5 cpumask: centrali... |
19 |
#ifdef CONFIG_SMP |
b3199c025 cpumask: switch o... |
20 |
/* Serializes the updates to cpu_online_mask, cpu_present_mask */ |
aa9538777 cpu hotplug: simp... |
21 |
static DEFINE_MUTEX(cpu_add_remove_lock); |
1da177e4c Linux-2.6.12-rc2 |
22 |
|
79a6cdeb7 cpuhotplug: do no... |
23 24 25 26 27 28 29 30 31 32 33 34 35 |
/* * 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... |
36 |
static RAW_NOTIFIER_HEAD(cpu_chain); |
1da177e4c Linux-2.6.12-rc2 |
37 |
|
e3920fb42 [PATCH] Disable C... |
38 39 40 41 |
/* 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... |
42 |
#ifdef CONFIG_HOTPLUG_CPU |
d221938c0 cpu-hotplug: refc... |
43 44 45 46 47 48 49 50 |
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... |
51 52 53 54 55 |
} cpu_hotplug = { .active_writer = NULL, .lock = __MUTEX_INITIALIZER(cpu_hotplug.lock), .refcount = 0, }; |
d221938c0 cpu-hotplug: refc... |
56 |
|
86ef5c9a8 cpu-hotplug: repl... |
57 |
void get_online_cpus(void) |
a9d9baa1e [PATCH] clean up ... |
58 |
{ |
d221938c0 cpu-hotplug: refc... |
59 60 |
might_sleep(); if (cpu_hotplug.active_writer == current) |
aa9538777 cpu hotplug: simp... |
61 |
return; |
d221938c0 cpu-hotplug: refc... |
62 63 64 |
mutex_lock(&cpu_hotplug.lock); cpu_hotplug.refcount++; mutex_unlock(&cpu_hotplug.lock); |
a9d9baa1e [PATCH] clean up ... |
65 |
} |
86ef5c9a8 cpu-hotplug: repl... |
66 |
EXPORT_SYMBOL_GPL(get_online_cpus); |
90d45d17f [PATCH] cpu hotpl... |
67 |
|
86ef5c9a8 cpu-hotplug: repl... |
68 |
void put_online_cpus(void) |
a9d9baa1e [PATCH] clean up ... |
69 |
{ |
d221938c0 cpu-hotplug: refc... |
70 |
if (cpu_hotplug.active_writer == current) |
aa9538777 cpu hotplug: simp... |
71 |
return; |
d221938c0 cpu-hotplug: refc... |
72 |
mutex_lock(&cpu_hotplug.lock); |
d2ba7e2ae simplify cpu_hotp... |
73 74 |
if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer)) wake_up_process(cpu_hotplug.active_writer); |
d221938c0 cpu-hotplug: refc... |
75 |
mutex_unlock(&cpu_hotplug.lock); |
a9d9baa1e [PATCH] clean up ... |
76 |
} |
86ef5c9a8 cpu-hotplug: repl... |
77 |
EXPORT_SYMBOL_GPL(put_online_cpus); |
a9d9baa1e [PATCH] clean up ... |
78 |
|
d221938c0 cpu-hotplug: refc... |
79 80 81 82 83 84 85 |
/* * 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... |
86 87 |
* 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... |
88 89 90 91 92 93 94 95 96 97 |
* * 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... |
98 |
* get_online_cpus() not an api which is called all that often. |
d221938c0 cpu-hotplug: refc... |
99 100 101 102 |
* */ static void cpu_hotplug_begin(void) { |
d221938c0 cpu-hotplug: refc... |
103 |
cpu_hotplug.active_writer = current; |
d2ba7e2ae simplify cpu_hotp... |
104 105 106 107 108 109 |
for (;;) { mutex_lock(&cpu_hotplug.lock); if (likely(!cpu_hotplug.refcount)) break; __set_current_state(TASK_UNINTERRUPTIBLE); |
d221938c0 cpu-hotplug: refc... |
110 111 |
mutex_unlock(&cpu_hotplug.lock); schedule(); |
d221938c0 cpu-hotplug: refc... |
112 |
} |
d221938c0 cpu-hotplug: refc... |
113 114 115 116 117 118 119 |
} static void cpu_hotplug_done(void) { cpu_hotplug.active_writer = NULL; mutex_unlock(&cpu_hotplug.lock); } |
79a6cdeb7 cpuhotplug: do no... |
120 121 122 123 |
#else /* #if CONFIG_HOTPLUG_CPU */ static void cpu_hotplug_begin(void) {} static void cpu_hotplug_done(void) {} |
25985edce Fix common misspe... |
124 |
#endif /* #else #if CONFIG_HOTPLUG_CPU */ |
79a6cdeb7 cpuhotplug: do no... |
125 |
|
1da177e4c Linux-2.6.12-rc2 |
126 |
/* Need to know about CPUs going up/down? */ |
f7b16c108 cpu: fix section ... |
127 |
int __ref register_cpu_notifier(struct notifier_block *nb) |
1da177e4c Linux-2.6.12-rc2 |
128 |
{ |
bd5349cfd [PATCH] Convert c... |
129 |
int ret; |
d221938c0 cpu-hotplug: refc... |
130 |
cpu_maps_update_begin(); |
bd5349cfd [PATCH] Convert c... |
131 |
ret = raw_notifier_chain_register(&cpu_chain, nb); |
d221938c0 cpu-hotplug: refc... |
132 |
cpu_maps_update_done(); |
bd5349cfd [PATCH] Convert c... |
133 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
134 |
} |
65edc68c3 [PATCH] cpu hotpl... |
135 |
|
e9fb7631e cpu-hotplug: intr... |
136 137 138 |
static int __cpu_notify(unsigned long val, void *v, int nr_to_call, int *nr_calls) { |
e6bde73b0 cpu-hotplug: retu... |
139 140 141 |
int ret; ret = __raw_notifier_call_chain(&cpu_chain, val, v, nr_to_call, |
e9fb7631e cpu-hotplug: intr... |
142 |
nr_calls); |
e6bde73b0 cpu-hotplug: retu... |
143 144 |
return notifier_to_errno(ret); |
e9fb7631e cpu-hotplug: intr... |
145 146 147 148 149 150 |
} static int cpu_notify(unsigned long val, void *v) { return __cpu_notify(val, v, -1, NULL); } |
00b9b0af5 Avoid warning whe... |
151 |
#ifdef CONFIG_HOTPLUG_CPU |
e9fb7631e cpu-hotplug: intr... |
152 153 |
static void cpu_notify_nofail(unsigned long val, void *v) { |
00b9b0af5 Avoid warning whe... |
154 |
BUG_ON(cpu_notify(val, v)); |
e9fb7631e cpu-hotplug: intr... |
155 |
} |
1da177e4c Linux-2.6.12-rc2 |
156 |
EXPORT_SYMBOL(register_cpu_notifier); |
9647155ff cpu: fix section ... |
157 |
void __ref unregister_cpu_notifier(struct notifier_block *nb) |
1da177e4c Linux-2.6.12-rc2 |
158 |
{ |
d221938c0 cpu-hotplug: refc... |
159 |
cpu_maps_update_begin(); |
bd5349cfd [PATCH] Convert c... |
160 |
raw_notifier_chain_unregister(&cpu_chain, nb); |
d221938c0 cpu-hotplug: refc... |
161 |
cpu_maps_update_done(); |
1da177e4c Linux-2.6.12-rc2 |
162 163 |
} EXPORT_SYMBOL(unregister_cpu_notifier); |
1da177e4c Linux-2.6.12-rc2 |
164 165 166 167 168 169 |
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... |
170 |
if (task_cpu(p) == cpu && p->state == TASK_RUNNING && |
1da177e4c Linux-2.6.12-rc2 |
171 172 |
(!cputime_eq(p->utime, cputime_zero) || !cputime_eq(p->stime, cputime_zero))) |
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; } |
f3de4be9d PM: Fix dependenc... |
364 |
#ifdef CONFIG_PM_SLEEP_SMP |
e0b582ec5 cpumask: convert ... |
365 |
static cpumask_var_t frozen_cpus; |
e3920fb42 [PATCH] Disable C... |
366 |
|
3fb82d56a x86, suspend: Avo... |
367 368 369 370 371 372 373 |
void __weak arch_disable_nonboot_cpus_begin(void) { } void __weak arch_disable_nonboot_cpus_end(void) { } |
e3920fb42 [PATCH] Disable C... |
374 375 |
int disable_nonboot_cpus(void) { |
e9a5f426b CPU: Avoid using ... |
376 |
int cpu, first_cpu, error = 0; |
e3920fb42 [PATCH] Disable C... |
377 |
|
d221938c0 cpu-hotplug: refc... |
378 |
cpu_maps_update_begin(); |
e0b582ec5 cpumask: convert ... |
379 |
first_cpu = cpumask_first(cpu_online_mask); |
9ee349ad6 sched: Fix set_cp... |
380 381 |
/* * We take down all of the non-boot CPUs in one shot to avoid races |
e3920fb42 [PATCH] Disable C... |
382 383 |
* with the userspace trying to use the CPU hotplug at the same time */ |
e0b582ec5 cpumask: convert ... |
384 |
cpumask_clear(frozen_cpus); |
3fb82d56a x86, suspend: Avo... |
385 |
arch_disable_nonboot_cpus_begin(); |
6ad4c1888 sched: Fix balanc... |
386 |
|
e3920fb42 [PATCH] Disable C... |
387 388 389 390 391 |
printk("Disabling non-boot CPUs ... "); for_each_online_cpu(cpu) { if (cpu == first_cpu) continue; |
8bb784428 Add suspend-relat... |
392 |
error = _cpu_down(cpu, 1); |
feae3203d timers, init: Lim... |
393 |
if (!error) |
e0b582ec5 cpumask: convert ... |
394 |
cpumask_set_cpu(cpu, frozen_cpus); |
feae3203d timers, init: Lim... |
395 |
else { |
e3920fb42 [PATCH] Disable C... |
396 397 398 399 400 401 |
printk(KERN_ERR "Error taking CPU%d down: %d ", cpu, error); break; } } |
86886e55b x86, intel_txt: I... |
402 |
|
3fb82d56a x86, suspend: Avo... |
403 |
arch_disable_nonboot_cpus_end(); |
e3920fb42 [PATCH] Disable C... |
404 405 406 407 408 |
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: ... |
409 410 |
printk(KERN_ERR "Non-boot CPUs are not disabled "); |
e3920fb42 [PATCH] Disable C... |
411 |
} |
d221938c0 cpu-hotplug: refc... |
412 |
cpu_maps_update_done(); |
e3920fb42 [PATCH] Disable C... |
413 414 |
return error; } |
d0af9eed5 x86, pat/mtrr: Re... |
415 416 417 418 419 420 421 |
void __weak arch_enable_nonboot_cpus_begin(void) { } void __weak arch_enable_nonboot_cpus_end(void) { } |
fa7303e22 cpu: fix section ... |
422 |
void __ref enable_nonboot_cpus(void) |
e3920fb42 [PATCH] Disable C... |
423 424 425 426 |
{ int cpu, error; /* Allow everyone to use the CPU hotplug again */ |
d221938c0 cpu-hotplug: refc... |
427 |
cpu_maps_update_begin(); |
e3920fb42 [PATCH] Disable C... |
428 |
cpu_hotplug_disabled = 0; |
e0b582ec5 cpumask: convert ... |
429 |
if (cpumask_empty(frozen_cpus)) |
1d64b9cb1 [PATCH] Fix micro... |
430 |
goto out; |
e3920fb42 [PATCH] Disable C... |
431 |
|
4d51985e4 kernel/cpu.c: fix... |
432 433 |
printk(KERN_INFO "Enabling non-boot CPUs ... "); |
d0af9eed5 x86, pat/mtrr: Re... |
434 435 |
arch_enable_nonboot_cpus_begin(); |
e0b582ec5 cpumask: convert ... |
436 |
for_each_cpu(cpu, frozen_cpus) { |
8bb784428 Add suspend-relat... |
437 |
error = _cpu_up(cpu, 1); |
e3920fb42 [PATCH] Disable C... |
438 |
if (!error) { |
4d51985e4 kernel/cpu.c: fix... |
439 440 |
printk(KERN_INFO "CPU%d is up ", cpu); |
e3920fb42 [PATCH] Disable C... |
441 442 |
continue; } |
1d64b9cb1 [PATCH] Fix micro... |
443 444 |
printk(KERN_WARNING "Error taking CPU%d up: %d ", cpu, error); |
e3920fb42 [PATCH] Disable C... |
445 |
} |
d0af9eed5 x86, pat/mtrr: Re... |
446 447 |
arch_enable_nonboot_cpus_end(); |
e0b582ec5 cpumask: convert ... |
448 |
cpumask_clear(frozen_cpus); |
1d64b9cb1 [PATCH] Fix micro... |
449 |
out: |
d221938c0 cpu-hotplug: refc... |
450 |
cpu_maps_update_done(); |
1da177e4c Linux-2.6.12-rc2 |
451 |
} |
e0b582ec5 cpumask: convert ... |
452 453 454 455 456 457 458 459 |
static int alloc_frozen_cpus(void) { if (!alloc_cpumask_var(&frozen_cpus, GFP_KERNEL|__GFP_ZERO)) return -ENOMEM; return 0; } core_initcall(alloc_frozen_cpus); |
f3de4be9d PM: Fix dependenc... |
460 |
#endif /* CONFIG_PM_SLEEP_SMP */ |
68f4f1ec0 sched: Move cpu m... |
461 |
|
e545a6140 kernel/cpu.c: cre... |
462 463 464 465 466 467 468 469 |
/** * 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 ... |
470 |
void __cpuinit notify_cpu_starting(unsigned int cpu) |
e545a6140 kernel/cpu.c: cre... |
471 472 473 474 |
{ unsigned long val = CPU_STARTING; #ifdef CONFIG_PM_SLEEP_SMP |
e0b582ec5 cpumask: convert ... |
475 |
if (frozen_cpus != NULL && cpumask_test_cpu(cpu, frozen_cpus)) |
e545a6140 kernel/cpu.c: cre... |
476 477 |
val = CPU_STARTING_FROZEN; #endif /* CONFIG_PM_SLEEP_SMP */ |
e9fb7631e cpu-hotplug: intr... |
478 |
cpu_notify(val, (void *)(long)cpu); |
e545a6140 kernel/cpu.c: cre... |
479 |
} |
68f4f1ec0 sched: Move cpu m... |
480 |
#endif /* CONFIG_SMP */ |
b8d317d10 cpumask: make cpu... |
481 |
|
e56b3bc79 cpu masks: optimi... |
482 483 484 485 |
/* * cpu_bit_bitmap[] is a special, "compressed" data structure that * represents all NR_CPUS bits binary values of 1<<nr. * |
e0b582ec5 cpumask: convert ... |
486 |
* It is used by cpumask_of() to get a constant address to a CPU |
e56b3bc79 cpu masks: optimi... |
487 488 |
* mask value that has a single bit set only. */ |
b8d317d10 cpumask: make cpu... |
489 |
|
e56b3bc79 cpu masks: optimi... |
490 |
/* cpu_bit_bitmap[0] is empty - so we can back into it */ |
4d51985e4 kernel/cpu.c: fix... |
491 |
#define MASK_DECLARE_1(x) [x+1][0] = (1UL << (x)) |
e56b3bc79 cpu masks: optimi... |
492 493 494 |
#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... |
495 |
|
e56b3bc79 cpu masks: optimi... |
496 497 498 499 500 501 502 |
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... |
503 504 |
#endif }; |
e56b3bc79 cpu masks: optimi... |
505 |
EXPORT_SYMBOL_GPL(cpu_bit_bitmap); |
2d3854a37 cpumask: introduc... |
506 507 508 |
const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL; EXPORT_SYMBOL(cpu_all_bits); |
b3199c025 cpumask: switch o... |
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 |
#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... |
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 |
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); } |