aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_events.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_events.c')
-rw-r--r--kernel/trace/trace_events.c184
1 files changed, 62 insertions, 122 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 880073d0b94..c212a7f934e 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -147,8 +147,7 @@ int trace_event_raw_init(struct ftrace_event_call *call)
147} 147}
148EXPORT_SYMBOL_GPL(trace_event_raw_init); 148EXPORT_SYMBOL_GPL(trace_event_raw_init);
149 149
150int ftrace_event_reg(struct ftrace_event_call *call, 150int ftrace_event_reg(struct ftrace_event_call *call, enum trace_reg type)
151 enum trace_reg type, void *data)
152{ 151{
153 switch (type) { 152 switch (type) {
154 case TRACE_REG_REGISTER: 153 case TRACE_REG_REGISTER:
@@ -171,11 +170,6 @@ int ftrace_event_reg(struct ftrace_event_call *call,
171 call->class->perf_probe, 170 call->class->perf_probe,
172 call); 171 call);
173 return 0; 172 return 0;
174 case TRACE_REG_PERF_OPEN:
175 case TRACE_REG_PERF_CLOSE:
176 case TRACE_REG_PERF_ADD:
177 case TRACE_REG_PERF_DEL:
178 return 0;
179#endif 173#endif
180 } 174 }
181 return 0; 175 return 0;
@@ -215,7 +209,7 @@ static int ftrace_event_enable_disable(struct ftrace_event_call *call,
215 tracing_stop_cmdline_record(); 209 tracing_stop_cmdline_record();
216 call->flags &= ~TRACE_EVENT_FL_RECORDED_CMD; 210 call->flags &= ~TRACE_EVENT_FL_RECORDED_CMD;
217 } 211 }
218 call->class->reg(call, TRACE_REG_UNREGISTER, NULL); 212 call->class->reg(call, TRACE_REG_UNREGISTER);
219 } 213 }
220 break; 214 break;
221 case 1: 215 case 1:
@@ -224,7 +218,7 @@ static int ftrace_event_enable_disable(struct ftrace_event_call *call,
224 tracing_start_cmdline_record(); 218 tracing_start_cmdline_record();
225 call->flags |= TRACE_EVENT_FL_RECORDED_CMD; 219 call->flags |= TRACE_EVENT_FL_RECORDED_CMD;
226 } 220 }
227 ret = call->class->reg(call, TRACE_REG_REGISTER, NULL); 221 ret = call->class->reg(call, TRACE_REG_REGISTER);
228 if (ret) { 222 if (ret) {
229 tracing_stop_cmdline_record(); 223 tracing_stop_cmdline_record();
230 pr_info("event trace: Could not enable event " 224 pr_info("event trace: Could not enable event "
@@ -294,9 +288,6 @@ static int __ftrace_set_clr_event(const char *match, const char *sub,
294 if (!call->name || !call->class || !call->class->reg) 288 if (!call->name || !call->class || !call->class->reg)
295 continue; 289 continue;
296 290
297 if (call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)
298 continue;
299
300 if (match && 291 if (match &&
301 strcmp(match, call->name) != 0 && 292 strcmp(match, call->name) != 0 &&
302 strcmp(match, call->class->system) != 0) 293 strcmp(match, call->class->system) != 0)
@@ -491,6 +482,19 @@ static void t_stop(struct seq_file *m, void *p)
491 mutex_unlock(&event_mutex); 482 mutex_unlock(&event_mutex);
492} 483}
493 484
485static int
486ftrace_event_seq_open(struct inode *inode, struct file *file)
487{
488 const struct seq_operations *seq_ops;
489
490 if ((file->f_mode & FMODE_WRITE) &&
491 (file->f_flags & O_TRUNC))
492 ftrace_clear_events();
493
494 seq_ops = inode->i_private;
495 return seq_open(file, seq_ops);
496}
497
494static ssize_t 498static ssize_t
495event_enable_read(struct file *filp, char __user *ubuf, size_t cnt, 499event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
496 loff_t *ppos) 500 loff_t *ppos)
@@ -967,9 +971,6 @@ show_header(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
967 return r; 971 return r;
968} 972}
969 973
970static int ftrace_event_avail_open(struct inode *inode, struct file *file);
971static int ftrace_event_set_open(struct inode *inode, struct file *file);
972
973static const struct seq_operations show_event_seq_ops = { 974static const struct seq_operations show_event_seq_ops = {
974 .start = t_start, 975 .start = t_start,
975 .next = t_next, 976 .next = t_next,
@@ -985,14 +986,14 @@ static const struct seq_operations show_set_event_seq_ops = {
985}; 986};
986 987
987static const struct file_operations ftrace_avail_fops = { 988static const struct file_operations ftrace_avail_fops = {
988 .open = ftrace_event_avail_open, 989 .open = ftrace_event_seq_open,
989 .read = seq_read, 990 .read = seq_read,
990 .llseek = seq_lseek, 991 .llseek = seq_lseek,
991 .release = seq_release, 992 .release = seq_release,
992}; 993};
993 994
994static const struct file_operations ftrace_set_event_fops = { 995static const struct file_operations ftrace_set_event_fops = {
995 .open = ftrace_event_set_open, 996 .open = ftrace_event_seq_open,
996 .read = seq_read, 997 .read = seq_read,
997 .write = ftrace_event_write, 998 .write = ftrace_event_write,
998 .llseek = seq_lseek, 999 .llseek = seq_lseek,
@@ -1068,26 +1069,6 @@ static struct dentry *event_trace_events_dir(void)
1068 return d_events; 1069 return d_events;
1069} 1070}
1070 1071
1071static int
1072ftrace_event_avail_open(struct inode *inode, struct file *file)
1073{
1074 const struct seq_operations *seq_ops = &show_event_seq_ops;
1075
1076 return seq_open(file, seq_ops);
1077}
1078
1079static int
1080ftrace_event_set_open(struct inode *inode, struct file *file)
1081{
1082 const struct seq_operations *seq_ops = &show_set_event_seq_ops;
1083
1084 if ((file->f_mode & FMODE_WRITE) &&
1085 (file->f_flags & O_TRUNC))
1086 ftrace_clear_events();
1087
1088 return seq_open(file, seq_ops);
1089}
1090
1091static struct dentry * 1072static struct dentry *
1092event_subsystem_dir(const char *name, struct dentry *d_events) 1073event_subsystem_dir(const char *name, struct dentry *d_events)
1093{ 1074{
@@ -1177,7 +1158,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
1177 return -1; 1158 return -1;
1178 } 1159 }
1179 1160
1180 if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) 1161 if (call->class->reg)
1181 trace_create_file("enable", 0644, call->dir, call, 1162 trace_create_file("enable", 0644, call->dir, call,
1182 enable); 1163 enable);
1183 1164
@@ -1209,31 +1190,6 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
1209 return 0; 1190 return 0;
1210} 1191}
1211 1192
1212static void event_remove(struct ftrace_event_call *call)
1213{
1214 ftrace_event_enable_disable(call, 0);
1215 if (call->event.funcs)
1216 __unregister_ftrace_event(&call->event);
1217 list_del(&call->list);
1218}
1219
1220static int event_init(struct ftrace_event_call *call)
1221{
1222 int ret = 0;
1223
1224 if (WARN_ON(!call->name))
1225 return -EINVAL;
1226
1227 if (call->class->raw_init) {
1228 ret = call->class->raw_init(call);
1229 if (ret < 0 && ret != -ENOSYS)
1230 pr_warn("Could not initialize trace events/%s\n",
1231 call->name);
1232 }
1233
1234 return ret;
1235}
1236
1237static int 1193static int
1238__trace_add_event_call(struct ftrace_event_call *call, struct module *mod, 1194__trace_add_event_call(struct ftrace_event_call *call, struct module *mod,
1239 const struct file_operations *id, 1195 const struct file_operations *id,
@@ -1244,9 +1200,19 @@ __trace_add_event_call(struct ftrace_event_call *call, struct module *mod,
1244 struct dentry *d_events; 1200 struct dentry *d_events;
1245 int ret; 1201 int ret;
1246 1202
1247 ret = event_init(call); 1203 /* The linker may leave blanks */
1248 if (ret < 0) 1204 if (!call->name)
1249 return ret; 1205 return -EINVAL;
1206
1207 if (call->class->raw_init) {
1208 ret = call->class->raw_init(call);
1209 if (ret < 0) {
1210 if (ret != -ENOSYS)
1211 pr_warning("Could not initialize trace events/%s\n",
1212 call->name);
1213 return ret;
1214 }
1215 }
1250 1216
1251 d_events = event_trace_events_dir(); 1217 d_events = event_trace_events_dir();
1252 if (!d_events) 1218 if (!d_events)
@@ -1297,10 +1263,13 @@ static void remove_subsystem_dir(const char *name)
1297 */ 1263 */
1298static void __trace_remove_event_call(struct ftrace_event_call *call) 1264static void __trace_remove_event_call(struct ftrace_event_call *call)
1299{ 1265{
1300 event_remove(call); 1266 ftrace_event_enable_disable(call, 0);
1267 if (call->event.funcs)
1268 __unregister_ftrace_event(&call->event);
1269 debugfs_remove_recursive(call->dir);
1270 list_del(&call->list);
1301 trace_destroy_fields(call); 1271 trace_destroy_fields(call);
1302 destroy_preds(call); 1272 destroy_preds(call);
1303 debugfs_remove_recursive(call->dir);
1304 remove_subsystem_dir(call->class->system); 1273 remove_subsystem_dir(call->class->system);
1305} 1274}
1306 1275
@@ -1472,59 +1441,30 @@ static __init int setup_trace_event(char *str)
1472} 1441}
1473__setup("trace_event=", setup_trace_event); 1442__setup("trace_event=", setup_trace_event);
1474 1443
1475static __init int event_trace_enable(void)
1476{
1477 struct ftrace_event_call **iter, *call;
1478 char *buf = bootup_event_buf;
1479 char *token;
1480 int ret;
1481
1482 for_each_event(iter, __start_ftrace_events, __stop_ftrace_events) {
1483
1484 call = *iter;
1485 ret = event_init(call);
1486 if (!ret)
1487 list_add(&call->list, &ftrace_events);
1488 }
1489
1490 while (true) {
1491 token = strsep(&buf, ",");
1492
1493 if (!token)
1494 break;
1495 if (!*token)
1496 continue;
1497
1498 ret = ftrace_set_clr_event(token, 1);
1499 if (ret)
1500 pr_warn("Failed to enable trace event: %s\n", token);
1501 }
1502
1503 trace_printk_start_comm();
1504
1505 return 0;
1506}
1507
1508static __init int event_trace_init(void) 1444static __init int event_trace_init(void)
1509{ 1445{
1510 struct ftrace_event_call *call; 1446 struct ftrace_event_call **call;
1511 struct dentry *d_tracer; 1447 struct dentry *d_tracer;
1512 struct dentry *entry; 1448 struct dentry *entry;
1513 struct dentry *d_events; 1449 struct dentry *d_events;
1514 int ret; 1450 int ret;
1451 char *buf = bootup_event_buf;
1452 char *token;
1515 1453
1516 d_tracer = tracing_init_dentry(); 1454 d_tracer = tracing_init_dentry();
1517 if (!d_tracer) 1455 if (!d_tracer)
1518 return 0; 1456 return 0;
1519 1457
1520 entry = debugfs_create_file("available_events", 0444, d_tracer, 1458 entry = debugfs_create_file("available_events", 0444, d_tracer,
1521 NULL, &ftrace_avail_fops); 1459 (void *)&show_event_seq_ops,
1460 &ftrace_avail_fops);
1522 if (!entry) 1461 if (!entry)
1523 pr_warning("Could not create debugfs " 1462 pr_warning("Could not create debugfs "
1524 "'available_events' entry\n"); 1463 "'available_events' entry\n");
1525 1464
1526 entry = debugfs_create_file("set_event", 0644, d_tracer, 1465 entry = debugfs_create_file("set_event", 0644, d_tracer,
1527 NULL, &ftrace_set_event_fops); 1466 (void *)&show_set_event_seq_ops,
1467 &ftrace_set_event_fops);
1528 if (!entry) 1468 if (!entry)
1529 pr_warning("Could not create debugfs " 1469 pr_warning("Could not create debugfs "
1530 "'set_event' entry\n"); 1470 "'set_event' entry\n");
@@ -1548,19 +1488,24 @@ static __init int event_trace_init(void)
1548 if (trace_define_common_fields()) 1488 if (trace_define_common_fields())
1549 pr_warning("tracing: Failed to allocate common fields"); 1489 pr_warning("tracing: Failed to allocate common fields");
1550 1490
1551 /* 1491 for_each_event(call, __start_ftrace_events, __stop_ftrace_events) {
1552 * Early initialization already enabled ftrace event. 1492 __trace_add_event_call(*call, NULL, &ftrace_event_id_fops,
1553 * Now it's only necessary to create the event directory.
1554 */
1555 list_for_each_entry(call, &ftrace_events, list) {
1556
1557 ret = event_create_dir(call, d_events,
1558 &ftrace_event_id_fops,
1559 &ftrace_enable_fops, 1493 &ftrace_enable_fops,
1560 &ftrace_event_filter_fops, 1494 &ftrace_event_filter_fops,
1561 &ftrace_event_format_fops); 1495 &ftrace_event_format_fops);
1562 if (ret < 0) 1496 }
1563 event_remove(call); 1497
1498 while (true) {
1499 token = strsep(&buf, ",");
1500
1501 if (!token)
1502 break;
1503 if (!*token)
1504 continue;
1505
1506 ret = ftrace_set_clr_event(token, 1);
1507 if (ret)
1508 pr_warning("Failed to enable trace event: %s\n", token);
1564 } 1509 }
1565 1510
1566 ret = register_module_notifier(&trace_module_nb); 1511 ret = register_module_notifier(&trace_module_nb);
@@ -1569,7 +1514,6 @@ static __init int event_trace_init(void)
1569 1514
1570 return 0; 1515 return 0;
1571} 1516}
1572core_initcall(event_trace_enable);
1573fs_initcall(event_trace_init); 1517fs_initcall(event_trace_init);
1574 1518
1575#ifdef CONFIG_FTRACE_STARTUP_TEST 1519#ifdef CONFIG_FTRACE_STARTUP_TEST
@@ -1693,11 +1637,9 @@ static __init void event_trace_self_tests(void)
1693 event_test_stuff(); 1637 event_test_stuff();
1694 1638
1695 ret = __ftrace_set_clr_event(NULL, system->name, NULL, 0); 1639 ret = __ftrace_set_clr_event(NULL, system->name, NULL, 0);
1696 if (WARN_ON_ONCE(ret)) { 1640 if (WARN_ON_ONCE(ret))
1697 pr_warning("error disabling system %s\n", 1641 pr_warning("error disabling system %s\n",
1698 system->name); 1642 system->name);
1699 continue;
1700 }
1701 1643
1702 pr_cont("OK\n"); 1644 pr_cont("OK\n");
1703 } 1645 }
@@ -1730,8 +1672,7 @@ static __init void event_trace_self_tests(void)
1730static DEFINE_PER_CPU(atomic_t, ftrace_test_event_disable); 1672static DEFINE_PER_CPU(atomic_t, ftrace_test_event_disable);
1731 1673
1732static void 1674static void
1733function_test_events_call(unsigned long ip, unsigned long parent_ip, 1675function_test_events_call(unsigned long ip, unsigned long parent_ip)
1734 struct ftrace_ops *op, struct pt_regs *pt_regs)
1735{ 1676{
1736 struct ring_buffer_event *event; 1677 struct ring_buffer_event *event;
1737 struct ring_buffer *buffer; 1678 struct ring_buffer *buffer;
@@ -1760,7 +1701,7 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip,
1760 entry->ip = ip; 1701 entry->ip = ip;
1761 entry->parent_ip = parent_ip; 1702 entry->parent_ip = parent_ip;
1762 1703
1763 trace_buffer_unlock_commit(buffer, event, flags, pc); 1704 trace_nowake_buffer_unlock_commit(buffer, event, flags, pc);
1764 1705
1765 out: 1706 out:
1766 atomic_dec(&per_cpu(ftrace_test_event_disable, cpu)); 1707 atomic_dec(&per_cpu(ftrace_test_event_disable, cpu));
@@ -1770,7 +1711,6 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip,
1770static struct ftrace_ops trace_ops __initdata = 1711static struct ftrace_ops trace_ops __initdata =
1771{ 1712{
1772 .func = function_test_events_call, 1713 .func = function_test_events_call,
1773 .flags = FTRACE_OPS_FL_RECURSION_SAFE,
1774}; 1714};
1775 1715
1776static __init void event_trace_self_test_with_function(void) 1716static __init void event_trace_self_test_with_function(void)