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 */ |
