1/*
2 * lib/smp_processor_id.c
3 *
4 * DEBUG_PREEMPT variant of smp_processor_id().
5 */
6#include <linux/module.h>
7#include <linux/kallsyms.h>
8#include <linux/sched.h>
9
10unsigned int debug_smp_processor_id(void)
11{
12	unsigned long preempt_count = preempt_count();
13	int this_cpu = raw_smp_processor_id();
14	cpumask_t this_mask;
15
16	if (likely(preempt_count))
17		goto out;
18
19	if (irqs_disabled())
20		goto out;
21
22	/*
23	 * Kernel threads bound to a single CPU can safely use
24	 * smp_processor_id():
25	 */
26	this_mask = cpumask_of_cpu(this_cpu);
27
28	if (cpus_equal(current->cpus_allowed, this_mask))
29		goto out;
30
31	/*
32	 * It is valid to assume CPU-locality during early bootup:
33	 */
34	if (system_state != SYSTEM_RUNNING)
35		goto out;
36
37	/*
38	 * Avoid recursion:
39	 */
40	preempt_disable();
41
42	if (!printk_ratelimit())
43		goto out_enable;
44
45	printk(KERN_ERR "BUG: using smp_processor_id() in preemptible [%08x] code: %s/%d\n", preempt_count(), current->comm, current->pid);
46	print_symbol("caller is %s\n", (long)__builtin_return_address(0));
47	dump_stack();
48
49out_enable:
50	preempt_enable_no_resched();
51out:
52	return this_cpu;
53}
54
55EXPORT_SYMBOL(debug_smp_processor_id);
56