opal-tracepoints.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #include <linux/percpu.h>
  2. #include <linux/jump_label.h>
  3. #include <asm/trace.h>
  4. #include <asm/asm-prototypes.h>
  5. #ifdef HAVE_JUMP_LABEL
  6. struct static_key opal_tracepoint_key = STATIC_KEY_INIT;
  7. void opal_tracepoint_regfunc(void)
  8. {
  9. static_key_slow_inc(&opal_tracepoint_key);
  10. }
  11. void opal_tracepoint_unregfunc(void)
  12. {
  13. static_key_slow_dec(&opal_tracepoint_key);
  14. }
  15. #else
  16. /*
  17. * We optimise OPAL calls by placing opal_tracepoint_refcount
  18. * directly in the TOC so we can check if the opal tracepoints are
  19. * enabled via a single load.
  20. */
  21. /* NB: reg/unreg are called while guarded with the tracepoints_mutex */
  22. extern long opal_tracepoint_refcount;
  23. void opal_tracepoint_regfunc(void)
  24. {
  25. opal_tracepoint_refcount++;
  26. }
  27. void opal_tracepoint_unregfunc(void)
  28. {
  29. opal_tracepoint_refcount--;
  30. }
  31. #endif
  32. /*
  33. * Since the tracing code might execute OPAL calls we need to guard against
  34. * recursion.
  35. */
  36. static DEFINE_PER_CPU(unsigned int, opal_trace_depth);
  37. void __trace_opal_entry(unsigned long opcode, unsigned long *args)
  38. {
  39. unsigned long flags;
  40. unsigned int *depth;
  41. local_irq_save(flags);
  42. depth = this_cpu_ptr(&opal_trace_depth);
  43. if (*depth)
  44. goto out;
  45. (*depth)++;
  46. preempt_disable();
  47. trace_opal_entry(opcode, args);
  48. (*depth)--;
  49. out:
  50. local_irq_restore(flags);
  51. }
  52. void __trace_opal_exit(long opcode, unsigned long retval)
  53. {
  54. unsigned long flags;
  55. unsigned int *depth;
  56. local_irq_save(flags);
  57. depth = this_cpu_ptr(&opal_trace_depth);
  58. if (*depth)
  59. goto out;
  60. (*depth)++;
  61. trace_opal_exit(opcode, retval);
  62. preempt_enable();
  63. (*depth)--;
  64. out:
  65. local_irq_restore(flags);
  66. }