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 <mhira...@redhat.com>
Cc: Ananth N Mavinakayanahalli <ana...@in.ibm.com>
Cc: Avi Kivity <a...@redhat.com>
Cc: Andi Kleen <a...@linux.intel.com>
Cc: Christoph Hellwig <h...@infradead.org>
Cc: Frank Ch. Eigler <f...@redhat.com>
Cc: Frederic Weisbecker <fweis...@gmail.com>
Cc: H. Peter Anvin <h...@zytor.com>
Cc: Ingo Molnar <mi...@elte.hu>
Cc: Jason Baron <jba...@redhat.com>
Cc: Jim Keniston <jkeni...@us.ibm.com>
Cc: K.Prasad <pra...@linux.vnet.ibm.com>
Cc: Lai Jiangshan <la...@cn.fujitsu.com>
Cc: Li Zefan <l...@cn.fujitsu.com>
Cc: Przemysław Pawełczyk <przemys...@pawelczyk.it>
Cc: Roland McGrath <rol...@redhat.com>
Cc: Sam Ravnborg <s...@ravnborg.org>
Cc: Srikar Dronamraju <sri...@linux.vnet.ibm.com>
Cc: Steven Rostedt <rost...@goodmis.org>
Cc: Tom Zanussi <tzanu...@gmail.com>
Cc: Vegard Nossum <vegard.nos...@gmail.com>
---

 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: mhira...@redhat.com
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to