From 2c3c1048746a4622d8c89a29670120dc8fab93c4 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:49:45 +0200 Subject: Adding upstream version 6.1.76. Signed-off-by: Daniel Baumann --- include/trace/trace_events.h | 469 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 469 insertions(+) create mode 100644 include/trace/trace_events.h (limited to 'include/trace/trace_events.h') diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h new file mode 100644 index 000000000..c2f9cabf1 --- /dev/null +++ b/include/trace/trace_events.h @@ -0,0 +1,469 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Stage 1 of the trace events. + * + * Override the macros in the event tracepoint header + * to include the following: + * + * struct trace_event_raw_ { + * struct trace_entry ent; + * ; + * []; + * [...] + * }; + * + * The is created by the __field(type, item) macro or + * the __array(type2, item2, len) macro. + * We simply do "type item;", and that will create the fields + * in the structure. + */ + +#include + +#ifndef TRACE_SYSTEM_VAR +#define TRACE_SYSTEM_VAR TRACE_SYSTEM +#endif + +#include "stages/init.h" + +/* + * DECLARE_EVENT_CLASS can be used to add a generic function + * handlers for events. That is, if all events have the same + * parameters and just have distinct trace points. + * Each tracepoint can be defined with DEFINE_EVENT and that + * will map the DECLARE_EVENT_CLASS to the tracepoint. + * + * TRACE_EVENT is a one to one mapping between tracepoint and template. + */ +#undef TRACE_EVENT +#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ + DECLARE_EVENT_CLASS(name, \ + PARAMS(proto), \ + PARAMS(args), \ + PARAMS(tstruct), \ + PARAMS(assign), \ + PARAMS(print)); \ + DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)); + +#include "stages/stage1_struct_define.h" + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) \ + struct trace_event_raw_##name { \ + struct trace_entry ent; \ + tstruct \ + char __data[]; \ + }; \ + \ + static struct trace_event_class event_class_##name; + +#undef DEFINE_EVENT +#define DEFINE_EVENT(template, name, proto, args) \ + static struct trace_event_call __used \ + __attribute__((__aligned__(4))) event_##name + +#undef DEFINE_EVENT_FN +#define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg) \ + DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) + +#undef DEFINE_EVENT_PRINT +#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ + DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) + +/* Callbacks are meaningless to ftrace. */ +#undef TRACE_EVENT_FN +#define TRACE_EVENT_FN(name, proto, args, tstruct, \ + assign, print, reg, unreg) \ + TRACE_EVENT(name, PARAMS(proto), PARAMS(args), \ + PARAMS(tstruct), PARAMS(assign), PARAMS(print)) \ + +#undef TRACE_EVENT_FN_COND +#define TRACE_EVENT_FN_COND(name, proto, args, cond, tstruct, \ + assign, print, reg, unreg) \ + TRACE_EVENT_CONDITION(name, PARAMS(proto), PARAMS(args), PARAMS(cond), \ + PARAMS(tstruct), PARAMS(assign), PARAMS(print)) \ + +#undef TRACE_EVENT_FLAGS +#define TRACE_EVENT_FLAGS(name, value) \ + __TRACE_EVENT_FLAGS(name, value) + +#undef TRACE_EVENT_PERF_PERM +#define TRACE_EVENT_PERF_PERM(name, expr...) \ + __TRACE_EVENT_PERF_PERM(name, expr) + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 2 of the trace events. + * + * Include the following: + * + * struct trace_event_data_offsets_ { + * u32 ; + * u32 ; + * [...] + * }; + * + * The __dynamic_array() macro will create each u32 , this is + * to keep the offset of each array from the beginning of the event. + * The size of an array is also encoded, in the higher 16 bits of . + */ + +#include "stages/stage2_data_offsets.h" + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ + struct trace_event_data_offsets_##call { \ + tstruct; \ + }; + +#undef DEFINE_EVENT +#define DEFINE_EVENT(template, name, proto, args) + +#undef DEFINE_EVENT_PRINT +#define DEFINE_EVENT_PRINT(template, name, proto, args, print) + +#undef TRACE_EVENT_FLAGS +#define TRACE_EVENT_FLAGS(event, flag) + +#undef TRACE_EVENT_PERF_PERM +#define TRACE_EVENT_PERF_PERM(event, expr...) + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 3 of the trace events. + * + * Override the macros in the event tracepoint header + * to include the following: + * + * enum print_line_t + * trace_raw_output_(struct trace_iterator *iter, int flags) + * { + * struct trace_seq *s = &iter->seq; + * struct trace_event_raw_ *field; <-- defined in stage 1 + * struct trace_seq *p = &iter->tmp_seq; + * + * -------(for event)------- + * + * struct trace_entry *entry; + * + * entry = iter->ent; + * + * if (entry->type != event_->event.type) { + * WARN_ON_ONCE(1); + * return TRACE_TYPE_UNHANDLED; + * } + * + * field = (typeof(field))entry; + * + * trace_seq_init(p); + * return trace_output_call(iter, , "\n"); + * + * ------(or, for event class)------ + * + * int ret; + * + * field = (typeof(field))iter->ent; + * + * ret = trace_raw_output_prep(iter, trace_event); + * if (ret != TRACE_TYPE_HANDLED) + * return ret; + * + * trace_event_printf(iter, "\n"); + * + * return trace_handle_return(s); + * ------- + * } + * + * This is the method used to print the raw event to the trace + * output format. Note, this is not needed if the data is read + * in binary. + */ + +#include "stages/stage3_trace_output.h" + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ +static notrace enum print_line_t \ +trace_raw_output_##call(struct trace_iterator *iter, int flags, \ + struct trace_event *trace_event) \ +{ \ + struct trace_seq *s = &iter->seq; \ + struct trace_seq __maybe_unused *p = &iter->tmp_seq; \ + struct trace_event_raw_##call *field; \ + int ret; \ + \ + field = (typeof(field))iter->ent; \ + \ + ret = trace_raw_output_prep(iter, trace_event); \ + if (ret != TRACE_TYPE_HANDLED) \ + return ret; \ + \ + trace_event_printf(iter, print); \ + \ + return trace_handle_return(s); \ +} \ +static struct trace_event_functions trace_event_type_funcs_##call = { \ + .trace = trace_raw_output_##call, \ +}; + +#undef DEFINE_EVENT_PRINT +#define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ +static notrace enum print_line_t \ +trace_raw_output_##call(struct trace_iterator *iter, int flags, \ + struct trace_event *event) \ +{ \ + struct trace_event_raw_##template *field; \ + struct trace_entry *entry; \ + struct trace_seq *p = &iter->tmp_seq; \ + \ + entry = iter->ent; \ + \ + if (entry->type != event_##call.event.type) { \ + WARN_ON_ONCE(1); \ + return TRACE_TYPE_UNHANDLED; \ + } \ + \ + field = (typeof(field))entry; \ + \ + trace_seq_init(p); \ + return trace_output_call(iter, #call, print); \ +} \ +static struct trace_event_functions trace_event_type_funcs_##call = { \ + .trace = trace_raw_output_##call, \ +}; + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +#include "stages/stage4_event_fields.h" + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print) \ +static struct trace_event_fields trace_event_fields_##call[] = { \ + tstruct \ + {} }; + +#undef DEFINE_EVENT_PRINT +#define DEFINE_EVENT_PRINT(template, name, proto, args, print) + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +#include "stages/stage5_get_offsets.h" + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ +static inline notrace int trace_event_get_offsets_##call( \ + struct trace_event_data_offsets_##call *__data_offsets, proto) \ +{ \ + int __data_size = 0; \ + int __maybe_unused __item_length; \ + struct trace_event_raw_##call __maybe_unused *entry; \ + \ + tstruct; \ + \ + return __data_size; \ +} + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 4 of the trace events. + * + * Override the macros in the event tracepoint header + * to include the following: + * + * For those macros defined with TRACE_EVENT: + * + * static struct trace_event_call event_; + * + * static void trace_event_raw_event_(void *__data, proto) + * { + * struct trace_event_file *trace_file = __data; + * struct trace_event_call *event_call = trace_file->event_call; + * struct trace_event_data_offsets_ __maybe_unused __data_offsets; + * unsigned long eflags = trace_file->flags; + * enum event_trigger_type __tt = ETT_NONE; + * struct ring_buffer_event *event; + * struct trace_event_raw_ *entry; <-- defined in stage 1 + * struct trace_buffer *buffer; + * unsigned long irq_flags; + * int __data_size; + * int pc; + * + * if (!(eflags & EVENT_FILE_FL_TRIGGER_COND)) { + * if (eflags & EVENT_FILE_FL_TRIGGER_MODE) + * event_triggers_call(trace_file, NULL); + * if (eflags & EVENT_FILE_FL_SOFT_DISABLED) + * return; + * } + * + * local_save_flags(irq_flags); + * pc = preempt_count(); + * + * __data_size = trace_event_get_offsets_(&__data_offsets, args); + * + * event = trace_event_buffer_lock_reserve(&buffer, trace_file, + * event_->event.type, + * sizeof(*entry) + __data_size, + * irq_flags, pc); + * if (!event) + * return; + * entry = ring_buffer_event_data(event); + * + * { ; } <-- Here we assign the entries by the __field and + * __array macros. + * + * if (eflags & EVENT_FILE_FL_TRIGGER_COND) + * __tt = event_triggers_call(trace_file, entry); + * + * if (test_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, + * &trace_file->flags)) + * ring_buffer_discard_commit(buffer, event); + * else if (!filter_check_discard(trace_file, entry, buffer, event)) + * trace_buffer_unlock_commit(buffer, event, irq_flags, pc); + * + * if (__tt) + * event_triggers_post_call(trace_file, __tt); + * } + * + * static struct trace_event ftrace_event_type_ = { + * .trace = trace_raw_output_, <-- stage 2 + * }; + * + * static char print_fmt_[] = ; + * + * static struct trace_event_class __used event_class_