0001
0002
0003
0004
0005
0006
0007 #include <linux/export.h>
0008 #include <linux/kprobes.h>
0009 #include <linux/sched.h>
0010
0011 noinstr static
0012 unsigned int check_preemption_disabled(const char *what1, const char *what2)
0013 {
0014 int this_cpu = raw_smp_processor_id();
0015
0016 if (likely(preempt_count()))
0017 goto out;
0018
0019 if (irqs_disabled())
0020 goto out;
0021
0022 if (is_percpu_thread())
0023 goto out;
0024
0025 #ifdef CONFIG_SMP
0026 if (current->migration_disabled)
0027 goto out;
0028 #endif
0029
0030
0031
0032
0033 if (system_state < SYSTEM_SCHEDULING)
0034 goto out;
0035
0036
0037
0038
0039 preempt_disable_notrace();
0040
0041 instrumentation_begin();
0042 if (!printk_ratelimit())
0043 goto out_enable;
0044
0045 printk(KERN_ERR "BUG: using %s%s() in preemptible [%08x] code: %s/%d\n",
0046 what1, what2, preempt_count() - 1, current->comm, current->pid);
0047
0048 printk("caller is %pS\n", __builtin_return_address(0));
0049 dump_stack();
0050
0051 out_enable:
0052 instrumentation_end();
0053 preempt_enable_no_resched_notrace();
0054 out:
0055 return this_cpu;
0056 }
0057
0058 noinstr unsigned int debug_smp_processor_id(void)
0059 {
0060 return check_preemption_disabled("smp_processor_id", "");
0061 }
0062 EXPORT_SYMBOL(debug_smp_processor_id);
0063
0064 noinstr void __this_cpu_preempt_check(const char *op)
0065 {
0066 check_preemption_disabled("__this_cpu_", op);
0067 }
0068 EXPORT_SYMBOL(__this_cpu_preempt_check);