diff options
author | Lai Jiangshan <laijs@cn.fujitsu.com> | 2009-12-15 02:39:49 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2010-01-06 12:01:35 -0500 |
commit | a342a0280b981c130e32dbb94dbd3a57959c4d04 (patch) | |
tree | 7ef72d962cf1f0fd5b124b46995edb9b56e8c1f0 /kernel/trace/trace_kprobe.c | |
parent | 50307a45f8515f6244e3b08e6b19824b9fbfe293 (diff) |
tracing/kprobes: Init print_fmt for kprobe events
This is part of a patch set that removes the show_format method
in the ftrace event macros.
Add the print_fmt initialization to the kprobe events.
The print_fmt is still not used, but will be in the follow up
patches.
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
LKML-Reference: <4B273D45.3080100@cn.fujitsu.com>
Acked-by: Masami Hiramatsu <mhiramat@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
-rw-r--r-- | kernel/trace/trace_kprobe.c | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 6ea90c0e2c96..147491dccead 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -1250,6 +1250,62 @@ static int kretprobe_event_show_format(struct ftrace_event_call *call, | |||
1250 | ", REC->" FIELD_STRING_RETIP); | 1250 | ", REC->" FIELD_STRING_RETIP); |
1251 | } | 1251 | } |
1252 | 1252 | ||
1253 | static int __set_print_fmt(struct trace_probe *tp, char *buf, int len) | ||
1254 | { | ||
1255 | int i; | ||
1256 | int pos = 0; | ||
1257 | |||
1258 | const char *fmt, *arg; | ||
1259 | |||
1260 | if (!probe_is_return(tp)) { | ||
1261 | fmt = "(%lx)"; | ||
1262 | arg = "REC->" FIELD_STRING_IP; | ||
1263 | } else { | ||
1264 | fmt = "(%lx <- %lx)"; | ||
1265 | arg = "REC->" FIELD_STRING_FUNC ", REC->" FIELD_STRING_RETIP; | ||
1266 | } | ||
1267 | |||
1268 | /* When len=0, we just calculate the needed length */ | ||
1269 | #define LEN_OR_ZERO (len ? len - pos : 0) | ||
1270 | |||
1271 | pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt); | ||
1272 | |||
1273 | for (i = 0; i < tp->nr_args; i++) { | ||
1274 | pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%%lx", | ||
1275 | tp->args[i].name); | ||
1276 | } | ||
1277 | |||
1278 | pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg); | ||
1279 | |||
1280 | for (i = 0; i < tp->nr_args; i++) { | ||
1281 | pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s", | ||
1282 | tp->args[i].name); | ||
1283 | } | ||
1284 | |||
1285 | #undef LEN_OR_ZERO | ||
1286 | |||
1287 | /* return the length of print_fmt */ | ||
1288 | return pos; | ||
1289 | } | ||
1290 | |||
1291 | static int set_print_fmt(struct trace_probe *tp) | ||
1292 | { | ||
1293 | int len; | ||
1294 | char *print_fmt; | ||
1295 | |||
1296 | /* First: called with 0 length to calculate the needed length */ | ||
1297 | len = __set_print_fmt(tp, NULL, 0); | ||
1298 | print_fmt = kmalloc(len + 1, GFP_KERNEL); | ||
1299 | if (!print_fmt) | ||
1300 | return -ENOMEM; | ||
1301 | |||
1302 | /* Second: actually write the @print_fmt */ | ||
1303 | __set_print_fmt(tp, print_fmt, len + 1); | ||
1304 | tp->call.print_fmt = print_fmt; | ||
1305 | |||
1306 | return 0; | ||
1307 | } | ||
1308 | |||
1253 | #ifdef CONFIG_EVENT_PROFILE | 1309 | #ifdef CONFIG_EVENT_PROFILE |
1254 | 1310 | ||
1255 | /* Kprobe profile handler */ | 1311 | /* Kprobe profile handler */ |
@@ -1456,10 +1512,14 @@ static int register_probe_event(struct trace_probe *tp) | |||
1456 | call->show_format = kprobe_event_show_format; | 1512 | call->show_format = kprobe_event_show_format; |
1457 | call->define_fields = kprobe_event_define_fields; | 1513 | call->define_fields = kprobe_event_define_fields; |
1458 | } | 1514 | } |
1515 | if (set_print_fmt(tp) < 0) | ||
1516 | return -ENOMEM; | ||
1459 | call->event = &tp->event; | 1517 | call->event = &tp->event; |
1460 | call->id = register_ftrace_event(&tp->event); | 1518 | call->id = register_ftrace_event(&tp->event); |
1461 | if (!call->id) | 1519 | if (!call->id) { |
1520 | kfree(call->print_fmt); | ||
1462 | return -ENODEV; | 1521 | return -ENODEV; |
1522 | } | ||
1463 | call->enabled = 0; | 1523 | call->enabled = 0; |
1464 | call->regfunc = probe_event_enable; | 1524 | call->regfunc = probe_event_enable; |
1465 | call->unregfunc = probe_event_disable; | 1525 | call->unregfunc = probe_event_disable; |
@@ -1472,6 +1532,7 @@ static int register_probe_event(struct trace_probe *tp) | |||
1472 | ret = trace_add_event_call(call); | 1532 | ret = trace_add_event_call(call); |
1473 | if (ret) { | 1533 | if (ret) { |
1474 | pr_info("Failed to register kprobe event: %s\n", call->name); | 1534 | pr_info("Failed to register kprobe event: %s\n", call->name); |
1535 | kfree(call->print_fmt); | ||
1475 | unregister_ftrace_event(&tp->event); | 1536 | unregister_ftrace_event(&tp->event); |
1476 | } | 1537 | } |
1477 | return ret; | 1538 | return ret; |
@@ -1481,6 +1542,7 @@ static void unregister_probe_event(struct trace_probe *tp) | |||
1481 | { | 1542 | { |
1482 | /* tp->event is unregistered in trace_remove_event_call() */ | 1543 | /* tp->event is unregistered in trace_remove_event_call() */ |
1483 | trace_remove_event_call(&tp->call); | 1544 | trace_remove_event_call(&tp->call); |
1545 | kfree(tp->call.print_fmt); | ||
1484 | } | 1546 | } |
1485 | 1547 | ||
1486 | /* Make a debugfs interface for controling probe points */ | 1548 | /* Make a debugfs interface for controling probe points */ |