trace_sched_switch.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * trace context switch
  3. *
  4. * Copyright (C) 2007 Steven Rostedt <srostedt@redhat.com>
  5. *
  6. */
  7. #include <linux/module.h>
  8. #include <linux/fs.h>
  9. #include <linux/debugfs.h>
  10. #include <linux/kallsyms.h>
  11. #include <linux/uaccess.h>
  12. #include <linux/ftrace.h>
  13. #include <trace/events/sched.h>
  14. #include "trace.h"
  15. static int sched_ref;
  16. static DEFINE_MUTEX(sched_register_mutex);
  17. static void
  18. probe_sched_switch(void *ignore, struct task_struct *prev, struct task_struct *next)
  19. {
  20. if (unlikely(!sched_ref))
  21. return;
  22. tracing_record_cmdline(prev);
  23. tracing_record_cmdline(next);
  24. }
  25. static void
  26. probe_sched_wakeup(void *ignore, struct task_struct *wakee, int success)
  27. {
  28. if (unlikely(!sched_ref))
  29. return;
  30. tracing_record_cmdline(current);
  31. }
  32. static int tracing_sched_register(void)
  33. {
  34. int ret;
  35. ret = register_trace_sched_wakeup(probe_sched_wakeup, NULL);
  36. if (ret) {
  37. pr_info("wakeup trace: Couldn't activate tracepoint"
  38. " probe to kernel_sched_wakeup\n");
  39. return ret;
  40. }
  41. ret = register_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
  42. if (ret) {
  43. pr_info("wakeup trace: Couldn't activate tracepoint"
  44. " probe to kernel_sched_wakeup_new\n");
  45. goto fail_deprobe;
  46. }
  47. ret = register_trace_sched_switch(probe_sched_switch, NULL);
  48. if (ret) {
  49. pr_info("sched trace: Couldn't activate tracepoint"
  50. " probe to kernel_sched_switch\n");
  51. goto fail_deprobe_wake_new;
  52. }
  53. return ret;
  54. fail_deprobe_wake_new:
  55. unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
  56. fail_deprobe:
  57. unregister_trace_sched_wakeup(probe_sched_wakeup, NULL);
  58. return ret;
  59. }
  60. static void tracing_sched_unregister(void)
  61. {
  62. unregister_trace_sched_switch(probe_sched_switch, NULL);
  63. unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
  64. unregister_trace_sched_wakeup(probe_sched_wakeup, NULL);
  65. }
  66. static void tracing_start_sched_switch(void)
  67. {
  68. mutex_lock(&sched_register_mutex);
  69. if (!(sched_ref++))
  70. tracing_sched_register();
  71. mutex_unlock(&sched_register_mutex);
  72. }
  73. static void tracing_stop_sched_switch(void)
  74. {
  75. mutex_lock(&sched_register_mutex);
  76. if (!(--sched_ref))
  77. tracing_sched_unregister();
  78. mutex_unlock(&sched_register_mutex);
  79. }
  80. void tracing_start_cmdline_record(void)
  81. {
  82. tracing_start_sched_switch();
  83. }
  84. void tracing_stop_cmdline_record(void)
  85. {
  86. tracing_stop_sched_switch();
  87. }