smp_processor_id.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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. noinstr static
  11. unsigned int check_preemption_disabled(const char *what1, const char *what2)
  12. {
  13. int this_cpu = raw_smp_processor_id();
  14. if (likely(preempt_count()))
  15. goto out;
  16. if (irqs_disabled())
  17. goto out;
  18. if (is_percpu_thread())
  19. goto out;
  20. if (current->migration_disabled)
  21. goto out;
  22. /*
  23. * It is valid to assume CPU-locality during early bootup:
  24. */
  25. if (system_state < SYSTEM_SCHEDULING)
  26. goto out;
  27. /*
  28. * Avoid recursion:
  29. */
  30. preempt_disable_notrace();
  31. instrumentation_begin();
  32. if (!printk_ratelimit())
  33. goto out_enable;
  34. printk(KERN_ERR "BUG: using %s%s() in preemptible [%08x] code: %s/%d\n",
  35. what1, what2, preempt_count() - 1, current->comm, current->pid);
  36. printk("caller is %pS\n", __builtin_return_address(0));
  37. dump_stack();
  38. out_enable:
  39. instrumentation_end();
  40. preempt_enable_no_resched_notrace();
  41. out:
  42. return this_cpu;
  43. }
  44. noinstr unsigned int debug_smp_processor_id(void)
  45. {
  46. return check_preemption_disabled("smp_processor_id", "");
  47. }
  48. EXPORT_SYMBOL(debug_smp_processor_id);
  49. noinstr void __this_cpu_preempt_check(const char *op)
  50. {
  51. check_preemption_disabled("__this_cpu_", op);
  52. }
  53. EXPORT_SYMBOL(__this_cpu_preempt_check);