Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Stage 1 of the trace events.
0004  *
0005  * Override the macros in the event tracepoint header <trace/events/XXX.h>
0006  * to include the following:
0007  *
0008  * struct trace_event_raw_<call> {
0009  *  struct trace_entry      ent;
0010  *  <type>              <item>;
0011  *  <type2>             <item2>[<len>];
0012  *  [...]
0013  * };
0014  *
0015  * The <type> <item> is created by the __field(type, item) macro or
0016  * the __array(type2, item2, len) macro.
0017  * We simply do "type item;", and that will create the fields
0018  * in the structure.
0019  */
0020 
0021 #include <linux/trace_events.h>
0022 
0023 #ifndef TRACE_SYSTEM_VAR
0024 #define TRACE_SYSTEM_VAR TRACE_SYSTEM
0025 #endif
0026 
0027 #include "stages/init.h"
0028 
0029 /*
0030  * DECLARE_EVENT_CLASS can be used to add a generic function
0031  * handlers for events. That is, if all events have the same
0032  * parameters and just have distinct trace points.
0033  * Each tracepoint can be defined with DEFINE_EVENT and that
0034  * will map the DECLARE_EVENT_CLASS to the tracepoint.
0035  *
0036  * TRACE_EVENT is a one to one mapping between tracepoint and template.
0037  */
0038 #undef TRACE_EVENT
0039 #define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
0040     DECLARE_EVENT_CLASS(name,                  \
0041                  PARAMS(proto),            \
0042                  PARAMS(args),             \
0043                  PARAMS(tstruct),              \
0044                  PARAMS(assign),               \
0045                  PARAMS(print));               \
0046     DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args));
0047 
0048 #include "stages/stage1_struct_define.h"
0049 
0050 #undef DECLARE_EVENT_CLASS
0051 #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)  \
0052     struct trace_event_raw_##name {                 \
0053         struct trace_entry  ent;                \
0054         tstruct                         \
0055         char            __data[];           \
0056     };                              \
0057                                     \
0058     static struct trace_event_class event_class_##name;
0059 
0060 #undef DEFINE_EVENT
0061 #define DEFINE_EVENT(template, name, proto, args)   \
0062     static struct trace_event_call  __used      \
0063     __attribute__((__aligned__(4))) event_##name
0064 
0065 #undef DEFINE_EVENT_FN
0066 #define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)    \
0067     DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
0068 
0069 #undef DEFINE_EVENT_PRINT
0070 #define DEFINE_EVENT_PRINT(template, name, proto, args, print)  \
0071     DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
0072 
0073 /* Callbacks are meaningless to ftrace. */
0074 #undef TRACE_EVENT_FN
0075 #define TRACE_EVENT_FN(name, proto, args, tstruct,          \
0076         assign, print, reg, unreg)              \
0077     TRACE_EVENT(name, PARAMS(proto), PARAMS(args),          \
0078         PARAMS(tstruct), PARAMS(assign), PARAMS(print))     \
0079 
0080 #undef TRACE_EVENT_FN_COND
0081 #define TRACE_EVENT_FN_COND(name, proto, args, cond, tstruct,   \
0082         assign, print, reg, unreg)              \
0083     TRACE_EVENT_CONDITION(name, PARAMS(proto), PARAMS(args), PARAMS(cond),      \
0084         PARAMS(tstruct), PARAMS(assign), PARAMS(print))     \
0085 
0086 #undef TRACE_EVENT_FLAGS
0087 #define TRACE_EVENT_FLAGS(name, value)                  \
0088     __TRACE_EVENT_FLAGS(name, value)
0089 
0090 #undef TRACE_EVENT_PERF_PERM
0091 #define TRACE_EVENT_PERF_PERM(name, expr...)                \
0092     __TRACE_EVENT_PERF_PERM(name, expr)
0093 
0094 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
0095 
0096 /*
0097  * Stage 2 of the trace events.
0098  *
0099  * Include the following:
0100  *
0101  * struct trace_event_data_offsets_<call> {
0102  *  u32             <item1>;
0103  *  u32             <item2>;
0104  *  [...]
0105  * };
0106  *
0107  * The __dynamic_array() macro will create each u32 <item>, this is
0108  * to keep the offset of each array from the beginning of the event.
0109  * The size of an array is also encoded, in the higher 16 bits of <item>.
0110  */
0111 
0112 #include "stages/stage2_data_offsets.h"
0113 
0114 #undef DECLARE_EVENT_CLASS
0115 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)  \
0116     struct trace_event_data_offsets_##call {            \
0117         tstruct;                        \
0118     };
0119 
0120 #undef DEFINE_EVENT
0121 #define DEFINE_EVENT(template, name, proto, args)
0122 
0123 #undef DEFINE_EVENT_PRINT
0124 #define DEFINE_EVENT_PRINT(template, name, proto, args, print)
0125 
0126 #undef TRACE_EVENT_FLAGS
0127 #define TRACE_EVENT_FLAGS(event, flag)
0128 
0129 #undef TRACE_EVENT_PERF_PERM
0130 #define TRACE_EVENT_PERF_PERM(event, expr...)
0131 
0132 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
0133 
0134 /*
0135  * Stage 3 of the trace events.
0136  *
0137  * Override the macros in the event tracepoint header <trace/events/XXX.h>
0138  * to include the following:
0139  *
0140  * enum print_line_t
0141  * trace_raw_output_<call>(struct trace_iterator *iter, int flags)
0142  * {
0143  *  struct trace_seq *s = &iter->seq;
0144  *  struct trace_event_raw_<call> *field; <-- defined in stage 1
0145  *  struct trace_seq *p = &iter->tmp_seq;
0146  *
0147  * -------(for event)-------
0148  *
0149  *  struct trace_entry *entry;
0150  *
0151  *  entry = iter->ent;
0152  *
0153  *  if (entry->type != event_<call>->event.type) {
0154  *      WARN_ON_ONCE(1);
0155  *      return TRACE_TYPE_UNHANDLED;
0156  *  }
0157  *
0158  *  field = (typeof(field))entry;
0159  *
0160  *  trace_seq_init(p);
0161  *  return trace_output_call(iter, <call>, <TP_printk> "\n");
0162  *
0163  * ------(or, for event class)------
0164  *
0165  *  int ret;
0166  *
0167  *  field = (typeof(field))iter->ent;
0168  *
0169  *  ret = trace_raw_output_prep(iter, trace_event);
0170  *  if (ret != TRACE_TYPE_HANDLED)
0171  *      return ret;
0172  *
0173  *  trace_event_printf(iter, <TP_printk> "\n");
0174  *
0175  *  return trace_handle_return(s);
0176  * -------
0177  *  }
0178  *
0179  * This is the method used to print the raw event to the trace
0180  * output format. Note, this is not needed if the data is read
0181  * in binary.
0182  */
0183 
0184 #include "stages/stage3_trace_output.h"
0185 
0186 #undef DECLARE_EVENT_CLASS
0187 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)  \
0188 static notrace enum print_line_t                    \
0189 trace_raw_output_##call(struct trace_iterator *iter, int flags,     \
0190             struct trace_event *trace_event)        \
0191 {                                   \
0192     struct trace_seq *s = &iter->seq;               \
0193     struct trace_seq __maybe_unused *p = &iter->tmp_seq;        \
0194     struct trace_event_raw_##call *field;               \
0195     int ret;                            \
0196                                     \
0197     field = (typeof(field))iter->ent;               \
0198                                     \
0199     ret = trace_raw_output_prep(iter, trace_event);         \
0200     if (ret != TRACE_TYPE_HANDLED)                  \
0201         return ret;                     \
0202                                     \
0203     trace_event_printf(iter, print);                \
0204                                     \
0205     return trace_handle_return(s);                  \
0206 }                                   \
0207 static struct trace_event_functions trace_event_type_funcs_##call = {   \
0208     .trace          = trace_raw_output_##call,      \
0209 };
0210 
0211 #undef DEFINE_EVENT_PRINT
0212 #define DEFINE_EVENT_PRINT(template, call, proto, args, print)      \
0213 static notrace enum print_line_t                    \
0214 trace_raw_output_##call(struct trace_iterator *iter, int flags,     \
0215              struct trace_event *event)         \
0216 {                                   \
0217     struct trace_event_raw_##template *field;           \
0218     struct trace_entry *entry;                  \
0219     struct trace_seq *p = &iter->tmp_seq;               \
0220                                     \
0221     entry = iter->ent;                      \
0222                                     \
0223     if (entry->type != event_##call.event.type) {           \
0224         WARN_ON_ONCE(1);                    \
0225         return TRACE_TYPE_UNHANDLED;                \
0226     }                               \
0227                                     \
0228     field = (typeof(field))entry;                   \
0229                                     \
0230     trace_seq_init(p);                      \
0231     return trace_output_call(iter, #call, print);           \
0232 }                                   \
0233 static struct trace_event_functions trace_event_type_funcs_##call = {   \
0234     .trace          = trace_raw_output_##call,      \
0235 };
0236 
0237 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
0238 
0239 #include "stages/stage4_event_fields.h"
0240 
0241 #undef DECLARE_EVENT_CLASS
0242 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print)    \
0243 static struct trace_event_fields trace_event_fields_##call[] = {    \
0244     tstruct                             \
0245     {} };
0246 
0247 #undef DEFINE_EVENT_PRINT
0248 #define DEFINE_EVENT_PRINT(template, name, proto, args, print)
0249 
0250 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
0251 
0252 #include "stages/stage5_get_offsets.h"
0253 
0254 #undef DECLARE_EVENT_CLASS
0255 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)  \
0256 static inline notrace int trace_event_get_offsets_##call(       \
0257     struct trace_event_data_offsets_##call *__data_offsets, proto)  \
0258 {                                   \
0259     int __data_size = 0;                        \
0260     int __maybe_unused __item_length;               \
0261     struct trace_event_raw_##call __maybe_unused *entry;        \
0262                                     \
0263     tstruct;                            \
0264                                     \
0265     return __data_size;                     \
0266 }
0267 
0268 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
0269 
0270 /*
0271  * Stage 4 of the trace events.
0272  *
0273  * Override the macros in the event tracepoint header <trace/events/XXX.h>
0274  * to include the following:
0275  *
0276  * For those macros defined with TRACE_EVENT:
0277  *
0278  * static struct trace_event_call event_<call>;
0279  *
0280  * static void trace_event_raw_event_<call>(void *__data, proto)
0281  * {
0282  *  struct trace_event_file *trace_file = __data;
0283  *  struct trace_event_call *event_call = trace_file->event_call;
0284  *  struct trace_event_data_offsets_<call> __maybe_unused __data_offsets;
0285  *  unsigned long eflags = trace_file->flags;
0286  *  enum event_trigger_type __tt = ETT_NONE;
0287  *  struct ring_buffer_event *event;
0288  *  struct trace_event_raw_<call> *entry; <-- defined in stage 1
0289  *  struct trace_buffer *buffer;
0290  *  unsigned long irq_flags;
0291  *  int __data_size;
0292  *  int pc;
0293  *
0294  *  if (!(eflags & EVENT_FILE_FL_TRIGGER_COND)) {
0295  *      if (eflags & EVENT_FILE_FL_TRIGGER_MODE)
0296  *          event_triggers_call(trace_file, NULL);
0297  *      if (eflags & EVENT_FILE_FL_SOFT_DISABLED)
0298  *          return;
0299  *  }
0300  *
0301  *  local_save_flags(irq_flags);
0302  *  pc = preempt_count();
0303  *
0304  *  __data_size = trace_event_get_offsets_<call>(&__data_offsets, args);
0305  *
0306  *  event = trace_event_buffer_lock_reserve(&buffer, trace_file,
0307  *                event_<call>->event.type,
0308  *                sizeof(*entry) + __data_size,
0309  *                irq_flags, pc);
0310  *  if (!event)
0311  *      return;
0312  *  entry   = ring_buffer_event_data(event);
0313  *
0314  *  { <assign>; }  <-- Here we assign the entries by the __field and
0315  *             __array macros.
0316  *
0317  *  if (eflags & EVENT_FILE_FL_TRIGGER_COND)
0318  *      __tt = event_triggers_call(trace_file, entry);
0319  *
0320  *  if (test_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT,
0321  *           &trace_file->flags))
0322  *      ring_buffer_discard_commit(buffer, event);
0323  *  else if (!filter_check_discard(trace_file, entry, buffer, event))
0324  *      trace_buffer_unlock_commit(buffer, event, irq_flags, pc);
0325  *
0326  *  if (__tt)
0327  *      event_triggers_post_call(trace_file, __tt);
0328  * }
0329  *
0330  * static struct trace_event ftrace_event_type_<call> = {
0331  *  .trace          = trace_raw_output_<call>, <-- stage 2
0332  * };
0333  *
0334  * static char print_fmt_<call>[] = <TP_printk>;
0335  *
0336  * static struct trace_event_class __used event_class_<template> = {
0337  *  .system         = "<system>",
0338  *  .fields_array       = trace_event_fields_<call>,
0339  *  .fields         = LIST_HEAD_INIT(event_class_##call.fields),
0340  *  .raw_init       = trace_event_raw_init,
0341  *  .probe          = trace_event_raw_event_##call,
0342  *  .reg            = trace_event_reg,
0343  * };
0344  *
0345  * static struct trace_event_call event_<call> = {
0346  *  .class          = event_class_<template>,
0347  *  {
0348  *      .tp         = &__tracepoint_<call>,
0349  *  },
0350  *  .event          = &ftrace_event_type_<call>,
0351  *  .print_fmt      = print_fmt_<call>,
0352  *  .flags          = TRACE_EVENT_FL_TRACEPOINT,
0353  * };
0354  * // its only safe to use pointers when doing linker tricks to
0355  * // create an array.
0356  * static struct trace_event_call __used
0357  * __section("_ftrace_events") *__event_<call> = &event_<call>;
0358  *
0359  */
0360 
0361 #ifdef CONFIG_PERF_EVENTS
0362 
0363 #define _TRACE_PERF_PROTO(call, proto)                  \
0364     static notrace void                     \
0365     perf_trace_##call(void *__data, proto);
0366 
0367 #define _TRACE_PERF_INIT(call)                      \
0368     .perf_probe     = perf_trace_##call,
0369 
0370 #else
0371 #define _TRACE_PERF_PROTO(call, proto)
0372 #define _TRACE_PERF_INIT(call)
0373 #endif /* CONFIG_PERF_EVENTS */
0374 
0375 #include "stages/stage6_event_callback.h"
0376 
0377 #undef DECLARE_EVENT_CLASS
0378 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)  \
0379                                     \
0380 static notrace void                         \
0381 trace_event_raw_event_##call(void *__data, proto)           \
0382 {                                   \
0383     struct trace_event_file *trace_file = __data;           \
0384     struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\
0385     struct trace_event_buffer fbuffer;              \
0386     struct trace_event_raw_##call *entry;               \
0387     int __data_size;                        \
0388                                     \
0389     if (trace_trigger_soft_disabled(trace_file))            \
0390         return;                         \
0391                                     \
0392     __data_size = trace_event_get_offsets_##call(&__data_offsets, args); \
0393                                     \
0394     entry = trace_event_buffer_reserve(&fbuffer, trace_file,    \
0395                  sizeof(*entry) + __data_size);     \
0396                                     \
0397     if (!entry)                         \
0398         return;                         \
0399                                     \
0400     tstruct                             \
0401                                     \
0402     { assign; }                         \
0403                                     \
0404     trace_event_buffer_commit(&fbuffer);                \
0405 }
0406 /*
0407  * The ftrace_test_probe is compiled out, it is only here as a build time check
0408  * to make sure that if the tracepoint handling changes, the ftrace probe will
0409  * fail to compile unless it too is updated.
0410  */
0411 
0412 #undef DEFINE_EVENT
0413 #define DEFINE_EVENT(template, call, proto, args)           \
0414 static inline void ftrace_test_probe_##call(void)           \
0415 {                                   \
0416     check_trace_callback_type_##call(trace_event_raw_event_##template); \
0417 }
0418 
0419 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
0420 
0421 #include "stages/stage7_class_define.h"
0422 
0423 #undef DECLARE_EVENT_CLASS
0424 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)  \
0425 _TRACE_PERF_PROTO(call, PARAMS(proto));                 \
0426 static char print_fmt_##call[] = print;                 \
0427 static struct trace_event_class __used __refdata event_class_##call = { \
0428     .system         = TRACE_SYSTEM_STRING,          \
0429     .fields_array       = trace_event_fields_##call,        \
0430     .fields         = LIST_HEAD_INIT(event_class_##call.fields),\
0431     .raw_init       = trace_event_raw_init,         \
0432     .probe          = trace_event_raw_event_##call,     \
0433     .reg            = trace_event_reg,          \
0434     _TRACE_PERF_INIT(call)                      \
0435 };
0436 
0437 #undef DEFINE_EVENT
0438 #define DEFINE_EVENT(template, call, proto, args)           \
0439                                     \
0440 static struct trace_event_call __used event_##call = {          \
0441     .class          = &event_class_##template,      \
0442     {                               \
0443         .tp         = &__tracepoint_##call,     \
0444     },                              \
0445     .event.funcs        = &trace_event_type_funcs_##template,   \
0446     .print_fmt      = print_fmt_##template,         \
0447     .flags          = TRACE_EVENT_FL_TRACEPOINT,        \
0448 };                                  \
0449 static struct trace_event_call __used                   \
0450 __section("_ftrace_events") *__event_##call = &event_##call
0451 
0452 #undef DEFINE_EVENT_PRINT
0453 #define DEFINE_EVENT_PRINT(template, call, proto, args, print)      \
0454                                     \
0455 static char print_fmt_##call[] = print;                 \
0456                                     \
0457 static struct trace_event_call __used event_##call = {          \
0458     .class          = &event_class_##template,      \
0459     {                               \
0460         .tp         = &__tracepoint_##call,     \
0461     },                              \
0462     .event.funcs        = &trace_event_type_funcs_##call,   \
0463     .print_fmt      = print_fmt_##call,         \
0464     .flags          = TRACE_EVENT_FL_TRACEPOINT,        \
0465 };                                  \
0466 static struct trace_event_call __used                   \
0467 __section("_ftrace_events") *__event_##call = &event_##call
0468 
0469 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)