|
@@ -1,3 +1,216 @@
|
|
|
+/*
|
|
|
+ * Stage 1 of the trace events.
|
|
|
+ *
|
|
|
+ * Override the macros in <trace/trace_events.h> to include the following:
|
|
|
+ *
|
|
|
+ * struct ftrace_raw_<call> {
|
|
|
+ * struct trace_entry ent;
|
|
|
+ * <type> <item>;
|
|
|
+ * <type2> <item2>[<len>];
|
|
|
+ * [...]
|
|
|
+ * };
|
|
|
+ *
|
|
|
+ * The <type> <item> is created by the __field(type, item) macro or
|
|
|
+ * the __array(type2, item2, len) macro.
|
|
|
+ * We simply do "type item;", and that will create the fields
|
|
|
+ * in the structure.
|
|
|
+ */
|
|
|
+
|
|
|
+#include <linux/ftrace_event.h>
|
|
|
+
|
|
|
+#undef TRACE_FORMAT
|
|
|
+#define TRACE_FORMAT(call, proto, args, fmt)
|
|
|
+
|
|
|
+#undef __array
|
|
|
+#define __array(type, item, len) type item[len];
|
|
|
+
|
|
|
+#undef __field
|
|
|
+#define __field(type, item) type item;
|
|
|
+
|
|
|
+#undef TP_STRUCT__entry
|
|
|
+#define TP_STRUCT__entry(args...) args
|
|
|
+
|
|
|
+#undef TRACE_EVENT
|
|
|
+#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
|
|
|
+ struct ftrace_raw_##name { \
|
|
|
+ struct trace_entry ent; \
|
|
|
+ tstruct \
|
|
|
+ }; \
|
|
|
+ static struct ftrace_event_call event_##name
|
|
|
+
|
|
|
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Stage 2 of the trace events.
|
|
|
+ *
|
|
|
+ * Override the macros in <trace/trace_events.h> to include the following:
|
|
|
+ *
|
|
|
+ * enum print_line_t
|
|
|
+ * ftrace_raw_output_<call>(struct trace_iterator *iter, int flags)
|
|
|
+ * {
|
|
|
+ * struct trace_seq *s = &iter->seq;
|
|
|
+ * struct ftrace_raw_<call> *field; <-- defined in stage 1
|
|
|
+ * struct trace_entry *entry;
|
|
|
+ * int ret;
|
|
|
+ *
|
|
|
+ * entry = iter->ent;
|
|
|
+ *
|
|
|
+ * if (entry->type != event_<call>.id) {
|
|
|
+ * WARN_ON_ONCE(1);
|
|
|
+ * return TRACE_TYPE_UNHANDLED;
|
|
|
+ * }
|
|
|
+ *
|
|
|
+ * field = (typeof(field))entry;
|
|
|
+ *
|
|
|
+ * ret = trace_seq_printf(s, <TP_printk> "\n");
|
|
|
+ * if (!ret)
|
|
|
+ * return TRACE_TYPE_PARTIAL_LINE;
|
|
|
+ *
|
|
|
+ * return TRACE_TYPE_HANDLED;
|
|
|
+ * }
|
|
|
+ *
|
|
|
+ * This is the method used to print the raw event to the trace
|
|
|
+ * output format. Note, this is not needed if the data is read
|
|
|
+ * in binary.
|
|
|
+ */
|
|
|
+
|
|
|
+#undef __entry
|
|
|
+#define __entry field
|
|
|
+
|
|
|
+#undef TP_printk
|
|
|
+#define TP_printk(fmt, args...) fmt "\n", args
|
|
|
+
|
|
|
+#undef TRACE_EVENT
|
|
|
+#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
|
|
|
+enum print_line_t \
|
|
|
+ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
|
|
|
+{ \
|
|
|
+ struct trace_seq *s = &iter->seq; \
|
|
|
+ struct ftrace_raw_##call *field; \
|
|
|
+ struct trace_entry *entry; \
|
|
|
+ int ret; \
|
|
|
+ \
|
|
|
+ entry = iter->ent; \
|
|
|
+ \
|
|
|
+ if (entry->type != event_##call.id) { \
|
|
|
+ WARN_ON_ONCE(1); \
|
|
|
+ return TRACE_TYPE_UNHANDLED; \
|
|
|
+ } \
|
|
|
+ \
|
|
|
+ field = (typeof(field))entry; \
|
|
|
+ \
|
|
|
+ ret = trace_seq_printf(s, #call ": " print); \
|
|
|
+ if (!ret) \
|
|
|
+ return TRACE_TYPE_PARTIAL_LINE; \
|
|
|
+ \
|
|
|
+ return TRACE_TYPE_HANDLED; \
|
|
|
+}
|
|
|
+
|
|
|
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Setup the showing format of trace point.
|
|
|
+ *
|
|
|
+ * int
|
|
|
+ * ftrace_format_##call(struct trace_seq *s)
|
|
|
+ * {
|
|
|
+ * struct ftrace_raw_##call field;
|
|
|
+ * int ret;
|
|
|
+ *
|
|
|
+ * ret = trace_seq_printf(s, #type " " #item ";"
|
|
|
+ * " offset:%u; size:%u;\n",
|
|
|
+ * offsetof(struct ftrace_raw_##call, item),
|
|
|
+ * sizeof(field.type));
|
|
|
+ *
|
|
|
+ * }
|
|
|
+ */
|
|
|
+
|
|
|
+#undef TP_STRUCT__entry
|
|
|
+#define TP_STRUCT__entry(args...) args
|
|
|
+
|
|
|
+#undef __field
|
|
|
+#define __field(type, item) \
|
|
|
+ ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
|
|
|
+ "offset:%u;\tsize:%u;\n", \
|
|
|
+ (unsigned int)offsetof(typeof(field), item), \
|
|
|
+ (unsigned int)sizeof(field.item)); \
|
|
|
+ if (!ret) \
|
|
|
+ return 0;
|
|
|
+
|
|
|
+#undef __array
|
|
|
+#define __array(type, item, len) \
|
|
|
+ ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
|
|
|
+ "offset:%u;\tsize:%u;\n", \
|
|
|
+ (unsigned int)offsetof(typeof(field), item), \
|
|
|
+ (unsigned int)sizeof(field.item)); \
|
|
|
+ if (!ret) \
|
|
|
+ return 0;
|
|
|
+
|
|
|
+#undef __entry
|
|
|
+#define __entry REC
|
|
|
+
|
|
|
+#undef TP_printk
|
|
|
+#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
|
|
|
+
|
|
|
+#undef TP_fast_assign
|
|
|
+#define TP_fast_assign(args...) args
|
|
|
+
|
|
|
+#undef TRACE_EVENT
|
|
|
+#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
|
|
|
+static int \
|
|
|
+ftrace_format_##call(struct trace_seq *s) \
|
|
|
+{ \
|
|
|
+ struct ftrace_raw_##call field; \
|
|
|
+ int ret; \
|
|
|
+ \
|
|
|
+ tstruct; \
|
|
|
+ \
|
|
|
+ trace_seq_printf(s, "\nprint fmt: " print); \
|
|
|
+ \
|
|
|
+ return ret; \
|
|
|
+}
|
|
|
+
|
|
|
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
|
|
|
+
|
|
|
+#undef __field
|
|
|
+#define __field(type, item) \
|
|
|
+ ret = trace_define_field(event_call, #type, #item, \
|
|
|
+ offsetof(typeof(field), item), \
|
|
|
+ sizeof(field.item)); \
|
|
|
+ if (ret) \
|
|
|
+ return ret;
|
|
|
+
|
|
|
+#undef __array
|
|
|
+#define __array(type, item, len) \
|
|
|
+ BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \
|
|
|
+ ret = trace_define_field(event_call, #type "[" #len "]", #item, \
|
|
|
+ offsetof(typeof(field), item), \
|
|
|
+ sizeof(field.item)); \
|
|
|
+ if (ret) \
|
|
|
+ return ret;
|
|
|
+
|
|
|
+#undef TRACE_EVENT
|
|
|
+#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
|
|
|
+int \
|
|
|
+ftrace_define_fields_##call(void) \
|
|
|
+{ \
|
|
|
+ struct ftrace_raw_##call field; \
|
|
|
+ struct ftrace_event_call *event_call = &event_##call; \
|
|
|
+ int ret; \
|
|
|
+ \
|
|
|
+ __common_field(unsigned char, type); \
|
|
|
+ __common_field(unsigned char, flags); \
|
|
|
+ __common_field(unsigned char, preempt_count); \
|
|
|
+ __common_field(int, pid); \
|
|
|
+ __common_field(int, tgid); \
|
|
|
+ \
|
|
|
+ tstruct; \
|
|
|
+ \
|
|
|
+ return ret; \
|
|
|
+}
|
|
|
+
|
|
|
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
|
|
|
+
|
|
|
/*
|
|
|
* Stage 3 of the trace events.
|
|
|
*
|
|
@@ -272,7 +485,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
|
|
|
_TRACE_PROFILE_INIT(call) \
|
|
|
}
|
|
|
|
|
|
-#include <trace/trace_events.h>
|
|
|
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
|
|
|
|
|
|
#undef _TRACE_PROFILE
|
|
|
#undef _TRACE_PROFILE_INIT
|