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 85 86

	if (WARN_ON(!cpu_hotplug.refcount))
		cpu_hotplug.refcount++; /* try to fix things up */

87 88
	if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
		wake_up_process(cpu_hotplug.active_writer);
89 90
	mutex_unlock(&cpu_hotplug.lock);

91
}
92
EXPORT_SYMBOL_GPL(put_online_cpus);
93

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

	for (;;) {
		mutex_lock(&cpu_hotplug.lock);
		if (likely(!cpu_hotplug.refcount))
			break;
		__set_current_state(TASK_UNINTERRUPTIBLE);
125 126 127 128 129 130 131 132 133 134
		mutex_unlock(&cpu_hotplug.lock);
		schedule();
	}
}

static void cpu_hotplug_done(void)
{
	cpu_hotplug.active_writer = NULL;
	mutex_unlock(&cpu_hotplug.lock);
}
135

136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
/*
 * Wait for currently running CPU hotplug operations to complete (if any) and
 * disable future CPU hotplug (from sysfs). The 'cpu_add_remove_lock' protects
 * the 'cpu_hotplug_disabled' flag. The same lock is also acquired by the
 * hotplug path before performing hotplug operations. So acquiring that lock
 * guarantees mutual exclusion from any currently running hotplug operations.
 */
void cpu_hotplug_disable(void)
{
	cpu_maps_update_begin();
	cpu_hotplug_disabled = 1;
	cpu_maps_update_done();
}

void cpu_hotplug_enable(void)
{
	cpu_maps_update_begin();
	cpu_hotplug_disabled = 0;
	cpu_maps_update_done();
}

157 158 159
#else /* #if CONFIG_HOTPLUG_CPU */
static void cpu_hotplug_begin(void) {}
static void cpu_hotplug_done(void) {}
L
Lucas De Marchi 已提交
160
#endif	/* #else #if CONFIG_HOTPLUG_CPU */
161

L
Linus Torvalds 已提交
162
/* Need to know about CPUs going up/down? */
163
int __ref register_cpu_notifier(struct notifier_block *nb)
L
Linus Torvalds 已提交
164
{
165
	int ret;
166
	cpu_maps_update_begin();
167
	ret = raw_notifier_chain_register(&cpu_chain, nb);
168
	cpu_maps_update_done();
169
	return ret;
L
Linus Torvalds 已提交
170
}
171

172 173 174
static int __cpu_notify(unsigned long val, void *v, int nr_to_call,
			int *nr_calls)
{
175 176 177
	int ret;

	ret = __raw_notifier_call_chain(&cpu_chain, val, v, nr_to_call,
178
					nr_calls);
179 180

	return notifier_to_errno(ret);
181 182 183 184 185 186 187
}

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

188 189
#ifdef CONFIG_HOTPLUG_CPU

190 191
static void cpu_notify_nofail(unsigned long val, void *v)
{
192
	BUG_ON(cpu_notify(val, v));
193
}
L
Linus Torvalds 已提交
194 195
EXPORT_SYMBOL(register_cpu_notifier);

196
void __ref unregister_cpu_notifier(struct notifier_block *nb)
L
Linus Torvalds 已提交
197
{
198
	cpu_maps_update_begin();
199
	raw_notifier_chain_unregister(&cpu_chain, nb);
200
	cpu_maps_update_done();
L
Linus Torvalds 已提交
201 202 203
}
EXPORT_SYMBOL(unregister_cpu_notifier);

204 205 206 207 208 209 210 211 212 213 214 215
/**
 * 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.
 */
216 217 218 219 220 221 222 223 224 225 226
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.
	 */
227
	WARN_ON(cpu_online(cpu));
228 229 230 231
	rcu_read_lock();
	for_each_process(p) {
		struct task_struct *t;

232 233 234 235
		/*
		 * Main thread might exit, but other threads may still have
		 * a valid mm. Find one.
		 */
236 237 238 239 240 241 242 243 244
		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 已提交
245 246 247
static inline void check_for_tasks(int cpu)
{
	struct task_struct *p;
248
	cputime_t utime, stime;
L
Linus Torvalds 已提交
249 250 251

	write_lock_irq(&tasklist_lock);
	for_each_process(p) {
252
		task_cputime(p, &utime, &stime);
253
		if (task_cpu(p) == cpu && p->state == TASK_RUNNING &&
254
		    (utime || stime))
255 256 257 258
			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 已提交
259 260 261 262
	}
	write_unlock_irq(&tasklist_lock);
}

A
Avi Kivity 已提交
263 264 265 266 267
struct take_cpu_down_param {
	unsigned long mod;
	void *hcpu;
};

L
Linus Torvalds 已提交
268
/* Take this CPU down. */
269
static int __ref take_cpu_down(void *_param)
L
Linus Torvalds 已提交
270
{
A
Avi Kivity 已提交
271
	struct take_cpu_down_param *param = _param;
L
Linus Torvalds 已提交
272 273 274 275 276
	int err;

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

279
	cpu_notify(CPU_DYING | param->mod, param->hcpu);
280 281
	/* Park the stopper thread */
	kthread_park(current);
Z
Zwane Mwaikambo 已提交
282
	return 0;
L
Linus Torvalds 已提交
283 284
}

285
/* Requires cpu_add_remove_lock to be held */
286
static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
L
Linus Torvalds 已提交
287
{
288 289
	int err, nr_calls = 0;
	void *hcpu = (void *)(long)cpu;
290
	unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
A
Avi Kivity 已提交
291 292 293 294
	struct take_cpu_down_param tcd_param = {
		.mod = mod,
		.hcpu = hcpu,
	};
L
Linus Torvalds 已提交
295

296 297
	if (num_online_cpus() == 1)
		return -EBUSY;
L
Linus Torvalds 已提交
298

299 300
	if (!cpu_online(cpu))
		return -EINVAL;
L
Linus Torvalds 已提交
301

302
	cpu_hotplug_begin();
303

304
	err = __cpu_notify(CPU_DOWN_PREPARE | mod, hcpu, -1, &nr_calls);
305
	if (err) {
306
		nr_calls--;
307
		__cpu_notify(CPU_DOWN_FAILED | mod, hcpu, nr_calls, NULL);
L
Linus Torvalds 已提交
308
		printk("%s: attempt to take down CPU %u failed\n",
309
				__func__, cpu);
310
		goto out_release;
L
Linus Torvalds 已提交
311
	}
312
	smpboot_park_threads(cpu);
L
Linus Torvalds 已提交
313

R
Rusty Russell 已提交
314
	err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
315
	if (err) {
L
Linus Torvalds 已提交
316
		/* CPU didn't die: tell everyone.  Can't complain. */
317
		smpboot_unpark_threads(cpu);
318
		cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu);
319
		goto out_release;
320
	}
321
	BUG_ON(cpu_online(cpu));
L
Linus Torvalds 已提交
322

323 324 325 326
	/*
	 * 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 已提交
327 328
	 *
	 * Wait for the stop thread to go away.
329
	 */
P
Peter Zijlstra 已提交
330 331
	while (!idle_cpu(cpu))
		cpu_relax();
L
Linus Torvalds 已提交
332 333 334 335 336

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

	/* CPU is completely dead: tell everyone.  Too late to complain. */
337
	cpu_notify_nofail(CPU_DEAD | mod, hcpu);
L
Linus Torvalds 已提交
338 339 340

	check_for_tasks(cpu);

341
out_release:
342
	cpu_hotplug_done();
343 344
	if (!err)
		cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu);
345 346 347
	return err;
}

348
int __ref cpu_down(unsigned int cpu)
349
{
350
	int err;
351

352
	cpu_maps_update_begin();
353 354

	if (cpu_hotplug_disabled) {
355
		err = -EBUSY;
356 357 358 359
		goto out;
	}

	err = _cpu_down(cpu, 0);
360

361
out:
362
	cpu_maps_update_done();
L
Linus Torvalds 已提交
363 364
	return err;
}
365
EXPORT_SYMBOL(cpu_down);
L
Linus Torvalds 已提交
366 367
#endif /*CONFIG_HOTPLUG_CPU*/

368
/* Requires cpu_add_remove_lock to be held */
369
static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
L
Linus Torvalds 已提交
370
{
371
	int ret, nr_calls = 0;
L
Linus Torvalds 已提交
372
	void *hcpu = (void *)(long)cpu;
373
	unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
374
	struct task_struct *idle;
L
Linus Torvalds 已提交
375

376
	cpu_hotplug_begin();
377

378 379 380 381 382
	if (cpu_online(cpu) || !cpu_present(cpu)) {
		ret = -EINVAL;
		goto out;
	}

383 384 385
	idle = idle_thread_get(cpu);
	if (IS_ERR(idle)) {
		ret = PTR_ERR(idle);
386
		goto out;
387
	}
388

389 390 391 392
	ret = smpboot_create_threads(cpu);
	if (ret)
		goto out;

393
	ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls);
394
	if (ret) {
395
		nr_calls--;
396
		printk(KERN_WARNING "%s: attempt to bring up CPU %u failed\n",
397
				__func__, cpu);
L
Linus Torvalds 已提交
398 399 400 401
		goto out_notify;
	}

	/* Arch-specific enabling code. */
402
	ret = __cpu_up(cpu, idle);
L
Linus Torvalds 已提交
403 404
	if (ret != 0)
		goto out_notify;
405
	BUG_ON(!cpu_online(cpu));
L
Linus Torvalds 已提交
406

407 408 409
	/* Wake the per cpu threads */
	smpboot_unpark_threads(cpu);

L
Linus Torvalds 已提交
410
	/* Now call notifier in preparation. */
411
	cpu_notify(CPU_ONLINE | mod, hcpu);
L
Linus Torvalds 已提交
412 413 414

out_notify:
	if (ret != 0)
415
		__cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
416
out:
417
	cpu_hotplug_done();
418 419 420 421

	return ret;
}

422
int __cpuinit cpu_up(unsigned int cpu)
423 424
{
	int err = 0;
425 426 427 428 429 430

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

R
Rusty Russell 已提交
431
	if (!cpu_possible(cpu)) {
432 433
		printk(KERN_ERR "can't online cpu %d because it is not "
			"configured as may-hotadd at boot time\n", cpu);
434
#if defined(CONFIG_IA64)
435 436 437 438 439
		printk(KERN_ERR "please check additional_cpus= boot "
				"parameter\n");
#endif
		return -EINVAL;
	}
440

441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
#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;
	}

456 457
	if (pgdat->node_zonelists->_zonerefs->zone == NULL) {
		mutex_lock(&zonelists_mutex);
458
		build_all_zonelists(NULL, NULL);
459 460
		mutex_unlock(&zonelists_mutex);
	}
461 462
#endif

463
	cpu_maps_update_begin();
464 465

	if (cpu_hotplug_disabled) {
466
		err = -EBUSY;
467 468 469 470 471 472
		goto out;
	}

	err = _cpu_up(cpu, 0);

out:
473
	cpu_maps_update_done();
474 475
	return err;
}
P
Paul E. McKenney 已提交
476
EXPORT_SYMBOL_GPL(cpu_up);
477

478
#ifdef CONFIG_PM_SLEEP_SMP
R
Rusty Russell 已提交
479
static cpumask_var_t frozen_cpus;
480 481 482

int disable_nonboot_cpus(void)
{
483
	int cpu, first_cpu, error = 0;
484

485
	cpu_maps_update_begin();
R
Rusty Russell 已提交
486
	first_cpu = cpumask_first(cpu_online_mask);
487 488
	/*
	 * We take down all of the non-boot CPUs in one shot to avoid races
489 490
	 * with the userspace trying to use the CPU hotplug at the same time
	 */
R
Rusty Russell 已提交
491
	cpumask_clear(frozen_cpus);
492

493 494 495 496
	printk("Disabling non-boot CPUs ...\n");
	for_each_online_cpu(cpu) {
		if (cpu == first_cpu)
			continue;
497
		error = _cpu_down(cpu, 1);
498
		if (!error)
R
Rusty Russell 已提交
499
			cpumask_set_cpu(cpu, frozen_cpus);
500
		else {
501 502 503 504 505
			printk(KERN_ERR "Error taking CPU%d down: %d\n",
				cpu, error);
			break;
		}
	}
506

507 508 509 510 511
	if (!error) {
		BUG_ON(num_online_cpus() > 1);
		/* Make sure the CPUs won't be enabled by someone else */
		cpu_hotplug_disabled = 1;
	} else {
512
		printk(KERN_ERR "Non-boot CPUs are not disabled\n");
513
	}
514
	cpu_maps_update_done();
515 516 517
	return error;
}

518 519 520 521 522 523 524 525
void __weak arch_enable_nonboot_cpus_begin(void)
{
}

void __weak arch_enable_nonboot_cpus_end(void)
{
}

526
void __ref enable_nonboot_cpus(void)
527 528 529 530
{
	int cpu, error;

	/* Allow everyone to use the CPU hotplug again */
531
	cpu_maps_update_begin();
532
	cpu_hotplug_disabled = 0;
R
Rusty Russell 已提交
533
	if (cpumask_empty(frozen_cpus))
534
		goto out;
535

536
	printk(KERN_INFO "Enabling non-boot CPUs ...\n");
537 538 539

	arch_enable_nonboot_cpus_begin();

R
Rusty Russell 已提交
540
	for_each_cpu(cpu, frozen_cpus) {
541
		error = _cpu_up(cpu, 1);
542
		if (!error) {
543
			printk(KERN_INFO "CPU%d is up\n", cpu);
544 545
			continue;
		}
546
		printk(KERN_WARNING "Error taking CPU%d up: %d\n", cpu, error);
547
	}
548 549 550

	arch_enable_nonboot_cpus_end();

R
Rusty Russell 已提交
551
	cpumask_clear(frozen_cpus);
552
out:
553
	cpu_maps_update_done();
L
Linus Torvalds 已提交
554
}
R
Rusty Russell 已提交
555

556
static int __init alloc_frozen_cpus(void)
R
Rusty Russell 已提交
557 558 559 560 561 562
{
	if (!alloc_cpumask_var(&frozen_cpus, GFP_KERNEL|__GFP_ZERO))
		return -ENOMEM;
	return 0;
}
core_initcall(alloc_frozen_cpus);
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582

/*
 * 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:
583
		cpu_hotplug_disable();
584 585 586 587
		break;

	case PM_POST_SUSPEND:
	case PM_POST_HIBERNATION:
588
		cpu_hotplug_enable();
589 590 591 592 593 594 595 596 597 598
		break;

	default:
		return NOTIFY_DONE;
	}

	return NOTIFY_OK;
}


599
static int __init cpu_hotplug_pm_sync_init(void)
600
{
601 602 603 604 605
	/*
	 * cpu_hotplug_pm_callback has higher priority than x86
	 * bsp_pm_callback which depends on cpu_hotplug_pm_callback
	 * to disable cpu hotplug to avoid cpu hotplug race.
	 */
606 607 608 609 610
	pm_notifier(cpu_hotplug_pm_callback, 0);
	return 0;
}
core_initcall(cpu_hotplug_pm_sync_init);

611
#endif /* CONFIG_PM_SLEEP_SMP */
612

613 614 615 616 617 618 619 620
/**
 * 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 已提交
621
void __cpuinit notify_cpu_starting(unsigned int cpu)
622 623 624 625
{
	unsigned long val = CPU_STARTING;

#ifdef CONFIG_PM_SLEEP_SMP
R
Rusty Russell 已提交
626
	if (frozen_cpus != NULL && cpumask_test_cpu(cpu, frozen_cpus))
627 628
		val = CPU_STARTING_FROZEN;
#endif /* CONFIG_PM_SLEEP_SMP */
629
	cpu_notify(val, (void *)(long)cpu);
630 631
}

632
#endif /* CONFIG_SMP */
633

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

642
/* cpu_bit_bitmap[0] is empty - so we can back into it */
643
#define MASK_DECLARE_1(x)	[x+1][0] = (1UL << (x))
644 645 646
#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)
647

648 649 650 651 652 653 654
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),
655 656
#endif
};
657
EXPORT_SYMBOL_GPL(cpu_bit_bitmap);
658 659 660

const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL;
EXPORT_SYMBOL(cpu_all_bits);
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681

#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);
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 723 724 725 726 727 728

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