Commit 8781915ad2716adcd8cd5cc52cee791fc8b00fdf
Committed by
Steven Rostedt
1 parent
5224c3a315
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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>
Showing 2 changed files with 73 additions and 37 deletions Side-by-side Diff
kernel/trace/trace_events.c
... | ... | @@ -1199,6 +1199,31 @@ |
1199 | 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 | 1227 | static int |
1203 | 1228 | __trace_add_event_call(struct ftrace_event_call *call, struct module *mod, |
1204 | 1229 | const struct file_operations *id, |
1205 | 1230 | |
... | ... | @@ -1209,20 +1234,10 @@ |
1209 | 1234 | struct dentry *d_events; |
1210 | 1235 | int ret; |
1211 | 1236 | |
1212 | - /* The linker may leave blanks */ | |
1213 | - if (!call->name) | |
1214 | - return -EINVAL; | |
1237 | + ret = event_init(call); | |
1238 | + if (ret < 0) | |
1239 | + return ret; | |
1215 | 1240 | |
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 | - | |
1226 | 1241 | d_events = event_trace_events_dir(); |
1227 | 1242 | if (!d_events) |
1228 | 1243 | return -ENOENT; |
1229 | 1244 | |
... | ... | @@ -1272,13 +1287,10 @@ |
1272 | 1287 | */ |
1273 | 1288 | static void __trace_remove_event_call(struct ftrace_event_call *call) |
1274 | 1289 | { |
1275 | - ftrace_event_enable_disable(call, 0); | |
1276 | - if (call->event.funcs) | |
1277 | - __unregister_ftrace_event(&call->event); | |
1278 | - debugfs_remove_recursive(call->dir); | |
1279 | - list_del(&call->list); | |
1290 | + event_remove(call); | |
1280 | 1291 | trace_destroy_fields(call); |
1281 | 1292 | destroy_preds(call); |
1293 | + debugfs_remove_recursive(call->dir); | |
1282 | 1294 | remove_subsystem_dir(call->class->system); |
1283 | 1295 | } |
1284 | 1296 | |
1285 | 1297 | |
1286 | 1298 | |
... | ... | @@ -1450,15 +1462,43 @@ |
1450 | 1462 | } |
1451 | 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 | 1495 | static __init int event_trace_init(void) |
1454 | 1496 | { |
1455 | - struct ftrace_event_call **call; | |
1497 | + struct ftrace_event_call *call; | |
1456 | 1498 | struct dentry *d_tracer; |
1457 | 1499 | struct dentry *entry; |
1458 | 1500 | struct dentry *d_events; |
1459 | 1501 | int ret; |
1460 | - char *buf = bootup_event_buf; | |
1461 | - char *token; | |
1462 | 1502 | |
1463 | 1503 | d_tracer = tracing_init_dentry(); |
1464 | 1504 | if (!d_tracer) |
1465 | 1505 | |
1466 | 1506 | |
1467 | 1507 | |
... | ... | @@ -1497,32 +1537,28 @@ |
1497 | 1537 | if (trace_define_common_fields()) |
1498 | 1538 | pr_warning("tracing: Failed to allocate common fields"); |
1499 | 1539 | |
1500 | - for_each_event(call, __start_ftrace_events, __stop_ftrace_events) { | |
1501 | - __trace_add_event_call(*call, NULL, &ftrace_event_id_fops, | |
1540 | + /* | |
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 | 1548 | &ftrace_enable_fops, |
1503 | 1549 | &ftrace_event_filter_fops, |
1504 | 1550 | &ftrace_event_format_fops); |
1551 | + if (ret < 0) | |
1552 | + event_remove(call); | |
1505 | 1553 | } |
1506 | 1554 | |
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 | - } | |
1519 | - | |
1520 | 1555 | ret = register_module_notifier(&trace_module_nb); |
1521 | 1556 | if (ret) |
1522 | 1557 | pr_warning("Failed to register trace events module notifier\n"); |
1523 | 1558 | |
1524 | 1559 | return 0; |
1525 | 1560 | } |
1561 | +core_initcall(event_trace_enable); | |
1526 | 1562 | fs_initcall(event_trace_init); |
1527 | 1563 | |
1528 | 1564 | #ifdef CONFIG_FTRACE_STARTUP_TEST |