tracing: add TRACE_EVENT_MAP
authorJulien Desfossez <jdesfossez@efficios.com>
Fri, 9 Sep 2016 22:16:13 +0000 (18:16 -0400)
committerJulien Desfossez <jdesfossez@efficios.com>
Fri, 16 Sep 2016 21:05:58 +0000 (17:05 -0400)
This macro allows to create an alias of an existing TRACE_EVENT. A
TRACE_EVENT_MAP connects a new probe to an existing tracepoint, so we
can use it to create another output of the same tracepoint without
changing the instrumented code.

This allows to create alternate versions of existing tracepoints to
output more/other fields only in specific use-cases and not all the time
(which could break existing tools and/or bloat the trace with too many
useless fields).

The usage is the same as the TRACE_EVENT macro with the addition of the
"map" parameter which is the name of the alias, the "name" field is the
name of the original tracepoint:
TRACE_EVENT_MAP(name, map, proto, args, tstruct, assign, print)
DEFINE_EVENT_MAP(template, name, map, proto, args)

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt (Red Hat) <rostedt@goodmis.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Julien Desfossez <jdesfossez@efficios.com>
include/linux/trace_events.h
include/linux/tracepoint.h
include/trace/define_trace.h
include/trace/perf.h
include/trace/trace_events.h
kernel/trace/trace_events.c

index be007610ceb08aaa7cad1073effe73b24adff66d..1f7e0ec3bbf62376a907964869547d9ecb7968d2 100644 (file)
@@ -217,6 +217,7 @@ enum {
        TRACE_EVENT_FL_TRACEPOINT_BIT,
        TRACE_EVENT_FL_KPROBE_BIT,
        TRACE_EVENT_FL_UPROBE_BIT,
+       TRACE_EVENT_FL_MAP_BIT,
 };
 
 /*
@@ -231,6 +232,7 @@ enum {
  *  TRACEPOINT    - Event is a tracepoint
  *  KPROBE        - Event is a kprobe
  *  UPROBE        - Event is a uprobe
+ *  MAP           - Event maps to a tracepoint as an alias
  */
 enum {
        TRACE_EVENT_FL_FILTERED         = (1 << TRACE_EVENT_FL_FILTERED_BIT),
@@ -241,10 +243,16 @@ enum {
        TRACE_EVENT_FL_TRACEPOINT       = (1 << TRACE_EVENT_FL_TRACEPOINT_BIT),
        TRACE_EVENT_FL_KPROBE           = (1 << TRACE_EVENT_FL_KPROBE_BIT),
        TRACE_EVENT_FL_UPROBE           = (1 << TRACE_EVENT_FL_UPROBE_BIT),
+       TRACE_EVENT_FL_MAP              = (1 << TRACE_EVENT_FL_MAP_BIT),
 };
 
 #define TRACE_EVENT_FL_UKPROBE (TRACE_EVENT_FL_KPROBE | TRACE_EVENT_FL_UPROBE)
 
+struct trace_event_map {
+       struct tracepoint       *tp;
+       char                    *name;
+};
+
 struct trace_event_call {
        struct list_head        list;
        struct trace_event_class *class;
@@ -252,6 +260,8 @@ struct trace_event_call {
                char                    *name;
                /* Set TRACE_EVENT_FL_TRACEPOINT flag when using "tp" */
                struct tracepoint       *tp;
+               /* Set TRACE_EVENT_FL_MAP flag when using "map" instead */
+               struct trace_event_map  *map;
        };
        struct trace_event      event;
        char                    *print_fmt;
@@ -282,7 +292,9 @@ struct trace_event_call {
 static inline const char *
 trace_event_name(struct trace_event_call *call)
 {
-       if (call->flags & TRACE_EVENT_FL_TRACEPOINT)
+       if (call->flags & TRACE_EVENT_FL_MAP)
+               return call->map->name;
+       else if (call->flags & TRACE_EVENT_FL_TRACEPOINT)
                return call->tp ? call->tp->name : NULL;
        else
                return call->name;
index be586c632a0c04da3887ae6a0cf28357df98ef5c..b8ab12a70f81d83d66e19d2abdd9aba32451b686 100644 (file)
@@ -276,6 +276,7 @@ extern void syscall_unregfunc(void);
 
 #define DEFINE_TRACE_FN(name, reg, unreg)
 #define DEFINE_TRACE(name)
+#define DEFINE_TRACE_MAP(name, map)
 #define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
 #define EXPORT_TRACEPOINT_SYMBOL(name)
 
@@ -466,6 +467,13 @@ extern void syscall_unregfunc(void);
  *
  * A set of (un)registration functions can be passed to the variant
  * TRACE_EVENT_FN to perform any (un)registration work.
+ *
+ * TRACE_EVENT_MAP can be used to create alternate versions of a
+ * TRACE_EVENT without modifying the instrumented code. It connects
+ * a different probe to an existing tracepoint, so other fields can be
+ * extracted. The "name" field is the name of the original TRACE_EVENT,
+ * the "map" field is the name of the alias. They can be enabled
+ * independently.
  */
 
 #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
@@ -493,9 +501,10 @@ extern void syscall_unregfunc(void);
                              struct, assign, print)            \
        DECLARE_TRACE_CONDITION(name, PARAMS(proto),            \
                                PARAMS(args), PARAMS(cond))
-
 #define TRACE_EVENT_FLAGS(event, flag)
 
 #define TRACE_EVENT_PERF_PERM(event, expr...)
 
+#define TRACE_EVENT_MAP(name, map, proto, args, struct, assign, print)
+
 #endif /* ifdef TRACE_EVENT (see note above) */
index 6e3945f64102c275669fc3a0c21f910c3be7be03..fdd88459943a418858bbf55ebce57c37de422e89 100644 (file)
@@ -26,6 +26,9 @@
 #define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
        DEFINE_TRACE(name)
 
+#undef TRACE_EVENT_MAP
+#define TRACE_EVENT_MAP(name, map, proto, args, tstruct, assign, print)
+
 #undef TRACE_EVENT_CONDITION
 #define TRACE_EVENT_CONDITION(name, proto, args, cond, tstruct, assign, print) \
        TRACE_EVENT(name,                                               \
 #undef TRACE_EVENT_FN
 #undef TRACE_EVENT_FN_COND
 #undef TRACE_EVENT_CONDITION
+#undef TRACE_EVENT_MAP
 #undef DECLARE_EVENT_CLASS
 #undef DEFINE_EVENT
 #undef DEFINE_EVENT_FN
index 04fe68bbe7679f48ef5e58b883b7780a5b6fbbfd..563d44159ba208d67895442f2292c45075cec1af 100644 (file)
@@ -86,5 +86,12 @@ static inline void perf_test_probe_##call(void)                              \
 #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
        DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
 
+#undef DEFINE_EVENT_MAP
+#define DEFINE_EVENT_MAP(template, call, map, proto, args)             \
+static inline void perf_test_probe_##map(void)                         \
+{                                                                      \
+       check_trace_callback_type_##call(perf_trace_##template);        \
+}
+
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 #endif /* CONFIG_PERF_EVENTS */
index 467e12f780d863956b1b1b650c406d9d4cb5c0c2..deb5bc6954b181283dba24d50e9feca44b828f0c 100644 (file)
@@ -65,6 +65,15 @@ TRACE_MAKE_SYSTEM_STR();
                             PARAMS(print));                   \
        DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args));
 
+#undef TRACE_EVENT_MAP
+#define TRACE_EVENT_MAP(name, map, proto, args, tstruct, assign, print) \
+       DECLARE_EVENT_CLASS(map,                               \
+                            PARAMS(proto),                    \
+                            PARAMS(args),                     \
+                            PARAMS(tstruct),                  \
+                            PARAMS(assign),                   \
+                            PARAMS(print));                   \
+       DEFINE_EVENT_MAP(map, name, map, PARAMS(proto), PARAMS(args));
 
 #undef __field
 #define __field(type, item)            type    item;
@@ -108,6 +117,11 @@ TRACE_MAKE_SYSTEM_STR();
        static struct trace_event_call  __used          \
        __attribute__((__aligned__(4))) event_##name
 
+#undef DEFINE_EVENT_MAP
+#define DEFINE_EVENT_MAP(template, name, map, proto, args)     \
+       static struct trace_event_call  __used          \
+       __attribute__((__aligned__(4))) event_##map
+
 #undef DEFINE_EVENT_FN
 #define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)       \
        DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
@@ -191,6 +205,9 @@ TRACE_MAKE_SYSTEM_STR();
 #undef DEFINE_EVENT
 #define DEFINE_EVENT(template, name, proto, args)
 
+#undef DEFINE_EVENT_MAP
+#define DEFINE_EVENT_MAP(template, name, map, proto, args)
+
 #undef DEFINE_EVENT_PRINT
 #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
        DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
@@ -426,6 +443,9 @@ trace_event_define_fields_##call(struct trace_event_call *event_call)       \
 #undef DEFINE_EVENT
 #define DEFINE_EVENT(template, name, proto, args)
 
+#undef DEFINE_EVENT_MAP
+#define DEFINE_EVENT_MAP(template, name, map, proto, args)
+
 #undef DEFINE_EVENT_PRINT
 #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
        DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
@@ -506,6 +526,9 @@ static inline notrace int trace_event_get_offsets_##call(           \
 #undef DEFINE_EVENT
 #define DEFINE_EVENT(template, name, proto, args)
 
+#undef DEFINE_EVENT_MAP
+#define DEFINE_EVENT_MAP(template, name, map, proto, args)
+
 #undef DEFINE_EVENT_PRINT
 #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
        DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
@@ -700,6 +723,13 @@ static inline void ftrace_test_probe_##call(void)                  \
        check_trace_callback_type_##call(trace_event_raw_event_##template); \
 }
 
+#undef DEFINE_EVENT_MAP
+#define DEFINE_EVENT_MAP(template, call, map, proto, args)             \
+static inline void ftrace_test_probe_##map(void)                       \
+{                                                                      \
+       check_trace_callback_type_##call(trace_event_raw_event_##template); \
+}
+
 #undef DEFINE_EVENT_PRINT
 #define DEFINE_EVENT_PRINT(template, name, proto, args, print)
 
@@ -749,6 +779,26 @@ static struct trace_event_call __used event_##call = {                     \
 static struct trace_event_call __used                                  \
 __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call
 
+#undef DEFINE_EVENT_MAP
+#define DEFINE_EVENT_MAP(_template, _call, _map, _proto, _args)                \
+                                                                       \
+static struct trace_event_map event_map_##_map = {                     \
+       .tp = &__tracepoint_##_call,                                    \
+       .name = #_map,                                                  \
+};                                                                     \
+                                                                       \
+static struct trace_event_call __used event_##_map = {                 \
+       .class                  = &event_class_##_template,             \
+       {                                                               \
+               .map                    = &event_map_##_map,            \
+       },                                                              \
+       .event.funcs            = &trace_event_type_funcs_##_template,  \
+       .print_fmt              = print_fmt_##_template,                \
+       .flags                  = TRACE_EVENT_FL_TRACEPOINT | TRACE_EVENT_FL_MAP,\
+};                                                                     \
+static struct trace_event_call __used                                  \
+__attribute__((section("_ftrace_events"))) *__event_##_map = &event_##_map
+
 #undef DEFINE_EVENT_PRINT
 #define DEFINE_EVENT_PRINT(template, call, proto, args, print)         \
                                                                        \
index 03c0a48c3ac4f3daca47a46e401a75f02a826316..8b46dd8f3643ab5018638a09c58bb2db6023b907 100644 (file)
@@ -327,26 +327,33 @@ int trace_event_reg(struct trace_event_call *call,
                    enum trace_reg type, void *data)
 {
        struct trace_event_file *file = data;
+       struct tracepoint *tp;
 
        WARN_ON(!(call->flags & TRACE_EVENT_FL_TRACEPOINT));
+
+       if (call->flags & TRACE_EVENT_FL_MAP)
+               tp = call->map->tp;
+       else
+               tp = call->tp;
+
        switch (type) {
        case TRACE_REG_REGISTER:
-               return tracepoint_probe_register(call->tp,
+               return tracepoint_probe_register(tp,
                                                 call->class->probe,
                                                 file);
        case TRACE_REG_UNREGISTER:
-               tracepoint_probe_unregister(call->tp,
+               tracepoint_probe_unregister(tp,
                                            call->class->probe,
                                            file);
                return 0;
 
 #ifdef CONFIG_PERF_EVENTS
        case TRACE_REG_PERF_REGISTER:
-               return tracepoint_probe_register(call->tp,
+               return tracepoint_probe_register(tp,
                                                 call->class->perf_probe,
                                                 call);
        case TRACE_REG_PERF_UNREGISTER:
-               tracepoint_probe_unregister(call->tp,
+               tracepoint_probe_unregister(tp,
                                            call->class->perf_probe,
                                            call);
                return 0;
This page took 0.031684 seconds and 5 git commands to generate.