diff options
author | Ezequiel Garcia <elezegarcia@gmail.com> | 2012-09-12 10:47:57 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2012-09-24 14:13:02 -0400 |
commit | 8781915ad2716adcd8cd5cc52cee791fc8b00fdf (patch) | |
tree | 0d16c498542e57b9fe5d709dba9042af63c5c1d1 /kernel/trace | |
parent | 5224c3a31549f1c056039545b289e1b01ed02f12 (diff) |
trace: Move trace event enable from fs_initcall to core_initcall
This patch splits trace event initialization in two stages:
* ftrace enable
* sysfs event entry creation
This allows to capture trace events from an earlier point
by using 'trace_event' kernel parameter and is important
to trace boot-up allocations.
Note that, in order to enable events at core_initcall,
it's necessary to move init_ftrace_syscalls() from
core_initcall to early_initcall.
Link: http://lkml.kernel.org/r/1347461277-25302-1-git-send-email-elezegarcia@gmail.com
Signed-off-by: Ezequiel Garcia <elezegarcia@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
-rw-r--r-- | kernel/trace/trace_events.c | 108 | ||||
-rw-r--r-- | kernel/trace/trace_syscalls.c | 2 |
2 files changed, 73 insertions, 37 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index bbb0e63d78e9..d608d09d08c0 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -1199,6 +1199,31 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, | |||
1199 | return 0; | 1199 | return 0; |
1200 | } | 1200 | } |
1201 | 1201 | ||
1202 | static void event_remove(struct ftrace_event_call *call) | ||
1203 | { | ||
1204 | ftrace_event_enable_disable(call, 0); | ||
1205 | if (call->event.funcs) | ||
1206 | __unregister_ftrace_event(&call->event); | ||
1207 | list_del(&call->list); | ||
1208 | } | ||
1209 | |||
1210 | static int event_init(struct ftrace_event_call *call) | ||
1211 | { | ||
1212 | int ret = 0; | ||
1213 | |||
1214 | if (WARN_ON(!call->name)) | ||
1215 | return -EINVAL; | ||
1216 | |||
1217 | if (call->class->raw_init) { | ||
1218 | ret = call->class->raw_init(call); | ||
1219 | if (ret < 0 && ret != -ENOSYS) | ||
1220 | pr_warn("Could not initialize trace events/%s\n", | ||
1221 | call->name); | ||
1222 | } | ||
1223 | |||
1224 | return ret; | ||
1225 | } | ||
1226 | |||
1202 | static int | 1227 | static int |
1203 | __trace_add_event_call(struct ftrace_event_call *call, struct module *mod, | 1228 | __trace_add_event_call(struct ftrace_event_call *call, struct module *mod, |
1204 | const struct file_operations *id, | 1229 | const struct file_operations *id, |
@@ -1209,19 +1234,9 @@ __trace_add_event_call(struct ftrace_event_call *call, struct module *mod, | |||
1209 | struct dentry *d_events; | 1234 | struct dentry *d_events; |
1210 | int ret; | 1235 | int ret; |
1211 | 1236 | ||
1212 | /* The linker may leave blanks */ | 1237 | ret = event_init(call); |
1213 | if (!call->name) | 1238 | if (ret < 0) |
1214 | return -EINVAL; | 1239 | return ret; |
1215 | |||
1216 | if (call->class->raw_init) { | ||
1217 | ret = call->class->raw_init(call); | ||
1218 | if (ret < 0) { | ||
1219 | if (ret != -ENOSYS) | ||
1220 | pr_warning("Could not initialize trace events/%s\n", | ||
1221 | call->name); | ||
1222 | return ret; | ||
1223 | } | ||
1224 | } | ||
1225 | 1240 | ||
1226 | d_events = event_trace_events_dir(); | 1241 | d_events = event_trace_events_dir(); |
1227 | if (!d_events) | 1242 | if (!d_events) |
@@ -1272,13 +1287,10 @@ static void remove_subsystem_dir(const char *name) | |||
1272 | */ | 1287 | */ |
1273 | static void __trace_remove_event_call(struct ftrace_event_call *call) | 1288 | static void __trace_remove_event_call(struct ftrace_event_call *call) |
1274 | { | 1289 | { |
1275 | ftrace_event_enable_disable(call, 0); | 1290 | event_remove(call); |
1276 | if (call->event.funcs) | ||
1277 | __unregister_ftrace_event(&call->event); | ||
1278 | debugfs_remove_recursive(call->dir); | ||
1279 | list_del(&call->list); | ||
1280 | trace_destroy_fields(call); | 1291 | trace_destroy_fields(call); |
1281 | destroy_preds(call); | 1292 | destroy_preds(call); |
1293 | debugfs_remove_recursive(call->dir); | ||
1282 | remove_subsystem_dir(call->class->system); | 1294 | remove_subsystem_dir(call->class->system); |
1283 | } | 1295 | } |
1284 | 1296 | ||
@@ -1450,15 +1462,43 @@ static __init int setup_trace_event(char *str) | |||
1450 | } | 1462 | } |
1451 | __setup("trace_event=", setup_trace_event); | 1463 | __setup("trace_event=", setup_trace_event); |
1452 | 1464 | ||
1465 | static __init int event_trace_enable(void) | ||
1466 | { | ||
1467 | struct ftrace_event_call **iter, *call; | ||
1468 | char *buf = bootup_event_buf; | ||
1469 | char *token; | ||
1470 | int ret; | ||
1471 | |||
1472 | for_each_event(iter, __start_ftrace_events, __stop_ftrace_events) { | ||
1473 | |||
1474 | call = *iter; | ||
1475 | ret = event_init(call); | ||
1476 | if (!ret) | ||
1477 | list_add(&call->list, &ftrace_events); | ||
1478 | } | ||
1479 | |||
1480 | while (true) { | ||
1481 | token = strsep(&buf, ","); | ||
1482 | |||
1483 | if (!token) | ||
1484 | break; | ||
1485 | if (!*token) | ||
1486 | continue; | ||
1487 | |||
1488 | ret = ftrace_set_clr_event(token, 1); | ||
1489 | if (ret) | ||
1490 | pr_warn("Failed to enable trace event: %s\n", token); | ||
1491 | } | ||
1492 | return 0; | ||
1493 | } | ||
1494 | |||
1453 | static __init int event_trace_init(void) | 1495 | static __init int event_trace_init(void) |
1454 | { | 1496 | { |
1455 | struct ftrace_event_call **call; | 1497 | struct ftrace_event_call *call; |
1456 | struct dentry *d_tracer; | 1498 | struct dentry *d_tracer; |
1457 | struct dentry *entry; | 1499 | struct dentry *entry; |
1458 | struct dentry *d_events; | 1500 | struct dentry *d_events; |
1459 | int ret; | 1501 | int ret; |
1460 | char *buf = bootup_event_buf; | ||
1461 | char *token; | ||
1462 | 1502 | ||
1463 | d_tracer = tracing_init_dentry(); | 1503 | d_tracer = tracing_init_dentry(); |
1464 | if (!d_tracer) | 1504 | if (!d_tracer) |
@@ -1497,24 +1537,19 @@ static __init int event_trace_init(void) | |||
1497 | if (trace_define_common_fields()) | 1537 | if (trace_define_common_fields()) |
1498 | pr_warning("tracing: Failed to allocate common fields"); | 1538 | pr_warning("tracing: Failed to allocate common fields"); |
1499 | 1539 | ||
1500 | for_each_event(call, __start_ftrace_events, __stop_ftrace_events) { | 1540 | /* |
1501 | __trace_add_event_call(*call, NULL, &ftrace_event_id_fops, | 1541 | * Early initialization already enabled ftrace event. |
1542 | * Now it's only necessary to create the event directory. | ||
1543 | */ | ||
1544 | list_for_each_entry(call, &ftrace_events, list) { | ||
1545 | |||
1546 | ret = event_create_dir(call, d_events, | ||
1547 | &ftrace_event_id_fops, | ||
1502 | &ftrace_enable_fops, | 1548 | &ftrace_enable_fops, |
1503 | &ftrace_event_filter_fops, | 1549 | &ftrace_event_filter_fops, |
1504 | &ftrace_event_format_fops); | 1550 | &ftrace_event_format_fops); |
1505 | } | 1551 | if (ret < 0) |
1506 | 1552 | event_remove(call); | |
1507 | while (true) { | ||
1508 | token = strsep(&buf, ","); | ||
1509 | |||
1510 | if (!token) | ||
1511 | break; | ||
1512 | if (!*token) | ||
1513 | continue; | ||
1514 | |||
1515 | ret = ftrace_set_clr_event(token, 1); | ||
1516 | if (ret) | ||
1517 | pr_warning("Failed to enable trace event: %s\n", token); | ||
1518 | } | 1553 | } |
1519 | 1554 | ||
1520 | ret = register_module_notifier(&trace_module_nb); | 1555 | ret = register_module_notifier(&trace_module_nb); |
@@ -1523,6 +1558,7 @@ static __init int event_trace_init(void) | |||
1523 | 1558 | ||
1524 | return 0; | 1559 | return 0; |
1525 | } | 1560 | } |
1561 | core_initcall(event_trace_enable); | ||
1526 | fs_initcall(event_trace_init); | 1562 | fs_initcall(event_trace_init); |
1527 | 1563 | ||
1528 | #ifdef CONFIG_FTRACE_STARTUP_TEST | 1564 | #ifdef CONFIG_FTRACE_STARTUP_TEST |
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 6b245f64c8dd..2485a7d09b11 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
@@ -487,7 +487,7 @@ int __init init_ftrace_syscalls(void) | |||
487 | 487 | ||
488 | return 0; | 488 | return 0; |
489 | } | 489 | } |
490 | core_initcall(init_ftrace_syscalls); | 490 | early_initcall(init_ftrace_syscalls); |
491 | 491 | ||
492 | #ifdef CONFIG_PERF_EVENTS | 492 | #ifdef CONFIG_PERF_EVENTS |
493 | 493 | ||