cpu.c 15.8 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
#include <linux/export.h>
L
Linus Torvalds 已提交
14 15
#include <linux/kthread.h>
#include <linux/stop_machine.h>
16
#include <linux/mutex.h>
17
#include <linux/gfp.h>
18
#include <linux/suspend.h>
L
Linus Torvalds 已提交
19

20
#ifdef CONFIG_SMP
21
/* Serializes the updates to cpu_online_mask, cpu_present_mask */
22
static DEFINE_MUTEX(cpu_add_remove_lock);
L
Linus Torvalds 已提交
23

24 25 26 27 28 29 30 31 32 33 34 35 36 37
/*
 * 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);
}

38
static RAW_NOTIFIER_HEAD(cpu_chain);
L
Linus Torvalds 已提交
39

40 41 42 43 44
/* 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;

45 46
#ifdef CONFIG_HOTPLUG_CPU

47 48 49 50 51 52 53 54
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;
55 56 57 58 59
} cpu_hotplug = {
	.active_writer = NULL,
	.lock = __MUTEX_INITIALIZER(cpu_hotplug.lock),
	.refcount = 0,
};
60

61
void get_online_cpus(void)
62
{
63 64
	might_sleep();
	if (cpu_hotplug.active_writer == current)
65
		return;
66 67 68 69
	mutex_lock(&cpu_hotplug.lock);
	cpu_hotplug.refcount++;
	mutex_unlock(&cpu_hotplug.lock);

70
}
71
EXPORT_SYMBOL_GPL(get_online_cpus);
72

73
void put_online_cpus(void)
74
{
75
	if (cpu_hotplug.active_writer == current)
76
		return;
77
	mutex_lock(&cpu_hotplug.lock);
78 79
	if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
		wake_up_process(cpu_hotplug.active_writer);
80 81
	mutex_unlock(&cpu_hotplug.lock);

82
}
83
EXPORT_SYMBOL_GPL(put_online_cpus);
84

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

	for (;;) {
		mutex_lock(&cpu_hotplug.lock);
		if (likely(!cpu_hotplug.refcount))
			break;
		__set_current_state(TASK_UNINTERRUPTIBLE);
116 117 118 119 120 121 122 123 124 125
		mutex_unlock(&cpu_hotplug.lock);
		schedule();
	}
}

static void cpu_hotplug_done(void)
{
	cpu_hotplug.active_writer = NULL;
	mutex_unlock(&cpu_hotplug.lock);
}
126 127 128 129

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

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

142 143 144
static int __cpu_notify(unsigned long val, void *v, int nr_to_call,
			int *nr_calls)
{
145 146 147
	int ret;

	ret = __raw_notifier_call_chain(&cpu_chain, val, v, nr_to_call,
148
					nr_calls);
149 150

	return notifier_to_errno(ret);
151 152 153 154 155 156 157
}

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

158 159
#ifdef CONFIG_HOTPLUG_CPU

160 161
static void cpu_notify_nofail(unsigned long val, void *v)
{
162
	BUG_ON(cpu_notify(val, v));
163
}
L
Linus Torvalds 已提交
164 165
EXPORT_SYMBOL(register_cpu_notifier);

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

static inline void check_for_tasks(int cpu)
{
	struct task_struct *p;

	write_lock_irq(&tasklist_lock);
	for_each_process(p) {
180
		if (task_cpu(p) == cpu && p->state == TASK_RUNNING &&
L
Linus Torvalds 已提交
181 182
		    (!cputime_eq(p->utime, cputime_zero) ||
		     !cputime_eq(p->stime, cputime_zero)))
183 184 185 186
			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 已提交
187 188 189 190
	}
	write_unlock_irq(&tasklist_lock);
}

A
Avi Kivity 已提交
191 192 193 194 195
struct take_cpu_down_param {
	unsigned long mod;
	void *hcpu;
};

L
Linus Torvalds 已提交
196
/* Take this CPU down. */
197
static int __ref take_cpu_down(void *_param)
L
Linus Torvalds 已提交
198
{
A
Avi Kivity 已提交
199
	struct take_cpu_down_param *param = _param;
L
Linus Torvalds 已提交
200 201 202 203 204
	int err;

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

207
	cpu_notify(CPU_DYING | param->mod, param->hcpu);
Z
Zwane Mwaikambo 已提交
208
	return 0;
L
Linus Torvalds 已提交
209 210
}

211
/* Requires cpu_add_remove_lock to be held */
212
static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
L
Linus Torvalds 已提交
213
{
214 215
	int err, nr_calls = 0;
	void *hcpu = (void *)(long)cpu;
216
	unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
A
Avi Kivity 已提交
217 218 219 220
	struct take_cpu_down_param tcd_param = {
		.mod = mod,
		.hcpu = hcpu,
	};
L
Linus Torvalds 已提交
221

222 223
	if (num_online_cpus() == 1)
		return -EBUSY;
L
Linus Torvalds 已提交
224

225 226
	if (!cpu_online(cpu))
		return -EINVAL;
L
Linus Torvalds 已提交
227

228
	cpu_hotplug_begin();
229

230
	err = __cpu_notify(CPU_DOWN_PREPARE | mod, hcpu, -1, &nr_calls);
231
	if (err) {
232
		nr_calls--;
233
		__cpu_notify(CPU_DOWN_FAILED | mod, hcpu, nr_calls, NULL);
L
Linus Torvalds 已提交
234
		printk("%s: attempt to take down CPU %u failed\n",
235
				__func__, cpu);
236
		goto out_release;
L
Linus Torvalds 已提交
237 238
	}

R
Rusty Russell 已提交
239
	err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
240
	if (err) {
L
Linus Torvalds 已提交
241
		/* CPU didn't die: tell everyone.  Can't complain. */
242
		cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu);
L
Linus Torvalds 已提交
243

244
		goto out_release;
245
	}
246
	BUG_ON(cpu_online(cpu));
L
Linus Torvalds 已提交
247

248 249 250 251
	/*
	 * 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 已提交
252 253
	 *
	 * Wait for the stop thread to go away.
254
	 */
P
Peter Zijlstra 已提交
255 256
	while (!idle_cpu(cpu))
		cpu_relax();
L
Linus Torvalds 已提交
257 258 259 260 261

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

	/* CPU is completely dead: tell everyone.  Too late to complain. */
262
	cpu_notify_nofail(CPU_DEAD | mod, hcpu);
L
Linus Torvalds 已提交
263 264 265

	check_for_tasks(cpu);

266
out_release:
267
	cpu_hotplug_done();
268 269
	if (!err)
		cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu);
270 271 272
	return err;
}

273
int __ref cpu_down(unsigned int cpu)
274
{
275
	int err;
276

277
	cpu_maps_update_begin();
278 279

	if (cpu_hotplug_disabled) {
280
		err = -EBUSY;
281 282 283 284
		goto out;
	}

	err = _cpu_down(cpu, 0);
285

286
out:
287
	cpu_maps_update_done();
L
Linus Torvalds 已提交
288 289
	return err;
}
290
EXPORT_SYMBOL(cpu_down);
L
Linus Torvalds 已提交
291 292
#endif /*CONFIG_HOTPLUG_CPU*/

293
/* Requires cpu_add_remove_lock to be held */
294
static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
L
Linus Torvalds 已提交
295
{
296
	int ret, nr_calls = 0;
L
Linus Torvalds 已提交
297
	void *hcpu = (void *)(long)cpu;
298
	unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
L
Linus Torvalds 已提交
299

300 301
	if (cpu_online(cpu) || !cpu_present(cpu))
		return -EINVAL;
302

303
	cpu_hotplug_begin();
304
	ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls);
305
	if (ret) {
306
		nr_calls--;
307
		printk(KERN_WARNING "%s: attempt to bring up CPU %u failed\n",
308
				__func__, cpu);
L
Linus Torvalds 已提交
309 310 311 312 313 314 315
		goto out_notify;
	}

	/* Arch-specific enabling code. */
	ret = __cpu_up(cpu);
	if (ret != 0)
		goto out_notify;
316
	BUG_ON(!cpu_online(cpu));
L
Linus Torvalds 已提交
317 318

	/* Now call notifier in preparation. */
319
	cpu_notify(CPU_ONLINE | mod, hcpu);
L
Linus Torvalds 已提交
320 321 322

out_notify:
	if (ret != 0)
323
		__cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
324
	cpu_hotplug_done();
325 326 327 328

	return ret;
}

329
int __cpuinit cpu_up(unsigned int cpu)
330 331
{
	int err = 0;
332 333 334 335 336 337

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

R
Rusty Russell 已提交
338
	if (!cpu_possible(cpu)) {
339 340
		printk(KERN_ERR "can't online cpu %d because it is not "
			"configured as may-hotadd at boot time\n", cpu);
341
#if defined(CONFIG_IA64)
342 343 344 345 346
		printk(KERN_ERR "please check additional_cpus= boot "
				"parameter\n");
#endif
		return -EINVAL;
	}
347

348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
#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;
	}

363 364
	if (pgdat->node_zonelists->_zonerefs->zone == NULL) {
		mutex_lock(&zonelists_mutex);
365
		build_all_zonelists(NULL);
366 367
		mutex_unlock(&zonelists_mutex);
	}
368 369
#endif

370
	cpu_maps_update_begin();
371 372

	if (cpu_hotplug_disabled) {
373
		err = -EBUSY;
374 375 376 377 378 379
		goto out;
	}

	err = _cpu_up(cpu, 0);

out:
380
	cpu_maps_update_done();
381 382 383
	return err;
}

384
#ifdef CONFIG_PM_SLEEP_SMP
R
Rusty Russell 已提交
385
static cpumask_var_t frozen_cpus;
386

387 388 389 390 391 392 393 394
void __weak arch_disable_nonboot_cpus_begin(void)
{
}

void __weak arch_disable_nonboot_cpus_end(void)
{
}

395 396
int disable_nonboot_cpus(void)
{
397
	int cpu, first_cpu, error = 0;
398

399
	cpu_maps_update_begin();
R
Rusty Russell 已提交
400
	first_cpu = cpumask_first(cpu_online_mask);
401 402
	/*
	 * We take down all of the non-boot CPUs in one shot to avoid races
403 404
	 * with the userspace trying to use the CPU hotplug at the same time
	 */
R
Rusty Russell 已提交
405
	cpumask_clear(frozen_cpus);
406
	arch_disable_nonboot_cpus_begin();
407

408 409 410 411
	printk("Disabling non-boot CPUs ...\n");
	for_each_online_cpu(cpu) {
		if (cpu == first_cpu)
			continue;
412
		error = _cpu_down(cpu, 1);
413
		if (!error)
R
Rusty Russell 已提交
414
			cpumask_set_cpu(cpu, frozen_cpus);
415
		else {
416 417 418 419 420
			printk(KERN_ERR "Error taking CPU%d down: %d\n",
				cpu, error);
			break;
		}
	}
421

422 423
	arch_disable_nonboot_cpus_end();

424 425 426 427 428
	if (!error) {
		BUG_ON(num_online_cpus() > 1);
		/* Make sure the CPUs won't be enabled by someone else */
		cpu_hotplug_disabled = 1;
	} else {
429
		printk(KERN_ERR "Non-boot CPUs are not disabled\n");
430
	}
431
	cpu_maps_update_done();
432 433 434
	return error;
}

435 436 437 438 439 440 441 442
void __weak arch_enable_nonboot_cpus_begin(void)
{
}

void __weak arch_enable_nonboot_cpus_end(void)
{
}

443
void __ref enable_nonboot_cpus(void)
444 445 446 447
{
	int cpu, error;

	/* Allow everyone to use the CPU hotplug again */
448
	cpu_maps_update_begin();
449
	cpu_hotplug_disabled = 0;
R
Rusty Russell 已提交
450
	if (cpumask_empty(frozen_cpus))
451
		goto out;
452

453
	printk(KERN_INFO "Enabling non-boot CPUs ...\n");
454 455 456

	arch_enable_nonboot_cpus_begin();

R
Rusty Russell 已提交
457
	for_each_cpu(cpu, frozen_cpus) {
458
		error = _cpu_up(cpu, 1);
459
		if (!error) {
460
			printk(KERN_INFO "CPU%d is up\n", cpu);
461 462
			continue;
		}
463
		printk(KERN_WARNING "Error taking CPU%d up: %d\n", cpu, error);
464
	}
465 466 467

	arch_enable_nonboot_cpus_end();

R
Rusty Russell 已提交
468
	cpumask_clear(frozen_cpus);
469
out:
470
	cpu_maps_update_done();
L
Linus Torvalds 已提交
471
}
R
Rusty Russell 已提交
472

473
static int __init alloc_frozen_cpus(void)
R
Rusty Russell 已提交
474 475 476 477 478 479
{
	if (!alloc_cpumask_var(&frozen_cpus, GFP_KERNEL|__GFP_ZERO))
		return -ENOMEM;
	return 0;
}
core_initcall(alloc_frozen_cpus);
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545

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


546
static int __init cpu_hotplug_pm_sync_init(void)
547 548 549 550 551 552
{
	pm_notifier(cpu_hotplug_pm_callback, 0);
	return 0;
}
core_initcall(cpu_hotplug_pm_sync_init);

553
#endif /* CONFIG_PM_SLEEP_SMP */
554

555 556 557 558 559 560 561 562
/**
 * 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 已提交
563
void __cpuinit notify_cpu_starting(unsigned int cpu)
564 565 566 567
{
	unsigned long val = CPU_STARTING;

#ifdef CONFIG_PM_SLEEP_SMP
R
Rusty Russell 已提交
568
	if (frozen_cpus != NULL && cpumask_test_cpu(cpu, frozen_cpus))
569 570
		val = CPU_STARTING_FROZEN;
#endif /* CONFIG_PM_SLEEP_SMP */
571
	cpu_notify(val, (void *)(long)cpu);
572 573
}

574
#endif /* CONFIG_SMP */
575

576 577 578 579
/*
 * cpu_bit_bitmap[] is a special, "compressed" data structure that
 * represents all NR_CPUS bits binary values of 1<<nr.
 *
R
Rusty Russell 已提交
580
 * It is used by cpumask_of() to get a constant address to a CPU
581 582
 * mask value that has a single bit set only.
 */
583

584
/* cpu_bit_bitmap[0] is empty - so we can back into it */
585
#define MASK_DECLARE_1(x)	[x+1][0] = (1UL << (x))
586 587 588
#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)
589

590 591 592 593 594 595 596
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),
597 598
#endif
};
599
EXPORT_SYMBOL_GPL(cpu_bit_bitmap);
600 601 602

const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL;
EXPORT_SYMBOL(cpu_all_bits);
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623

#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);
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670

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