Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * lib/smp_processor_id.c
0004  *
0005  * DEBUG_PREEMPT variant of smp_processor_id().
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      * It is valid to assume CPU-locality during early bootup:
0032      */
0033     if (system_state < SYSTEM_SCHEDULING)
0034         goto out;
0035 
0036     /*
0037      * Avoid recursion:
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);