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