diff options
Diffstat (limited to 'include/trace')
-rw-r--r-- | include/trace/define_trace.h | 1 | ||||
-rw-r--r-- | include/trace/perf.h | 350 | ||||
-rw-r--r-- | include/trace/trace_events.h | 351 |
3 files changed, 351 insertions, 351 deletions
diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h index b13ba2fc76f7..09b3880105a9 100644 --- a/include/trace/define_trace.h +++ b/include/trace/define_trace.h @@ -88,6 +88,7 @@ #ifdef CONFIG_EVENT_TRACING #include <trace/trace_events.h> +#include <trace/perf.h> #endif #undef TRACE_EVENT diff --git a/include/trace/perf.h b/include/trace/perf.h new file mode 100644 index 000000000000..5e82add1647b --- /dev/null +++ b/include/trace/perf.h @@ -0,0 +1,350 @@ +/* + * Stage 4 of the trace events. + * + * Override the macros in <trace/trace_events.h> to include the following: + * + * For those macros defined with TRACE_EVENT: + * + * static struct ftrace_event_call event_<call>; + * + * static void ftrace_raw_event_<call>(void *__data, proto) + * { + * struct ftrace_event_file *ftrace_file = __data; + * struct ftrace_event_call *event_call = ftrace_file->event_call; + * struct ftrace_data_offsets_<call> __maybe_unused __data_offsets; + * unsigned long eflags = ftrace_file->flags; + * enum event_trigger_type __tt = ETT_NONE; + * struct ring_buffer_event *event; + * struct ftrace_raw_<call> *entry; <-- defined in stage 1 + * struct ring_buffer *buffer; + * unsigned long irq_flags; + * int __data_size; + * int pc; + * + * if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) { + * if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE) + * event_triggers_call(ftrace_file, NULL); + * if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED) + * return; + * } + * + * local_save_flags(irq_flags); + * pc = preempt_count(); + * + * __data_size = ftrace_get_offsets_<call>(&__data_offsets, args); + * + * event = trace_event_buffer_lock_reserve(&buffer, ftrace_file, + * event_<call>->event.type, + * sizeof(*entry) + __data_size, + * irq_flags, pc); + * if (!event) + * return; + * entry = ring_buffer_event_data(event); + * + * { <assign>; } <-- Here we assign the entries by the __field and + * __array macros. + * + * if (eflags & FTRACE_EVENT_FL_TRIGGER_COND) + * __tt = event_triggers_call(ftrace_file, entry); + * + * if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, + * &ftrace_file->flags)) + * ring_buffer_discard_commit(buffer, event); + * else if (!filter_check_discard(ftrace_file, entry, buffer, event)) + * trace_buffer_unlock_commit(buffer, event, irq_flags, pc); + * + * if (__tt) + * event_triggers_post_call(ftrace_file, __tt); + * } + * + * static struct trace_event ftrace_event_type_<call> = { + * .trace = ftrace_raw_output_<call>, <-- stage 2 + * }; + * + * static char print_fmt_<call>[] = <TP_printk>; + * + * static struct ftrace_event_class __used event_class_<template> = { + * .system = "<system>", + * .define_fields = ftrace_define_fields_<call>, + * .fields = LIST_HEAD_INIT(event_class_##call.fields), + * .raw_init = trace_event_raw_init, + * .probe = ftrace_raw_event_##call, + * .reg = ftrace_event_reg, + * }; + * + * static struct ftrace_event_call event_<call> = { + * .class = event_class_<template>, + * { + * .tp = &__tracepoint_<call>, + * }, + * .event = &ftrace_event_type_<call>, + * .print_fmt = print_fmt_<call>, + * .flags = TRACE_EVENT_FL_TRACEPOINT, + * }; + * // its only safe to use pointers when doing linker tricks to + * // create an array. + * static struct ftrace_event_call __used + * __attribute__((section("_ftrace_events"))) *__event_<call> = &event_<call>; + * + */ + +#ifdef CONFIG_PERF_EVENTS + +#define _TRACE_PERF_PROTO(call, proto) \ + static notrace void \ + perf_trace_##call(void *__data, proto); + +#define _TRACE_PERF_INIT(call) \ + .perf_probe = perf_trace_##call, + +#else +#define _TRACE_PERF_PROTO(call, proto) +#define _TRACE_PERF_INIT(call) +#endif /* CONFIG_PERF_EVENTS */ + +#undef __entry +#define __entry entry + +#undef __field +#define __field(type, item) + +#undef __field_struct +#define __field_struct(type, item) + +#undef __array +#define __array(type, item, len) + +#undef __dynamic_array +#define __dynamic_array(type, item, len) \ + __entry->__data_loc_##item = __data_offsets.item; + +#undef __string +#define __string(item, src) __dynamic_array(char, item, -1) + +#undef __assign_str +#define __assign_str(dst, src) \ + strcpy(__get_str(dst), (src) ? (const char *)(src) : "(null)"); + +#undef __bitmask +#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) + +#undef __get_bitmask +#define __get_bitmask(field) (char *)__get_dynamic_array(field) + +#undef __assign_bitmask +#define __assign_bitmask(dst, src, nr_bits) \ + memcpy(__get_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits)) + +#undef TP_fast_assign +#define TP_fast_assign(args...) args + +#undef __perf_addr +#define __perf_addr(a) (a) + +#undef __perf_count +#define __perf_count(c) (c) + +#undef __perf_task +#define __perf_task(t) (t) + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ + \ +static notrace void \ +ftrace_raw_event_##call(void *__data, proto) \ +{ \ + struct ftrace_event_file *ftrace_file = __data; \ + struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ + struct ftrace_event_buffer fbuffer; \ + struct ftrace_raw_##call *entry; \ + int __data_size; \ + \ + if (ftrace_trigger_soft_disabled(ftrace_file)) \ + return; \ + \ + __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ + \ + entry = ftrace_event_buffer_reserve(&fbuffer, ftrace_file, \ + sizeof(*entry) + __data_size); \ + \ + if (!entry) \ + return; \ + \ + tstruct \ + \ + { assign; } \ + \ + ftrace_event_buffer_commit(&fbuffer); \ +} +/* + * The ftrace_test_probe is compiled out, it is only here as a build time check + * to make sure that if the tracepoint handling changes, the ftrace probe will + * fail to compile unless it too is updated. + */ + +#undef DEFINE_EVENT +#define DEFINE_EVENT(template, call, proto, args) \ +static inline void ftrace_test_probe_##call(void) \ +{ \ + check_trace_callback_type_##call(ftrace_raw_event_##template); \ +} + +#undef DEFINE_EVENT_PRINT +#define DEFINE_EVENT_PRINT(template, name, proto, args, print) + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +#undef __entry +#define __entry REC + +#undef __print_flags +#undef __print_symbolic +#undef __print_hex +#undef __get_dynamic_array +#undef __get_dynamic_array_len +#undef __get_str +#undef __get_bitmask +#undef __print_array + +#undef TP_printk +#define TP_printk(fmt, args...) "\"" fmt "\", " __stringify(args) + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ +_TRACE_PERF_PROTO(call, PARAMS(proto)); \ +static char print_fmt_##call[] = print; \ +static struct ftrace_event_class __used __refdata event_class_##call = { \ + .system = TRACE_SYSTEM_STRING, \ + .define_fields = ftrace_define_fields_##call, \ + .fields = LIST_HEAD_INIT(event_class_##call.fields),\ + .raw_init = trace_event_raw_init, \ + .probe = ftrace_raw_event_##call, \ + .reg = ftrace_event_reg, \ + _TRACE_PERF_INIT(call) \ +}; + +#undef DEFINE_EVENT +#define DEFINE_EVENT(template, call, proto, args) \ + \ +static struct ftrace_event_call __used event_##call = { \ + .class = &event_class_##template, \ + { \ + .tp = &__tracepoint_##call, \ + }, \ + .event.funcs = &ftrace_event_type_funcs_##template, \ + .print_fmt = print_fmt_##template, \ + .flags = TRACE_EVENT_FL_TRACEPOINT, \ +}; \ +static struct ftrace_event_call __used \ +__attribute__((section("_ftrace_events"))) *__event_##call = &event_##call + +#undef DEFINE_EVENT_PRINT +#define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ + \ +static char print_fmt_##call[] = print; \ + \ +static struct ftrace_event_call __used event_##call = { \ + .class = &event_class_##template, \ + { \ + .tp = &__tracepoint_##call, \ + }, \ + .event.funcs = &ftrace_event_type_funcs_##call, \ + .print_fmt = print_fmt_##call, \ + .flags = TRACE_EVENT_FL_TRACEPOINT, \ +}; \ +static struct ftrace_event_call __used \ +__attribute__((section("_ftrace_events"))) *__event_##call = &event_##call + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +#undef TRACE_SYSTEM_VAR + +#ifdef CONFIG_PERF_EVENTS + +#undef __entry +#define __entry entry + +#undef __get_dynamic_array +#define __get_dynamic_array(field) \ + ((void *)__entry + (__entry->__data_loc_##field & 0xffff)) + +#undef __get_dynamic_array_len +#define __get_dynamic_array_len(field) \ + ((__entry->__data_loc_##field >> 16) & 0xffff) + +#undef __get_str +#define __get_str(field) (char *)__get_dynamic_array(field) + +#undef __get_bitmask +#define __get_bitmask(field) (char *)__get_dynamic_array(field) + +#undef __perf_addr +#define __perf_addr(a) (__addr = (a)) + +#undef __perf_count +#define __perf_count(c) (__count = (c)) + +#undef __perf_task +#define __perf_task(t) (__task = (t)) + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ +static notrace void \ +perf_trace_##call(void *__data, proto) \ +{ \ + struct ftrace_event_call *event_call = __data; \ + struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ + struct ftrace_raw_##call *entry; \ + struct pt_regs *__regs; \ + u64 __addr = 0, __count = 1; \ + struct task_struct *__task = NULL; \ + struct hlist_head *head; \ + int __entry_size; \ + int __data_size; \ + int rctx; \ + \ + __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ + \ + head = this_cpu_ptr(event_call->perf_events); \ + if (__builtin_constant_p(!__task) && !__task && \ + hlist_empty(head)) \ + return; \ + \ + __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),\ + sizeof(u64)); \ + __entry_size -= sizeof(u32); \ + \ + entry = perf_trace_buf_prepare(__entry_size, \ + event_call->event.type, &__regs, &rctx); \ + if (!entry) \ + return; \ + \ + perf_fetch_caller_regs(__regs); \ + \ + tstruct \ + \ + { assign; } \ + \ + perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ + __count, __regs, head, __task); \ +} + +/* + * This part is compiled out, it is only here as a build time check + * to make sure that if the tracepoint handling changes, the + * perf probe will fail to compile unless it too is updated. + */ +#undef DEFINE_EVENT +#define DEFINE_EVENT(template, call, proto, args) \ +static inline void perf_test_probe_##call(void) \ +{ \ + check_trace_callback_type_##call(perf_trace_##template); \ +} + + +#undef DEFINE_EVENT_PRINT +#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ + DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) +#endif /* CONFIG_PERF_EVENTS */ diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h index 37d4b10b111d..19af616e9dbd 100644 --- a/include/trace/trace_events.h +++ b/include/trace/trace_events.h @@ -506,354 +506,3 @@ static inline notrace int ftrace_get_offsets_##call( \ #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) -/* - * Stage 4 of the trace events. - * - * Override the macros in <trace/trace_events.h> to include the following: - * - * For those macros defined with TRACE_EVENT: - * - * static struct ftrace_event_call event_<call>; - * - * static void ftrace_raw_event_<call>(void *__data, proto) - * { - * struct ftrace_event_file *ftrace_file = __data; - * struct ftrace_event_call *event_call = ftrace_file->event_call; - * struct ftrace_data_offsets_<call> __maybe_unused __data_offsets; - * unsigned long eflags = ftrace_file->flags; - * enum event_trigger_type __tt = ETT_NONE; - * struct ring_buffer_event *event; - * struct ftrace_raw_<call> *entry; <-- defined in stage 1 - * struct ring_buffer *buffer; - * unsigned long irq_flags; - * int __data_size; - * int pc; - * - * if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) { - * if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE) - * event_triggers_call(ftrace_file, NULL); - * if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED) - * return; - * } - * - * local_save_flags(irq_flags); - * pc = preempt_count(); - * - * __data_size = ftrace_get_offsets_<call>(&__data_offsets, args); - * - * event = trace_event_buffer_lock_reserve(&buffer, ftrace_file, - * event_<call>->event.type, - * sizeof(*entry) + __data_size, - * irq_flags, pc); - * if (!event) - * return; - * entry = ring_buffer_event_data(event); - * - * { <assign>; } <-- Here we assign the entries by the __field and - * __array macros. - * - * if (eflags & FTRACE_EVENT_FL_TRIGGER_COND) - * __tt = event_triggers_call(ftrace_file, entry); - * - * if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, - * &ftrace_file->flags)) - * ring_buffer_discard_commit(buffer, event); - * else if (!filter_check_discard(ftrace_file, entry, buffer, event)) - * trace_buffer_unlock_commit(buffer, event, irq_flags, pc); - * - * if (__tt) - * event_triggers_post_call(ftrace_file, __tt); - * } - * - * static struct trace_event ftrace_event_type_<call> = { - * .trace = ftrace_raw_output_<call>, <-- stage 2 - * }; - * - * static char print_fmt_<call>[] = <TP_printk>; - * - * static struct ftrace_event_class __used event_class_<template> = { - * .system = "<system>", - * .define_fields = ftrace_define_fields_<call>, - * .fields = LIST_HEAD_INIT(event_class_##call.fields), - * .raw_init = trace_event_raw_init, - * .probe = ftrace_raw_event_##call, - * .reg = ftrace_event_reg, - * }; - * - * static struct ftrace_event_call event_<call> = { - * .class = event_class_<template>, - * { - * .tp = &__tracepoint_<call>, - * }, - * .event = &ftrace_event_type_<call>, - * .print_fmt = print_fmt_<call>, - * .flags = TRACE_EVENT_FL_TRACEPOINT, - * }; - * // its only safe to use pointers when doing linker tricks to - * // create an array. - * static struct ftrace_event_call __used - * __attribute__((section("_ftrace_events"))) *__event_<call> = &event_<call>; - * - */ - -#ifdef CONFIG_PERF_EVENTS - -#define _TRACE_PERF_PROTO(call, proto) \ - static notrace void \ - perf_trace_##call(void *__data, proto); - -#define _TRACE_PERF_INIT(call) \ - .perf_probe = perf_trace_##call, - -#else -#define _TRACE_PERF_PROTO(call, proto) -#define _TRACE_PERF_INIT(call) -#endif /* CONFIG_PERF_EVENTS */ - -#undef __entry -#define __entry entry - -#undef __field -#define __field(type, item) - -#undef __field_struct -#define __field_struct(type, item) - -#undef __array -#define __array(type, item, len) - -#undef __dynamic_array -#define __dynamic_array(type, item, len) \ - __entry->__data_loc_##item = __data_offsets.item; - -#undef __string -#define __string(item, src) __dynamic_array(char, item, -1) - -#undef __assign_str -#define __assign_str(dst, src) \ - strcpy(__get_str(dst), (src) ? (const char *)(src) : "(null)"); - -#undef __bitmask -#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) - -#undef __get_bitmask -#define __get_bitmask(field) (char *)__get_dynamic_array(field) - -#undef __assign_bitmask -#define __assign_bitmask(dst, src, nr_bits) \ - memcpy(__get_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits)) - -#undef TP_fast_assign -#define TP_fast_assign(args...) args - -#undef __perf_addr -#define __perf_addr(a) (a) - -#undef __perf_count -#define __perf_count(c) (c) - -#undef __perf_task -#define __perf_task(t) (t) - -#undef DECLARE_EVENT_CLASS -#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ - \ -static notrace void \ -ftrace_raw_event_##call(void *__data, proto) \ -{ \ - struct ftrace_event_file *ftrace_file = __data; \ - struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ - struct ftrace_event_buffer fbuffer; \ - struct ftrace_raw_##call *entry; \ - int __data_size; \ - \ - if (ftrace_trigger_soft_disabled(ftrace_file)) \ - return; \ - \ - __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ - \ - entry = ftrace_event_buffer_reserve(&fbuffer, ftrace_file, \ - sizeof(*entry) + __data_size); \ - \ - if (!entry) \ - return; \ - \ - tstruct \ - \ - { assign; } \ - \ - ftrace_event_buffer_commit(&fbuffer); \ -} -/* - * The ftrace_test_probe is compiled out, it is only here as a build time check - * to make sure that if the tracepoint handling changes, the ftrace probe will - * fail to compile unless it too is updated. - */ - -#undef DEFINE_EVENT -#define DEFINE_EVENT(template, call, proto, args) \ -static inline void ftrace_test_probe_##call(void) \ -{ \ - check_trace_callback_type_##call(ftrace_raw_event_##template); \ -} - -#undef DEFINE_EVENT_PRINT -#define DEFINE_EVENT_PRINT(template, name, proto, args, print) - -#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) - -#undef __entry -#define __entry REC - -#undef __print_flags -#undef __print_symbolic -#undef __print_hex -#undef __get_dynamic_array -#undef __get_dynamic_array_len -#undef __get_str -#undef __get_bitmask -#undef __print_array - -#undef TP_printk -#define TP_printk(fmt, args...) "\"" fmt "\", " __stringify(args) - -#undef DECLARE_EVENT_CLASS -#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ -_TRACE_PERF_PROTO(call, PARAMS(proto)); \ -static char print_fmt_##call[] = print; \ -static struct ftrace_event_class __used __refdata event_class_##call = { \ - .system = TRACE_SYSTEM_STRING, \ - .define_fields = ftrace_define_fields_##call, \ - .fields = LIST_HEAD_INIT(event_class_##call.fields),\ - .raw_init = trace_event_raw_init, \ - .probe = ftrace_raw_event_##call, \ - .reg = ftrace_event_reg, \ - _TRACE_PERF_INIT(call) \ -}; - -#undef DEFINE_EVENT -#define DEFINE_EVENT(template, call, proto, args) \ - \ -static struct ftrace_event_call __used event_##call = { \ - .class = &event_class_##template, \ - { \ - .tp = &__tracepoint_##call, \ - }, \ - .event.funcs = &ftrace_event_type_funcs_##template, \ - .print_fmt = print_fmt_##template, \ - .flags = TRACE_EVENT_FL_TRACEPOINT, \ -}; \ -static struct ftrace_event_call __used \ -__attribute__((section("_ftrace_events"))) *__event_##call = &event_##call - -#undef DEFINE_EVENT_PRINT -#define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ - \ -static char print_fmt_##call[] = print; \ - \ -static struct ftrace_event_call __used event_##call = { \ - .class = &event_class_##template, \ - { \ - .tp = &__tracepoint_##call, \ - }, \ - .event.funcs = &ftrace_event_type_funcs_##call, \ - .print_fmt = print_fmt_##call, \ - .flags = TRACE_EVENT_FL_TRACEPOINT, \ -}; \ -static struct ftrace_event_call __used \ -__attribute__((section("_ftrace_events"))) *__event_##call = &event_##call - -#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) - -#undef TRACE_SYSTEM_VAR - -#ifdef CONFIG_PERF_EVENTS - -#undef __entry -#define __entry entry - -#undef __get_dynamic_array -#define __get_dynamic_array(field) \ - ((void *)__entry + (__entry->__data_loc_##field & 0xffff)) - -#undef __get_dynamic_array_len -#define __get_dynamic_array_len(field) \ - ((__entry->__data_loc_##field >> 16) & 0xffff) - -#undef __get_str -#define __get_str(field) (char *)__get_dynamic_array(field) - -#undef __get_bitmask -#define __get_bitmask(field) (char *)__get_dynamic_array(field) - -#undef __perf_addr -#define __perf_addr(a) (__addr = (a)) - -#undef __perf_count -#define __perf_count(c) (__count = (c)) - -#undef __perf_task -#define __perf_task(t) (__task = (t)) - -#undef DECLARE_EVENT_CLASS -#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ -static notrace void \ -perf_trace_##call(void *__data, proto) \ -{ \ - struct ftrace_event_call *event_call = __data; \ - struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ - struct ftrace_raw_##call *entry; \ - struct pt_regs *__regs; \ - u64 __addr = 0, __count = 1; \ - struct task_struct *__task = NULL; \ - struct hlist_head *head; \ - int __entry_size; \ - int __data_size; \ - int rctx; \ - \ - __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ - \ - head = this_cpu_ptr(event_call->perf_events); \ - if (__builtin_constant_p(!__task) && !__task && \ - hlist_empty(head)) \ - return; \ - \ - __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),\ - sizeof(u64)); \ - __entry_size -= sizeof(u32); \ - \ - entry = perf_trace_buf_prepare(__entry_size, \ - event_call->event.type, &__regs, &rctx); \ - if (!entry) \ - return; \ - \ - perf_fetch_caller_regs(__regs); \ - \ - tstruct \ - \ - { assign; } \ - \ - perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ - __count, __regs, head, __task); \ -} - -/* - * This part is compiled out, it is only here as a build time check - * to make sure that if the tracepoint handling changes, the - * perf probe will fail to compile unless it too is updated. - */ -#undef DEFINE_EVENT -#define DEFINE_EVENT(template, call, proto, args) \ -static inline void perf_test_probe_##call(void) \ -{ \ - check_trace_callback_type_##call(perf_trace_##template); \ -} - - -#undef DEFINE_EVENT_PRINT -#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ - DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) - -#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) -#endif /* CONFIG_PERF_EVENTS */ - |