diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2009-08-13 16:35:34 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-08-26 20:32:33 -0400 |
commit | ff50d99136c3315513ef3b2921e77f35ab04d081 (patch) | |
tree | 133f4dc7b9b310a1d9b959c0c013d8fce30a2917 /kernel/trace/trace_kprobe.c | |
parent | 4263565d491145b57621a761714f2ca6f1293a45 (diff) |
tracing: Kprobe tracer assigns new event ids for each event
Assign 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@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Avi Kivity <avi@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: K.Prasad <prasad@linux.vnet.ibm.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Przemysław Pawełczyk <przemyslaw@pawelczyk.it>
Cc: Roland McGrath <roland@redhat.com>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Vegard Nossum <vegard.nossum@gmail.com>
LKML-Reference: <20090813203534.31965.49105.stgit@localhost.localdomain>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
-rw-r--r-- | kernel/trace/trace_kprobe.c | 51 |
1 files changed, 15 insertions, 36 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 8aeb24cc295f..9c067bf47d50 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -186,6 +186,7 @@ struct trace_probe { | |||
186 | }; | 186 | }; |
187 | const char *symbol; /* symbol name */ | 187 | const char *symbol; /* symbol name */ |
188 | struct ftrace_event_call call; | 188 | struct ftrace_event_call call; |
189 | struct trace_event event; | ||
189 | unsigned int nr_args; | 190 | unsigned int nr_args; |
190 | struct fetch_func args[]; | 191 | struct fetch_func args[]; |
191 | }; | 192 | }; |
@@ -795,7 +796,7 @@ static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | |||
795 | 796 | ||
796 | size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args); | 797 | size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args); |
797 | 798 | ||
798 | event = trace_current_buffer_lock_reserve(TRACE_KPROBE, size, | 799 | event = trace_current_buffer_lock_reserve(call->id, size, |
799 | irq_flags, pc); | 800 | irq_flags, pc); |
800 | if (!event) | 801 | if (!event) |
801 | return 0; | 802 | return 0; |
@@ -827,7 +828,7 @@ static __kprobes int kretprobe_trace_func(struct kretprobe_instance *ri, | |||
827 | 828 | ||
828 | size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args); | 829 | size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args); |
829 | 830 | ||
830 | event = trace_current_buffer_lock_reserve(TRACE_KRETPROBE, size, | 831 | event = trace_current_buffer_lock_reserve(call->id, size, |
831 | irq_flags, pc); | 832 | irq_flags, pc); |
832 | if (!event) | 833 | if (!event) |
833 | return 0; | 834 | return 0; |
@@ -853,7 +854,7 @@ print_kprobe_event(struct trace_iterator *iter, int flags) | |||
853 | struct trace_seq *s = &iter->seq; | 854 | struct trace_seq *s = &iter->seq; |
854 | int i; | 855 | int i; |
855 | 856 | ||
856 | trace_assign_type(field, iter->ent); | 857 | field = (struct kprobe_trace_entry *)iter->ent; |
857 | 858 | ||
858 | if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET)) | 859 | if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET)) |
859 | goto partial; | 860 | goto partial; |
@@ -880,7 +881,7 @@ print_kretprobe_event(struct trace_iterator *iter, int flags) | |||
880 | struct trace_seq *s = &iter->seq; | 881 | struct trace_seq *s = &iter->seq; |
881 | int i; | 882 | int i; |
882 | 883 | ||
883 | trace_assign_type(field, iter->ent); | 884 | field = (struct kretprobe_trace_entry *)iter->ent; |
884 | 885 | ||
885 | if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET)) | 886 | if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET)) |
886 | goto partial; | 887 | goto partial; |
@@ -906,16 +907,6 @@ partial: | |||
906 | return TRACE_TYPE_PARTIAL_LINE; | 907 | return TRACE_TYPE_PARTIAL_LINE; |
907 | } | 908 | } |
908 | 909 | ||
909 | static struct trace_event kprobe_trace_event = { | ||
910 | .type = TRACE_KPROBE, | ||
911 | .trace = print_kprobe_event, | ||
912 | }; | ||
913 | |||
914 | static struct trace_event kretprobe_trace_event = { | ||
915 | .type = TRACE_KRETPROBE, | ||
916 | .trace = print_kretprobe_event, | ||
917 | }; | ||
918 | |||
919 | static int probe_event_enable(struct ftrace_event_call *call) | 910 | static int probe_event_enable(struct ftrace_event_call *call) |
920 | { | 911 | { |
921 | struct trace_probe *tp = (struct trace_probe *)call->data; | 912 | struct trace_probe *tp = (struct trace_probe *)call->data; |
@@ -1104,35 +1095,35 @@ static int register_probe_event(struct trace_probe *tp) | |||
1104 | /* Initialize ftrace_event_call */ | 1095 | /* Initialize ftrace_event_call */ |
1105 | call->system = "kprobes"; | 1096 | call->system = "kprobes"; |
1106 | if (probe_is_return(tp)) { | 1097 | if (probe_is_return(tp)) { |
1107 | call->event = &kretprobe_trace_event; | 1098 | tp->event.trace = print_kretprobe_event; |
1108 | call->id = TRACE_KRETPROBE; | ||
1109 | call->raw_init = probe_event_raw_init; | 1099 | call->raw_init = probe_event_raw_init; |
1110 | call->show_format = kretprobe_event_show_format; | 1100 | call->show_format = kretprobe_event_show_format; |
1111 | call->define_fields = kretprobe_event_define_fields; | 1101 | call->define_fields = kretprobe_event_define_fields; |
1112 | } else { | 1102 | } else { |
1113 | call->event = &kprobe_trace_event; | 1103 | tp->event.trace = print_kprobe_event; |
1114 | call->id = TRACE_KPROBE; | ||
1115 | call->raw_init = probe_event_raw_init; | 1104 | call->raw_init = probe_event_raw_init; |
1116 | call->show_format = kprobe_event_show_format; | 1105 | call->show_format = kprobe_event_show_format; |
1117 | call->define_fields = kprobe_event_define_fields; | 1106 | call->define_fields = kprobe_event_define_fields; |
1118 | } | 1107 | } |
1108 | call->event = &tp->event; | ||
1109 | call->id = register_ftrace_event(&tp->event); | ||
1110 | if (!call->id) | ||
1111 | return -ENODEV; | ||
1119 | call->enabled = 1; | 1112 | call->enabled = 1; |
1120 | call->regfunc = probe_event_enable; | 1113 | call->regfunc = probe_event_enable; |
1121 | call->unregfunc = probe_event_disable; | 1114 | call->unregfunc = probe_event_disable; |
1122 | call->data = tp; | 1115 | call->data = tp; |
1123 | ret = trace_add_event_call(call); | 1116 | ret = trace_add_event_call(call); |
1124 | if (ret) | 1117 | if (ret) { |
1125 | pr_info("Failed to register kprobe event: %s\n", call->name); | 1118 | pr_info("Failed to register kprobe event: %s\n", call->name); |
1119 | unregister_ftrace_event(&tp->event); | ||
1120 | } | ||
1126 | return ret; | 1121 | return ret; |
1127 | } | 1122 | } |
1128 | 1123 | ||
1129 | static void unregister_probe_event(struct trace_probe *tp) | 1124 | static void unregister_probe_event(struct trace_probe *tp) |
1130 | { | 1125 | { |
1131 | /* | 1126 | /* tp->event is unregistered in trace_remove_event_call() */ |
1132 | * Prevent to unregister event itself because the event is shared | ||
1133 | * among other probes. | ||
1134 | */ | ||
1135 | tp->call.event = NULL; | ||
1136 | trace_remove_event_call(&tp->call); | 1127 | trace_remove_event_call(&tp->call); |
1137 | } | 1128 | } |
1138 | 1129 | ||
@@ -1141,18 +1132,6 @@ static __init int init_kprobe_trace(void) | |||
1141 | { | 1132 | { |
1142 | struct dentry *d_tracer; | 1133 | struct dentry *d_tracer; |
1143 | struct dentry *entry; | 1134 | struct dentry *entry; |
1144 | int ret; | ||
1145 | |||
1146 | ret = register_ftrace_event(&kprobe_trace_event); | ||
1147 | if (!ret) { | ||
1148 | pr_warning("Could not register kprobe_trace_event type.\n"); | ||
1149 | return 0; | ||
1150 | } | ||
1151 | ret = register_ftrace_event(&kretprobe_trace_event); | ||
1152 | if (!ret) { | ||
1153 | pr_warning("Could not register kretprobe_trace_event type.\n"); | ||
1154 | return 0; | ||
1155 | } | ||
1156 | 1135 | ||
1157 | d_tracer = tracing_init_dentry(); | 1136 | d_tracer = tracing_init_dentry(); |
1158 | if (!d_tracer) | 1137 | if (!d_tracer) |