162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Stage 1 of the trace events. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Override the macros in the event tracepoint header <trace/events/XXX.h> 662306a36Sopenharmony_ci * to include the following: 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * struct trace_event_raw_<call> { 962306a36Sopenharmony_ci * struct trace_entry ent; 1062306a36Sopenharmony_ci * <type> <item>; 1162306a36Sopenharmony_ci * <type2> <item2>[<len>]; 1262306a36Sopenharmony_ci * [...] 1362306a36Sopenharmony_ci * }; 1462306a36Sopenharmony_ci * 1562306a36Sopenharmony_ci * The <type> <item> is created by the __field(type, item) macro or 1662306a36Sopenharmony_ci * the __array(type2, item2, len) macro. 1762306a36Sopenharmony_ci * We simply do "type item;", and that will create the fields 1862306a36Sopenharmony_ci * in the structure. 1962306a36Sopenharmony_ci */ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <linux/trace_events.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#ifndef TRACE_SYSTEM_VAR 2462306a36Sopenharmony_ci#define TRACE_SYSTEM_VAR TRACE_SYSTEM 2562306a36Sopenharmony_ci#endif 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#include "stages/init.h" 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* 3062306a36Sopenharmony_ci * DECLARE_EVENT_CLASS can be used to add a generic function 3162306a36Sopenharmony_ci * handlers for events. That is, if all events have the same 3262306a36Sopenharmony_ci * parameters and just have distinct trace points. 3362306a36Sopenharmony_ci * Each tracepoint can be defined with DEFINE_EVENT and that 3462306a36Sopenharmony_ci * will map the DECLARE_EVENT_CLASS to the tracepoint. 3562306a36Sopenharmony_ci * 3662306a36Sopenharmony_ci * TRACE_EVENT is a one to one mapping between tracepoint and template. 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_ci#undef TRACE_EVENT 3962306a36Sopenharmony_ci#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ 4062306a36Sopenharmony_ci DECLARE_EVENT_CLASS(name, \ 4162306a36Sopenharmony_ci PARAMS(proto), \ 4262306a36Sopenharmony_ci PARAMS(args), \ 4362306a36Sopenharmony_ci PARAMS(tstruct), \ 4462306a36Sopenharmony_ci PARAMS(assign), \ 4562306a36Sopenharmony_ci PARAMS(print)); \ 4662306a36Sopenharmony_ci DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#include "stages/stage1_struct_define.h" 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS 5162306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) \ 5262306a36Sopenharmony_ci struct trace_event_raw_##name { \ 5362306a36Sopenharmony_ci struct trace_entry ent; \ 5462306a36Sopenharmony_ci tstruct \ 5562306a36Sopenharmony_ci char __data[]; \ 5662306a36Sopenharmony_ci }; \ 5762306a36Sopenharmony_ci \ 5862306a36Sopenharmony_ci static struct trace_event_class event_class_##name; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci#undef DEFINE_EVENT 6162306a36Sopenharmony_ci#define DEFINE_EVENT(template, name, proto, args) \ 6262306a36Sopenharmony_ci static struct trace_event_call __used \ 6362306a36Sopenharmony_ci __attribute__((__aligned__(4))) event_##name 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci#undef DEFINE_EVENT_FN 6662306a36Sopenharmony_ci#define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg) \ 6762306a36Sopenharmony_ci DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci#undef DEFINE_EVENT_PRINT 7062306a36Sopenharmony_ci#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ 7162306a36Sopenharmony_ci DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci/* Callbacks are meaningless to ftrace. */ 7462306a36Sopenharmony_ci#undef TRACE_EVENT_FN 7562306a36Sopenharmony_ci#define TRACE_EVENT_FN(name, proto, args, tstruct, \ 7662306a36Sopenharmony_ci assign, print, reg, unreg) \ 7762306a36Sopenharmony_ci TRACE_EVENT(name, PARAMS(proto), PARAMS(args), \ 7862306a36Sopenharmony_ci PARAMS(tstruct), PARAMS(assign), PARAMS(print)) \ 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci#undef TRACE_EVENT_FN_COND 8162306a36Sopenharmony_ci#define TRACE_EVENT_FN_COND(name, proto, args, cond, tstruct, \ 8262306a36Sopenharmony_ci assign, print, reg, unreg) \ 8362306a36Sopenharmony_ci TRACE_EVENT_CONDITION(name, PARAMS(proto), PARAMS(args), PARAMS(cond), \ 8462306a36Sopenharmony_ci PARAMS(tstruct), PARAMS(assign), PARAMS(print)) \ 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci#undef TRACE_EVENT_FLAGS 8762306a36Sopenharmony_ci#define TRACE_EVENT_FLAGS(name, value) \ 8862306a36Sopenharmony_ci __TRACE_EVENT_FLAGS(name, value) 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci#undef TRACE_EVENT_PERF_PERM 9162306a36Sopenharmony_ci#define TRACE_EVENT_PERF_PERM(name, expr...) \ 9262306a36Sopenharmony_ci __TRACE_EVENT_PERF_PERM(name, expr) 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* 9762306a36Sopenharmony_ci * Stage 2 of the trace events. 9862306a36Sopenharmony_ci * 9962306a36Sopenharmony_ci * Include the following: 10062306a36Sopenharmony_ci * 10162306a36Sopenharmony_ci * struct trace_event_data_offsets_<call> { 10262306a36Sopenharmony_ci * u32 <item1>; 10362306a36Sopenharmony_ci * u32 <item2>; 10462306a36Sopenharmony_ci * [...] 10562306a36Sopenharmony_ci * }; 10662306a36Sopenharmony_ci * 10762306a36Sopenharmony_ci * The __dynamic_array() macro will create each u32 <item>, this is 10862306a36Sopenharmony_ci * to keep the offset of each array from the beginning of the event. 10962306a36Sopenharmony_ci * The size of an array is also encoded, in the higher 16 bits of <item>. 11062306a36Sopenharmony_ci */ 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci#include "stages/stage2_data_offsets.h" 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS 11562306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 11662306a36Sopenharmony_ci struct trace_event_data_offsets_##call { \ 11762306a36Sopenharmony_ci tstruct; \ 11862306a36Sopenharmony_ci }; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci#undef DEFINE_EVENT 12162306a36Sopenharmony_ci#define DEFINE_EVENT(template, name, proto, args) 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci#undef DEFINE_EVENT_PRINT 12462306a36Sopenharmony_ci#define DEFINE_EVENT_PRINT(template, name, proto, args, print) 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci#undef TRACE_EVENT_FLAGS 12762306a36Sopenharmony_ci#define TRACE_EVENT_FLAGS(event, flag) 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci#undef TRACE_EVENT_PERF_PERM 13062306a36Sopenharmony_ci#define TRACE_EVENT_PERF_PERM(event, expr...) 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci/* 13562306a36Sopenharmony_ci * Stage 3 of the trace events. 13662306a36Sopenharmony_ci * 13762306a36Sopenharmony_ci * Override the macros in the event tracepoint header <trace/events/XXX.h> 13862306a36Sopenharmony_ci * to include the following: 13962306a36Sopenharmony_ci * 14062306a36Sopenharmony_ci * enum print_line_t 14162306a36Sopenharmony_ci * trace_raw_output_<call>(struct trace_iterator *iter, int flags) 14262306a36Sopenharmony_ci * { 14362306a36Sopenharmony_ci * struct trace_seq *s = &iter->seq; 14462306a36Sopenharmony_ci * struct trace_event_raw_<call> *field; <-- defined in stage 1 14562306a36Sopenharmony_ci * struct trace_seq *p = &iter->tmp_seq; 14662306a36Sopenharmony_ci * 14762306a36Sopenharmony_ci * -------(for event)------- 14862306a36Sopenharmony_ci * 14962306a36Sopenharmony_ci * struct trace_entry *entry; 15062306a36Sopenharmony_ci * 15162306a36Sopenharmony_ci * entry = iter->ent; 15262306a36Sopenharmony_ci * 15362306a36Sopenharmony_ci * if (entry->type != event_<call>->event.type) { 15462306a36Sopenharmony_ci * WARN_ON_ONCE(1); 15562306a36Sopenharmony_ci * return TRACE_TYPE_UNHANDLED; 15662306a36Sopenharmony_ci * } 15762306a36Sopenharmony_ci * 15862306a36Sopenharmony_ci * field = (typeof(field))entry; 15962306a36Sopenharmony_ci * 16062306a36Sopenharmony_ci * trace_seq_init(p); 16162306a36Sopenharmony_ci * return trace_output_call(iter, <call>, <TP_printk> "\n"); 16262306a36Sopenharmony_ci * 16362306a36Sopenharmony_ci * ------(or, for event class)------ 16462306a36Sopenharmony_ci * 16562306a36Sopenharmony_ci * int ret; 16662306a36Sopenharmony_ci * 16762306a36Sopenharmony_ci * field = (typeof(field))iter->ent; 16862306a36Sopenharmony_ci * 16962306a36Sopenharmony_ci * ret = trace_raw_output_prep(iter, trace_event); 17062306a36Sopenharmony_ci * if (ret != TRACE_TYPE_HANDLED) 17162306a36Sopenharmony_ci * return ret; 17262306a36Sopenharmony_ci * 17362306a36Sopenharmony_ci * trace_event_printf(iter, <TP_printk> "\n"); 17462306a36Sopenharmony_ci * 17562306a36Sopenharmony_ci * return trace_handle_return(s); 17662306a36Sopenharmony_ci * ------- 17762306a36Sopenharmony_ci * } 17862306a36Sopenharmony_ci * 17962306a36Sopenharmony_ci * This is the method used to print the raw event to the trace 18062306a36Sopenharmony_ci * output format. Note, this is not needed if the data is read 18162306a36Sopenharmony_ci * in binary. 18262306a36Sopenharmony_ci */ 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci#include "stages/stage3_trace_output.h" 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS 18762306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 18862306a36Sopenharmony_cistatic notrace enum print_line_t \ 18962306a36Sopenharmony_citrace_raw_output_##call(struct trace_iterator *iter, int flags, \ 19062306a36Sopenharmony_ci struct trace_event *trace_event) \ 19162306a36Sopenharmony_ci{ \ 19262306a36Sopenharmony_ci struct trace_seq *s = &iter->seq; \ 19362306a36Sopenharmony_ci struct trace_seq __maybe_unused *p = &iter->tmp_seq; \ 19462306a36Sopenharmony_ci struct trace_event_raw_##call *field; \ 19562306a36Sopenharmony_ci int ret; \ 19662306a36Sopenharmony_ci \ 19762306a36Sopenharmony_ci field = (typeof(field))iter->ent; \ 19862306a36Sopenharmony_ci \ 19962306a36Sopenharmony_ci ret = trace_raw_output_prep(iter, trace_event); \ 20062306a36Sopenharmony_ci if (ret != TRACE_TYPE_HANDLED) \ 20162306a36Sopenharmony_ci return ret; \ 20262306a36Sopenharmony_ci \ 20362306a36Sopenharmony_ci trace_event_printf(iter, print); \ 20462306a36Sopenharmony_ci \ 20562306a36Sopenharmony_ci return trace_handle_return(s); \ 20662306a36Sopenharmony_ci} \ 20762306a36Sopenharmony_cistatic struct trace_event_functions trace_event_type_funcs_##call = { \ 20862306a36Sopenharmony_ci .trace = trace_raw_output_##call, \ 20962306a36Sopenharmony_ci}; 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci#undef DEFINE_EVENT_PRINT 21262306a36Sopenharmony_ci#define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ 21362306a36Sopenharmony_cistatic notrace enum print_line_t \ 21462306a36Sopenharmony_citrace_raw_output_##call(struct trace_iterator *iter, int flags, \ 21562306a36Sopenharmony_ci struct trace_event *event) \ 21662306a36Sopenharmony_ci{ \ 21762306a36Sopenharmony_ci struct trace_event_raw_##template *field; \ 21862306a36Sopenharmony_ci struct trace_entry *entry; \ 21962306a36Sopenharmony_ci struct trace_seq *p = &iter->tmp_seq; \ 22062306a36Sopenharmony_ci \ 22162306a36Sopenharmony_ci entry = iter->ent; \ 22262306a36Sopenharmony_ci \ 22362306a36Sopenharmony_ci if (entry->type != event_##call.event.type) { \ 22462306a36Sopenharmony_ci WARN_ON_ONCE(1); \ 22562306a36Sopenharmony_ci return TRACE_TYPE_UNHANDLED; \ 22662306a36Sopenharmony_ci } \ 22762306a36Sopenharmony_ci \ 22862306a36Sopenharmony_ci field = (typeof(field))entry; \ 22962306a36Sopenharmony_ci \ 23062306a36Sopenharmony_ci trace_seq_init(p); \ 23162306a36Sopenharmony_ci return trace_output_call(iter, #call, print); \ 23262306a36Sopenharmony_ci} \ 23362306a36Sopenharmony_cistatic struct trace_event_functions trace_event_type_funcs_##call = { \ 23462306a36Sopenharmony_ci .trace = trace_raw_output_##call, \ 23562306a36Sopenharmony_ci}; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci#include "stages/stage4_event_fields.h" 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS 24262306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print) \ 24362306a36Sopenharmony_cistatic struct trace_event_fields trace_event_fields_##call[] = { \ 24462306a36Sopenharmony_ci tstruct \ 24562306a36Sopenharmony_ci {} }; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci#undef DEFINE_EVENT_PRINT 24862306a36Sopenharmony_ci#define DEFINE_EVENT_PRINT(template, name, proto, args, print) 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci#include "stages/stage5_get_offsets.h" 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS 25562306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 25662306a36Sopenharmony_cistatic inline notrace int trace_event_get_offsets_##call( \ 25762306a36Sopenharmony_ci struct trace_event_data_offsets_##call *__data_offsets, proto) \ 25862306a36Sopenharmony_ci{ \ 25962306a36Sopenharmony_ci int __data_size = 0; \ 26062306a36Sopenharmony_ci int __maybe_unused __item_length; \ 26162306a36Sopenharmony_ci struct trace_event_raw_##call __maybe_unused *entry; \ 26262306a36Sopenharmony_ci \ 26362306a36Sopenharmony_ci tstruct; \ 26462306a36Sopenharmony_ci \ 26562306a36Sopenharmony_ci return __data_size; \ 26662306a36Sopenharmony_ci} 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci/* 27162306a36Sopenharmony_ci * Stage 4 of the trace events. 27262306a36Sopenharmony_ci * 27362306a36Sopenharmony_ci * Override the macros in the event tracepoint header <trace/events/XXX.h> 27462306a36Sopenharmony_ci * to include the following: 27562306a36Sopenharmony_ci * 27662306a36Sopenharmony_ci * For those macros defined with TRACE_EVENT: 27762306a36Sopenharmony_ci * 27862306a36Sopenharmony_ci * static struct trace_event_call event_<call>; 27962306a36Sopenharmony_ci * 28062306a36Sopenharmony_ci * static void trace_event_raw_event_<call>(void *__data, proto) 28162306a36Sopenharmony_ci * { 28262306a36Sopenharmony_ci * struct trace_event_file *trace_file = __data; 28362306a36Sopenharmony_ci * struct trace_event_call *event_call = trace_file->event_call; 28462306a36Sopenharmony_ci * struct trace_event_data_offsets_<call> __maybe_unused __data_offsets; 28562306a36Sopenharmony_ci * unsigned long eflags = trace_file->flags; 28662306a36Sopenharmony_ci * enum event_trigger_type __tt = ETT_NONE; 28762306a36Sopenharmony_ci * struct ring_buffer_event *event; 28862306a36Sopenharmony_ci * struct trace_event_raw_<call> *entry; <-- defined in stage 1 28962306a36Sopenharmony_ci * struct trace_buffer *buffer; 29062306a36Sopenharmony_ci * unsigned long irq_flags; 29162306a36Sopenharmony_ci * int __data_size; 29262306a36Sopenharmony_ci * int pc; 29362306a36Sopenharmony_ci * 29462306a36Sopenharmony_ci * if (!(eflags & EVENT_FILE_FL_TRIGGER_COND)) { 29562306a36Sopenharmony_ci * if (eflags & EVENT_FILE_FL_TRIGGER_MODE) 29662306a36Sopenharmony_ci * event_triggers_call(trace_file, NULL); 29762306a36Sopenharmony_ci * if (eflags & EVENT_FILE_FL_SOFT_DISABLED) 29862306a36Sopenharmony_ci * return; 29962306a36Sopenharmony_ci * } 30062306a36Sopenharmony_ci * 30162306a36Sopenharmony_ci * local_save_flags(irq_flags); 30262306a36Sopenharmony_ci * pc = preempt_count(); 30362306a36Sopenharmony_ci * 30462306a36Sopenharmony_ci * __data_size = trace_event_get_offsets_<call>(&__data_offsets, args); 30562306a36Sopenharmony_ci * 30662306a36Sopenharmony_ci * event = trace_event_buffer_lock_reserve(&buffer, trace_file, 30762306a36Sopenharmony_ci * event_<call>->event.type, 30862306a36Sopenharmony_ci * sizeof(*entry) + __data_size, 30962306a36Sopenharmony_ci * irq_flags, pc); 31062306a36Sopenharmony_ci * if (!event) 31162306a36Sopenharmony_ci * return; 31262306a36Sopenharmony_ci * entry = ring_buffer_event_data(event); 31362306a36Sopenharmony_ci * 31462306a36Sopenharmony_ci * { <assign>; } <-- Here we assign the entries by the __field and 31562306a36Sopenharmony_ci * __array macros. 31662306a36Sopenharmony_ci * 31762306a36Sopenharmony_ci * if (eflags & EVENT_FILE_FL_TRIGGER_COND) 31862306a36Sopenharmony_ci * __tt = event_triggers_call(trace_file, entry); 31962306a36Sopenharmony_ci * 32062306a36Sopenharmony_ci * if (test_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, 32162306a36Sopenharmony_ci * &trace_file->flags)) 32262306a36Sopenharmony_ci * ring_buffer_discard_commit(buffer, event); 32362306a36Sopenharmony_ci * else if (!filter_check_discard(trace_file, entry, buffer, event)) 32462306a36Sopenharmony_ci * trace_buffer_unlock_commit(buffer, event, irq_flags, pc); 32562306a36Sopenharmony_ci * 32662306a36Sopenharmony_ci * if (__tt) 32762306a36Sopenharmony_ci * event_triggers_post_call(trace_file, __tt); 32862306a36Sopenharmony_ci * } 32962306a36Sopenharmony_ci * 33062306a36Sopenharmony_ci * static struct trace_event ftrace_event_type_<call> = { 33162306a36Sopenharmony_ci * .trace = trace_raw_output_<call>, <-- stage 2 33262306a36Sopenharmony_ci * }; 33362306a36Sopenharmony_ci * 33462306a36Sopenharmony_ci * static char print_fmt_<call>[] = <TP_printk>; 33562306a36Sopenharmony_ci * 33662306a36Sopenharmony_ci * static struct trace_event_class __used event_class_<template> = { 33762306a36Sopenharmony_ci * .system = "<system>", 33862306a36Sopenharmony_ci * .fields_array = trace_event_fields_<call>, 33962306a36Sopenharmony_ci * .fields = LIST_HEAD_INIT(event_class_##call.fields), 34062306a36Sopenharmony_ci * .raw_init = trace_event_raw_init, 34162306a36Sopenharmony_ci * .probe = trace_event_raw_event_##call, 34262306a36Sopenharmony_ci * .reg = trace_event_reg, 34362306a36Sopenharmony_ci * }; 34462306a36Sopenharmony_ci * 34562306a36Sopenharmony_ci * static struct trace_event_call event_<call> = { 34662306a36Sopenharmony_ci * .class = event_class_<template>, 34762306a36Sopenharmony_ci * { 34862306a36Sopenharmony_ci * .tp = &__tracepoint_<call>, 34962306a36Sopenharmony_ci * }, 35062306a36Sopenharmony_ci * .event = &ftrace_event_type_<call>, 35162306a36Sopenharmony_ci * .print_fmt = print_fmt_<call>, 35262306a36Sopenharmony_ci * .flags = TRACE_EVENT_FL_TRACEPOINT, 35362306a36Sopenharmony_ci * }; 35462306a36Sopenharmony_ci * // its only safe to use pointers when doing linker tricks to 35562306a36Sopenharmony_ci * // create an array. 35662306a36Sopenharmony_ci * static struct trace_event_call __used 35762306a36Sopenharmony_ci * __section("_ftrace_events") *__event_<call> = &event_<call>; 35862306a36Sopenharmony_ci * 35962306a36Sopenharmony_ci */ 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci#ifdef CONFIG_PERF_EVENTS 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci#define _TRACE_PERF_PROTO(call, proto) \ 36462306a36Sopenharmony_ci static notrace void \ 36562306a36Sopenharmony_ci perf_trace_##call(void *__data, proto); 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci#define _TRACE_PERF_INIT(call) \ 36862306a36Sopenharmony_ci .perf_probe = perf_trace_##call, 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci#else 37162306a36Sopenharmony_ci#define _TRACE_PERF_PROTO(call, proto) 37262306a36Sopenharmony_ci#define _TRACE_PERF_INIT(call) 37362306a36Sopenharmony_ci#endif /* CONFIG_PERF_EVENTS */ 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci#include "stages/stage6_event_callback.h" 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS 37862306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 37962306a36Sopenharmony_ci \ 38062306a36Sopenharmony_cistatic notrace void \ 38162306a36Sopenharmony_citrace_event_raw_event_##call(void *__data, proto) \ 38262306a36Sopenharmony_ci{ \ 38362306a36Sopenharmony_ci struct trace_event_file *trace_file = __data; \ 38462306a36Sopenharmony_ci struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\ 38562306a36Sopenharmony_ci struct trace_event_buffer fbuffer; \ 38662306a36Sopenharmony_ci struct trace_event_raw_##call *entry; \ 38762306a36Sopenharmony_ci int __data_size; \ 38862306a36Sopenharmony_ci \ 38962306a36Sopenharmony_ci if (trace_trigger_soft_disabled(trace_file)) \ 39062306a36Sopenharmony_ci return; \ 39162306a36Sopenharmony_ci \ 39262306a36Sopenharmony_ci __data_size = trace_event_get_offsets_##call(&__data_offsets, args); \ 39362306a36Sopenharmony_ci \ 39462306a36Sopenharmony_ci entry = trace_event_buffer_reserve(&fbuffer, trace_file, \ 39562306a36Sopenharmony_ci sizeof(*entry) + __data_size); \ 39662306a36Sopenharmony_ci \ 39762306a36Sopenharmony_ci if (!entry) \ 39862306a36Sopenharmony_ci return; \ 39962306a36Sopenharmony_ci \ 40062306a36Sopenharmony_ci tstruct \ 40162306a36Sopenharmony_ci \ 40262306a36Sopenharmony_ci { assign; } \ 40362306a36Sopenharmony_ci \ 40462306a36Sopenharmony_ci trace_event_buffer_commit(&fbuffer); \ 40562306a36Sopenharmony_ci} 40662306a36Sopenharmony_ci/* 40762306a36Sopenharmony_ci * The ftrace_test_probe is compiled out, it is only here as a build time check 40862306a36Sopenharmony_ci * to make sure that if the tracepoint handling changes, the ftrace probe will 40962306a36Sopenharmony_ci * fail to compile unless it too is updated. 41062306a36Sopenharmony_ci */ 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci#undef DEFINE_EVENT 41362306a36Sopenharmony_ci#define DEFINE_EVENT(template, call, proto, args) \ 41462306a36Sopenharmony_cistatic inline void ftrace_test_probe_##call(void) \ 41562306a36Sopenharmony_ci{ \ 41662306a36Sopenharmony_ci check_trace_callback_type_##call(trace_event_raw_event_##template); \ 41762306a36Sopenharmony_ci} 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci#include "stages/stage7_class_define.h" 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS 42462306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 42562306a36Sopenharmony_ci_TRACE_PERF_PROTO(call, PARAMS(proto)); \ 42662306a36Sopenharmony_cistatic char print_fmt_##call[] = print; \ 42762306a36Sopenharmony_cistatic struct trace_event_class __used __refdata event_class_##call = { \ 42862306a36Sopenharmony_ci .system = TRACE_SYSTEM_STRING, \ 42962306a36Sopenharmony_ci .fields_array = trace_event_fields_##call, \ 43062306a36Sopenharmony_ci .fields = LIST_HEAD_INIT(event_class_##call.fields),\ 43162306a36Sopenharmony_ci .raw_init = trace_event_raw_init, \ 43262306a36Sopenharmony_ci .probe = trace_event_raw_event_##call, \ 43362306a36Sopenharmony_ci .reg = trace_event_reg, \ 43462306a36Sopenharmony_ci _TRACE_PERF_INIT(call) \ 43562306a36Sopenharmony_ci}; 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci#undef DEFINE_EVENT 43862306a36Sopenharmony_ci#define DEFINE_EVENT(template, call, proto, args) \ 43962306a36Sopenharmony_ci \ 44062306a36Sopenharmony_cistatic struct trace_event_call __used event_##call = { \ 44162306a36Sopenharmony_ci .class = &event_class_##template, \ 44262306a36Sopenharmony_ci { \ 44362306a36Sopenharmony_ci .tp = &__tracepoint_##call, \ 44462306a36Sopenharmony_ci }, \ 44562306a36Sopenharmony_ci .event.funcs = &trace_event_type_funcs_##template, \ 44662306a36Sopenharmony_ci .print_fmt = print_fmt_##template, \ 44762306a36Sopenharmony_ci .flags = TRACE_EVENT_FL_TRACEPOINT, \ 44862306a36Sopenharmony_ci}; \ 44962306a36Sopenharmony_cistatic struct trace_event_call __used \ 45062306a36Sopenharmony_ci__section("_ftrace_events") *__event_##call = &event_##call 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci#undef DEFINE_EVENT_PRINT 45362306a36Sopenharmony_ci#define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ 45462306a36Sopenharmony_ci \ 45562306a36Sopenharmony_cistatic char print_fmt_##call[] = print; \ 45662306a36Sopenharmony_ci \ 45762306a36Sopenharmony_cistatic struct trace_event_call __used event_##call = { \ 45862306a36Sopenharmony_ci .class = &event_class_##template, \ 45962306a36Sopenharmony_ci { \ 46062306a36Sopenharmony_ci .tp = &__tracepoint_##call, \ 46162306a36Sopenharmony_ci }, \ 46262306a36Sopenharmony_ci .event.funcs = &trace_event_type_funcs_##call, \ 46362306a36Sopenharmony_ci .print_fmt = print_fmt_##call, \ 46462306a36Sopenharmony_ci .flags = TRACE_EVENT_FL_TRACEPOINT, \ 46562306a36Sopenharmony_ci}; \ 46662306a36Sopenharmony_cistatic struct trace_event_call __used \ 46762306a36Sopenharmony_ci__section("_ftrace_events") *__event_##call = &event_##call 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 470