Blame view

kernel/cpu.c 12 KB
1da177e4c   Linus Torvalds   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   Ingo Molnar   [PATCH] Convert k...
16
  #include <linux/mutex.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17

68f4f1ec0   Max Krasnyansky   sched: Move cpu m...
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  /*
   * Represents all cpu's present in the system
   * In systems capable of hotplug, this map could dynamically grow
   * as new cpu's are detected in the system via any platform specific
   * method, such as ACPI for e.g.
   */
  cpumask_t cpu_present_map __read_mostly;
  EXPORT_SYMBOL(cpu_present_map);
  
  #ifndef CONFIG_SMP
  
  /*
   * Represents all cpu's that are currently online.
   */
  cpumask_t cpu_online_map __read_mostly = CPU_MASK_ALL;
  EXPORT_SYMBOL(cpu_online_map);
  
  cpumask_t cpu_possible_map __read_mostly = CPU_MASK_ALL;
  EXPORT_SYMBOL(cpu_possible_map);
  
  #else /* CONFIG_SMP */
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
39
  /* Serializes the updates to cpu_online_map, cpu_present_map */
aa9538777   Linus Torvalds   cpu hotplug: simp...
40
  static DEFINE_MUTEX(cpu_add_remove_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41

bd5349cfd   Neil Brown   [PATCH] Convert c...
42
  static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43

e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
44
45
46
47
  /* 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;
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
48
49
50
51
52
53
54
55
  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;
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
56
  } cpu_hotplug;
90d45d17f   Ashok Raj   [PATCH] cpu hotpl...
57

d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
58
59
60
61
62
  void __init cpu_hotplug_init(void)
  {
  	cpu_hotplug.active_writer = NULL;
  	mutex_init(&cpu_hotplug.lock);
  	cpu_hotplug.refcount = 0;
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
63
  }
e761b7725   Max Krasnyansky   cpu hotplug, sche...
64
  cpumask_t cpu_active_map;
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
65
  #ifdef CONFIG_HOTPLUG_CPU
90d45d17f   Ashok Raj   [PATCH] cpu hotpl...
66

86ef5c9a8   Gautham R Shenoy   cpu-hotplug: repl...
67
  void get_online_cpus(void)
a9d9baa1e   Ashok Raj   [PATCH] clean up ...
68
  {
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
69
70
  	might_sleep();
  	if (cpu_hotplug.active_writer == current)
aa9538777   Linus Torvalds   cpu hotplug: simp...
71
  		return;
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
72
73
74
  	mutex_lock(&cpu_hotplug.lock);
  	cpu_hotplug.refcount++;
  	mutex_unlock(&cpu_hotplug.lock);
a9d9baa1e   Ashok Raj   [PATCH] clean up ...
75
  }
86ef5c9a8   Gautham R Shenoy   cpu-hotplug: repl...
76
  EXPORT_SYMBOL_GPL(get_online_cpus);
90d45d17f   Ashok Raj   [PATCH] cpu hotpl...
77

86ef5c9a8   Gautham R Shenoy   cpu-hotplug: repl...
78
  void put_online_cpus(void)
a9d9baa1e   Ashok Raj   [PATCH] clean up ...
79
  {
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
80
  	if (cpu_hotplug.active_writer == current)
aa9538777   Linus Torvalds   cpu hotplug: simp...
81
  		return;
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
82
  	mutex_lock(&cpu_hotplug.lock);
d2ba7e2ae   Oleg Nesterov   simplify cpu_hotp...
83
84
  	if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
  		wake_up_process(cpu_hotplug.active_writer);
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
85
  	mutex_unlock(&cpu_hotplug.lock);
a9d9baa1e   Ashok Raj   [PATCH] clean up ...
86
  }
86ef5c9a8   Gautham R Shenoy   cpu-hotplug: repl...
87
  EXPORT_SYMBOL_GPL(put_online_cpus);
a9d9baa1e   Ashok Raj   [PATCH] clean up ...
88

a9d9baa1e   Ashok Raj   [PATCH] clean up ...
89
  #endif	/* CONFIG_HOTPLUG_CPU */
90d45d17f   Ashok Raj   [PATCH] cpu hotpl...
90

d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  /*
   * The following two API's must be used when attempting
   * to serialize the updates to cpu_online_map, cpu_present_map.
   */
  void cpu_maps_update_begin(void)
  {
  	mutex_lock(&cpu_add_remove_lock);
  }
  
  void cpu_maps_update_done(void)
  {
  	mutex_unlock(&cpu_add_remove_lock);
  }
  
  /*
   * 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   Oleg Nesterov   simplify cpu_hotp...
112
113
   * Since cpu_hotplug_begin() is always called after invoking
   * cpu_maps_update_begin(), we can be sure that only one writer is active.
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
114
115
116
117
118
119
120
121
122
123
   *
   * 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   Gautham R Shenoy   cpu-hotplug: repl...
124
   * get_online_cpus() not an api which is called all that often.
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
125
126
127
128
   *
   */
  static void cpu_hotplug_begin(void)
  {
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
129
  	cpu_hotplug.active_writer = current;
d2ba7e2ae   Oleg Nesterov   simplify cpu_hotp...
130
131
132
133
134
135
  
  	for (;;) {
  		mutex_lock(&cpu_hotplug.lock);
  		if (likely(!cpu_hotplug.refcount))
  			break;
  		__set_current_state(TASK_UNINTERRUPTIBLE);
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
136
137
  		mutex_unlock(&cpu_hotplug.lock);
  		schedule();
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
138
  	}
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
139
140
141
142
143
144
145
  }
  
  static void cpu_hotplug_done(void)
  {
  	cpu_hotplug.active_writer = NULL;
  	mutex_unlock(&cpu_hotplug.lock);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
  /* Need to know about CPUs going up/down? */
f7b16c108   Sam Ravnborg   cpu: fix section ...
147
  int __ref register_cpu_notifier(struct notifier_block *nb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
  {
bd5349cfd   Neil Brown   [PATCH] Convert c...
149
  	int ret;
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
150
  	cpu_maps_update_begin();
bd5349cfd   Neil Brown   [PATCH] Convert c...
151
  	ret = raw_notifier_chain_register(&cpu_chain, nb);
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
152
  	cpu_maps_update_done();
bd5349cfd   Neil Brown   [PATCH] Convert c...
153
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
  }
65edc68c3   Chandra Seetharaman   [PATCH] cpu hotpl...
155
156
  
  #ifdef CONFIG_HOTPLUG_CPU
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  EXPORT_SYMBOL(register_cpu_notifier);
9647155ff   Sam Ravnborg   cpu: fix section ...
158
  void __ref unregister_cpu_notifier(struct notifier_block *nb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
  {
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
160
  	cpu_maps_update_begin();
bd5349cfd   Neil Brown   [PATCH] Convert c...
161
  	raw_notifier_chain_unregister(&cpu_chain, nb);
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
162
  	cpu_maps_update_done();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
164
  }
  EXPORT_SYMBOL(unregister_cpu_notifier);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
166
167
168
169
170
171
172
173
174
  static inline void check_for_tasks(int cpu)
  {
  	struct task_struct *p;
  
  	write_lock_irq(&tasklist_lock);
  	for_each_process(p) {
  		if (task_cpu(p) == cpu &&
  		    (!cputime_eq(p->utime, cputime_zero) ||
  		     !cputime_eq(p->stime, cputime_zero)))
  			printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d\
e7407dcc6   Heiko Carstens   call cpu_chain wi...
175
176
  				(state = %ld, flags = %x) 
  ",
ba25f9dcc   Pavel Emelyanov   Use helpers to ob...
177
178
  				 p->comm, task_pid_nr(p), cpu,
  				 p->state, p->flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
180
181
  	}
  	write_unlock_irq(&tasklist_lock);
  }
db912f963   Avi Kivity   HOTPLUG: Add CPU_...
182
183
184
185
  struct take_cpu_down_param {
  	unsigned long mod;
  	void *hcpu;
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  /* Take this CPU down. */
514a20a5d   Sam Ravnborg   cpu: fix section ...
187
  static int __ref take_cpu_down(void *_param)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
  {
db912f963   Avi Kivity   HOTPLUG: Add CPU_...
189
  	struct take_cpu_down_param *param = _param;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
193
  	/* Ensure this CPU doesn't handle any more interrupts. */
  	err = __cpu_disable();
  	if (err < 0)
f37051364   Zwane Mwaikambo   [PATCH] i386 CPU ...
194
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195

3ba35573a   Manfred Spraul   kernel/cpu.c: Mov...
196
197
  	raw_notifier_call_chain(&cpu_chain, CPU_DYING | param->mod,
  				param->hcpu);
f37051364   Zwane Mwaikambo   [PATCH] i386 CPU ...
198
199
200
201
  	/* Force idle task to run as soon as we yield: it should
  	   immediately notice cpu is offline and die quickly. */
  	sched_idle_next();
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
  }
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
203
  /* Requires cpu_add_remove_lock to be held */
514a20a5d   Sam Ravnborg   cpu: fix section ...
204
  static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205
  {
e7407dcc6   Heiko Carstens   call cpu_chain wi...
206
  	int err, nr_calls = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
  	cpumask_t old_allowed, tmp;
e7407dcc6   Heiko Carstens   call cpu_chain wi...
208
  	void *hcpu = (void *)(long)cpu;
8bb784428   Rafael J. Wysocki   Add suspend-relat...
209
  	unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
db912f963   Avi Kivity   HOTPLUG: Add CPU_...
210
211
212
213
  	struct take_cpu_down_param tcd_param = {
  		.mod = mod,
  		.hcpu = hcpu,
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214

e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
215
216
  	if (num_online_cpus() == 1)
  		return -EBUSY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217

e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
218
219
  	if (!cpu_online(cpu))
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220

d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
221
  	cpu_hotplug_begin();
8bb784428   Rafael J. Wysocki   Add suspend-relat...
222
  	err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
e7407dcc6   Heiko Carstens   call cpu_chain wi...
223
  					hcpu, -1, &nr_calls);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
  	if (err == NOTIFY_BAD) {
a0d8cdb65   Akinobu Mita   cpu hotplug: cpu:...
225
  		nr_calls--;
8bb784428   Rafael J. Wysocki   Add suspend-relat...
226
227
  		__raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod,
  					  hcpu, nr_calls, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
229
  		printk("%s: attempt to take down CPU %u failed
  ",
af1f16d08   Harvey Harrison   kernel: replace r...
230
  				__func__, cpu);
baaca49f4   Gautham R Shenoy   Define and use ne...
231
232
  		err = -EINVAL;
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
234
235
236
  	}
  
  	/* Ensure that we are not runnable on dying cpu */
  	old_allowed = current->cpus_allowed;
f70316dac   Mike Travis   generic: use new ...
237
  	cpus_setall(tmp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238
  	cpu_clear(cpu, tmp);
f70316dac   Mike Travis   generic: use new ...
239
  	set_cpus_allowed_ptr(current, &tmp);
eeec4fad9   Rusty Russell   stop_machine(): s...
240
  	tmp = cpumask_of_cpu(cpu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241

eeec4fad9   Rusty Russell   stop_machine(): s...
242
  	err = __stop_machine(take_cpu_down, &tcd_param, &tmp);
043215875   Rusty Russell   Hotplug CPU: don'...
243
  	if (err) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
  		/* CPU didn't die: tell everyone.  Can't complain. */
8bb784428   Rafael J. Wysocki   Add suspend-relat...
245
  		if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod,
e7407dcc6   Heiko Carstens   call cpu_chain wi...
246
  					    hcpu) == NOTIFY_BAD)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
  			BUG();
ffdb5976c   Rusty Russell   Simplify stop_mac...
248
  		goto out_allowed;
8fa1d7d3b   Satoru Takeuchi   [PATCH] cpu-hotpl...
249
  	}
043215875   Rusty Russell   Hotplug CPU: don'...
250
  	BUG_ON(cpu_online(cpu));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
252
253
254
255
256
257
  
  	/* Wait for it to sleep (leaving idle task). */
  	while (!idle_cpu(cpu))
  		yield();
  
  	/* This actually kills the CPU. */
  	__cpu_die(cpu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
258
  	/* CPU is completely dead: tell everyone.  Too late to complain. */
8bb784428   Rafael J. Wysocki   Add suspend-relat...
259
260
  	if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD | mod,
  				    hcpu) == NOTIFY_BAD)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
262
263
  		BUG();
  
  	check_for_tasks(cpu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
264
  out_allowed:
f70316dac   Mike Travis   generic: use new ...
265
  	set_cpus_allowed_ptr(current, &old_allowed);
baaca49f4   Gautham R Shenoy   Define and use ne...
266
  out_release:
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
267
  	cpu_hotplug_done();
3da1c84c0   Oleg Nesterov   workqueues: make ...
268
269
270
271
272
  	if (!err) {
  		if (raw_notifier_call_chain(&cpu_chain, CPU_POST_DEAD | mod,
  					    hcpu) == NOTIFY_BAD)
  			BUG();
  	}
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
273
274
  	return err;
  }
514a20a5d   Sam Ravnborg   cpu: fix section ...
275
  int __ref cpu_down(unsigned int cpu)
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
276
277
  {
  	int err = 0;
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
278
  	cpu_maps_update_begin();
e761b7725   Max Krasnyansky   cpu hotplug, sche...
279
280
  
  	if (cpu_hotplug_disabled) {
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
281
  		err = -EBUSY;
e761b7725   Max Krasnyansky   cpu hotplug, sche...
282
283
284
285
  		goto out;
  	}
  
  	cpu_clear(cpu, cpu_active_map);
39b0fad71   Max Krasnyansky   cpu hotplug: Make...
286
287
288
289
290
291
292
293
294
  	/*
  	 * Make sure the all cpus did the reschedule and are not
  	 * using stale version of the cpu_active_map.
  	 * This is not strictly necessary becuase stop_machine()
  	 * that we run down the line already provides the required
  	 * synchronization. But it's really a side effect and we do not
  	 * want to depend on the innards of the stop_machine here.
  	 */
  	synchronize_sched();
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
295

e761b7725   Max Krasnyansky   cpu hotplug, sche...
296
  	err = _cpu_down(cpu, 0);
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
297

e761b7725   Max Krasnyansky   cpu hotplug, sche...
298
299
300
301
  	if (cpu_online(cpu))
  		cpu_set(cpu, cpu_active_map);
  
  out:
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
302
  	cpu_maps_update_done();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
304
  	return err;
  }
b62b8ef90   Zhang Rui   force offline the...
305
  EXPORT_SYMBOL(cpu_down);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
  #endif /*CONFIG_HOTPLUG_CPU*/
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
307
  /* Requires cpu_add_remove_lock to be held */
8bb784428   Rafael J. Wysocki   Add suspend-relat...
308
  static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
  {
baaca49f4   Gautham R Shenoy   Define and use ne...
310
  	int ret, nr_calls = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311
  	void *hcpu = (void *)(long)cpu;
8bb784428   Rafael J. Wysocki   Add suspend-relat...
312
  	unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313

e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
314
315
  	if (cpu_online(cpu) || !cpu_present(cpu))
  		return -EINVAL;
90d45d17f   Ashok Raj   [PATCH] cpu hotpl...
316

d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
317
  	cpu_hotplug_begin();
8bb784428   Rafael J. Wysocki   Add suspend-relat...
318
  	ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu,
baaca49f4   Gautham R Shenoy   Define and use ne...
319
  							-1, &nr_calls);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
  	if (ret == NOTIFY_BAD) {
a0d8cdb65   Akinobu Mita   cpu hotplug: cpu:...
321
  		nr_calls--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
323
  		printk("%s: attempt to bring up CPU %u failed
  ",
af1f16d08   Harvey Harrison   kernel: replace r...
324
  				__func__, cpu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
325
326
327
328
329
330
331
332
  		ret = -EINVAL;
  		goto out_notify;
  	}
  
  	/* Arch-specific enabling code. */
  	ret = __cpu_up(cpu);
  	if (ret != 0)
  		goto out_notify;
6978c7052   Eric Sesterhenn   BUG_ON() Conversi...
333
  	BUG_ON(!cpu_online(cpu));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334

279ef6bbb   Dmitry Adamushko   sched, cpu hotplu...
335
  	cpu_set(cpu, cpu_active_map);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
  	/* Now call notifier in preparation. */
8bb784428   Rafael J. Wysocki   Add suspend-relat...
337
  	raw_notifier_call_chain(&cpu_chain, CPU_ONLINE | mod, hcpu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
339
340
  
  out_notify:
  	if (ret != 0)
baaca49f4   Gautham R Shenoy   Define and use ne...
341
  		__raw_notifier_call_chain(&cpu_chain,
8bb784428   Rafael J. Wysocki   Add suspend-relat...
342
  				CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
343
  	cpu_hotplug_done();
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
344
345
346
  
  	return ret;
  }
b282b6f8a   Gautham R Shenoy   [PATCH] Change cp...
347
  int __cpuinit cpu_up(unsigned int cpu)
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
348
349
  {
  	int err = 0;
73e753a50   KAMEZAWA Hiroyuki   CPU HOTPLUG: avoi...
350
351
352
353
  	if (!cpu_isset(cpu, cpu_possible_map)) {
  		printk(KERN_ERR "can't online cpu %d because it is not "
  			"configured as may-hotadd at boot time
  ", cpu);
3ee1062b4   Heiko Carstens   cpu hotplug: s390...
354
  #if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
73e753a50   KAMEZAWA Hiroyuki   CPU HOTPLUG: avoi...
355
356
357
358
359
360
  		printk(KERN_ERR "please check additional_cpus= boot "
  				"parameter
  ");
  #endif
  		return -EINVAL;
  	}
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
361

d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
362
  	cpu_maps_update_begin();
e761b7725   Max Krasnyansky   cpu hotplug, sche...
363
364
  
  	if (cpu_hotplug_disabled) {
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
365
  		err = -EBUSY;
e761b7725   Max Krasnyansky   cpu hotplug, sche...
366
367
368
369
  		goto out;
  	}
  
  	err = _cpu_up(cpu, 0);
e761b7725   Max Krasnyansky   cpu hotplug, sche...
370
  out:
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
371
  	cpu_maps_update_done();
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
372
373
  	return err;
  }
f3de4be9d   Rafael J. Wysocki   PM: Fix dependenc...
374
  #ifdef CONFIG_PM_SLEEP_SMP
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
375
376
377
378
  static cpumask_t frozen_cpus;
  
  int disable_nonboot_cpus(void)
  {
e1d9fd2e3   Ingo Molnar   [PATCH] suspend: ...
379
  	int cpu, first_cpu, error = 0;
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
380

d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
381
  	cpu_maps_update_begin();
1d64b9cb1   Rafael J. Wysocki   [PATCH] Fix micro...
382
  	first_cpu = first_cpu(cpu_online_map);
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
383
384
385
386
387
388
389
390
391
  	/* We take down all of the non-boot CPUs in one shot to avoid races
  	 * with the userspace trying to use the CPU hotplug at the same time
  	 */
  	cpus_clear(frozen_cpus);
  	printk("Disabling non-boot CPUs ...
  ");
  	for_each_online_cpu(cpu) {
  		if (cpu == first_cpu)
  			continue;
8bb784428   Rafael J. Wysocki   Add suspend-relat...
392
  		error = _cpu_down(cpu, 1);
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
  		if (!error) {
  			cpu_set(cpu, frozen_cpus);
  			printk("CPU%d is down
  ", cpu);
  		} else {
  			printk(KERN_ERR "Error taking CPU%d down: %d
  ",
  				cpu, error);
  			break;
  		}
  	}
  	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   Ingo Molnar   [PATCH] suspend: ...
409
410
  		printk(KERN_ERR "Non-boot CPUs are not disabled
  ");
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
411
  	}
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
412
  	cpu_maps_update_done();
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
413
414
  	return error;
  }
fa7303e22   Sam Ravnborg   cpu: fix section ...
415
  void __ref enable_nonboot_cpus(void)
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
416
417
418
419
  {
  	int cpu, error;
  
  	/* Allow everyone to use the CPU hotplug again */
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
420
  	cpu_maps_update_begin();
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
421
  	cpu_hotplug_disabled = 0;
ed746e3b1   Rafael J. Wysocki   [PATCH] swsusp: C...
422
  	if (cpus_empty(frozen_cpus))
1d64b9cb1   Rafael J. Wysocki   [PATCH] Fix micro...
423
  		goto out;
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
424
425
426
  
  	printk("Enabling non-boot CPUs ...
  ");
363ab6f14   Mike Travis   core: use perform...
427
  	for_each_cpu_mask_nr(cpu, frozen_cpus) {
8bb784428   Rafael J. Wysocki   Add suspend-relat...
428
  		error = _cpu_up(cpu, 1);
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
429
430
431
432
433
  		if (!error) {
  			printk("CPU%d is up
  ", cpu);
  			continue;
  		}
1d64b9cb1   Rafael J. Wysocki   [PATCH] Fix micro...
434
435
  		printk(KERN_WARNING "Error taking CPU%d up: %d
  ", cpu, error);
e3920fb42   Rafael J. Wysocki   [PATCH] Disable C...
436
437
  	}
  	cpus_clear(frozen_cpus);
1d64b9cb1   Rafael J. Wysocki   [PATCH] Fix micro...
438
  out:
d221938c0   Gautham R Shenoy   cpu-hotplug: refc...
439
  	cpu_maps_update_done();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
  }
f3de4be9d   Rafael J. Wysocki   PM: Fix dependenc...
441
  #endif /* CONFIG_PM_SLEEP_SMP */
68f4f1ec0   Max Krasnyansky   sched: Move cpu m...
442

e545a6140   Manfred Spraul   kernel/cpu.c: cre...
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
  /**
   * 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().
   */
  void notify_cpu_starting(unsigned int cpu)
  {
  	unsigned long val = CPU_STARTING;
  
  #ifdef CONFIG_PM_SLEEP_SMP
  	if (cpu_isset(cpu, frozen_cpus))
  		val = CPU_STARTING_FROZEN;
  #endif /* CONFIG_PM_SLEEP_SMP */
  	raw_notifier_call_chain(&cpu_chain, val, (void *)(long)cpu);
  }
68f4f1ec0   Max Krasnyansky   sched: Move cpu m...
461
  #endif /* CONFIG_SMP */
b8d317d10   Mike Travis   cpumask: make cpu...
462

e56b3bc79   Linus Torvalds   cpu masks: optimi...
463
464
465
466
467
468
469
  /*
   * cpu_bit_bitmap[] is a special, "compressed" data structure that
   * represents all NR_CPUS bits binary values of 1<<nr.
   *
   * It is used by cpumask_of_cpu() to get a constant address to a CPU
   * mask value that has a single bit set only.
   */
b8d317d10   Mike Travis   cpumask: make cpu...
470

e56b3bc79   Linus Torvalds   cpu masks: optimi...
471
472
473
474
475
  /* cpu_bit_bitmap[0] is empty - so we can back into it */
  #define MASK_DECLARE_1(x)	[x+1][0] = 1UL << (x)
  #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   Mike Travis   cpumask: make cpu...
476

e56b3bc79   Linus Torvalds   cpu masks: optimi...
477
478
479
480
481
482
483
  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   Mike Travis   cpumask: make cpu...
484
485
  #endif
  };
e56b3bc79   Linus Torvalds   cpu masks: optimi...
486
  EXPORT_SYMBOL_GPL(cpu_bit_bitmap);