cpu.c 17.1 KB
Newer Older
L
Linus Torvalds 已提交
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>
13 14
#include <linux/oom.h>
#include <linux/rcupdate.h>
15
#include <linux/export.h>
16
#include <linux/bug.h>
L
Linus Torvalds 已提交
17 18
#include <linux/kthread.h>
#include <linux/stop_machine.h>
19
#include <linux/mutex.h>
20
#include <linux/gfp.h>
21
#include <linux/suspend.h>
L
Linus Torvalds 已提交
22

23 24
#include "smpboot.h"

25
#ifdef CONFIG_SMP
26
/* Serializes the updates to cpu_online_mask, cpu_present_mask */
27
static DEFINE_MUTEX(cpu_add_remove_lock);
L
Linus Torvalds 已提交
28

29 30 31 32 33 34 35 36 37 38 39 40 41 42
/*
 * 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);
}

43
static RAW_NOTIFIER_HEAD(cpu_chain);
L
Linus Torvalds 已提交
44

45 46 47 48 49
/* 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;

50 51
#ifdef CONFIG_HOTPLUG_CPU

52 53 54 55 56 57 58 59
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;
60 61 62 63 64
} cpu_hotplug = {
	.active_writer = NULL,
	.lock = __MUTEX_INITIALIZER(cpu_hotplug.lock),
	.refcount = 0,
};
65

66
void get_online_cpus(void)
67
{
68 69
	might_sleep();
	if (cpu_hotplug.active_writer == current)
70
		return;
71 72 73 74
	mutex_lock(&cpu_hotplug.lock);
	cpu_hotplug.refcount++;
	mutex_unlock(&cpu_hotplug.lock);

75
}
76
EXPORT_SYMBOL_GPL(get_online_cpus);
77

78
void put_online_cpus(void)
79
{
80
	if (cpu_hotplug.active_writer == current)
81
		return;
82
	mutex_lock(&cpu_hotplug.lock);
83 84
	if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
		wake_up_process(cpu_hotplug.active_writer);
85 86
	mutex_unlock(&cpu_hotplug.lock);

87
}
88
EXPORT_SYMBOL_GPL(put_online_cpus);
89

90 91 92 93 94 95 96
/*
 * 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
 *
97 98
 * Since cpu_hotplug_begin() is always called after invoking
 * cpu_maps_update_begin(), we can be sure that only one writer is active.
99 100 101 102 103 104 105 106 107 108
 *
 * 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
109
 * get_online_cpus() not an api which is called all that often.
110 111 112 113 114
 *
 */
static void cpu_hotplug_begin(void)
{
	cpu_hotplug.active_writer = current;
115 116 117 118 119 120

	for (;;) {
		mutex_lock(&cpu_hotplug.lock);
		if (likely(!cpu_hotplug.refcount))
			break;
		__set_current_state(TASK_UNINTERRUPTIBLE);
121 122 123 124 125 126 127 128 129 130
		mutex_unlock(&cpu_hotplug.lock);
		schedule();
	}
}

static void cpu_hotplug_done(void)
{
	cpu_hotplug.active_writer = NULL;
	mutex_unlock(&cpu_hotplug.lock);
}
131 132 133 134

#else /* #if CONFIG_HOTPLUG_CPU */
static void cpu_hotplug_begin(void) {}
static void cpu_hotplug_done(void) {}
L
Lucas De Marchi 已提交
135
#endif	/* #else #if CONFIG_HOTPLUG_CPU */
136

L
Linus Torvalds 已提交
137
/* Need to know about CPUs going up/down? */
138
int __ref register_cpu_notifier(struct notifier_block *nb)
L
Linus Torvalds 已提交
139
{
140
	int ret;
141
	cpu_maps_update_begin();
142
	ret = raw_notifier_chain_register(&cpu_chain, nb);
143
	cpu_maps_update_done();
144
	return ret;
L
Linus Torvalds 已提交
145
}
146

147 148 149
static int __cpu_notify(unsigned long val, void *v, int nr_to_call,
			int *nr_calls)
{
150 151 152
	int ret;

	ret = __raw_notifier_call_chain(&cpu_chain, val, v, nr_to_call,
153
					nr_calls);
154 155

	return notifier_to_errno(ret);
156 157 158 159 160 161 162
}

static int cpu_notify(unsigned long val, void *v)
{
	return __cpu_notify(val, v, -1, NULL);
}

163 164
#ifdef CONFIG_HOTPLUG_CPU

165 166
static void cpu_notify_nofail(unsigned long val, void *v)
{
167
	BUG_ON(cpu_notify(val, v));
168
}
L
Linus Torvalds 已提交
169 170
EXPORT_SYMBOL(register_cpu_notifier);

171
void __ref unregister_cpu_notifier(struct notifier_block *nb)
L
Linus Torvalds 已提交
172
{
173
	cpu_maps_update_begin();
174
	raw_notifier_chain_unregister(&cpu_chain, nb);
175
	cpu_maps_update_done();
L
Linus Torvalds 已提交
176 177 178
}
EXPORT_SYMBOL(unregister_cpu_notifier);

179 180 181 182 183 184 185 186 187 188 189 190
/**
 * clear_tasks_mm_cpumask - Safely clear tasks' mm_cpumask for a CPU
 * @cpu: a CPU id
 *
 * This function walks all processes, finds a valid mm struct for each one and
 * then clears a corresponding bit in mm's cpumask.  While this all sounds
 * trivial, there are various non-obvious corner cases, which this function
 * tries to solve in a safe manner.
 *
 * Also note that the function uses a somewhat relaxed locking scheme, so it may
 * be called only for an already offlined CPU.
 */
191 192 193 194 195 196 197 198 199 200 201
void clear_tasks_mm_cpumask(int cpu)
{
	struct task_struct *p;

	/*
	 * This function is called after the cpu is taken down and marked
	 * offline, so its not like new tasks will ever get this cpu set in
	 * their mm mask. -- Peter Zijlstra
	 * Thus, we may use rcu_read_lock() here, instead of grabbing
	 * full-fledged tasklist_lock.
	 */
202
	WARN_ON(cpu_online(cpu));
203 204 205 206
	rcu_read_lock();
	for_each_process(p) {
		struct task_struct *t;

207 208 209 210
		/*
		 * Main thread might exit, but other threads may still have
		 * a valid mm. Find one.
		 */
211 212 213 214 215 216 217 218 219
		t = find_lock_task_mm(p);
		if (!t)
			continue;
		cpumask_clear_cpu(cpu, mm_cpumask(t->mm));
		task_unlock(t);
	}
	rcu_read_unlock();
}

L
Linus Torvalds 已提交
220 221 222 223 224 225
static inline void check_for_tasks(int cpu)
{
	struct task_struct *p;

	write_lock_irq(&tasklist_lock);
	for_each_process(p) {
226
		if (task_cpu(p) == cpu && p->state == TASK_RUNNING &&
227
		    (p->utime || p->stime))
228 229 230 231
			printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d "
				"(state = %ld, flags = %x)\n",
				p->comm, task_pid_nr(p), cpu,
				p->state, p->flags);
L
Linus Torvalds 已提交
232 233 234 235
	}
	write_unlock_irq(&tasklist_lock);
}

A
Avi Kivity 已提交
236 237 238 239 240
struct take_cpu_down_param {
	unsigned long mod;
	void *hcpu;
};

L
Linus Torvalds 已提交
241
/* Take this CPU down. */
242
static int __ref take_cpu_down(void *_param)
L
Linus Torvalds 已提交
243
{
A
Avi Kivity 已提交
244
	struct take_cpu_down_param *param = _param;
L
Linus Torvalds 已提交
245 246 247 248 249
	int err;

	/* Ensure this CPU doesn't handle any more interrupts. */
	err = __cpu_disable();
	if (err < 0)
Z
Zwane Mwaikambo 已提交
250
		return err;
L
Linus Torvalds 已提交
251

252
	cpu_notify(CPU_DYING | param->mod, param->hcpu);
Z
Zwane Mwaikambo 已提交
253
	return 0;
L
Linus Torvalds 已提交
254 255
}

256
/* Requires cpu_add_remove_lock to be held */
257
static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
L
Linus Torvalds 已提交
258
{
259 260
	int err, nr_calls = 0;
	void *hcpu = (void *)(long)cpu;
261
	unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
A
Avi Kivity 已提交
262 263 264 265
	struct take_cpu_down_param tcd_param = {
		.mod = mod,
		.hcpu = hcpu,
	};
L
Linus Torvalds 已提交
266

267 268
	if (num_online_cpus() == 1)
		return -EBUSY;
L
Linus Torvalds 已提交
269

270 271
	if (!cpu_online(cpu))
		return -EINVAL;
L
Linus Torvalds 已提交
272

273
	cpu_hotplug_begin();
274

275
	err = __cpu_notify(CPU_DOWN_PREPARE | mod, hcpu, -1, &nr_calls);
276
	if (err) {
277
		nr_calls--;
278
		__cpu_notify(CPU_DOWN_FAILED | mod, hcpu, nr_calls, NULL);
L
Linus Torvalds 已提交
279
		printk("%s: attempt to take down CPU %u failed\n",
280
				__func__, cpu);
281
		goto out_release;
L
Linus Torvalds 已提交
282
	}
283
	smpboot_park_threads(cpu);
L
Linus Torvalds 已提交
284

R
Rusty Russell 已提交
285
	err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
286
	if (err) {
L
Linus Torvalds 已提交
287
		/* CPU didn't die: tell everyone.  Can't complain. */
288
		smpboot_unpark_threads(cpu);
289
		cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu);
290
		goto out_release;
291
	}
292
	BUG_ON(cpu_online(cpu));
L
Linus Torvalds 已提交
293

294 295 296 297
	/*
	 * 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.
P
Peter Zijlstra 已提交
298 299
	 *
	 * Wait for the stop thread to go away.
300
	 */
P
Peter Zijlstra 已提交
301 302
	while (!idle_cpu(cpu))
		cpu_relax();
L
Linus Torvalds 已提交
303 304 305 306 307

	/* This actually kills the CPU. */
	__cpu_die(cpu);

	/* CPU is completely dead: tell everyone.  Too late to complain. */
308
	cpu_notify_nofail(CPU_DEAD | mod, hcpu);
L
Linus Torvalds 已提交
309 310 311

	check_for_tasks(cpu);

312
out_release:
313
	cpu_hotplug_done();
314 315
	if (!err)
		cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu);
316 317 318
	return err;
}

319
int __ref cpu_down(unsigned int cpu)
320
{
321
	int err;
322

323
	cpu_maps_update_begin();
324 325

	if (cpu_hotplug_disabled) {
326
		err = -EBUSY;
327 328 329 330
		goto out;
	}

	err = _cpu_down(cpu, 0);
331

332
out:
333
	cpu_maps_update_done();
L
Linus Torvalds 已提交
334 335
	return err;
}
336
EXPORT_SYMBOL(cpu_down);
L
Linus Torvalds 已提交
337 338
#endif /*CONFIG_HOTPLUG_CPU*/

339
/* Requires cpu_add_remove_lock to be held */
340
static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
L
Linus Torvalds 已提交
341
{
342
	int ret, nr_calls = 0;
L
Linus Torvalds 已提交
343
	void *hcpu = (void *)(long)cpu;
344
	unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
345
	struct task_struct *idle;
L
Linus Torvalds 已提交
346

347 348
	if (cpu_online(cpu) || !cpu_present(cpu))
		return -EINVAL;
349

350
	cpu_hotplug_begin();
351

352 353 354
	idle = idle_thread_get(cpu);
	if (IS_ERR(idle)) {
		ret = PTR_ERR(idle);
355
		goto out;
356
	}
357

358 359 360 361
	ret = smpboot_create_threads(cpu);
	if (ret)
		goto out;

362
	ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls);
363
	if (ret) {
364
		nr_calls--;
365
		printk(KERN_WARNING "%s: attempt to bring up CPU %u failed\n",
366
				__func__, cpu);
L
Linus Torvalds 已提交
367 368 369 370
		goto out_notify;
	}

	/* Arch-specific enabling code. */
371
	ret = __cpu_up(cpu, idle);
L
Linus Torvalds 已提交
372 373
	if (ret != 0)
		goto out_notify;
374
	BUG_ON(!cpu_online(cpu));
L
Linus Torvalds 已提交
375

376 377 378
	/* Wake the per cpu threads */
	smpboot_unpark_threads(cpu);

L
Linus Torvalds 已提交
379
	/* Now call notifier in preparation. */
380
	cpu_notify(CPU_ONLINE | mod, hcpu);
L
Linus Torvalds 已提交
381 382 383

out_notify:
	if (ret != 0)
384
		__cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
385
out:
386
	cpu_hotplug_done();
387 388 389 390

	return ret;
}

391
int __cpuinit cpu_up(unsigned int cpu)
392 393
{
	int err = 0;
394 395 396 397 398 399

#ifdef	CONFIG_MEMORY_HOTPLUG
	int nid;
	pg_data_t	*pgdat;
#endif

R
Rusty Russell 已提交
400
	if (!cpu_possible(cpu)) {
401 402
		printk(KERN_ERR "can't online cpu %d because it is not "
			"configured as may-hotadd at boot time\n", cpu);
403
#if defined(CONFIG_IA64)
404 405 406 407 408
		printk(KERN_ERR "please check additional_cpus= boot "
				"parameter\n");
#endif
		return -EINVAL;
	}
409

410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
#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\n", cpu);
		return -ENOMEM;
	}

425 426
	if (pgdat->node_zonelists->_zonerefs->zone == NULL) {
		mutex_lock(&zonelists_mutex);
427
		build_all_zonelists(NULL, NULL);
428 429
		mutex_unlock(&zonelists_mutex);
	}
430 431
#endif

432
	cpu_maps_update_begin();
433 434

	if (cpu_hotplug_disabled) {
435
		err = -EBUSY;
436 437 438 439 440 441
		goto out;
	}

	err = _cpu_up(cpu, 0);

out:
442
	cpu_maps_update_done();
443 444
	return err;
}
P
Paul E. McKenney 已提交
445
EXPORT_SYMBOL_GPL(cpu_up);
446

447
#ifdef CONFIG_PM_SLEEP_SMP
R
Rusty Russell 已提交
448
static cpumask_var_t frozen_cpus;
449 450 451

int disable_nonboot_cpus(void)
{
452
	int cpu, first_cpu, error = 0;
453

454
	cpu_maps_update_begin();
R
Rusty Russell 已提交
455
	first_cpu = cpumask_first(cpu_online_mask);
456 457
	/*
	 * We take down all of the non-boot CPUs in one shot to avoid races
458 459
	 * with the userspace trying to use the CPU hotplug at the same time
	 */
R
Rusty Russell 已提交
460
	cpumask_clear(frozen_cpus);
461

462 463 464 465
	printk("Disabling non-boot CPUs ...\n");
	for_each_online_cpu(cpu) {
		if (cpu == first_cpu)
			continue;
466
		error = _cpu_down(cpu, 1);
467
		if (!error)
R
Rusty Russell 已提交
468
			cpumask_set_cpu(cpu, frozen_cpus);
469
		else {
470 471 472 473 474
			printk(KERN_ERR "Error taking CPU%d down: %d\n",
				cpu, error);
			break;
		}
	}
475

476 477 478 479 480
	if (!error) {
		BUG_ON(num_online_cpus() > 1);
		/* Make sure the CPUs won't be enabled by someone else */
		cpu_hotplug_disabled = 1;
	} else {
481
		printk(KERN_ERR "Non-boot CPUs are not disabled\n");
482
	}
483
	cpu_maps_update_done();
484 485 486
	return error;
}

487 488 489 490 491 492 493 494
void __weak arch_enable_nonboot_cpus_begin(void)
{
}

void __weak arch_enable_nonboot_cpus_end(void)
{
}

495
void __ref enable_nonboot_cpus(void)
496 497 498 499
{
	int cpu, error;

	/* Allow everyone to use the CPU hotplug again */
500
	cpu_maps_update_begin();
501
	cpu_hotplug_disabled = 0;
R
Rusty Russell 已提交
502
	if (cpumask_empty(frozen_cpus))
503
		goto out;
504

505
	printk(KERN_INFO "Enabling non-boot CPUs ...\n");
506 507 508

	arch_enable_nonboot_cpus_begin();

R
Rusty Russell 已提交
509
	for_each_cpu(cpu, frozen_cpus) {
510
		error = _cpu_up(cpu, 1);
511
		if (!error) {
512
			printk(KERN_INFO "CPU%d is up\n", cpu);
513 514
			continue;
		}
515
		printk(KERN_WARNING "Error taking CPU%d up: %d\n", cpu, error);
516
	}
517 518 519

	arch_enable_nonboot_cpus_end();

R
Rusty Russell 已提交
520
	cpumask_clear(frozen_cpus);
521
out:
522
	cpu_maps_update_done();
L
Linus Torvalds 已提交
523
}
R
Rusty Russell 已提交
524

525
static int __init alloc_frozen_cpus(void)
R
Rusty Russell 已提交
526 527 528 529 530 531
{
	if (!alloc_cpumask_var(&frozen_cpus, GFP_KERNEL|__GFP_ZERO))
		return -ENOMEM;
	return 0;
}
core_initcall(alloc_frozen_cpus);
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 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597

/*
 * 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;
}


598
static int __init cpu_hotplug_pm_sync_init(void)
599 600 601 602 603 604
{
	pm_notifier(cpu_hotplug_pm_callback, 0);
	return 0;
}
core_initcall(cpu_hotplug_pm_sync_init);

605
#endif /* CONFIG_PM_SLEEP_SMP */
606

607 608 609 610 611 612 613 614
/**
 * 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().
 */
A
Al Viro 已提交
615
void __cpuinit notify_cpu_starting(unsigned int cpu)
616 617 618 619
{
	unsigned long val = CPU_STARTING;

#ifdef CONFIG_PM_SLEEP_SMP
R
Rusty Russell 已提交
620
	if (frozen_cpus != NULL && cpumask_test_cpu(cpu, frozen_cpus))
621 622
		val = CPU_STARTING_FROZEN;
#endif /* CONFIG_PM_SLEEP_SMP */
623
	cpu_notify(val, (void *)(long)cpu);
624 625
}

626
#endif /* CONFIG_SMP */
627

628 629 630 631
/*
 * cpu_bit_bitmap[] is a special, "compressed" data structure that
 * represents all NR_CPUS bits binary values of 1<<nr.
 *
R
Rusty Russell 已提交
632
 * It is used by cpumask_of() to get a constant address to a CPU
633 634
 * mask value that has a single bit set only.
 */
635

636
/* cpu_bit_bitmap[0] is empty - so we can back into it */
637
#define MASK_DECLARE_1(x)	[x+1][0] = (1UL << (x))
638 639 640
#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)
641

642 643 644 645 646 647 648
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),
649 650
#endif
};
651
EXPORT_SYMBOL_GPL(cpu_bit_bitmap);
652 653 654

const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL;
EXPORT_SYMBOL(cpu_all_bits);
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675

#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);
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722

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);
}