@@ -149,6 +149,7 @@ struct trace_event {
struct hlist_node node;
int type;
struct trace_event_functions *funcs;
+ const char *name;
};
extern int register_trace_event(struct trace_event *event);
@@ -443,6 +443,7 @@ static struct trace_event_call __used event_##call = { \
.tp = &__tracepoint_##call, \
}, \
.event.funcs = &trace_event_type_funcs_##template, \
+ .event.name = __stringify(call), \
.print_fmt = print_fmt_##template, \
.flags = TRACE_EVENT_FL_TRACEPOINT, \
}; \
@@ -460,6 +461,7 @@ static struct trace_event_call __used event_##call = { \
.tp = &__tracepoint_##call, \
}, \
.event.funcs = &trace_event_type_funcs_##call, \
+ .event.name = __stringify(template), \
.print_fmt = print_fmt_##call, \
.flags = TRACE_EVENT_FL_TRACEPOINT, \
}; \
@@ -1584,6 +1584,7 @@ static struct trace_event_functions trace_blk_event_funcs = {
static struct trace_event trace_blk_event = {
.type = TRACE_BLK,
.funcs = &trace_blk_event_funcs,
+ .name = "blk",
};
static int __init init_blk_tracer(void)
@@ -168,6 +168,7 @@ static struct trace_event_functions trace_branch_funcs = {
static struct trace_event trace_branch_event = {
.type = TRACE_BRANCH,
.funcs = &trace_branch_funcs,
+ .name = "branch",
};
static struct tracer branch_trace __read_mostly =
@@ -2658,6 +2658,9 @@ static int event_init(struct trace_event_call *call)
if (WARN_ON(!name))
return -EINVAL;
+ if (!call->event.name)
+ call->event.name = name;
+
if (call->class->raw_init) {
ret = call->class->raw_init(call);
if (ret < 0 && ret != -ENOSYS)
@@ -1342,11 +1342,13 @@ static struct trace_event_functions graph_functions = {
static struct trace_event graph_trace_entry_event = {
.type = TRACE_GRAPH_ENT,
.funcs = &graph_functions,
+ .name = "graph_ent",
};
static struct trace_event graph_trace_ret_event = {
.type = TRACE_GRAPH_RET,
- .funcs = &graph_functions
+ .funcs = &graph_functions,
+ .name = "graph_ret",
};
static struct tracer graph_trace __tracer_data = {
@@ -1067,6 +1067,7 @@ static struct trace_event_functions trace_fn_funcs = {
static struct trace_event trace_fn_event = {
.type = TRACE_FN,
.funcs = &trace_fn_funcs,
+ .name = "fn",
};
/* TRACE_CTX an TRACE_WAKE */
@@ -1207,6 +1208,7 @@ static struct trace_event_functions trace_ctx_funcs = {
static struct trace_event trace_ctx_event = {
.type = TRACE_CTX,
.funcs = &trace_ctx_funcs,
+ .name = "ctx",
};
static struct trace_event_functions trace_wake_funcs = {
@@ -1219,6 +1221,7 @@ static struct trace_event_functions trace_wake_funcs = {
static struct trace_event trace_wake_event = {
.type = TRACE_WAKE,
.funcs = &trace_wake_funcs,
+ .name = "wake",
};
/* TRACE_STACK */
@@ -1256,6 +1259,7 @@ static struct trace_event_functions trace_stack_funcs = {
static struct trace_event trace_stack_event = {
.type = TRACE_STACK,
.funcs = &trace_stack_funcs,
+ .name = "stack",
};
/* TRACE_USER_STACK */
@@ -1309,6 +1313,7 @@ static struct trace_event_functions trace_user_stack_funcs = {
static struct trace_event trace_user_stack_event = {
.type = TRACE_USER_STACK,
.funcs = &trace_user_stack_funcs,
+ .name = "user_stack",
};
/* TRACE_HWLAT */
@@ -1373,6 +1378,7 @@ static struct trace_event_functions trace_hwlat_funcs = {
static struct trace_event trace_hwlat_event = {
.type = TRACE_HWLAT,
.funcs = &trace_hwlat_funcs,
+ .name = "hwlat",
};
/* TRACE_OSNOISE */
@@ -1443,6 +1449,7 @@ static struct trace_event_functions trace_osnoise_funcs = {
static struct trace_event trace_osnoise_event = {
.type = TRACE_OSNOISE,
.funcs = &trace_osnoise_funcs,
+ .name = "osnoise",
};
/* TRACE_TIMERLAT */
@@ -1491,6 +1498,7 @@ static struct trace_event_functions trace_timerlat_funcs = {
static struct trace_event trace_timerlat_event = {
.type = TRACE_TIMERLAT,
.funcs = &trace_timerlat_funcs,
+ .name = "timerlat",
};
/* TRACE_BPUTS */
@@ -1535,6 +1543,7 @@ static struct trace_event_functions trace_bputs_funcs = {
static struct trace_event trace_bputs_event = {
.type = TRACE_BPUTS,
.funcs = &trace_bputs_funcs,
+ .name = "bputs",
};
/* TRACE_BPRINT */
@@ -1579,6 +1588,7 @@ static struct trace_event_functions trace_bprint_funcs = {
static struct trace_event trace_bprint_event = {
.type = TRACE_BPRINT,
.funcs = &trace_bprint_funcs,
+ .name = "bprint",
};
/* TRACE_PRINT */
@@ -1616,6 +1626,7 @@ static struct trace_event_functions trace_print_funcs = {
static struct trace_event trace_print_event = {
.type = TRACE_PRINT,
.funcs = &trace_print_funcs,
+ .name = "print",
};
static enum print_line_t trace_raw_data(struct trace_iterator *iter, int flags,
@@ -1645,6 +1656,7 @@ static struct trace_event_functions trace_raw_data_funcs = {
static struct trace_event trace_raw_data_event = {
.type = TRACE_RAW_DATA,
.funcs = &trace_raw_data_funcs,
+ .name = "raw_data",
};
static enum print_line_t
@@ -1691,6 +1703,7 @@ static struct trace_event_functions trace_func_repeats_funcs = {
static struct trace_event trace_func_repeats_event = {
.type = TRACE_FUNC_REPEATS,
.funcs = &trace_func_repeats_funcs,
+ .name = "func_repeats",
};
static struct trace_event *events[] __initdata = {
@@ -1835,6 +1835,9 @@ int trace_probe_register_event_call(struct trace_probe *tp)
trace_probe_name(tp)))
return -EEXIST;
+ if (!call->event.name)
+ call->event.name = call->name;
+
ret = register_trace_event(&call->event);
if (!ret)
return -ENODEV;
@@ -441,8 +441,29 @@ static void unreg_event_syscall_exit(struct trace_event_file *file,
mutex_unlock(&syscall_trace_lock);
}
+/**
+ * trace_csum - a simple checksum generator
+ *
+ * This returns a checksum for data that should not generate
+ * a lot of collisions, but is trivial to read.
+ */
+static u32 __init trace_csum(void *data, u32 len)
+{
+ u32 r = 0, i;
+ char *p = data;
+
+ if (!data)
+ return 0;
+
+ for (i = 0; i < len; i++)
+ r = (r >> 31) + (r << 1) + p[i];
+
+ return (r << 4) + len;
+}
+
static int __init init_syscall_trace(struct trace_event_call *call)
{
+ u32 csum;
int id;
int num;
@@ -456,9 +477,17 @@ static int __init init_syscall_trace(struct trace_event_call *call)
if (set_syscall_print_fmt(call) < 0)
return -ENOMEM;
+ csum = (trace_csum(call->print_fmt, strlen(call->print_fmt)) << 4) + num;
+ call->event.name = kasprintf(GFP_KERNEL, "sc-%x", csum);
+ if (!call->event.name) {
+ free_syscall_print_fmt(call);
+ return -ENOMEM;
+ }
+
id = trace_event_raw_init(call);
if (id < 0) {
+ kfree(call->event.name);
free_syscall_print_fmt(call);
return id;
}
With KHO (Kexec HandOver), we want to preserve trace buffers. To parse them, we need to ensure that all trace events that exist in the logs are identical to the ones we parse as. That means we need to match the events before and after kexec. As a first step towards that, let's give every event a unique name. That way we can clearly identify the event before and after kexec and restore its ID post-kexec. Signed-off-by: Alexander Graf <graf@amazon.com> --- include/linux/trace_events.h | 1 + include/trace/trace_events.h | 2 ++ kernel/trace/blktrace.c | 1 + kernel/trace/trace_branch.c | 1 + kernel/trace/trace_events.c | 3 +++ kernel/trace/trace_functions_graph.c | 4 +++- kernel/trace/trace_output.c | 13 +++++++++++++ kernel/trace/trace_probe.c | 3 +++ kernel/trace/trace_syscalls.c | 29 ++++++++++++++++++++++++++++ 9 files changed, 56 insertions(+), 1 deletion(-)