This class almost same as DECLARE_EVENT_CLASS, it allow user add some
init operation before print at output stage.

Add a new macro TP_printk_init(), user can add operation in it.

Also add a new TRACE_EVENT_PRINT_INIT() macro.

Signed-off-by: Linyu Yuan <[email protected]>
---
 include/linux/tracepoint.h                 |  22 ++++
 include/trace/bpf_probe.h                  |   4 +
 include/trace/perf.h                       |  43 ++++++++
 include/trace/stages/stage3_trace_output.h |   3 +
 include/trace/trace_events.h               | 118 +++++++++++++++++++++
 5 files changed, 190 insertions(+)

diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 88c0ba623ee6..3fd42640236a 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -551,6 +551,7 @@ static inline struct tracepoint 
*tracepoint_ptr_deref(tracepoint_ptr_t *p)
  */
 
 #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
+#define DECLARE_EVENT_CLASS_PRINT_INIT(name, proto, args, tstruct, assign, 
print, init)
 #define DEFINE_EVENT(template, name, proto, args)              \
        DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
 #define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)\
@@ -576,6 +577,20 @@ static inline struct tracepoint 
*tracepoint_ptr_deref(tracepoint_ptr_t *p)
        DECLARE_TRACE_CONDITION(name, PARAMS(proto),            \
                                PARAMS(args), PARAMS(cond))
 
+#define TRACE_EVENT_PRINT_INIT(name, proto, args, struct, assign, print, init) 
\
+       DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
+#define TRACE_EVENT_FN_PRINT_INIT(name, proto, args, struct,           \
+               assign, print, reg, unreg, init)                        \
+       DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
+#define TRACE_EVENT_FN_COND_PRINT_INIT(name, proto, args, cond, struct,        
        \
+               assign, print, reg, unreg, init)                        \
+       DECLARE_TRACE_CONDITION(name, PARAMS(proto),    \
+                       PARAMS(args), PARAMS(cond))
+#define TRACE_EVENT_CONDITION_PRINT_INIT(name, proto, args, cond,              
\
+                             struct, assign, print, init)              \
+       DECLARE_TRACE_CONDITION(name, PARAMS(proto),            \
+                               PARAMS(args), PARAMS(cond))
+
 #define TRACE_EVENT_FLAGS(event, flag)
 
 #define TRACE_EVENT_PERF_PERM(event, expr...)
@@ -595,4 +610,11 @@ static inline struct tracepoint 
*tracepoint_ptr_deref(tracepoint_ptr_t *p)
 #define DEFINE_EVENT_NOP(template, name, proto, args)                  \
        DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args))
 
+#define TRACE_EVENT_NOP_PRINT_INIT(name, proto, args, struct, assign, print, 
init)     \
+       DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args))
+
+#define DECLARE_EVENT_CLASS_NOP_PRINT_INIT(name, proto, args, tstruct, assign, 
print, init)
+#define DEFINE_EVENT_NOP(template, name, proto, args)                  \
+       DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args))
+
 #endif /* ifdef TRACE_EVENT (see note above) */
diff --git a/include/trace/bpf_probe.h b/include/trace/bpf_probe.h
index e609cd7da47e..99b5594a4a8e 100644
--- a/include/trace/bpf_probe.h
+++ b/include/trace/bpf_probe.h
@@ -54,6 +54,10 @@ __bpf_trace_##call(void *__data, proto)                      
                \
 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
        __BPF_DECLARE_TRACE(call, PARAMS(proto), PARAMS(args))
 
+#undef DECLARE_EVENT_CLASS_PRINT_INIT
+#define DECLARE_EVENT_CLASS_PRINT_INIT(call, proto, args, tstruct, assign, 
print, init)        \
+       __BPF_DECLARE_TRACE(call, PARAMS(proto), PARAMS(args))
+
 /*
  * This part is compiled out, it is only here as a build time check
  * to make sure that if the tracepoint handling changes, the
diff --git a/include/trace/perf.h b/include/trace/perf.h
index 2c11181c82e0..bee78e8eef5d 100644
--- a/include/trace/perf.h
+++ b/include/trace/perf.h
@@ -55,6 +55,49 @@ perf_trace_##call(void *__data, proto)                       
                \
                                  head, __task);                        \
 }
 
+#undef DECLARE_EVENT_CLASS_PRINT_INIT
+#define DECLARE_EVENT_CLASS_PRINT_INIT(call, proto, args, tstruct, assign, 
print, init)        \
+static notrace void                                                    \
+perf_trace_##call(void *__data, proto)                                 \
+{                                                                      \
+       struct trace_event_call *event_call = __data;                   \
+       struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\
+       struct trace_event_raw_##call *entry;                           \
+       struct pt_regs *__regs;                                         \
+       u64 __count = 1;                                                \
+       struct task_struct *__task = NULL;                              \
+       struct hlist_head *head;                                        \
+       int __entry_size;                                               \
+       int __data_size;                                                \
+       int rctx;                                                       \
+                                                                       \
+       __data_size = trace_event_get_offsets_##call(&__data_offsets, args); \
+                                                                       \
+       head = this_cpu_ptr(event_call->perf_events);                   \
+       if (!bpf_prog_array_valid(event_call) &&                        \
+           __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_alloc(__entry_size, &__regs, &rctx);     \
+       if (!entry)                                                     \
+               return;                                                 \
+                                                                       \
+       perf_fetch_caller_regs(__regs);                                 \
+                                                                       \
+       tstruct                                                         \
+                                                                       \
+       { assign; }                                                     \
+                                                                       \
+       perf_trace_run_bpf_submit(entry, __entry_size, rctx,            \
+                                 event_call, __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
diff --git a/include/trace/stages/stage3_trace_output.h 
b/include/trace/stages/stage3_trace_output.h
index c1fb1355d309..121425e695f5 100644
--- a/include/trace/stages/stage3_trace_output.h
+++ b/include/trace/stages/stage3_trace_output.h
@@ -142,3 +142,6 @@
 
 #undef __get_buf
 #define __get_buf(len)         trace_seq_acquire(p, (len))
+
+#undef TP_printk_init
+#define TP_printk_init(args...) args
diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h
index c2f9cabf154d..9a8872544a8b 100644
--- a/include/trace/trace_events.h
+++ b/include/trace/trace_events.h
@@ -45,6 +45,17 @@
                             PARAMS(print));                   \
        DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args));
 
+#undef TRACE_EVENT_PRINT_INIT
+#define TRACE_EVENT_PRINT_INIT(name, proto, args, tstruct, assign, print, 
init) \
+       DECLARE_EVENT_CLASS_PRINT_INIT(name,                           \
+                            PARAMS(proto),                    \
+                            PARAMS(args),                     \
+                            PARAMS(tstruct),                  \
+                            PARAMS(assign),                   \
+                            PARAMS(print),                     \
+                            PARAMS(init));                    \
+       DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args));
+
 #include "stages/stage1_struct_define.h"
 
 #undef DECLARE_EVENT_CLASS
@@ -57,6 +68,16 @@
                                                                        \
        static struct trace_event_class event_class_##name;
 
+#undef DECLARE_EVENT_CLASS_PRINT_INIT
+#define DECLARE_EVENT_CLASS_PRINT_INIT(name, proto, args, tstruct, assign, 
print, init)        \
+       struct trace_event_raw_##name {                                 \
+               struct trace_entry      ent;                            \
+               tstruct                                                 \
+               char                    __data[];                       \
+       };                                                              \
+                                                                       \
+       static struct trace_event_class event_class_##name;
+
 #undef DEFINE_EVENT
 #define DEFINE_EVENT(template, name, proto, args)      \
        static struct trace_event_call  __used          \
@@ -117,6 +138,12 @@
                tstruct;                                                \
        };
 
+#undef DECLARE_EVENT_CLASS_PRINT_INIT
+#define DECLARE_EVENT_CLASS_PRINT_INIT(call, proto, args, tstruct, assign, 
print, init)        \
+       struct trace_event_data_offsets_##call {                        \
+               tstruct;                                                \
+       };
+
 #undef DEFINE_EVENT
 #define DEFINE_EVENT(template, name, proto, args)
 
@@ -208,6 +235,32 @@ static struct trace_event_functions 
trace_event_type_funcs_##call = {      \
        .trace                  = trace_raw_output_##call,              \
 };
 
+#undef DECLARE_EVENT_CLASS_PRINT_INIT
+#define DECLARE_EVENT_CLASS_PRINT_INIT(call, proto, args, tstruct, assign, 
print, init)        \
+static notrace enum print_line_t                                       \
+trace_raw_output_##call(struct trace_iterator *iter, int flags,                
\
+                       struct trace_event *trace_event)                \
+{                                                                      \
+       struct trace_seq *s = &iter->seq;                               \
+       struct trace_seq __maybe_unused *p = &iter->tmp_seq;            \
+       struct trace_event_raw_##call *field;                           \
+       int ret;                                                        \
+                                                                       \
+       field = (typeof(field))iter->ent;                               \
+                                                                       \
+       ret = trace_raw_output_prep(iter, trace_event);                 \
+       if (ret != TRACE_TYPE_HANDLED)                                  \
+               return ret;                                             \
+                                                                       \
+       init                                                            \
+       trace_event_printf(iter, print);                                \
+                                                                       \
+       return trace_handle_return(s);                                  \
+}                                                                      \
+static struct trace_event_functions trace_event_type_funcs_##call = {  \
+       .trace                  = trace_raw_output_##call,              \
+};
+
 #undef DEFINE_EVENT_PRINT
 #define DEFINE_EVENT_PRINT(template, call, proto, args, print)         \
 static notrace enum print_line_t                                       \
@@ -244,6 +297,12 @@ static struct trace_event_fields 
trace_event_fields_##call[] = {   \
        tstruct                                                         \
        {} };
 
+#undef DECLARE_EVENT_CLASS_PRINT_INIT
+#define DECLARE_EVENT_CLASS_PRINT_INIT(call, proto, args, tstruct, func, 
print, init)  \
+static struct trace_event_fields trace_event_fields_##call[] = {       \
+       tstruct                                                         \
+       {} };
+
 #undef DEFINE_EVENT_PRINT
 #define DEFINE_EVENT_PRINT(template, name, proto, args, print)
 
@@ -265,6 +324,20 @@ static inline notrace int trace_event_get_offsets_##call(  
        \
        return __data_size;                                             \
 }
 
+#undef DECLARE_EVENT_CLASS_PRINT_INIT
+#define DECLARE_EVENT_CLASS_PRINT_INIT(call, proto, args, tstruct, assign, 
print, init)        \
+static inline notrace int trace_event_get_offsets_##call(              \
+       struct trace_event_data_offsets_##call *__data_offsets, proto)  \
+{                                                                      \
+       int __data_size = 0;                                            \
+       int __maybe_unused __item_length;                               \
+       struct trace_event_raw_##call __maybe_unused *entry;            \
+                                                                       \
+       tstruct;                                                        \
+                                                                       \
+       return __data_size;                                             \
+}
+
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
 /*
@@ -403,6 +476,37 @@ trace_event_raw_event_##call(void *__data, proto)          
        \
                                                                        \
        trace_event_buffer_commit(&fbuffer);                            \
 }
+
+#undef DECLARE_EVENT_CLASS_PRINT_INIT
+#define DECLARE_EVENT_CLASS_PRINT_INIT(call, proto, args, tstruct, assign, 
print, init)        \
+                                                                       \
+static notrace void                                                    \
+trace_event_raw_event_##call(void *__data, proto)                      \
+{                                                                      \
+       struct trace_event_file *trace_file = __data;                   \
+       struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\
+       struct trace_event_buffer fbuffer;                              \
+       struct trace_event_raw_##call *entry;                           \
+       int __data_size;                                                \
+                                                                       \
+       if (trace_trigger_soft_disabled(trace_file))                    \
+               return;                                                 \
+                                                                       \
+       __data_size = trace_event_get_offsets_##call(&__data_offsets, args); \
+                                                                       \
+       entry = trace_event_buffer_reserve(&fbuffer, trace_file,        \
+                                sizeof(*entry) + __data_size);         \
+                                                                       \
+       if (!entry)                                                     \
+               return;                                                 \
+                                                                       \
+       tstruct                                                         \
+                                                                       \
+       { assign; }                                                     \
+                                                                       \
+       trace_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
@@ -434,6 +538,20 @@ static struct trace_event_class __used __refdata 
event_class_##call = { \
        _TRACE_PERF_INIT(call)                                          \
 };
 
+#undef DECLARE_EVENT_CLASS_PRINT_INIT
+#define DECLARE_EVENT_CLASS_PRINT_INIT(call, proto, args, tstruct, assign, 
print, init)        \
+_TRACE_PERF_PROTO(call, PARAMS(proto));                                        
\
+static char print_fmt_##call[] = print;                                        
\
+static struct trace_event_class __used __refdata event_class_##call = { \
+       .system                 = TRACE_SYSTEM_STRING,                  \
+       .fields_array           = trace_event_fields_##call,            \
+       .fields                 = LIST_HEAD_INIT(event_class_##call.fields),\
+       .raw_init               = trace_event_raw_init,                 \
+       .probe                  = trace_event_raw_event_##call,         \
+       .reg                    = trace_event_reg,                      \
+       _TRACE_PERF_INIT(call)                                          \
+};
+
 #undef DEFINE_EVENT
 #define DEFINE_EVENT(template, call, proto, args)                      \
                                                                        \
-- 
2.17.1

Reply via email to