1 | // SPDX-License-Identifier: GPL-2.0 |
---|---|
2 | /* |
3 | * lib/smp_processor_id.c |
4 | * |
5 | * DEBUG_PREEMPT variant of smp_processor_id(). |
6 | */ |
7 | #include <linux/export.h> |
8 | #include <linux/kprobes.h> |
9 | #include <linux/sched.h> |
10 | |
11 | noinstr static |
12 | unsigned int check_preemption_disabled(const char *what1, const char *what2) |
13 | { |
14 | int this_cpu = raw_smp_processor_id(); |
15 | |
16 | if (likely(preempt_count())) |
17 | goto out; |
18 | |
19 | if (irqs_disabled()) |
20 | goto out; |
21 | |
22 | if (is_percpu_thread()) |
23 | goto out; |
24 | |
25 | #ifdef CONFIG_SMP |
26 | if (current->migration_disabled) |
27 | goto out; |
28 | #endif |
29 | |
30 | /* |
31 | * It is valid to assume CPU-locality during early bootup: |
32 | */ |
33 | if (system_state < SYSTEM_SCHEDULING) |
34 | goto out; |
35 | |
36 | /* |
37 | * Avoid recursion: |
38 | */ |
39 | preempt_disable_notrace(); |
40 | |
41 | instrumentation_begin(); |
42 | if (!printk_ratelimit()) |
43 | goto out_enable; |
44 | |
45 | printk(KERN_ERR "BUG: using %s%s() in preemptible [%08x] code: %s/%d\n", |
46 | what1, what2, preempt_count() - 1, current->comm, current->pid); |
47 | |
48 | printk("caller is %pS\n", __builtin_return_address(0)); |
49 | dump_stack(); |
50 | |
51 | out_enable: |
52 | instrumentation_end(); |
53 | preempt_enable_no_resched_notrace(); |
54 | out: |
55 | return this_cpu; |
56 | } |
57 | |
58 | noinstr unsigned int debug_smp_processor_id(void) |
59 | { |
60 | return check_preemption_disabled(what1: "smp_processor_id", what2: ""); |
61 | } |
62 | EXPORT_SYMBOL(debug_smp_processor_id); |
63 | |
64 | noinstr void __this_cpu_preempt_check(const char *op) |
65 | { |
66 | check_preemption_disabled(what1: "__this_cpu_", what2: op); |
67 | } |
68 | EXPORT_SYMBOL(__this_cpu_preempt_check); |
69 |