aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_kprobe.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2009-08-13 16:35:34 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2009-08-26 20:32:33 -0400
commitff50d99136c3315513ef3b2921e77f35ab04d081 (patch)
tree133f4dc7b9b310a1d9b959c0c013d8fce30a2917 /kernel/trace/trace_kprobe.c
parent4263565d491145b57621a761714f2ca6f1293a45 (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.c51
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
909static struct trace_event kprobe_trace_event = {
910 .type = TRACE_KPROBE,
911 .trace = print_kprobe_event,
912};
913
914static struct trace_event kretprobe_trace_event = {
915 .type = TRACE_KRETPROBE,
916 .trace = print_kretprobe_event,
917};
918
919static int probe_event_enable(struct ftrace_event_call *call) 910static 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
1129static void unregister_probe_event(struct trace_probe *tp) 1124static 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)