Back to home page

LXR

 
 

    


0001 /*
0002  * lib/smp_processor_id.c
0003  *
0004  * DEBUG_PREEMPT variant of smp_processor_id().
0005  */
0006 #include <linux/export.h>
0007 #include <linux/kallsyms.h>
0008 #include <linux/sched.h>
0009 
0010 notrace static unsigned int check_preemption_disabled(const char *what1,
0011                             const char *what2)
0012 {
0013     int this_cpu = raw_smp_processor_id();
0014 
0015     if (likely(preempt_count()))
0016         goto out;
0017 
0018     if (irqs_disabled())
0019         goto out;
0020 
0021     /*
0022      * Kernel threads bound to a single CPU can safely use
0023      * smp_processor_id():
0024      */
0025     if (cpumask_equal(tsk_cpus_allowed(current), cpumask_of(this_cpu)))
0026         goto out;
0027 
0028     /*
0029      * It is valid to assume CPU-locality during early bootup:
0030      */
0031     if (system_state != SYSTEM_RUNNING)
0032         goto out;
0033 
0034     /*
0035      * Avoid recursion:
0036      */
0037     preempt_disable_notrace();
0038 
0039     if (!printk_ratelimit())
0040         goto out_enable;
0041 
0042     printk(KERN_ERR "BUG: using %s%s() in preemptible [%08x] code: %s/%d\n",
0043         what1, what2, preempt_count() - 1, current->comm, current->pid);
0044 
0045     print_symbol("caller is %s\n", (long)__builtin_return_address(0));
0046     dump_stack();
0047 
0048 out_enable:
0049     preempt_enable_no_resched_notrace();
0050 out:
0051     return this_cpu;
0052 }
0053 
0054 notrace unsigned int debug_smp_processor_id(void)
0055 {
0056     return check_preemption_disabled("smp_processor_id", "");
0057 }
0058 EXPORT_SYMBOL(debug_smp_processor_id);
0059 
0060 notrace void __this_cpu_preempt_check(const char *op)
0061 {
0062     check_preemption_disabled("__this_cpu_", op);
0063 }
0064 EXPORT_SYMBOL(__this_cpu_preempt_check);