sample-trace-array.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/module.h>
  3. #include <linux/kthread.h>
  4. #include <linux/trace.h>
  5. #include <linux/trace_events.h>
  6. #include <linux/timer.h>
  7. #include <linux/err.h>
  8. #include <linux/jiffies.h>
  9. #include <linux/workqueue.h>
  10. /*
  11. * Any file that uses trace points, must include the header.
  12. * But only one file, must include the header by defining
  13. * CREATE_TRACE_POINTS first. This will make the C code that
  14. * creates the handles for the trace points.
  15. */
  16. #define CREATE_TRACE_POINTS
  17. #include "sample-trace-array.h"
  18. struct trace_array *tr;
  19. static void mytimer_handler(struct timer_list *unused);
  20. static struct task_struct *simple_tsk;
  21. static void trace_work_fn(struct work_struct *work)
  22. {
  23. /*
  24. * Disable tracing for event "sample_event".
  25. */
  26. trace_array_set_clr_event(tr, "sample-subsystem", "sample_event",
  27. false);
  28. }
  29. static DECLARE_WORK(trace_work, trace_work_fn);
  30. /*
  31. * mytimer: Timer setup to disable tracing for event "sample_event". This
  32. * timer is only for the purposes of the sample module to demonstrate access of
  33. * Ftrace instances from within kernel.
  34. */
  35. static DEFINE_TIMER(mytimer, mytimer_handler);
  36. static void mytimer_handler(struct timer_list *unused)
  37. {
  38. schedule_work(&trace_work);
  39. }
  40. static void simple_thread_func(int count)
  41. {
  42. set_current_state(TASK_INTERRUPTIBLE);
  43. schedule_timeout(HZ);
  44. /*
  45. * Printing count value using trace_array_printk() - trace_printk()
  46. * equivalent for the instance buffers.
  47. */
  48. trace_array_printk(tr, _THIS_IP_, "trace_array_printk: count=%d\n",
  49. count);
  50. /*
  51. * Tracepoint for event "sample_event". This will print the
  52. * current value of count and current jiffies.
  53. */
  54. trace_sample_event(count, jiffies);
  55. }
  56. static int simple_thread(void *arg)
  57. {
  58. int count = 0;
  59. unsigned long delay = msecs_to_jiffies(5000);
  60. /*
  61. * Enable tracing for "sample_event".
  62. */
  63. trace_array_set_clr_event(tr, "sample-subsystem", "sample_event", true);
  64. /*
  65. * Adding timer - mytimer. This timer will disable tracing after
  66. * delay seconds.
  67. *
  68. */
  69. add_timer(&mytimer);
  70. mod_timer(&mytimer, jiffies+delay);
  71. while (!kthread_should_stop())
  72. simple_thread_func(count++);
  73. del_timer(&mytimer);
  74. cancel_work_sync(&trace_work);
  75. /*
  76. * trace_array_put() decrements the reference counter associated with
  77. * the trace array - "tr". We are done using the trace array, hence
  78. * decrement the reference counter so that it can be destroyed using
  79. * trace_array_destroy().
  80. */
  81. trace_array_put(tr);
  82. return 0;
  83. }
  84. static int __init sample_trace_array_init(void)
  85. {
  86. /*
  87. * Return a pointer to the trace array with name "sample-instance" if it
  88. * exists, else create a new trace array.
  89. *
  90. * NOTE: This function increments the reference counter
  91. * associated with the trace array - "tr".
  92. */
  93. tr = trace_array_get_by_name("sample-instance");
  94. if (!tr)
  95. return -1;
  96. /*
  97. * If context specific per-cpu buffers havent already been allocated.
  98. */
  99. trace_printk_init_buffers();
  100. simple_tsk = kthread_run(simple_thread, NULL, "sample-instance");
  101. if (IS_ERR(simple_tsk)) {
  102. trace_array_put(tr);
  103. trace_array_destroy(tr);
  104. return -1;
  105. }
  106. return 0;
  107. }
  108. static void __exit sample_trace_array_exit(void)
  109. {
  110. kthread_stop(simple_tsk);
  111. /*
  112. * We are unloading our module and no longer require the trace array.
  113. * Remove/destroy "tr" using trace_array_destroy()
  114. */
  115. trace_array_destroy(tr);
  116. }
  117. module_init(sample_trace_array_init);
  118. module_exit(sample_trace_array_exit);
  119. MODULE_AUTHOR("Divya Indi");
  120. MODULE_DESCRIPTION("Sample module for kernel access to Ftrace instances");
  121. MODULE_LICENSE("GPL");