Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
39c715b7 IM |
2 | /* |
3 | * lib/smp_processor_id.c | |
4 | * | |
5 | * DEBUG_PREEMPT variant of smp_processor_id(). | |
6 | */ | |
8bc3bcc9 | 7 | #include <linux/export.h> |
39c715b7 | 8 | #include <linux/kallsyms.h> |
4e57b681 | 9 | #include <linux/sched.h> |
39c715b7 | 10 | |
188a8140 CL |
11 | notrace static unsigned int check_preemption_disabled(const char *what1, |
12 | const char *what2) | |
39c715b7 | 13 | { |
39c715b7 | 14 | int this_cpu = raw_smp_processor_id(); |
39c715b7 | 15 | |
4a2b4b22 | 16 | if (likely(preempt_count())) |
39c715b7 IM |
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 | */ | |
0c98d344 | 26 | if (cpumask_equal(¤t->cpus_allowed, cpumask_of(this_cpu))) |
39c715b7 IM |
27 | goto out; |
28 | ||
29 | /* | |
30 | * It is valid to assume CPU-locality during early bootup: | |
31 | */ | |
1c3c5eab | 32 | if (system_state < SYSTEM_SCHEDULING) |
39c715b7 IM |
33 | goto out; |
34 | ||
35 | /* | |
36 | * Avoid recursion: | |
37 | */ | |
5568b139 | 38 | preempt_disable_notrace(); |
39c715b7 IM |
39 | |
40 | if (!printk_ratelimit()) | |
41 | goto out_enable; | |
42 | ||
188a8140 CL |
43 | printk(KERN_ERR "BUG: using %s%s() in preemptible [%08x] code: %s/%d\n", |
44 | what1, what2, preempt_count() - 1, current->comm, current->pid); | |
45 | ||
39c715b7 IM |
46 | print_symbol("caller is %s\n", (long)__builtin_return_address(0)); |
47 | dump_stack(); | |
48 | ||
49 | out_enable: | |
5568b139 | 50 | preempt_enable_no_resched_notrace(); |
39c715b7 IM |
51 | out: |
52 | return this_cpu; | |
53 | } | |
54 | ||
188a8140 CL |
55 | notrace unsigned int debug_smp_processor_id(void) |
56 | { | |
57 | return check_preemption_disabled("smp_processor_id", ""); | |
58 | } | |
39c715b7 IM |
59 | EXPORT_SYMBOL(debug_smp_processor_id); |
60 | ||
188a8140 CL |
61 | notrace void __this_cpu_preempt_check(const char *op) |
62 | { | |
63 | check_preemption_disabled("__this_cpu_", op); | |
64 | } | |
65 | EXPORT_SYMBOL(__this_cpu_preempt_check); |