aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_kprobe.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-04-21 12:27:06 -0400
committerSteven Rostedt <rostedt@goodmis.org>2010-05-14 14:19:14 -0400
commit2239291aeb0379fe47980b0e560e0eb9fd7e82ec (patch)
treee75bb60ec24e6fd7137f01db48e0ea7e5b1eddd4 /kernel/trace/trace_kprobe.c
parent38516ab59fbc5b3bb278cf5e1fe2867c70cff32e (diff)
tracing: Remove per event trace registering
This patch removes the register functions of TRACE_EVENT() to enable and disable tracepoints. The registering of a event is now down directly in the trace_events.c file. The tracepoint_probe_register() is now called directly. The prototypes are no longer type checked, but this should not be an issue since the tracepoints are created automatically by the macros. If a prototype is incorrect in the TRACE_EVENT() macro, then other macros will catch it. The trace_event_class structure now holds the probes to be called by the callbacks. This removes needing to have each event have a separate pointer for the probe. To handle kprobes and syscalls, since they register probes in a different manner, a "reg" field is added to the ftrace_event_class structure. If the "reg" field is assigned, then it will be called for enabling and disabling of the probe for either ftrace or perf. To let the reg function know what is happening, a new enum (trace_reg) is created that has the type of control that is needed. With this new rework, the 82 kernel events and 618 syscall events has their footprint dramatically lowered: text data bss dec hex filename 4913961 1088356 861512 6863829 68bbd5 vmlinux.orig 4914025 1088868 861512 6864405 68be15 vmlinux.class 4918492 1084612 861512 6864616 68bee8 vmlinux.tracepoint 4900252 1057412 861512 6819176 680d68 vmlinux.regs The size went from 6863829 to 6819176, that's a total of 44K in savings. With tracepoints being continuously added, this is critical that the footprint becomes minimal. v5: Added #ifdef CONFIG_PERF_EVENTS around a reference to perf specific structure in trace_events.c. v4: Fixed trace self tests to check probe because regfunc no longer exists. v3: Updated to handle void *data in beginning of probe parameters. Also added the tracepoint: check_trace_callback_type_##call(). v2: Changed the callback probes to pass void * and typecast the value within the function. Acked-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Acked-by: Masami Hiramatsu <mhiramat@redhat.com> Acked-by: Frederic Weisbecker <fweisbec@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
-rw-r--r--kernel/trace/trace_kprobe.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index eda220bf2065..f8af21a53f0c 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -202,6 +202,7 @@ struct trace_probe {
202 unsigned long nhit; 202 unsigned long nhit;
203 unsigned int flags; /* For TP_FLAG_* */ 203 unsigned int flags; /* For TP_FLAG_* */
204 const char *symbol; /* symbol name */ 204 const char *symbol; /* symbol name */
205 struct ftrace_event_class class;
205 struct ftrace_event_call call; 206 struct ftrace_event_call call;
206 struct trace_event event; 207 struct trace_event event;
207 unsigned int nr_args; 208 unsigned int nr_args;
@@ -323,6 +324,7 @@ static struct trace_probe *alloc_trace_probe(const char *group,
323 goto error; 324 goto error;
324 } 325 }
325 326
327 tp->call.class = &tp->class;
326 tp->call.name = kstrdup(event, GFP_KERNEL); 328 tp->call.name = kstrdup(event, GFP_KERNEL);
327 if (!tp->call.name) 329 if (!tp->call.name)
328 goto error; 330 goto error;
@@ -332,8 +334,8 @@ static struct trace_probe *alloc_trace_probe(const char *group,
332 goto error; 334 goto error;
333 } 335 }
334 336
335 tp->call.class->system = kstrdup(group, GFP_KERNEL); 337 tp->class.system = kstrdup(group, GFP_KERNEL);
336 if (!tp->call.class->system) 338 if (!tp->class.system)
337 goto error; 339 goto error;
338 340
339 INIT_LIST_HEAD(&tp->list); 341 INIT_LIST_HEAD(&tp->list);
@@ -1302,6 +1304,26 @@ static void probe_perf_disable(struct ftrace_event_call *call)
1302} 1304}
1303#endif /* CONFIG_PERF_EVENTS */ 1305#endif /* CONFIG_PERF_EVENTS */
1304 1306
1307static __kprobes
1308int kprobe_register(struct ftrace_event_call *event, enum trace_reg type)
1309{
1310 switch (type) {
1311 case TRACE_REG_REGISTER:
1312 return probe_event_enable(event);
1313 case TRACE_REG_UNREGISTER:
1314 probe_event_disable(event);
1315 return 0;
1316
1317#ifdef CONFIG_PERF_EVENTS
1318 case TRACE_REG_PERF_REGISTER:
1319 return probe_perf_enable(event);
1320 case TRACE_REG_PERF_UNREGISTER:
1321 probe_perf_disable(event);
1322 return 0;
1323#endif
1324 }
1325 return 0;
1326}
1305 1327
1306static __kprobes 1328static __kprobes
1307int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) 1329int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs)
@@ -1355,13 +1377,7 @@ static int register_probe_event(struct trace_probe *tp)
1355 return -ENODEV; 1377 return -ENODEV;
1356 } 1378 }
1357 call->enabled = 0; 1379 call->enabled = 0;
1358 call->regfunc = probe_event_enable; 1380 call->class->reg = kprobe_register;
1359 call->unregfunc = probe_event_disable;
1360
1361#ifdef CONFIG_PERF_EVENTS
1362 call->perf_event_enable = probe_perf_enable;
1363 call->perf_event_disable = probe_perf_disable;
1364#endif
1365 call->data = tp; 1381 call->data = tp;
1366 ret = trace_add_event_call(call); 1382 ret = trace_add_event_call(call);
1367 if (ret) { 1383 if (ret) {