12167ae72SSteven Rostedt (Red Hat) /* 22167ae72SSteven Rostedt (Red Hat) * Stage 1 of the trace events. 32167ae72SSteven Rostedt (Red Hat) * 42167ae72SSteven Rostedt (Red Hat) * Override the macros in <trace/trace_events.h> to include the following: 52167ae72SSteven Rostedt (Red Hat) * 62167ae72SSteven Rostedt (Red Hat) * struct ftrace_raw_<call> { 72167ae72SSteven Rostedt (Red Hat) * struct trace_entry ent; 82167ae72SSteven Rostedt (Red Hat) * <type> <item>; 92167ae72SSteven Rostedt (Red Hat) * <type2> <item2>[<len>]; 102167ae72SSteven Rostedt (Red Hat) * [...] 112167ae72SSteven Rostedt (Red Hat) * }; 122167ae72SSteven Rostedt (Red Hat) * 132167ae72SSteven Rostedt (Red Hat) * The <type> <item> is created by the __field(type, item) macro or 142167ae72SSteven Rostedt (Red Hat) * the __array(type2, item2, len) macro. 152167ae72SSteven Rostedt (Red Hat) * We simply do "type item;", and that will create the fields 162167ae72SSteven Rostedt (Red Hat) * in the structure. 172167ae72SSteven Rostedt (Red Hat) */ 182167ae72SSteven Rostedt (Red Hat) 192167ae72SSteven Rostedt (Red Hat) #include <linux/ftrace_event.h> 202167ae72SSteven Rostedt (Red Hat) 212167ae72SSteven Rostedt (Red Hat) #ifndef TRACE_SYSTEM_VAR 222167ae72SSteven Rostedt (Red Hat) #define TRACE_SYSTEM_VAR TRACE_SYSTEM 232167ae72SSteven Rostedt (Red Hat) #endif 242167ae72SSteven Rostedt (Red Hat) 252167ae72SSteven Rostedt (Red Hat) #define __app__(x, y) str__##x##y 262167ae72SSteven Rostedt (Red Hat) #define __app(x, y) __app__(x, y) 272167ae72SSteven Rostedt (Red Hat) 282167ae72SSteven Rostedt (Red Hat) #define TRACE_SYSTEM_STRING __app(TRACE_SYSTEM_VAR,__trace_system_name) 292167ae72SSteven Rostedt (Red Hat) 302167ae72SSteven Rostedt (Red Hat) #define TRACE_MAKE_SYSTEM_STR() \ 312167ae72SSteven Rostedt (Red Hat) static const char TRACE_SYSTEM_STRING[] = \ 322167ae72SSteven Rostedt (Red Hat) __stringify(TRACE_SYSTEM) 332167ae72SSteven Rostedt (Red Hat) 342167ae72SSteven Rostedt (Red Hat) TRACE_MAKE_SYSTEM_STR(); 352167ae72SSteven Rostedt (Red Hat) 362167ae72SSteven Rostedt (Red Hat) #undef TRACE_DEFINE_ENUM 372167ae72SSteven Rostedt (Red Hat) #define TRACE_DEFINE_ENUM(a) \ 382167ae72SSteven Rostedt (Red Hat) static struct trace_enum_map __used __initdata \ 392167ae72SSteven Rostedt (Red Hat) __##TRACE_SYSTEM##_##a = \ 402167ae72SSteven Rostedt (Red Hat) { \ 412167ae72SSteven Rostedt (Red Hat) .system = TRACE_SYSTEM_STRING, \ 422167ae72SSteven Rostedt (Red Hat) .enum_string = #a, \ 432167ae72SSteven Rostedt (Red Hat) .enum_value = a \ 442167ae72SSteven Rostedt (Red Hat) }; \ 452167ae72SSteven Rostedt (Red Hat) static struct trace_enum_map __used \ 462167ae72SSteven Rostedt (Red Hat) __attribute__((section("_ftrace_enum_map"))) \ 472167ae72SSteven Rostedt (Red Hat) *TRACE_SYSTEM##_##a = &__##TRACE_SYSTEM##_##a 482167ae72SSteven Rostedt (Red Hat) 492167ae72SSteven Rostedt (Red Hat) /* 502167ae72SSteven Rostedt (Red Hat) * DECLARE_EVENT_CLASS can be used to add a generic function 512167ae72SSteven Rostedt (Red Hat) * handlers for events. That is, if all events have the same 522167ae72SSteven Rostedt (Red Hat) * parameters and just have distinct trace points. 532167ae72SSteven Rostedt (Red Hat) * Each tracepoint can be defined with DEFINE_EVENT and that 542167ae72SSteven Rostedt (Red Hat) * will map the DECLARE_EVENT_CLASS to the tracepoint. 552167ae72SSteven Rostedt (Red Hat) * 562167ae72SSteven Rostedt (Red Hat) * TRACE_EVENT is a one to one mapping between tracepoint and template. 572167ae72SSteven Rostedt (Red Hat) */ 582167ae72SSteven Rostedt (Red Hat) #undef TRACE_EVENT 592167ae72SSteven Rostedt (Red Hat) #define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ 602167ae72SSteven Rostedt (Red Hat) DECLARE_EVENT_CLASS(name, \ 612167ae72SSteven Rostedt (Red Hat) PARAMS(proto), \ 622167ae72SSteven Rostedt (Red Hat) PARAMS(args), \ 632167ae72SSteven Rostedt (Red Hat) PARAMS(tstruct), \ 642167ae72SSteven Rostedt (Red Hat) PARAMS(assign), \ 652167ae72SSteven Rostedt (Red Hat) PARAMS(print)); \ 662167ae72SSteven Rostedt (Red Hat) DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)); 672167ae72SSteven Rostedt (Red Hat) 682167ae72SSteven Rostedt (Red Hat) 692167ae72SSteven Rostedt (Red Hat) #undef __field 702167ae72SSteven Rostedt (Red Hat) #define __field(type, item) type item; 712167ae72SSteven Rostedt (Red Hat) 722167ae72SSteven Rostedt (Red Hat) #undef __field_ext 732167ae72SSteven Rostedt (Red Hat) #define __field_ext(type, item, filter_type) type item; 742167ae72SSteven Rostedt (Red Hat) 752167ae72SSteven Rostedt (Red Hat) #undef __field_struct 762167ae72SSteven Rostedt (Red Hat) #define __field_struct(type, item) type item; 772167ae72SSteven Rostedt (Red Hat) 782167ae72SSteven Rostedt (Red Hat) #undef __field_struct_ext 792167ae72SSteven Rostedt (Red Hat) #define __field_struct_ext(type, item, filter_type) type item; 802167ae72SSteven Rostedt (Red Hat) 812167ae72SSteven Rostedt (Red Hat) #undef __array 822167ae72SSteven Rostedt (Red Hat) #define __array(type, item, len) type item[len]; 832167ae72SSteven Rostedt (Red Hat) 842167ae72SSteven Rostedt (Red Hat) #undef __dynamic_array 852167ae72SSteven Rostedt (Red Hat) #define __dynamic_array(type, item, len) u32 __data_loc_##item; 862167ae72SSteven Rostedt (Red Hat) 872167ae72SSteven Rostedt (Red Hat) #undef __string 882167ae72SSteven Rostedt (Red Hat) #define __string(item, src) __dynamic_array(char, item, -1) 892167ae72SSteven Rostedt (Red Hat) 902167ae72SSteven Rostedt (Red Hat) #undef __bitmask 912167ae72SSteven Rostedt (Red Hat) #define __bitmask(item, nr_bits) __dynamic_array(char, item, -1) 922167ae72SSteven Rostedt (Red Hat) 932167ae72SSteven Rostedt (Red Hat) #undef TP_STRUCT__entry 942167ae72SSteven Rostedt (Red Hat) #define TP_STRUCT__entry(args...) args 952167ae72SSteven Rostedt (Red Hat) 962167ae72SSteven Rostedt (Red Hat) #undef DECLARE_EVENT_CLASS 972167ae72SSteven Rostedt (Red Hat) #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) \ 982167ae72SSteven Rostedt (Red Hat) struct ftrace_raw_##name { \ 992167ae72SSteven Rostedt (Red Hat) struct trace_entry ent; \ 1002167ae72SSteven Rostedt (Red Hat) tstruct \ 1012167ae72SSteven Rostedt (Red Hat) char __data[0]; \ 1022167ae72SSteven Rostedt (Red Hat) }; \ 1032167ae72SSteven Rostedt (Red Hat) \ 1042167ae72SSteven Rostedt (Red Hat) static struct ftrace_event_class event_class_##name; 1052167ae72SSteven Rostedt (Red Hat) 1062167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT 1072167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT(template, name, proto, args) \ 1082167ae72SSteven Rostedt (Red Hat) static struct ftrace_event_call __used \ 1092167ae72SSteven Rostedt (Red Hat) __attribute__((__aligned__(4))) event_##name 1102167ae72SSteven Rostedt (Red Hat) 1112167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT_FN 1122167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg) \ 1132167ae72SSteven Rostedt (Red Hat) DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) 1142167ae72SSteven Rostedt (Red Hat) 1152167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT_PRINT 1162167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ 1172167ae72SSteven Rostedt (Red Hat) DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) 1182167ae72SSteven Rostedt (Red Hat) 1192167ae72SSteven Rostedt (Red Hat) /* Callbacks are meaningless to ftrace. */ 1202167ae72SSteven Rostedt (Red Hat) #undef TRACE_EVENT_FN 1212167ae72SSteven Rostedt (Red Hat) #define TRACE_EVENT_FN(name, proto, args, tstruct, \ 1222167ae72SSteven Rostedt (Red Hat) assign, print, reg, unreg) \ 1232167ae72SSteven Rostedt (Red Hat) TRACE_EVENT(name, PARAMS(proto), PARAMS(args), \ 1242167ae72SSteven Rostedt (Red Hat) PARAMS(tstruct), PARAMS(assign), PARAMS(print)) \ 1252167ae72SSteven Rostedt (Red Hat) 1262167ae72SSteven Rostedt (Red Hat) #undef TRACE_EVENT_FLAGS 1272167ae72SSteven Rostedt (Red Hat) #define TRACE_EVENT_FLAGS(name, value) \ 1282167ae72SSteven Rostedt (Red Hat) __TRACE_EVENT_FLAGS(name, value) 1292167ae72SSteven Rostedt (Red Hat) 1302167ae72SSteven Rostedt (Red Hat) #undef TRACE_EVENT_PERF_PERM 1312167ae72SSteven Rostedt (Red Hat) #define TRACE_EVENT_PERF_PERM(name, expr...) \ 1322167ae72SSteven Rostedt (Red Hat) __TRACE_EVENT_PERF_PERM(name, expr) 1332167ae72SSteven Rostedt (Red Hat) 1342167ae72SSteven Rostedt (Red Hat) #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 1352167ae72SSteven Rostedt (Red Hat) 1362167ae72SSteven Rostedt (Red Hat) /* 1372167ae72SSteven Rostedt (Red Hat) * Stage 2 of the trace events. 1382167ae72SSteven Rostedt (Red Hat) * 1392167ae72SSteven Rostedt (Red Hat) * Include the following: 1402167ae72SSteven Rostedt (Red Hat) * 1412167ae72SSteven Rostedt (Red Hat) * struct ftrace_data_offsets_<call> { 1422167ae72SSteven Rostedt (Red Hat) * u32 <item1>; 1432167ae72SSteven Rostedt (Red Hat) * u32 <item2>; 1442167ae72SSteven Rostedt (Red Hat) * [...] 1452167ae72SSteven Rostedt (Red Hat) * }; 1462167ae72SSteven Rostedt (Red Hat) * 1472167ae72SSteven Rostedt (Red Hat) * The __dynamic_array() macro will create each u32 <item>, this is 1482167ae72SSteven Rostedt (Red Hat) * to keep the offset of each array from the beginning of the event. 1492167ae72SSteven Rostedt (Red Hat) * The size of an array is also encoded, in the higher 16 bits of <item>. 1502167ae72SSteven Rostedt (Red Hat) */ 1512167ae72SSteven Rostedt (Red Hat) 1522167ae72SSteven Rostedt (Red Hat) #undef TRACE_DEFINE_ENUM 1532167ae72SSteven Rostedt (Red Hat) #define TRACE_DEFINE_ENUM(a) 1542167ae72SSteven Rostedt (Red Hat) 1552167ae72SSteven Rostedt (Red Hat) #undef __field 1562167ae72SSteven Rostedt (Red Hat) #define __field(type, item) 1572167ae72SSteven Rostedt (Red Hat) 1582167ae72SSteven Rostedt (Red Hat) #undef __field_ext 1592167ae72SSteven Rostedt (Red Hat) #define __field_ext(type, item, filter_type) 1602167ae72SSteven Rostedt (Red Hat) 1612167ae72SSteven Rostedt (Red Hat) #undef __field_struct 1622167ae72SSteven Rostedt (Red Hat) #define __field_struct(type, item) 1632167ae72SSteven Rostedt (Red Hat) 1642167ae72SSteven Rostedt (Red Hat) #undef __field_struct_ext 1652167ae72SSteven Rostedt (Red Hat) #define __field_struct_ext(type, item, filter_type) 1662167ae72SSteven Rostedt (Red Hat) 1672167ae72SSteven Rostedt (Red Hat) #undef __array 1682167ae72SSteven Rostedt (Red Hat) #define __array(type, item, len) 1692167ae72SSteven Rostedt (Red Hat) 1702167ae72SSteven Rostedt (Red Hat) #undef __dynamic_array 1712167ae72SSteven Rostedt (Red Hat) #define __dynamic_array(type, item, len) u32 item; 1722167ae72SSteven Rostedt (Red Hat) 1732167ae72SSteven Rostedt (Red Hat) #undef __string 1742167ae72SSteven Rostedt (Red Hat) #define __string(item, src) __dynamic_array(char, item, -1) 1752167ae72SSteven Rostedt (Red Hat) 1762167ae72SSteven Rostedt (Red Hat) #undef __bitmask 1772167ae72SSteven Rostedt (Red Hat) #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) 1782167ae72SSteven Rostedt (Red Hat) 1792167ae72SSteven Rostedt (Red Hat) #undef DECLARE_EVENT_CLASS 1802167ae72SSteven Rostedt (Red Hat) #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 1812167ae72SSteven Rostedt (Red Hat) struct ftrace_data_offsets_##call { \ 1822167ae72SSteven Rostedt (Red Hat) tstruct; \ 1832167ae72SSteven Rostedt (Red Hat) }; 1842167ae72SSteven Rostedt (Red Hat) 1852167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT 1862167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT(template, name, proto, args) 1872167ae72SSteven Rostedt (Red Hat) 1882167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT_PRINT 1892167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ 1902167ae72SSteven Rostedt (Red Hat) DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) 1912167ae72SSteven Rostedt (Red Hat) 1922167ae72SSteven Rostedt (Red Hat) #undef TRACE_EVENT_FLAGS 1932167ae72SSteven Rostedt (Red Hat) #define TRACE_EVENT_FLAGS(event, flag) 1942167ae72SSteven Rostedt (Red Hat) 1952167ae72SSteven Rostedt (Red Hat) #undef TRACE_EVENT_PERF_PERM 1962167ae72SSteven Rostedt (Red Hat) #define TRACE_EVENT_PERF_PERM(event, expr...) 1972167ae72SSteven Rostedt (Red Hat) 1982167ae72SSteven Rostedt (Red Hat) #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 1992167ae72SSteven Rostedt (Red Hat) 2002167ae72SSteven Rostedt (Red Hat) /* 2012167ae72SSteven Rostedt (Red Hat) * Stage 3 of the trace events. 2022167ae72SSteven Rostedt (Red Hat) * 2032167ae72SSteven Rostedt (Red Hat) * Override the macros in <trace/trace_events.h> to include the following: 2042167ae72SSteven Rostedt (Red Hat) * 2052167ae72SSteven Rostedt (Red Hat) * enum print_line_t 2062167ae72SSteven Rostedt (Red Hat) * ftrace_raw_output_<call>(struct trace_iterator *iter, int flags) 2072167ae72SSteven Rostedt (Red Hat) * { 2082167ae72SSteven Rostedt (Red Hat) * struct trace_seq *s = &iter->seq; 2092167ae72SSteven Rostedt (Red Hat) * struct ftrace_raw_<call> *field; <-- defined in stage 1 2102167ae72SSteven Rostedt (Red Hat) * struct trace_entry *entry; 2112167ae72SSteven Rostedt (Red Hat) * struct trace_seq *p = &iter->tmp_seq; 2122167ae72SSteven Rostedt (Red Hat) * int ret; 2132167ae72SSteven Rostedt (Red Hat) * 2142167ae72SSteven Rostedt (Red Hat) * entry = iter->ent; 2152167ae72SSteven Rostedt (Red Hat) * 2162167ae72SSteven Rostedt (Red Hat) * if (entry->type != event_<call>->event.type) { 2172167ae72SSteven Rostedt (Red Hat) * WARN_ON_ONCE(1); 2182167ae72SSteven Rostedt (Red Hat) * return TRACE_TYPE_UNHANDLED; 2192167ae72SSteven Rostedt (Red Hat) * } 2202167ae72SSteven Rostedt (Red Hat) * 2212167ae72SSteven Rostedt (Red Hat) * field = (typeof(field))entry; 2222167ae72SSteven Rostedt (Red Hat) * 2232167ae72SSteven Rostedt (Red Hat) * trace_seq_init(p); 2242167ae72SSteven Rostedt (Red Hat) * ret = trace_seq_printf(s, "%s: ", <call>); 2252167ae72SSteven Rostedt (Red Hat) * if (ret) 2262167ae72SSteven Rostedt (Red Hat) * ret = trace_seq_printf(s, <TP_printk> "\n"); 2272167ae72SSteven Rostedt (Red Hat) * if (!ret) 2282167ae72SSteven Rostedt (Red Hat) * return TRACE_TYPE_PARTIAL_LINE; 2292167ae72SSteven Rostedt (Red Hat) * 2302167ae72SSteven Rostedt (Red Hat) * return TRACE_TYPE_HANDLED; 2312167ae72SSteven Rostedt (Red Hat) * } 2322167ae72SSteven Rostedt (Red Hat) * 2332167ae72SSteven Rostedt (Red Hat) * This is the method used to print the raw event to the trace 2342167ae72SSteven Rostedt (Red Hat) * output format. Note, this is not needed if the data is read 2352167ae72SSteven Rostedt (Red Hat) * in binary. 2362167ae72SSteven Rostedt (Red Hat) */ 2372167ae72SSteven Rostedt (Red Hat) 2382167ae72SSteven Rostedt (Red Hat) #undef __entry 2392167ae72SSteven Rostedt (Red Hat) #define __entry field 2402167ae72SSteven Rostedt (Red Hat) 2412167ae72SSteven Rostedt (Red Hat) #undef TP_printk 2422167ae72SSteven Rostedt (Red Hat) #define TP_printk(fmt, args...) fmt "\n", args 2432167ae72SSteven Rostedt (Red Hat) 2442167ae72SSteven Rostedt (Red Hat) #undef __get_dynamic_array 2452167ae72SSteven Rostedt (Red Hat) #define __get_dynamic_array(field) \ 2462167ae72SSteven Rostedt (Red Hat) ((void *)__entry + (__entry->__data_loc_##field & 0xffff)) 2472167ae72SSteven Rostedt (Red Hat) 2482167ae72SSteven Rostedt (Red Hat) #undef __get_dynamic_array_len 2492167ae72SSteven Rostedt (Red Hat) #define __get_dynamic_array_len(field) \ 2502167ae72SSteven Rostedt (Red Hat) ((__entry->__data_loc_##field >> 16) & 0xffff) 2512167ae72SSteven Rostedt (Red Hat) 2522167ae72SSteven Rostedt (Red Hat) #undef __get_str 2532167ae72SSteven Rostedt (Red Hat) #define __get_str(field) (char *)__get_dynamic_array(field) 2542167ae72SSteven Rostedt (Red Hat) 2552167ae72SSteven Rostedt (Red Hat) #undef __get_bitmask 2562167ae72SSteven Rostedt (Red Hat) #define __get_bitmask(field) \ 2572167ae72SSteven Rostedt (Red Hat) ({ \ 2582167ae72SSteven Rostedt (Red Hat) void *__bitmask = __get_dynamic_array(field); \ 2592167ae72SSteven Rostedt (Red Hat) unsigned int __bitmask_size; \ 2602167ae72SSteven Rostedt (Red Hat) __bitmask_size = __get_dynamic_array_len(field); \ 2612167ae72SSteven Rostedt (Red Hat) ftrace_print_bitmask_seq(p, __bitmask, __bitmask_size); \ 2622167ae72SSteven Rostedt (Red Hat) }) 2632167ae72SSteven Rostedt (Red Hat) 2642167ae72SSteven Rostedt (Red Hat) #undef __print_flags 2652167ae72SSteven Rostedt (Red Hat) #define __print_flags(flag, delim, flag_array...) \ 2662167ae72SSteven Rostedt (Red Hat) ({ \ 2672167ae72SSteven Rostedt (Red Hat) static const struct trace_print_flags __flags[] = \ 2682167ae72SSteven Rostedt (Red Hat) { flag_array, { -1, NULL }}; \ 2692167ae72SSteven Rostedt (Red Hat) ftrace_print_flags_seq(p, delim, flag, __flags); \ 2702167ae72SSteven Rostedt (Red Hat) }) 2712167ae72SSteven Rostedt (Red Hat) 2722167ae72SSteven Rostedt (Red Hat) #undef __print_symbolic 2732167ae72SSteven Rostedt (Red Hat) #define __print_symbolic(value, symbol_array...) \ 2742167ae72SSteven Rostedt (Red Hat) ({ \ 2752167ae72SSteven Rostedt (Red Hat) static const struct trace_print_flags symbols[] = \ 2762167ae72SSteven Rostedt (Red Hat) { symbol_array, { -1, NULL }}; \ 2772167ae72SSteven Rostedt (Red Hat) ftrace_print_symbols_seq(p, value, symbols); \ 2782167ae72SSteven Rostedt (Red Hat) }) 2792167ae72SSteven Rostedt (Red Hat) 2802167ae72SSteven Rostedt (Red Hat) #undef __print_symbolic_u64 2812167ae72SSteven Rostedt (Red Hat) #if BITS_PER_LONG == 32 2822167ae72SSteven Rostedt (Red Hat) #define __print_symbolic_u64(value, symbol_array...) \ 2832167ae72SSteven Rostedt (Red Hat) ({ \ 2842167ae72SSteven Rostedt (Red Hat) static const struct trace_print_flags_u64 symbols[] = \ 2852167ae72SSteven Rostedt (Red Hat) { symbol_array, { -1, NULL } }; \ 2862167ae72SSteven Rostedt (Red Hat) ftrace_print_symbols_seq_u64(p, value, symbols); \ 2872167ae72SSteven Rostedt (Red Hat) }) 2882167ae72SSteven Rostedt (Red Hat) #else 2892167ae72SSteven Rostedt (Red Hat) #define __print_symbolic_u64(value, symbol_array...) \ 2902167ae72SSteven Rostedt (Red Hat) __print_symbolic(value, symbol_array) 2912167ae72SSteven Rostedt (Red Hat) #endif 2922167ae72SSteven Rostedt (Red Hat) 2932167ae72SSteven Rostedt (Red Hat) #undef __print_hex 2942167ae72SSteven Rostedt (Red Hat) #define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len) 2952167ae72SSteven Rostedt (Red Hat) 2962167ae72SSteven Rostedt (Red Hat) #undef __print_array 2972167ae72SSteven Rostedt (Red Hat) #define __print_array(array, count, el_size) \ 2982167ae72SSteven Rostedt (Red Hat) ({ \ 2992167ae72SSteven Rostedt (Red Hat) BUILD_BUG_ON(el_size != 1 && el_size != 2 && \ 3002167ae72SSteven Rostedt (Red Hat) el_size != 4 && el_size != 8); \ 3012167ae72SSteven Rostedt (Red Hat) ftrace_print_array_seq(p, array, count, el_size); \ 3022167ae72SSteven Rostedt (Red Hat) }) 3032167ae72SSteven Rostedt (Red Hat) 3042167ae72SSteven Rostedt (Red Hat) #undef DECLARE_EVENT_CLASS 3052167ae72SSteven Rostedt (Red Hat) #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 3062167ae72SSteven Rostedt (Red Hat) static notrace enum print_line_t \ 3072167ae72SSteven Rostedt (Red Hat) ftrace_raw_output_##call(struct trace_iterator *iter, int flags, \ 3082167ae72SSteven Rostedt (Red Hat) struct trace_event *trace_event) \ 3092167ae72SSteven Rostedt (Red Hat) { \ 3102167ae72SSteven Rostedt (Red Hat) struct trace_seq *s = &iter->seq; \ 3112167ae72SSteven Rostedt (Red Hat) struct trace_seq __maybe_unused *p = &iter->tmp_seq; \ 3122167ae72SSteven Rostedt (Red Hat) struct ftrace_raw_##call *field; \ 3132167ae72SSteven Rostedt (Red Hat) int ret; \ 3142167ae72SSteven Rostedt (Red Hat) \ 3152167ae72SSteven Rostedt (Red Hat) field = (typeof(field))iter->ent; \ 3162167ae72SSteven Rostedt (Red Hat) \ 3172167ae72SSteven Rostedt (Red Hat) ret = ftrace_raw_output_prep(iter, trace_event); \ 3182167ae72SSteven Rostedt (Red Hat) if (ret != TRACE_TYPE_HANDLED) \ 3192167ae72SSteven Rostedt (Red Hat) return ret; \ 3202167ae72SSteven Rostedt (Red Hat) \ 3212167ae72SSteven Rostedt (Red Hat) trace_seq_printf(s, print); \ 3222167ae72SSteven Rostedt (Red Hat) \ 3232167ae72SSteven Rostedt (Red Hat) return trace_handle_return(s); \ 3242167ae72SSteven Rostedt (Red Hat) } \ 3252167ae72SSteven Rostedt (Red Hat) static struct trace_event_functions ftrace_event_type_funcs_##call = { \ 3262167ae72SSteven Rostedt (Red Hat) .trace = ftrace_raw_output_##call, \ 3272167ae72SSteven Rostedt (Red Hat) }; 3282167ae72SSteven Rostedt (Red Hat) 3292167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT_PRINT 3302167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ 3312167ae72SSteven Rostedt (Red Hat) static notrace enum print_line_t \ 3322167ae72SSteven Rostedt (Red Hat) ftrace_raw_output_##call(struct trace_iterator *iter, int flags, \ 3332167ae72SSteven Rostedt (Red Hat) struct trace_event *event) \ 3342167ae72SSteven Rostedt (Red Hat) { \ 3352167ae72SSteven Rostedt (Red Hat) struct ftrace_raw_##template *field; \ 3362167ae72SSteven Rostedt (Red Hat) struct trace_entry *entry; \ 3372167ae72SSteven Rostedt (Red Hat) struct trace_seq *p = &iter->tmp_seq; \ 3382167ae72SSteven Rostedt (Red Hat) \ 3392167ae72SSteven Rostedt (Red Hat) entry = iter->ent; \ 3402167ae72SSteven Rostedt (Red Hat) \ 3412167ae72SSteven Rostedt (Red Hat) if (entry->type != event_##call.event.type) { \ 3422167ae72SSteven Rostedt (Red Hat) WARN_ON_ONCE(1); \ 3432167ae72SSteven Rostedt (Red Hat) return TRACE_TYPE_UNHANDLED; \ 3442167ae72SSteven Rostedt (Red Hat) } \ 3452167ae72SSteven Rostedt (Red Hat) \ 3462167ae72SSteven Rostedt (Red Hat) field = (typeof(field))entry; \ 3472167ae72SSteven Rostedt (Red Hat) \ 3482167ae72SSteven Rostedt (Red Hat) trace_seq_init(p); \ 3492167ae72SSteven Rostedt (Red Hat) return ftrace_output_call(iter, #call, print); \ 3502167ae72SSteven Rostedt (Red Hat) } \ 3512167ae72SSteven Rostedt (Red Hat) static struct trace_event_functions ftrace_event_type_funcs_##call = { \ 3522167ae72SSteven Rostedt (Red Hat) .trace = ftrace_raw_output_##call, \ 3532167ae72SSteven Rostedt (Red Hat) }; 3542167ae72SSteven Rostedt (Red Hat) 3552167ae72SSteven Rostedt (Red Hat) #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 3562167ae72SSteven Rostedt (Red Hat) 3572167ae72SSteven Rostedt (Red Hat) #undef __field_ext 3582167ae72SSteven Rostedt (Red Hat) #define __field_ext(type, item, filter_type) \ 3592167ae72SSteven Rostedt (Red Hat) ret = trace_define_field(event_call, #type, #item, \ 3602167ae72SSteven Rostedt (Red Hat) offsetof(typeof(field), item), \ 3612167ae72SSteven Rostedt (Red Hat) sizeof(field.item), \ 3622167ae72SSteven Rostedt (Red Hat) is_signed_type(type), filter_type); \ 3632167ae72SSteven Rostedt (Red Hat) if (ret) \ 3642167ae72SSteven Rostedt (Red Hat) return ret; 3652167ae72SSteven Rostedt (Red Hat) 3662167ae72SSteven Rostedt (Red Hat) #undef __field_struct_ext 3672167ae72SSteven Rostedt (Red Hat) #define __field_struct_ext(type, item, filter_type) \ 3682167ae72SSteven Rostedt (Red Hat) ret = trace_define_field(event_call, #type, #item, \ 3692167ae72SSteven Rostedt (Red Hat) offsetof(typeof(field), item), \ 3702167ae72SSteven Rostedt (Red Hat) sizeof(field.item), \ 3712167ae72SSteven Rostedt (Red Hat) 0, filter_type); \ 3722167ae72SSteven Rostedt (Red Hat) if (ret) \ 3732167ae72SSteven Rostedt (Red Hat) return ret; 3742167ae72SSteven Rostedt (Red Hat) 3752167ae72SSteven Rostedt (Red Hat) #undef __field 3762167ae72SSteven Rostedt (Red Hat) #define __field(type, item) __field_ext(type, item, FILTER_OTHER) 3772167ae72SSteven Rostedt (Red Hat) 3782167ae72SSteven Rostedt (Red Hat) #undef __field_struct 3792167ae72SSteven Rostedt (Red Hat) #define __field_struct(type, item) __field_struct_ext(type, item, FILTER_OTHER) 3802167ae72SSteven Rostedt (Red Hat) 3812167ae72SSteven Rostedt (Red Hat) #undef __array 3822167ae72SSteven Rostedt (Red Hat) #define __array(type, item, len) \ 3832167ae72SSteven Rostedt (Red Hat) do { \ 3842167ae72SSteven Rostedt (Red Hat) char *type_str = #type"["__stringify(len)"]"; \ 3852167ae72SSteven Rostedt (Red Hat) BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ 3862167ae72SSteven Rostedt (Red Hat) ret = trace_define_field(event_call, type_str, #item, \ 3872167ae72SSteven Rostedt (Red Hat) offsetof(typeof(field), item), \ 3882167ae72SSteven Rostedt (Red Hat) sizeof(field.item), \ 3892167ae72SSteven Rostedt (Red Hat) is_signed_type(type), FILTER_OTHER); \ 3902167ae72SSteven Rostedt (Red Hat) if (ret) \ 3912167ae72SSteven Rostedt (Red Hat) return ret; \ 3922167ae72SSteven Rostedt (Red Hat) } while (0); 3932167ae72SSteven Rostedt (Red Hat) 3942167ae72SSteven Rostedt (Red Hat) #undef __dynamic_array 3952167ae72SSteven Rostedt (Red Hat) #define __dynamic_array(type, item, len) \ 3962167ae72SSteven Rostedt (Red Hat) ret = trace_define_field(event_call, "__data_loc " #type "[]", #item, \ 3972167ae72SSteven Rostedt (Red Hat) offsetof(typeof(field), __data_loc_##item), \ 3982167ae72SSteven Rostedt (Red Hat) sizeof(field.__data_loc_##item), \ 3992167ae72SSteven Rostedt (Red Hat) is_signed_type(type), FILTER_OTHER); 4002167ae72SSteven Rostedt (Red Hat) 4012167ae72SSteven Rostedt (Red Hat) #undef __string 4022167ae72SSteven Rostedt (Red Hat) #define __string(item, src) __dynamic_array(char, item, -1) 4032167ae72SSteven Rostedt (Red Hat) 4042167ae72SSteven Rostedt (Red Hat) #undef __bitmask 4052167ae72SSteven Rostedt (Red Hat) #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) 4062167ae72SSteven Rostedt (Red Hat) 4072167ae72SSteven Rostedt (Red Hat) #undef DECLARE_EVENT_CLASS 4082167ae72SSteven Rostedt (Red Hat) #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print) \ 4092167ae72SSteven Rostedt (Red Hat) static int notrace __init \ 4102167ae72SSteven Rostedt (Red Hat) ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ 4112167ae72SSteven Rostedt (Red Hat) { \ 4122167ae72SSteven Rostedt (Red Hat) struct ftrace_raw_##call field; \ 4132167ae72SSteven Rostedt (Red Hat) int ret; \ 4142167ae72SSteven Rostedt (Red Hat) \ 4152167ae72SSteven Rostedt (Red Hat) tstruct; \ 4162167ae72SSteven Rostedt (Red Hat) \ 4172167ae72SSteven Rostedt (Red Hat) return ret; \ 4182167ae72SSteven Rostedt (Red Hat) } 4192167ae72SSteven Rostedt (Red Hat) 4202167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT 4212167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT(template, name, proto, args) 4222167ae72SSteven Rostedt (Red Hat) 4232167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT_PRINT 4242167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ 4252167ae72SSteven Rostedt (Red Hat) DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) 4262167ae72SSteven Rostedt (Red Hat) 4272167ae72SSteven Rostedt (Red Hat) #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 4282167ae72SSteven Rostedt (Red Hat) 4292167ae72SSteven Rostedt (Red Hat) /* 4302167ae72SSteven Rostedt (Red Hat) * remember the offset of each array from the beginning of the event. 4312167ae72SSteven Rostedt (Red Hat) */ 4322167ae72SSteven Rostedt (Red Hat) 4332167ae72SSteven Rostedt (Red Hat) #undef __entry 4342167ae72SSteven Rostedt (Red Hat) #define __entry entry 4352167ae72SSteven Rostedt (Red Hat) 4362167ae72SSteven Rostedt (Red Hat) #undef __field 4372167ae72SSteven Rostedt (Red Hat) #define __field(type, item) 4382167ae72SSteven Rostedt (Red Hat) 4392167ae72SSteven Rostedt (Red Hat) #undef __field_ext 4402167ae72SSteven Rostedt (Red Hat) #define __field_ext(type, item, filter_type) 4412167ae72SSteven Rostedt (Red Hat) 4422167ae72SSteven Rostedt (Red Hat) #undef __field_struct 4432167ae72SSteven Rostedt (Red Hat) #define __field_struct(type, item) 4442167ae72SSteven Rostedt (Red Hat) 4452167ae72SSteven Rostedt (Red Hat) #undef __field_struct_ext 4462167ae72SSteven Rostedt (Red Hat) #define __field_struct_ext(type, item, filter_type) 4472167ae72SSteven Rostedt (Red Hat) 4482167ae72SSteven Rostedt (Red Hat) #undef __array 4492167ae72SSteven Rostedt (Red Hat) #define __array(type, item, len) 4502167ae72SSteven Rostedt (Red Hat) 4512167ae72SSteven Rostedt (Red Hat) #undef __dynamic_array 4522167ae72SSteven Rostedt (Red Hat) #define __dynamic_array(type, item, len) \ 4532167ae72SSteven Rostedt (Red Hat) __item_length = (len) * sizeof(type); \ 4542167ae72SSteven Rostedt (Red Hat) __data_offsets->item = __data_size + \ 4552167ae72SSteven Rostedt (Red Hat) offsetof(typeof(*entry), __data); \ 4562167ae72SSteven Rostedt (Red Hat) __data_offsets->item |= __item_length << 16; \ 4572167ae72SSteven Rostedt (Red Hat) __data_size += __item_length; 4582167ae72SSteven Rostedt (Red Hat) 4592167ae72SSteven Rostedt (Red Hat) #undef __string 4602167ae72SSteven Rostedt (Red Hat) #define __string(item, src) __dynamic_array(char, item, \ 4612167ae72SSteven Rostedt (Red Hat) strlen((src) ? (const char *)(src) : "(null)") + 1) 4622167ae72SSteven Rostedt (Red Hat) 4632167ae72SSteven Rostedt (Red Hat) /* 4642167ae72SSteven Rostedt (Red Hat) * __bitmask_size_in_bytes_raw is the number of bytes needed to hold 4652167ae72SSteven Rostedt (Red Hat) * num_possible_cpus(). 4662167ae72SSteven Rostedt (Red Hat) */ 4672167ae72SSteven Rostedt (Red Hat) #define __bitmask_size_in_bytes_raw(nr_bits) \ 4682167ae72SSteven Rostedt (Red Hat) (((nr_bits) + 7) / 8) 4692167ae72SSteven Rostedt (Red Hat) 4702167ae72SSteven Rostedt (Red Hat) #define __bitmask_size_in_longs(nr_bits) \ 4712167ae72SSteven Rostedt (Red Hat) ((__bitmask_size_in_bytes_raw(nr_bits) + \ 4722167ae72SSteven Rostedt (Red Hat) ((BITS_PER_LONG / 8) - 1)) / (BITS_PER_LONG / 8)) 4732167ae72SSteven Rostedt (Red Hat) 4742167ae72SSteven Rostedt (Red Hat) /* 4752167ae72SSteven Rostedt (Red Hat) * __bitmask_size_in_bytes is the number of bytes needed to hold 4762167ae72SSteven Rostedt (Red Hat) * num_possible_cpus() padded out to the nearest long. This is what 4772167ae72SSteven Rostedt (Red Hat) * is saved in the buffer, just to be consistent. 4782167ae72SSteven Rostedt (Red Hat) */ 4792167ae72SSteven Rostedt (Red Hat) #define __bitmask_size_in_bytes(nr_bits) \ 4802167ae72SSteven Rostedt (Red Hat) (__bitmask_size_in_longs(nr_bits) * (BITS_PER_LONG / 8)) 4812167ae72SSteven Rostedt (Red Hat) 4822167ae72SSteven Rostedt (Red Hat) #undef __bitmask 4832167ae72SSteven Rostedt (Red Hat) #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, \ 4842167ae72SSteven Rostedt (Red Hat) __bitmask_size_in_longs(nr_bits)) 4852167ae72SSteven Rostedt (Red Hat) 4862167ae72SSteven Rostedt (Red Hat) #undef DECLARE_EVENT_CLASS 4872167ae72SSteven Rostedt (Red Hat) #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 4882167ae72SSteven Rostedt (Red Hat) static inline notrace int ftrace_get_offsets_##call( \ 4892167ae72SSteven Rostedt (Red Hat) struct ftrace_data_offsets_##call *__data_offsets, proto) \ 4902167ae72SSteven Rostedt (Red Hat) { \ 4912167ae72SSteven Rostedt (Red Hat) int __data_size = 0; \ 4922167ae72SSteven Rostedt (Red Hat) int __maybe_unused __item_length; \ 4932167ae72SSteven Rostedt (Red Hat) struct ftrace_raw_##call __maybe_unused *entry; \ 4942167ae72SSteven Rostedt (Red Hat) \ 4952167ae72SSteven Rostedt (Red Hat) tstruct; \ 4962167ae72SSteven Rostedt (Red Hat) \ 4972167ae72SSteven Rostedt (Red Hat) return __data_size; \ 4982167ae72SSteven Rostedt (Red Hat) } 4992167ae72SSteven Rostedt (Red Hat) 5002167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT 5012167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT(template, name, proto, args) 5022167ae72SSteven Rostedt (Red Hat) 5032167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT_PRINT 5042167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ 5052167ae72SSteven Rostedt (Red Hat) DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) 5062167ae72SSteven Rostedt (Red Hat) 5072167ae72SSteven Rostedt (Red Hat) #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 5082167ae72SSteven Rostedt (Red Hat) 5092167ae72SSteven Rostedt (Red Hat) /* 5102167ae72SSteven Rostedt (Red Hat) * Stage 4 of the trace events. 5112167ae72SSteven Rostedt (Red Hat) * 5122167ae72SSteven Rostedt (Red Hat) * Override the macros in <trace/trace_events.h> to include the following: 5132167ae72SSteven Rostedt (Red Hat) * 5142167ae72SSteven Rostedt (Red Hat) * For those macros defined with TRACE_EVENT: 5152167ae72SSteven Rostedt (Red Hat) * 5162167ae72SSteven Rostedt (Red Hat) * static struct ftrace_event_call event_<call>; 5172167ae72SSteven Rostedt (Red Hat) * 5182167ae72SSteven Rostedt (Red Hat) * static void ftrace_raw_event_<call>(void *__data, proto) 5192167ae72SSteven Rostedt (Red Hat) * { 5202167ae72SSteven Rostedt (Red Hat) * struct ftrace_event_file *ftrace_file = __data; 5212167ae72SSteven Rostedt (Red Hat) * struct ftrace_event_call *event_call = ftrace_file->event_call; 5222167ae72SSteven Rostedt (Red Hat) * struct ftrace_data_offsets_<call> __maybe_unused __data_offsets; 5232167ae72SSteven Rostedt (Red Hat) * unsigned long eflags = ftrace_file->flags; 5242167ae72SSteven Rostedt (Red Hat) * enum event_trigger_type __tt = ETT_NONE; 5252167ae72SSteven Rostedt (Red Hat) * struct ring_buffer_event *event; 5262167ae72SSteven Rostedt (Red Hat) * struct ftrace_raw_<call> *entry; <-- defined in stage 1 5272167ae72SSteven Rostedt (Red Hat) * struct ring_buffer *buffer; 5282167ae72SSteven Rostedt (Red Hat) * unsigned long irq_flags; 5292167ae72SSteven Rostedt (Red Hat) * int __data_size; 5302167ae72SSteven Rostedt (Red Hat) * int pc; 5312167ae72SSteven Rostedt (Red Hat) * 5322167ae72SSteven Rostedt (Red Hat) * if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) { 5332167ae72SSteven Rostedt (Red Hat) * if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE) 5342167ae72SSteven Rostedt (Red Hat) * event_triggers_call(ftrace_file, NULL); 5352167ae72SSteven Rostedt (Red Hat) * if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED) 5362167ae72SSteven Rostedt (Red Hat) * return; 5372167ae72SSteven Rostedt (Red Hat) * } 5382167ae72SSteven Rostedt (Red Hat) * 5392167ae72SSteven Rostedt (Red Hat) * local_save_flags(irq_flags); 5402167ae72SSteven Rostedt (Red Hat) * pc = preempt_count(); 5412167ae72SSteven Rostedt (Red Hat) * 5422167ae72SSteven Rostedt (Red Hat) * __data_size = ftrace_get_offsets_<call>(&__data_offsets, args); 5432167ae72SSteven Rostedt (Red Hat) * 5442167ae72SSteven Rostedt (Red Hat) * event = trace_event_buffer_lock_reserve(&buffer, ftrace_file, 5452167ae72SSteven Rostedt (Red Hat) * event_<call>->event.type, 5462167ae72SSteven Rostedt (Red Hat) * sizeof(*entry) + __data_size, 5472167ae72SSteven Rostedt (Red Hat) * irq_flags, pc); 5482167ae72SSteven Rostedt (Red Hat) * if (!event) 5492167ae72SSteven Rostedt (Red Hat) * return; 5502167ae72SSteven Rostedt (Red Hat) * entry = ring_buffer_event_data(event); 5512167ae72SSteven Rostedt (Red Hat) * 5522167ae72SSteven Rostedt (Red Hat) * { <assign>; } <-- Here we assign the entries by the __field and 5532167ae72SSteven Rostedt (Red Hat) * __array macros. 5542167ae72SSteven Rostedt (Red Hat) * 5552167ae72SSteven Rostedt (Red Hat) * if (eflags & FTRACE_EVENT_FL_TRIGGER_COND) 5562167ae72SSteven Rostedt (Red Hat) * __tt = event_triggers_call(ftrace_file, entry); 5572167ae72SSteven Rostedt (Red Hat) * 5582167ae72SSteven Rostedt (Red Hat) * if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, 5592167ae72SSteven Rostedt (Red Hat) * &ftrace_file->flags)) 5602167ae72SSteven Rostedt (Red Hat) * ring_buffer_discard_commit(buffer, event); 5612167ae72SSteven Rostedt (Red Hat) * else if (!filter_check_discard(ftrace_file, entry, buffer, event)) 5622167ae72SSteven Rostedt (Red Hat) * trace_buffer_unlock_commit(buffer, event, irq_flags, pc); 5632167ae72SSteven Rostedt (Red Hat) * 5642167ae72SSteven Rostedt (Red Hat) * if (__tt) 5652167ae72SSteven Rostedt (Red Hat) * event_triggers_post_call(ftrace_file, __tt); 5662167ae72SSteven Rostedt (Red Hat) * } 5672167ae72SSteven Rostedt (Red Hat) * 5682167ae72SSteven Rostedt (Red Hat) * static struct trace_event ftrace_event_type_<call> = { 5692167ae72SSteven Rostedt (Red Hat) * .trace = ftrace_raw_output_<call>, <-- stage 2 5702167ae72SSteven Rostedt (Red Hat) * }; 5712167ae72SSteven Rostedt (Red Hat) * 5722167ae72SSteven Rostedt (Red Hat) * static char print_fmt_<call>[] = <TP_printk>; 5732167ae72SSteven Rostedt (Red Hat) * 5742167ae72SSteven Rostedt (Red Hat) * static struct ftrace_event_class __used event_class_<template> = { 5752167ae72SSteven Rostedt (Red Hat) * .system = "<system>", 5762167ae72SSteven Rostedt (Red Hat) * .define_fields = ftrace_define_fields_<call>, 5772167ae72SSteven Rostedt (Red Hat) * .fields = LIST_HEAD_INIT(event_class_##call.fields), 5782167ae72SSteven Rostedt (Red Hat) * .raw_init = trace_event_raw_init, 5792167ae72SSteven Rostedt (Red Hat) * .probe = ftrace_raw_event_##call, 5802167ae72SSteven Rostedt (Red Hat) * .reg = ftrace_event_reg, 5812167ae72SSteven Rostedt (Red Hat) * }; 5822167ae72SSteven Rostedt (Red Hat) * 5832167ae72SSteven Rostedt (Red Hat) * static struct ftrace_event_call event_<call> = { 5842167ae72SSteven Rostedt (Red Hat) * .class = event_class_<template>, 5852167ae72SSteven Rostedt (Red Hat) * { 5862167ae72SSteven Rostedt (Red Hat) * .tp = &__tracepoint_<call>, 5872167ae72SSteven Rostedt (Red Hat) * }, 5882167ae72SSteven Rostedt (Red Hat) * .event = &ftrace_event_type_<call>, 5892167ae72SSteven Rostedt (Red Hat) * .print_fmt = print_fmt_<call>, 5902167ae72SSteven Rostedt (Red Hat) * .flags = TRACE_EVENT_FL_TRACEPOINT, 5912167ae72SSteven Rostedt (Red Hat) * }; 5922167ae72SSteven Rostedt (Red Hat) * // its only safe to use pointers when doing linker tricks to 5932167ae72SSteven Rostedt (Red Hat) * // create an array. 5942167ae72SSteven Rostedt (Red Hat) * static struct ftrace_event_call __used 5952167ae72SSteven Rostedt (Red Hat) * __attribute__((section("_ftrace_events"))) *__event_<call> = &event_<call>; 5962167ae72SSteven Rostedt (Red Hat) * 5972167ae72SSteven Rostedt (Red Hat) */ 5982167ae72SSteven Rostedt (Red Hat) 5992167ae72SSteven Rostedt (Red Hat) #ifdef CONFIG_PERF_EVENTS 6002167ae72SSteven Rostedt (Red Hat) 6012167ae72SSteven Rostedt (Red Hat) #define _TRACE_PERF_PROTO(call, proto) \ 6022167ae72SSteven Rostedt (Red Hat) static notrace void \ 6032167ae72SSteven Rostedt (Red Hat) perf_trace_##call(void *__data, proto); 6042167ae72SSteven Rostedt (Red Hat) 6052167ae72SSteven Rostedt (Red Hat) #define _TRACE_PERF_INIT(call) \ 6062167ae72SSteven Rostedt (Red Hat) .perf_probe = perf_trace_##call, 6072167ae72SSteven Rostedt (Red Hat) 6082167ae72SSteven Rostedt (Red Hat) #else 6092167ae72SSteven Rostedt (Red Hat) #define _TRACE_PERF_PROTO(call, proto) 6102167ae72SSteven Rostedt (Red Hat) #define _TRACE_PERF_INIT(call) 6112167ae72SSteven Rostedt (Red Hat) #endif /* CONFIG_PERF_EVENTS */ 6122167ae72SSteven Rostedt (Red Hat) 6132167ae72SSteven Rostedt (Red Hat) #undef __entry 6142167ae72SSteven Rostedt (Red Hat) #define __entry entry 6152167ae72SSteven Rostedt (Red Hat) 6162167ae72SSteven Rostedt (Red Hat) #undef __field 6172167ae72SSteven Rostedt (Red Hat) #define __field(type, item) 6182167ae72SSteven Rostedt (Red Hat) 6192167ae72SSteven Rostedt (Red Hat) #undef __field_struct 6202167ae72SSteven Rostedt (Red Hat) #define __field_struct(type, item) 6212167ae72SSteven Rostedt (Red Hat) 6222167ae72SSteven Rostedt (Red Hat) #undef __array 6232167ae72SSteven Rostedt (Red Hat) #define __array(type, item, len) 6242167ae72SSteven Rostedt (Red Hat) 6252167ae72SSteven Rostedt (Red Hat) #undef __dynamic_array 6262167ae72SSteven Rostedt (Red Hat) #define __dynamic_array(type, item, len) \ 6272167ae72SSteven Rostedt (Red Hat) __entry->__data_loc_##item = __data_offsets.item; 6282167ae72SSteven Rostedt (Red Hat) 6292167ae72SSteven Rostedt (Red Hat) #undef __string 6302167ae72SSteven Rostedt (Red Hat) #define __string(item, src) __dynamic_array(char, item, -1) 6312167ae72SSteven Rostedt (Red Hat) 6322167ae72SSteven Rostedt (Red Hat) #undef __assign_str 6332167ae72SSteven Rostedt (Red Hat) #define __assign_str(dst, src) \ 6342167ae72SSteven Rostedt (Red Hat) strcpy(__get_str(dst), (src) ? (const char *)(src) : "(null)"); 6352167ae72SSteven Rostedt (Red Hat) 6362167ae72SSteven Rostedt (Red Hat) #undef __bitmask 6372167ae72SSteven Rostedt (Red Hat) #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) 6382167ae72SSteven Rostedt (Red Hat) 6392167ae72SSteven Rostedt (Red Hat) #undef __get_bitmask 6402167ae72SSteven Rostedt (Red Hat) #define __get_bitmask(field) (char *)__get_dynamic_array(field) 6412167ae72SSteven Rostedt (Red Hat) 6422167ae72SSteven Rostedt (Red Hat) #undef __assign_bitmask 6432167ae72SSteven Rostedt (Red Hat) #define __assign_bitmask(dst, src, nr_bits) \ 6442167ae72SSteven Rostedt (Red Hat) memcpy(__get_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits)) 6452167ae72SSteven Rostedt (Red Hat) 6462167ae72SSteven Rostedt (Red Hat) #undef TP_fast_assign 6472167ae72SSteven Rostedt (Red Hat) #define TP_fast_assign(args...) args 6482167ae72SSteven Rostedt (Red Hat) 6492167ae72SSteven Rostedt (Red Hat) #undef __perf_addr 6502167ae72SSteven Rostedt (Red Hat) #define __perf_addr(a) (a) 6512167ae72SSteven Rostedt (Red Hat) 6522167ae72SSteven Rostedt (Red Hat) #undef __perf_count 6532167ae72SSteven Rostedt (Red Hat) #define __perf_count(c) (c) 6542167ae72SSteven Rostedt (Red Hat) 6552167ae72SSteven Rostedt (Red Hat) #undef __perf_task 6562167ae72SSteven Rostedt (Red Hat) #define __perf_task(t) (t) 6572167ae72SSteven Rostedt (Red Hat) 6582167ae72SSteven Rostedt (Red Hat) #undef DECLARE_EVENT_CLASS 6592167ae72SSteven Rostedt (Red Hat) #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 6602167ae72SSteven Rostedt (Red Hat) \ 6612167ae72SSteven Rostedt (Red Hat) static notrace void \ 6622167ae72SSteven Rostedt (Red Hat) ftrace_raw_event_##call(void *__data, proto) \ 6632167ae72SSteven Rostedt (Red Hat) { \ 6642167ae72SSteven Rostedt (Red Hat) struct ftrace_event_file *ftrace_file = __data; \ 6652167ae72SSteven Rostedt (Red Hat) struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ 6662167ae72SSteven Rostedt (Red Hat) struct ftrace_event_buffer fbuffer; \ 6672167ae72SSteven Rostedt (Red Hat) struct ftrace_raw_##call *entry; \ 6682167ae72SSteven Rostedt (Red Hat) int __data_size; \ 6692167ae72SSteven Rostedt (Red Hat) \ 6702167ae72SSteven Rostedt (Red Hat) if (ftrace_trigger_soft_disabled(ftrace_file)) \ 6712167ae72SSteven Rostedt (Red Hat) return; \ 6722167ae72SSteven Rostedt (Red Hat) \ 6732167ae72SSteven Rostedt (Red Hat) __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ 6742167ae72SSteven Rostedt (Red Hat) \ 6752167ae72SSteven Rostedt (Red Hat) entry = ftrace_event_buffer_reserve(&fbuffer, ftrace_file, \ 6762167ae72SSteven Rostedt (Red Hat) sizeof(*entry) + __data_size); \ 6772167ae72SSteven Rostedt (Red Hat) \ 6782167ae72SSteven Rostedt (Red Hat) if (!entry) \ 6792167ae72SSteven Rostedt (Red Hat) return; \ 6802167ae72SSteven Rostedt (Red Hat) \ 6812167ae72SSteven Rostedt (Red Hat) tstruct \ 6822167ae72SSteven Rostedt (Red Hat) \ 6832167ae72SSteven Rostedt (Red Hat) { assign; } \ 6842167ae72SSteven Rostedt (Red Hat) \ 6852167ae72SSteven Rostedt (Red Hat) ftrace_event_buffer_commit(&fbuffer); \ 6862167ae72SSteven Rostedt (Red Hat) } 6872167ae72SSteven Rostedt (Red Hat) /* 6882167ae72SSteven Rostedt (Red Hat) * The ftrace_test_probe is compiled out, it is only here as a build time check 6892167ae72SSteven Rostedt (Red Hat) * to make sure that if the tracepoint handling changes, the ftrace probe will 6902167ae72SSteven Rostedt (Red Hat) * fail to compile unless it too is updated. 6912167ae72SSteven Rostedt (Red Hat) */ 6922167ae72SSteven Rostedt (Red Hat) 6932167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT 6942167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT(template, call, proto, args) \ 6952167ae72SSteven Rostedt (Red Hat) static inline void ftrace_test_probe_##call(void) \ 6962167ae72SSteven Rostedt (Red Hat) { \ 6972167ae72SSteven Rostedt (Red Hat) check_trace_callback_type_##call(ftrace_raw_event_##template); \ 6982167ae72SSteven Rostedt (Red Hat) } 6992167ae72SSteven Rostedt (Red Hat) 7002167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT_PRINT 7012167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT_PRINT(template, name, proto, args, print) 7022167ae72SSteven Rostedt (Red Hat) 7032167ae72SSteven Rostedt (Red Hat) #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 7042167ae72SSteven Rostedt (Red Hat) 7052167ae72SSteven Rostedt (Red Hat) #undef __entry 7062167ae72SSteven Rostedt (Red Hat) #define __entry REC 7072167ae72SSteven Rostedt (Red Hat) 7082167ae72SSteven Rostedt (Red Hat) #undef __print_flags 7092167ae72SSteven Rostedt (Red Hat) #undef __print_symbolic 7102167ae72SSteven Rostedt (Red Hat) #undef __print_hex 7112167ae72SSteven Rostedt (Red Hat) #undef __get_dynamic_array 7122167ae72SSteven Rostedt (Red Hat) #undef __get_dynamic_array_len 7132167ae72SSteven Rostedt (Red Hat) #undef __get_str 7142167ae72SSteven Rostedt (Red Hat) #undef __get_bitmask 7152167ae72SSteven Rostedt (Red Hat) #undef __print_array 7162167ae72SSteven Rostedt (Red Hat) 7172167ae72SSteven Rostedt (Red Hat) #undef TP_printk 7182167ae72SSteven Rostedt (Red Hat) #define TP_printk(fmt, args...) "\"" fmt "\", " __stringify(args) 7192167ae72SSteven Rostedt (Red Hat) 7202167ae72SSteven Rostedt (Red Hat) #undef DECLARE_EVENT_CLASS 7212167ae72SSteven Rostedt (Red Hat) #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 7222167ae72SSteven Rostedt (Red Hat) _TRACE_PERF_PROTO(call, PARAMS(proto)); \ 7232167ae72SSteven Rostedt (Red Hat) static char print_fmt_##call[] = print; \ 7242167ae72SSteven Rostedt (Red Hat) static struct ftrace_event_class __used __refdata event_class_##call = { \ 7252167ae72SSteven Rostedt (Red Hat) .system = TRACE_SYSTEM_STRING, \ 7262167ae72SSteven Rostedt (Red Hat) .define_fields = ftrace_define_fields_##call, \ 7272167ae72SSteven Rostedt (Red Hat) .fields = LIST_HEAD_INIT(event_class_##call.fields),\ 7282167ae72SSteven Rostedt (Red Hat) .raw_init = trace_event_raw_init, \ 7292167ae72SSteven Rostedt (Red Hat) .probe = ftrace_raw_event_##call, \ 7302167ae72SSteven Rostedt (Red Hat) .reg = ftrace_event_reg, \ 7312167ae72SSteven Rostedt (Red Hat) _TRACE_PERF_INIT(call) \ 7322167ae72SSteven Rostedt (Red Hat) }; 7332167ae72SSteven Rostedt (Red Hat) 7342167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT 7352167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT(template, call, proto, args) \ 7362167ae72SSteven Rostedt (Red Hat) \ 7372167ae72SSteven Rostedt (Red Hat) static struct ftrace_event_call __used event_##call = { \ 7382167ae72SSteven Rostedt (Red Hat) .class = &event_class_##template, \ 7392167ae72SSteven Rostedt (Red Hat) { \ 7402167ae72SSteven Rostedt (Red Hat) .tp = &__tracepoint_##call, \ 7412167ae72SSteven Rostedt (Red Hat) }, \ 7422167ae72SSteven Rostedt (Red Hat) .event.funcs = &ftrace_event_type_funcs_##template, \ 7432167ae72SSteven Rostedt (Red Hat) .print_fmt = print_fmt_##template, \ 7442167ae72SSteven Rostedt (Red Hat) .flags = TRACE_EVENT_FL_TRACEPOINT, \ 7452167ae72SSteven Rostedt (Red Hat) }; \ 7462167ae72SSteven Rostedt (Red Hat) static struct ftrace_event_call __used \ 7472167ae72SSteven Rostedt (Red Hat) __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call 7482167ae72SSteven Rostedt (Red Hat) 7492167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT_PRINT 7502167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ 7512167ae72SSteven Rostedt (Red Hat) \ 7522167ae72SSteven Rostedt (Red Hat) static char print_fmt_##call[] = print; \ 7532167ae72SSteven Rostedt (Red Hat) \ 7542167ae72SSteven Rostedt (Red Hat) static struct ftrace_event_call __used event_##call = { \ 7552167ae72SSteven Rostedt (Red Hat) .class = &event_class_##template, \ 7562167ae72SSteven Rostedt (Red Hat) { \ 7572167ae72SSteven Rostedt (Red Hat) .tp = &__tracepoint_##call, \ 7582167ae72SSteven Rostedt (Red Hat) }, \ 7592167ae72SSteven Rostedt (Red Hat) .event.funcs = &ftrace_event_type_funcs_##call, \ 7602167ae72SSteven Rostedt (Red Hat) .print_fmt = print_fmt_##call, \ 7612167ae72SSteven Rostedt (Red Hat) .flags = TRACE_EVENT_FL_TRACEPOINT, \ 7622167ae72SSteven Rostedt (Red Hat) }; \ 7632167ae72SSteven Rostedt (Red Hat) static struct ftrace_event_call __used \ 7642167ae72SSteven Rostedt (Red Hat) __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call 7652167ae72SSteven Rostedt (Red Hat) 7662167ae72SSteven Rostedt (Red Hat) #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 7672167ae72SSteven Rostedt (Red Hat) 7682167ae72SSteven Rostedt (Red Hat) #undef TRACE_SYSTEM_VAR 7692167ae72SSteven Rostedt (Red Hat) 7702167ae72SSteven Rostedt (Red Hat) #ifdef CONFIG_PERF_EVENTS 7712167ae72SSteven Rostedt (Red Hat) 7722167ae72SSteven Rostedt (Red Hat) #undef __entry 7732167ae72SSteven Rostedt (Red Hat) #define __entry entry 7742167ae72SSteven Rostedt (Red Hat) 7752167ae72SSteven Rostedt (Red Hat) #undef __get_dynamic_array 7762167ae72SSteven Rostedt (Red Hat) #define __get_dynamic_array(field) \ 7772167ae72SSteven Rostedt (Red Hat) ((void *)__entry + (__entry->__data_loc_##field & 0xffff)) 7782167ae72SSteven Rostedt (Red Hat) 7792167ae72SSteven Rostedt (Red Hat) #undef __get_dynamic_array_len 7802167ae72SSteven Rostedt (Red Hat) #define __get_dynamic_array_len(field) \ 7812167ae72SSteven Rostedt (Red Hat) ((__entry->__data_loc_##field >> 16) & 0xffff) 7822167ae72SSteven Rostedt (Red Hat) 7832167ae72SSteven Rostedt (Red Hat) #undef __get_str 7842167ae72SSteven Rostedt (Red Hat) #define __get_str(field) (char *)__get_dynamic_array(field) 7852167ae72SSteven Rostedt (Red Hat) 7862167ae72SSteven Rostedt (Red Hat) #undef __get_bitmask 7872167ae72SSteven Rostedt (Red Hat) #define __get_bitmask(field) (char *)__get_dynamic_array(field) 7882167ae72SSteven Rostedt (Red Hat) 7892167ae72SSteven Rostedt (Red Hat) #undef __perf_addr 7902167ae72SSteven Rostedt (Red Hat) #define __perf_addr(a) (__addr = (a)) 7912167ae72SSteven Rostedt (Red Hat) 7922167ae72SSteven Rostedt (Red Hat) #undef __perf_count 7932167ae72SSteven Rostedt (Red Hat) #define __perf_count(c) (__count = (c)) 7942167ae72SSteven Rostedt (Red Hat) 7952167ae72SSteven Rostedt (Red Hat) #undef __perf_task 7962167ae72SSteven Rostedt (Red Hat) #define __perf_task(t) (__task = (t)) 7972167ae72SSteven Rostedt (Red Hat) 7982167ae72SSteven Rostedt (Red Hat) #undef DECLARE_EVENT_CLASS 7992167ae72SSteven Rostedt (Red Hat) #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 8002167ae72SSteven Rostedt (Red Hat) static notrace void \ 8012167ae72SSteven Rostedt (Red Hat) perf_trace_##call(void *__data, proto) \ 8022167ae72SSteven Rostedt (Red Hat) { \ 8032167ae72SSteven Rostedt (Red Hat) struct ftrace_event_call *event_call = __data; \ 8042167ae72SSteven Rostedt (Red Hat) struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ 8052167ae72SSteven Rostedt (Red Hat) struct ftrace_raw_##call *entry; \ 8062167ae72SSteven Rostedt (Red Hat) struct pt_regs *__regs; \ 8072167ae72SSteven Rostedt (Red Hat) u64 __addr = 0, __count = 1; \ 8082167ae72SSteven Rostedt (Red Hat) struct task_struct *__task = NULL; \ 8092167ae72SSteven Rostedt (Red Hat) struct hlist_head *head; \ 8102167ae72SSteven Rostedt (Red Hat) int __entry_size; \ 8112167ae72SSteven Rostedt (Red Hat) int __data_size; \ 8122167ae72SSteven Rostedt (Red Hat) int rctx; \ 8132167ae72SSteven Rostedt (Red Hat) \ 8142167ae72SSteven Rostedt (Red Hat) __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ 8152167ae72SSteven Rostedt (Red Hat) \ 8162167ae72SSteven Rostedt (Red Hat) head = this_cpu_ptr(event_call->perf_events); \ 8172167ae72SSteven Rostedt (Red Hat) if (__builtin_constant_p(!__task) && !__task && \ 8182167ae72SSteven Rostedt (Red Hat) hlist_empty(head)) \ 8192167ae72SSteven Rostedt (Red Hat) return; \ 8202167ae72SSteven Rostedt (Red Hat) \ 8212167ae72SSteven Rostedt (Red Hat) __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),\ 8222167ae72SSteven Rostedt (Red Hat) sizeof(u64)); \ 8232167ae72SSteven Rostedt (Red Hat) __entry_size -= sizeof(u32); \ 8242167ae72SSteven Rostedt (Red Hat) \ 8252167ae72SSteven Rostedt (Red Hat) entry = perf_trace_buf_prepare(__entry_size, \ 8262167ae72SSteven Rostedt (Red Hat) event_call->event.type, &__regs, &rctx); \ 8272167ae72SSteven Rostedt (Red Hat) if (!entry) \ 8282167ae72SSteven Rostedt (Red Hat) return; \ 8292167ae72SSteven Rostedt (Red Hat) \ 8302167ae72SSteven Rostedt (Red Hat) perf_fetch_caller_regs(__regs); \ 8312167ae72SSteven Rostedt (Red Hat) \ 8322167ae72SSteven Rostedt (Red Hat) tstruct \ 8332167ae72SSteven Rostedt (Red Hat) \ 8342167ae72SSteven Rostedt (Red Hat) { assign; } \ 8352167ae72SSteven Rostedt (Red Hat) \ 8362167ae72SSteven Rostedt (Red Hat) perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ 8372167ae72SSteven Rostedt (Red Hat) __count, __regs, head, __task); \ 8382167ae72SSteven Rostedt (Red Hat) } 8392167ae72SSteven Rostedt (Red Hat) 8402167ae72SSteven Rostedt (Red Hat) /* 8412167ae72SSteven Rostedt (Red Hat) * This part is compiled out, it is only here as a build time check 8422167ae72SSteven Rostedt (Red Hat) * to make sure that if the tracepoint handling changes, the 8432167ae72SSteven Rostedt (Red Hat) * perf probe will fail to compile unless it too is updated. 8442167ae72SSteven Rostedt (Red Hat) */ 8452167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT 8462167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT(template, call, proto, args) \ 8472167ae72SSteven Rostedt (Red Hat) static inline void perf_test_probe_##call(void) \ 8482167ae72SSteven Rostedt (Red Hat) { \ 8492167ae72SSteven Rostedt (Red Hat) check_trace_callback_type_##call(perf_trace_##template); \ 8502167ae72SSteven Rostedt (Red Hat) } 8512167ae72SSteven Rostedt (Red Hat) 8522167ae72SSteven Rostedt (Red Hat) 8532167ae72SSteven Rostedt (Red Hat) #undef DEFINE_EVENT_PRINT 8542167ae72SSteven Rostedt (Red Hat) #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ 8552167ae72SSteven Rostedt (Red Hat) DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) 8562167ae72SSteven Rostedt (Red Hat) 8572167ae72SSteven Rostedt (Red Hat) #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 8582167ae72SSteven Rostedt (Red Hat) #endif /* CONFIG_PERF_EVENTS */ 8592167ae72SSteven Rostedt (Red Hat) 860