trace_custom_events.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * This is similar to the trace_events.h file, but is to only
  4. * create custom trace events to be attached to existing tracepoints.
  5. * Where as the TRACE_EVENT() macro (from trace_events.h) will create
  6. * both the trace event and the tracepoint it will attach the event to,
  7. * TRACE_CUSTOM_EVENT() is to create only a custom version of an existing
  8. * trace event (created by TRACE_EVENT() or DEFINE_EVENT()), and will
  9. * be placed in the "custom" system.
  10. */
  11. #include <linux/trace_events.h>
  12. /* All custom events are placed in the custom group */
  13. #undef TRACE_SYSTEM
  14. #define TRACE_SYSTEM custom
  15. #ifndef TRACE_SYSTEM_VAR
  16. #define TRACE_SYSTEM_VAR TRACE_SYSTEM
  17. #endif
  18. /* The init stage creates the system string and enum mappings */
  19. #include "stages/init.h"
  20. #undef TRACE_CUSTOM_EVENT
  21. #define TRACE_CUSTOM_EVENT(name, proto, args, tstruct, assign, print) \
  22. DECLARE_CUSTOM_EVENT_CLASS(name, \
  23. PARAMS(proto), \
  24. PARAMS(args), \
  25. PARAMS(tstruct), \
  26. PARAMS(assign), \
  27. PARAMS(print)); \
  28. DEFINE_CUSTOM_EVENT(name, name, PARAMS(proto), PARAMS(args));
  29. /* Stage 1 creates the structure of the recorded event layout */
  30. #include "stages/stage1_struct_define.h"
  31. #undef DECLARE_CUSTOM_EVENT_CLASS
  32. #define DECLARE_CUSTOM_EVENT_CLASS(name, proto, args, tstruct, assign, print) \
  33. struct trace_custom_event_raw_##name { \
  34. struct trace_entry ent; \
  35. tstruct \
  36. char __data[]; \
  37. }; \
  38. \
  39. static struct trace_event_class custom_event_class_##name;
  40. #undef DEFINE_CUSTOM_EVENT
  41. #define DEFINE_CUSTOM_EVENT(template, name, proto, args) \
  42. static struct trace_event_call __used \
  43. __attribute__((__aligned__(4))) custom_event_##name
  44. #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
  45. /* Stage 2 creates the custom class */
  46. #include "stages/stage2_data_offsets.h"
  47. #undef DECLARE_CUSTOM_EVENT_CLASS
  48. #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
  49. struct trace_custom_event_data_offsets_##call { \
  50. tstruct; \
  51. };
  52. #undef DEFINE_CUSTOM_EVENT
  53. #define DEFINE_CUSTOM_EVENT(template, name, proto, args)
  54. #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
  55. /* Stage 3 create the way to print the custom event */
  56. #include "stages/stage3_trace_output.h"
  57. #undef DECLARE_CUSTOM_EVENT_CLASS
  58. #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
  59. static notrace enum print_line_t \
  60. trace_custom_raw_output_##call(struct trace_iterator *iter, int flags, \
  61. struct trace_event *trace_event) \
  62. { \
  63. struct trace_seq *s = &iter->seq; \
  64. struct trace_seq __maybe_unused *p = &iter->tmp_seq; \
  65. struct trace_custom_event_raw_##call *field; \
  66. int ret; \
  67. \
  68. field = (typeof(field))iter->ent; \
  69. \
  70. ret = trace_raw_output_prep(iter, trace_event); \
  71. if (ret != TRACE_TYPE_HANDLED) \
  72. return ret; \
  73. \
  74. trace_event_printf(iter, print); \
  75. \
  76. return trace_handle_return(s); \
  77. } \
  78. static struct trace_event_functions trace_custom_event_type_funcs_##call = { \
  79. .trace = trace_custom_raw_output_##call, \
  80. };
  81. #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
  82. /* Stage 4 creates the offset layout for the fields */
  83. #include "stages/stage4_event_fields.h"
  84. #undef DECLARE_CUSTOM_EVENT_CLASS
  85. #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, func, print) \
  86. static struct trace_event_fields trace_custom_event_fields_##call[] = { \
  87. tstruct \
  88. {} };
  89. #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
  90. /* Stage 5 creates the helper function for dynamic fields */
  91. #include "stages/stage5_get_offsets.h"
  92. #undef DECLARE_CUSTOM_EVENT_CLASS
  93. #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
  94. static inline notrace int trace_custom_event_get_offsets_##call( \
  95. struct trace_custom_event_data_offsets_##call *__data_offsets, proto) \
  96. { \
  97. int __data_size = 0; \
  98. int __maybe_unused __item_length; \
  99. struct trace_custom_event_raw_##call __maybe_unused *entry; \
  100. \
  101. tstruct; \
  102. \
  103. return __data_size; \
  104. }
  105. #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
  106. /* Stage 6 creates the probe function that records the event */
  107. #include "stages/stage6_event_callback.h"
  108. #undef DECLARE_CUSTOM_EVENT_CLASS
  109. #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
  110. \
  111. static notrace void \
  112. trace_custom_event_raw_event_##call(void *__data, proto) \
  113. { \
  114. struct trace_event_file *trace_file = __data; \
  115. struct trace_custom_event_data_offsets_##call __maybe_unused __data_offsets; \
  116. struct trace_event_buffer fbuffer; \
  117. struct trace_custom_event_raw_##call *entry; \
  118. int __data_size; \
  119. \
  120. if (trace_trigger_soft_disabled(trace_file)) \
  121. return; \
  122. \
  123. __data_size = trace_custom_event_get_offsets_##call(&__data_offsets, args); \
  124. \
  125. entry = trace_event_buffer_reserve(&fbuffer, trace_file, \
  126. sizeof(*entry) + __data_size); \
  127. \
  128. if (!entry) \
  129. return; \
  130. \
  131. tstruct \
  132. \
  133. { assign; } \
  134. \
  135. trace_event_buffer_commit(&fbuffer); \
  136. }
  137. /*
  138. * The ftrace_test_custom_probe is compiled out, it is only here as a build time check
  139. * to make sure that if the tracepoint handling changes, the ftrace probe will
  140. * fail to compile unless it too is updated.
  141. */
  142. #undef DEFINE_CUSTOM_EVENT
  143. #define DEFINE_CUSTOM_EVENT(template, call, proto, args) \
  144. static inline void ftrace_test_custom_probe_##call(void) \
  145. { \
  146. check_trace_callback_type_##call(trace_custom_event_raw_event_##template); \
  147. }
  148. #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
  149. /* Stage 7 creates the actual class and event structure for the custom event */
  150. #include "stages/stage7_class_define.h"
  151. #undef DECLARE_CUSTOM_EVENT_CLASS
  152. #define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
  153. static char custom_print_fmt_##call[] = print; \
  154. static struct trace_event_class __used __refdata custom_event_class_##call = { \
  155. .system = TRACE_SYSTEM_STRING, \
  156. .fields_array = trace_custom_event_fields_##call, \
  157. .fields = LIST_HEAD_INIT(custom_event_class_##call.fields),\
  158. .raw_init = trace_event_raw_init, \
  159. .probe = trace_custom_event_raw_event_##call, \
  160. .reg = trace_event_reg, \
  161. };
  162. #undef DEFINE_CUSTOM_EVENT
  163. #define DEFINE_CUSTOM_EVENT(template, call, proto, args) \
  164. \
  165. static struct trace_event_call __used custom_event_##call = { \
  166. .name = #call, \
  167. .class = &custom_event_class_##template, \
  168. .event.funcs = &trace_custom_event_type_funcs_##template, \
  169. .print_fmt = custom_print_fmt_##template, \
  170. .flags = TRACE_EVENT_FL_CUSTOM, \
  171. }; \
  172. static inline int trace_custom_event_##call##_update(struct tracepoint *tp) \
  173. { \
  174. if (tp->name && strcmp(tp->name, #call) == 0) { \
  175. custom_event_##call.tp = tp; \
  176. custom_event_##call.flags = TRACE_EVENT_FL_TRACEPOINT; \
  177. return 1; \
  178. } \
  179. return 0; \
  180. } \
  181. static struct trace_event_call __used \
  182. __section("_ftrace_events") *__custom_event_##call = &custom_event_##call
  183. #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)