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.c288
1 files changed, 187 insertions, 101 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index d128f65778e6..c697c7043349 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -15,6 +15,7 @@
15#include <linux/uaccess.h> 15#include <linux/uaccess.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/ctype.h> 17#include <linux/ctype.h>
18#include <linux/slab.h>
18#include <linux/delay.h> 19#include <linux/delay.h>
19 20
20#include <asm/setup.h> 21#include <asm/setup.h>
@@ -60,10 +61,8 @@ int trace_define_field(struct ftrace_event_call *call, const char *type,
60 return 0; 61 return 0;
61 62
62err: 63err:
63 if (field) { 64 if (field)
64 kfree(field->name); 65 kfree(field->name);
65 kfree(field->type);
66 }
67 kfree(field); 66 kfree(field);
68 67
69 return -ENOMEM; 68 return -ENOMEM;
@@ -78,7 +77,7 @@ EXPORT_SYMBOL_GPL(trace_define_field);
78 if (ret) \ 77 if (ret) \
79 return ret; 78 return ret;
80 79
81int trace_define_common_fields(struct ftrace_event_call *call) 80static int trace_define_common_fields(struct ftrace_event_call *call)
82{ 81{
83 int ret; 82 int ret;
84 struct trace_entry ent; 83 struct trace_entry ent;
@@ -91,11 +90,8 @@ int trace_define_common_fields(struct ftrace_event_call *call)
91 90
92 return ret; 91 return ret;
93} 92}
94EXPORT_SYMBOL_GPL(trace_define_common_fields);
95
96#ifdef CONFIG_MODULES
97 93
98static void trace_destroy_fields(struct ftrace_event_call *call) 94void trace_destroy_fields(struct ftrace_event_call *call)
99{ 95{
100 struct ftrace_event_field *field, *next; 96 struct ftrace_event_field *field, *next;
101 97
@@ -107,27 +103,49 @@ static void trace_destroy_fields(struct ftrace_event_call *call)
107 } 103 }
108} 104}
109 105
110#endif /* CONFIG_MODULES */ 106int trace_event_raw_init(struct ftrace_event_call *call)
107{
108 int id;
111 109
112static void ftrace_event_enable_disable(struct ftrace_event_call *call, 110 id = register_ftrace_event(call->event);
111 if (!id)
112 return -ENODEV;
113 call->id = id;
114 INIT_LIST_HEAD(&call->fields);
115
116 return 0;
117}
118EXPORT_SYMBOL_GPL(trace_event_raw_init);
119
120static int ftrace_event_enable_disable(struct ftrace_event_call *call,
113 int enable) 121 int enable)
114{ 122{
123 int ret = 0;
124
115 switch (enable) { 125 switch (enable) {
116 case 0: 126 case 0:
117 if (call->enabled) { 127 if (call->enabled) {
118 call->enabled = 0; 128 call->enabled = 0;
119 tracing_stop_cmdline_record(); 129 tracing_stop_cmdline_record();
120 call->unregfunc(call->data); 130 call->unregfunc(call);
121 } 131 }
122 break; 132 break;
123 case 1: 133 case 1:
124 if (!call->enabled) { 134 if (!call->enabled) {
125 call->enabled = 1;
126 tracing_start_cmdline_record(); 135 tracing_start_cmdline_record();
127 call->regfunc(call->data); 136 ret = call->regfunc(call);
137 if (ret) {
138 tracing_stop_cmdline_record();
139 pr_info("event trace: Could not enable event "
140 "%s\n", call->name);
141 break;
142 }
143 call->enabled = 1;
128 } 144 }
129 break; 145 break;
130 } 146 }
147
148 return ret;
131} 149}
132 150
133static void ftrace_clear_events(void) 151static void ftrace_clear_events(void)
@@ -406,7 +424,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
406 case 0: 424 case 0:
407 case 1: 425 case 1:
408 mutex_lock(&event_mutex); 426 mutex_lock(&event_mutex);
409 ftrace_event_enable_disable(call, val); 427 ret = ftrace_event_enable_disable(call, val);
410 mutex_unlock(&event_mutex); 428 mutex_unlock(&event_mutex);
411 break; 429 break;
412 430
@@ -416,7 +434,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
416 434
417 *ppos += cnt; 435 *ppos += cnt;
418 436
419 return cnt; 437 return ret ? ret : cnt;
420} 438}
421 439
422static ssize_t 440static ssize_t
@@ -501,41 +519,16 @@ out:
501 return ret; 519 return ret;
502} 520}
503 521
504extern char *__bad_type_size(void);
505
506#undef FIELD
507#define FIELD(type, name) \
508 sizeof(type) != sizeof(field.name) ? __bad_type_size() : \
509 #type, "common_" #name, offsetof(typeof(field), name), \
510 sizeof(field.name)
511
512static int trace_write_header(struct trace_seq *s)
513{
514 struct trace_entry field;
515
516 /* struct trace_entry */
517 return trace_seq_printf(s,
518 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
519 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
520 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
521 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
522 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
523 "\n",
524 FIELD(unsigned short, type),
525 FIELD(unsigned char, flags),
526 FIELD(unsigned char, preempt_count),
527 FIELD(int, pid),
528 FIELD(int, lock_depth));
529}
530
531static ssize_t 522static ssize_t
532event_format_read(struct file *filp, char __user *ubuf, size_t cnt, 523event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
533 loff_t *ppos) 524 loff_t *ppos)
534{ 525{
535 struct ftrace_event_call *call = filp->private_data; 526 struct ftrace_event_call *call = filp->private_data;
527 struct ftrace_event_field *field;
536 struct trace_seq *s; 528 struct trace_seq *s;
529 int common_field_count = 5;
537 char *buf; 530 char *buf;
538 int r; 531 int r = 0;
539 532
540 if (*ppos) 533 if (*ppos)
541 return 0; 534 return 0;
@@ -546,14 +539,48 @@ event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
546 539
547 trace_seq_init(s); 540 trace_seq_init(s);
548 541
549 /* If any of the first writes fail, so will the show_format. */
550
551 trace_seq_printf(s, "name: %s\n", call->name); 542 trace_seq_printf(s, "name: %s\n", call->name);
552 trace_seq_printf(s, "ID: %d\n", call->id); 543 trace_seq_printf(s, "ID: %d\n", call->id);
553 trace_seq_printf(s, "format:\n"); 544 trace_seq_printf(s, "format:\n");
554 trace_write_header(s);
555 545
556 r = call->show_format(call, s); 546 list_for_each_entry_reverse(field, &call->fields, link) {
547 /*
548 * Smartly shows the array type(except dynamic array).
549 * Normal:
550 * field:TYPE VAR
551 * If TYPE := TYPE[LEN], it is shown:
552 * field:TYPE VAR[LEN]
553 */
554 const char *array_descriptor = strchr(field->type, '[');
555
556 if (!strncmp(field->type, "__data_loc", 10))
557 array_descriptor = NULL;
558
559 if (!array_descriptor) {
560 r = trace_seq_printf(s, "\tfield:%s %s;\toffset:%u;"
561 "\tsize:%u;\tsigned:%d;\n",
562 field->type, field->name, field->offset,
563 field->size, !!field->is_signed);
564 } else {
565 r = trace_seq_printf(s, "\tfield:%.*s %s%s;\toffset:%u;"
566 "\tsize:%u;\tsigned:%d;\n",
567 (int)(array_descriptor - field->type),
568 field->type, field->name,
569 array_descriptor, field->offset,
570 field->size, !!field->is_signed);
571 }
572
573 if (--common_field_count == 0)
574 r = trace_seq_printf(s, "\n");
575
576 if (!r)
577 break;
578 }
579
580 if (r)
581 r = trace_seq_printf(s, "\nprint fmt: %s\n",
582 call->print_fmt);
583
557 if (!r) { 584 if (!r) {
558 /* 585 /*
559 * ug! The format output is bigger than a PAGE!! 586 * ug! The format output is bigger than a PAGE!!
@@ -878,9 +905,9 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
878 "'%s/filter' entry\n", name); 905 "'%s/filter' entry\n", name);
879 } 906 }
880 907
881 entry = trace_create_file("enable", 0644, system->entry, 908 trace_create_file("enable", 0644, system->entry,
882 (void *)system->name, 909 (void *)system->name,
883 &ftrace_system_enable_fops); 910 &ftrace_system_enable_fops);
884 911
885 return system->entry; 912 return system->entry;
886} 913}
@@ -892,7 +919,6 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
892 const struct file_operations *filter, 919 const struct file_operations *filter,
893 const struct file_operations *format) 920 const struct file_operations *format)
894{ 921{
895 struct dentry *entry;
896 int ret; 922 int ret;
897 923
898 /* 924 /*
@@ -910,55 +936,72 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
910 } 936 }
911 937
912 if (call->regfunc) 938 if (call->regfunc)
913 entry = trace_create_file("enable", 0644, call->dir, call, 939 trace_create_file("enable", 0644, call->dir, call,
914 enable); 940 enable);
915 941
916 if (call->id && call->profile_enable) 942 if (call->id && call->perf_event_enable)
917 entry = trace_create_file("id", 0444, call->dir, call, 943 trace_create_file("id", 0444, call->dir, call,
918 id); 944 id);
919 945
920 if (call->define_fields) { 946 if (call->define_fields) {
921 ret = call->define_fields(call); 947 ret = trace_define_common_fields(call);
948 if (!ret)
949 ret = call->define_fields(call);
922 if (ret < 0) { 950 if (ret < 0) {
923 pr_warning("Could not initialize trace point" 951 pr_warning("Could not initialize trace point"
924 " events/%s\n", call->name); 952 " events/%s\n", call->name);
925 return ret; 953 return ret;
926 } 954 }
927 entry = trace_create_file("filter", 0644, call->dir, call, 955 trace_create_file("filter", 0644, call->dir, call,
928 filter); 956 filter);
929 } 957 }
930 958
931 /* A trace may not want to export its format */ 959 trace_create_file("format", 0444, call->dir, call,
932 if (!call->show_format) 960 format);
933 return 0;
934
935 entry = trace_create_file("format", 0444, call->dir, call,
936 format);
937 961
938 return 0; 962 return 0;
939} 963}
940 964
941#define for_each_event(event, start, end) \ 965static int __trace_add_event_call(struct ftrace_event_call *call)
942 for (event = start; \ 966{
943 (unsigned long)event < (unsigned long)end; \ 967 struct dentry *d_events;
944 event++) 968 int ret;
945 969
946#ifdef CONFIG_MODULES 970 if (!call->name)
971 return -EINVAL;
947 972
948static LIST_HEAD(ftrace_module_file_list); 973 if (call->raw_init) {
974 ret = call->raw_init(call);
975 if (ret < 0) {
976 if (ret != -ENOSYS)
977 pr_warning("Could not initialize trace "
978 "events/%s\n", call->name);
979 return ret;
980 }
981 }
949 982
950/* 983 d_events = event_trace_events_dir();
951 * Modules must own their file_operations to keep up with 984 if (!d_events)
952 * reference counting. 985 return -ENOENT;
953 */ 986
954struct ftrace_module_file_ops { 987 ret = event_create_dir(call, d_events, &ftrace_event_id_fops,
955 struct list_head list; 988 &ftrace_enable_fops, &ftrace_event_filter_fops,
956 struct module *mod; 989 &ftrace_event_format_fops);
957 struct file_operations id; 990 if (!ret)
958 struct file_operations enable; 991 list_add(&call->list, &ftrace_events);
959 struct file_operations format; 992
960 struct file_operations filter; 993 return ret;
961}; 994}
995
996/* Add an additional event_call dynamically */
997int trace_add_event_call(struct ftrace_event_call *call)
998{
999 int ret;
1000 mutex_lock(&event_mutex);
1001 ret = __trace_add_event_call(call);
1002 mutex_unlock(&event_mutex);
1003 return ret;
1004}
962 1005
963static void remove_subsystem_dir(const char *name) 1006static void remove_subsystem_dir(const char *name)
964{ 1007{
@@ -986,6 +1029,53 @@ static void remove_subsystem_dir(const char *name)
986 } 1029 }
987} 1030}
988 1031
1032/*
1033 * Must be called under locking both of event_mutex and trace_event_mutex.
1034 */
1035static void __trace_remove_event_call(struct ftrace_event_call *call)
1036{
1037 ftrace_event_enable_disable(call, 0);
1038 if (call->event)
1039 __unregister_ftrace_event(call->event);
1040 debugfs_remove_recursive(call->dir);
1041 list_del(&call->list);
1042 trace_destroy_fields(call);
1043 destroy_preds(call);
1044 remove_subsystem_dir(call->system);
1045}
1046
1047/* Remove an event_call */
1048void trace_remove_event_call(struct ftrace_event_call *call)
1049{
1050 mutex_lock(&event_mutex);
1051 down_write(&trace_event_mutex);
1052 __trace_remove_event_call(call);
1053 up_write(&trace_event_mutex);
1054 mutex_unlock(&event_mutex);
1055}
1056
1057#define for_each_event(event, start, end) \
1058 for (event = start; \
1059 (unsigned long)event < (unsigned long)end; \
1060 event++)
1061
1062#ifdef CONFIG_MODULES
1063
1064static LIST_HEAD(ftrace_module_file_list);
1065
1066/*
1067 * Modules must own their file_operations to keep up with
1068 * reference counting.
1069 */
1070struct ftrace_module_file_ops {
1071 struct list_head list;
1072 struct module *mod;
1073 struct file_operations id;
1074 struct file_operations enable;
1075 struct file_operations format;
1076 struct file_operations filter;
1077};
1078
989static struct ftrace_module_file_ops * 1079static struct ftrace_module_file_ops *
990trace_create_file_ops(struct module *mod) 1080trace_create_file_ops(struct module *mod)
991{ 1081{
@@ -1043,7 +1133,7 @@ static void trace_module_add_events(struct module *mod)
1043 if (!call->name) 1133 if (!call->name)
1044 continue; 1134 continue;
1045 if (call->raw_init) { 1135 if (call->raw_init) {
1046 ret = call->raw_init(); 1136 ret = call->raw_init(call);
1047 if (ret < 0) { 1137 if (ret < 0) {
1048 if (ret != -ENOSYS) 1138 if (ret != -ENOSYS)
1049 pr_warning("Could not initialize trace " 1139 pr_warning("Could not initialize trace "
@@ -1061,10 +1151,11 @@ static void trace_module_add_events(struct module *mod)
1061 return; 1151 return;
1062 } 1152 }
1063 call->mod = mod; 1153 call->mod = mod;
1064 list_add(&call->list, &ftrace_events); 1154 ret = event_create_dir(call, d_events,
1065 event_create_dir(call, d_events, 1155 &file_ops->id, &file_ops->enable,
1066 &file_ops->id, &file_ops->enable, 1156 &file_ops->filter, &file_ops->format);
1067 &file_ops->filter, &file_ops->format); 1157 if (!ret)
1158 list_add(&call->list, &ftrace_events);
1068 } 1159 }
1069} 1160}
1070 1161
@@ -1078,14 +1169,7 @@ static void trace_module_remove_events(struct module *mod)
1078 list_for_each_entry_safe(call, p, &ftrace_events, list) { 1169 list_for_each_entry_safe(call, p, &ftrace_events, list) {
1079 if (call->mod == mod) { 1170 if (call->mod == mod) {
1080 found = true; 1171 found = true;
1081 ftrace_event_enable_disable(call, 0); 1172 __trace_remove_event_call(call);
1082 if (call->event)
1083 __unregister_ftrace_event(call->event);
1084 debugfs_remove_recursive(call->dir);
1085 list_del(&call->list);
1086 trace_destroy_fields(call);
1087 destroy_preds(call);
1088 remove_subsystem_dir(call->system);
1089 } 1173 }
1090 } 1174 }
1091 1175
@@ -1203,7 +1287,7 @@ static __init int event_trace_init(void)
1203 if (!call->name) 1287 if (!call->name)
1204 continue; 1288 continue;
1205 if (call->raw_init) { 1289 if (call->raw_init) {
1206 ret = call->raw_init(); 1290 ret = call->raw_init(call);
1207 if (ret < 0) { 1291 if (ret < 0) {
1208 if (ret != -ENOSYS) 1292 if (ret != -ENOSYS)
1209 pr_warning("Could not initialize trace " 1293 pr_warning("Could not initialize trace "
@@ -1211,10 +1295,12 @@ static __init int event_trace_init(void)
1211 continue; 1295 continue;
1212 } 1296 }
1213 } 1297 }
1214 list_add(&call->list, &ftrace_events); 1298 ret = event_create_dir(call, d_events, &ftrace_event_id_fops,
1215 event_create_dir(call, d_events, &ftrace_event_id_fops, 1299 &ftrace_enable_fops,
1216 &ftrace_enable_fops, &ftrace_event_filter_fops, 1300 &ftrace_event_filter_fops,
1217 &ftrace_event_format_fops); 1301 &ftrace_event_format_fops);
1302 if (!ret)
1303 list_add(&call->list, &ftrace_events);
1218 } 1304 }
1219 1305
1220 while (true) { 1306 while (true) {