linux/lib/smp_processor_id.c
<<
>>
Prefs
   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
  11noinstr static
  12unsigned 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        instrumentation_end();
  51
  52out_enable:
  53        preempt_enable_no_resched_notrace();
  54out:
  55        return this_cpu;
  56}
  57
  58noinstr unsigned int debug_smp_processor_id(void)
  59{
  60        return check_preemption_disabled("smp_processor_id", "");
  61}
  62EXPORT_SYMBOL(debug_smp_processor_id);
  63
  64noinstr void __this_cpu_preempt_check(const char *op)
  65{
  66        check_preemption_disabled("__this_cpu_", op);
  67}
  68EXPORT_SYMBOL(__this_cpu_preempt_check);
  69