]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - lib/smp_processor_id.c
[PATCH] Fix fs/exec.c:788 (de_thread()) BUG_ON
[linux-2.6.git] / lib / smp_processor_id.c
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
9 unsigned int debug_smp_processor_id(void)
10 {
11         unsigned long preempt_count = preempt_count();
12         int this_cpu = raw_smp_processor_id();
13         cpumask_t this_mask;
14
15         if (likely(preempt_count))
16                 goto out;
17
18         if (irqs_disabled())
19                 goto out;
20
21         /*
22          * Kernel threads bound to a single CPU can safely use
23          * smp_processor_id():
24          */
25         this_mask = cpumask_of_cpu(this_cpu);
26
27         if (cpus_equal(current->cpus_allowed, this_mask))
28                 goto out;
29
30         /*
31          * It is valid to assume CPU-locality during early bootup:
32          */
33         if (system_state != SYSTEM_RUNNING)
34                 goto out;
35
36         /*
37          * Avoid recursion:
38          */
39         preempt_disable();
40
41         if (!printk_ratelimit())
42                 goto out_enable;
43
44         printk(KERN_ERR "BUG: using smp_processor_id() in preemptible [%08x] code: %s/%d\n", preempt_count(), current->comm, current->pid);
45         print_symbol("caller is %s\n", (long)__builtin_return_address(0));
46         dump_stack();
47
48 out_enable:
49         preempt_enable_no_resched();
50 out:
51         return this_cpu;
52 }
53
54 EXPORT_SYMBOL(debug_smp_processor_id);
55