Assigns new event ids for each kprobes event. This doesn't clear ring_buffer when unregistering each kprobe event. Thus, if you mind 'Unknown event' messages, clear the buffer manually after changing kprobe events. Signed-off-by: Masami Hiramatsu <mhiramat@xxxxxxxxxx> Cc: Ananth N Mavinakayanahalli <ananth@xxxxxxxxxx> Cc: Avi Kivity <avi@xxxxxxxxxx> Cc: Andi Kleen <ak@xxxxxxxxxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxxxxxxxxx> Cc: Frank Ch. Eigler <fche@xxxxxxxxxx> Cc: Frederic Weisbecker <fweisbec@xxxxxxxxx> Cc: H. Peter Anvin <hpa@xxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxx> Cc: Jason Baron <jbaron@xxxxxxxxxx> Cc: Jim Keniston <jkenisto@xxxxxxxxxx> Cc: K.Prasad <prasad@xxxxxxxxxxxxxxxxxx> Cc: Lai Jiangshan <laijs@xxxxxxxxxxxxxx> Cc: Li Zefan <lizf@xxxxxxxxxxxxxx> Cc: Przemysław Pawełczyk <przemyslaw@xxxxxxxxxxxx> Cc: Roland McGrath <roland@xxxxxxxxxx> Cc: Sam Ravnborg <sam@xxxxxxxxxxxx> Cc: Srikar Dronamraju <srikar@xxxxxxxxxxxxxxxxxx> Cc: Steven Rostedt <rostedt@xxxxxxxxxxx> Cc: Tom Zanussi <tzanussi@xxxxxxxxx> Cc: Vegard Nossum <vegard.nossum@xxxxxxxxx> --- kernel/trace/trace.h | 6 ----- kernel/trace/trace_kprobe.c | 51 +++++++++++++------------------------------ 2 files changed, 15 insertions(+), 42 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 4ce4525..0b78d76 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -43,8 +43,6 @@ enum trace_type { TRACE_POWER, TRACE_BLK, TRACE_KSYM, - TRACE_KPROBE, - TRACE_KRETPROBE, __TRACE_LAST_TYPE, }; @@ -358,10 +356,6 @@ extern void __ftrace_bad_type(void); IF_ASSIGN(var, ent, struct kmemtrace_free_entry, \ TRACE_KMEM_FREE); \ IF_ASSIGN(var, ent, struct ksym_trace_entry, TRACE_KSYM);\ - IF_ASSIGN(var, ent, struct kprobe_trace_entry, \ - TRACE_KPROBE); \ - IF_ASSIGN(var, ent, struct kretprobe_trace_entry, \ - TRACE_KRETPROBE); \ __ftrace_bad_type(); \ } while (0) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index ec137ed..0e8498e 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -186,6 +186,7 @@ struct trace_probe { }; const char *symbol; /* symbol name */ struct ftrace_event_call call; + struct trace_event event; unsigned int nr_args; struct fetch_func args[]; }; @@ -795,7 +796,7 @@ static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args); - event = trace_current_buffer_lock_reserve(TRACE_KPROBE, size, + event = trace_current_buffer_lock_reserve(call->id, size, irq_flags, pc); if (!event) return 0; @@ -827,7 +828,7 @@ static __kprobes int kretprobe_trace_func(struct kretprobe_instance *ri, size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args); - event = trace_current_buffer_lock_reserve(TRACE_KRETPROBE, size, + event = trace_current_buffer_lock_reserve(call->id, size, irq_flags, pc); if (!event) return 0; @@ -853,7 +854,7 @@ print_kprobe_event(struct trace_iterator *iter, int flags) struct trace_seq *s = &iter->seq; int i; - trace_assign_type(field, iter->ent); + field = (struct kprobe_trace_entry *)iter->ent; if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET)) goto partial; @@ -880,7 +881,7 @@ print_kretprobe_event(struct trace_iterator *iter, int flags) struct trace_seq *s = &iter->seq; int i; - trace_assign_type(field, iter->ent); + field = (struct kretprobe_trace_entry *)iter->ent; if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET)) goto partial; @@ -906,16 +907,6 @@ partial: return TRACE_TYPE_PARTIAL_LINE; } -static struct trace_event kprobe_trace_event = { - .type = TRACE_KPROBE, - .trace = print_kprobe_event, -}; - -static struct trace_event kretprobe_trace_event = { - .type = TRACE_KRETPROBE, - .trace = print_kretprobe_event, -}; - static int probe_event_enable(struct ftrace_event_call *call) { struct trace_probe *tp = (struct trace_probe *)call->data; @@ -1107,35 +1098,35 @@ static int register_probe_event(struct trace_probe *tp) /* Initialize ftrace_event_call */ call->system = "kprobes"; if (probe_is_return(tp)) { - call->event = &kretprobe_trace_event; - call->id = TRACE_KRETPROBE; + tp->event.trace = print_kretprobe_event; call->raw_init = probe_event_raw_init; call->show_format = kretprobe_event_show_format; call->define_fields = kretprobe_event_define_fields; } else { - call->event = &kprobe_trace_event; - call->id = TRACE_KPROBE; + tp->event.trace = print_kprobe_event; call->raw_init = probe_event_raw_init; call->show_format = kprobe_event_show_format; call->define_fields = kprobe_event_define_fields; } + call->event = &tp->event; + call->id = register_ftrace_event(&tp->event); + if (!call->id) + return -ENODEV; call->enabled = 1; call->regfunc = probe_event_enable; call->unregfunc = probe_event_disable; call->data = tp; ret = trace_add_event_call(call); - if (ret) + if (ret) { pr_info("Failed to register kprobe event: %s\n", call->name); + unregister_ftrace_event(&tp->event); + } return ret; } static void unregister_probe_event(struct trace_probe *tp) { - /* - * Prevent to unregister event itself because the event is shared - * among other probes. - */ - tp->call.event = NULL; + /* tp->event is unregistered in trace_remove_event_call() */ trace_remove_event_call(&tp->call); } @@ -1144,18 +1135,6 @@ static __init int init_kprobe_trace(void) { struct dentry *d_tracer; struct dentry *entry; - int ret; - - ret = register_ftrace_event(&kprobe_trace_event); - if (!ret) { - pr_warning("Could not register kprobe_trace_event type.\n"); - return 0; - } - ret = register_ftrace_event(&kretprobe_trace_event); - if (!ret) { - pr_warning("Could not register kretprobe_trace_event type.\n"); - return 0; - } d_tracer = tracing_init_dentry(); if (!d_tracer) -- Masami Hiramatsu Software Engineer Hitachi Computer Products (America), Inc. Software Solutions Division e-mail: mhiramat@xxxxxxxxxx -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html