Merge tag 'mm-hotfixes-stable-2023-05-03-16-27' of git://git.kernel.org/pub/scm/linux...
[linux-block.git] / include / trace / trace_custom_events.h
CommitLineData
3a73333f
SRG
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
84055411 38#include "stages/stage1_struct_define.h"
3a73333f
SRG
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
84055411 59#include "stages/stage2_data_offsets.h"
3a73333f
SRG
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
84055411 74#include "stages/stage3_trace_output.h"
3a73333f
SRG
75
76#undef DECLARE_CUSTOM_EVENT_CLASS
77#define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
78static notrace enum print_line_t \
79trace_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} \
97static 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
84055411 105#include "stages/stage4_event_fields.h"
3a73333f
SRG
106
107#undef DECLARE_CUSTOM_EVENT_CLASS
108#define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, func, print) \
109static 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
84055411 117#include "stages/stage5_get_offsets.h"
3a73333f
SRG
118
119#undef DECLARE_CUSTOM_EVENT_CLASS
120#define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
121static 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
84055411 137#include "stages/stage6_event_callback.h"
3a73333f
SRG
138
139#undef DECLARE_CUSTOM_EVENT_CLASS
140#define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
141 \
142static notrace void \
143trace_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) \
176static 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
84055411 185#include "stages/stage7_class_define.h"
3a73333f
SRG
186
187#undef DECLARE_CUSTOM_EVENT_CLASS
188#define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
189static char custom_print_fmt_##call[] = print; \
190static 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 \
202static 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}; \
209static 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} \
218static struct trace_event_call __used \
219__section("_ftrace_events") *__custom_event_##call = &custom_event_##call
220
221#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)