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.c228
1 files changed, 155 insertions, 73 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index d128f65778e6..189b09baf4fb 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -78,7 +78,7 @@ EXPORT_SYMBOL_GPL(trace_define_field);
78 if (ret) \ 78 if (ret) \
79 return ret; 79 return ret;
80 80
81int trace_define_common_fields(struct ftrace_event_call *call) 81static int trace_define_common_fields(struct ftrace_event_call *call)
82{ 82{
83 int ret; 83 int ret;
84 struct trace_entry ent; 84 struct trace_entry ent;
@@ -91,11 +91,8 @@ int trace_define_common_fields(struct ftrace_event_call *call)
91 91
92 return ret; 92 return ret;
93} 93}
94EXPORT_SYMBOL_GPL(trace_define_common_fields);
95 94
96#ifdef CONFIG_MODULES 95void trace_destroy_fields(struct ftrace_event_call *call)
97
98static void trace_destroy_fields(struct ftrace_event_call *call)
99{ 96{
100 struct ftrace_event_field *field, *next; 97 struct ftrace_event_field *field, *next;
101 98
@@ -107,27 +104,49 @@ static void trace_destroy_fields(struct ftrace_event_call *call)
107 } 104 }
108} 105}
109 106
110#endif /* CONFIG_MODULES */ 107int trace_event_raw_init(struct ftrace_event_call *call)
108{
109 int id;
110
111 id = register_ftrace_event(call->event);
112 if (!id)
113 return -ENODEV;
114 call->id = id;
115 INIT_LIST_HEAD(&call->fields);
116
117 return 0;
118}
119EXPORT_SYMBOL_GPL(trace_event_raw_init);
111 120
112static void ftrace_event_enable_disable(struct ftrace_event_call *call, 121static int ftrace_event_enable_disable(struct ftrace_event_call *call,
113 int enable) 122 int enable)
114{ 123{
124 int ret = 0;
125
115 switch (enable) { 126 switch (enable) {
116 case 0: 127 case 0:
117 if (call->enabled) { 128 if (call->enabled) {
118 call->enabled = 0; 129 call->enabled = 0;
119 tracing_stop_cmdline_record(); 130 tracing_stop_cmdline_record();
120 call->unregfunc(call->data); 131 call->unregfunc(call);
121 } 132 }
122 break; 133 break;
123 case 1: 134 case 1:
124 if (!call->enabled) { 135 if (!call->enabled) {
125 call->enabled = 1;
126 tracing_start_cmdline_record(); 136 tracing_start_cmdline_record();
127 call->regfunc(call->data); 137 ret = call->regfunc(call);
138 if (ret) {
139 tracing_stop_cmdline_record();
140 pr_info("event trace: Could not enable event "
141 "%s\n", call->name);
142 break;
143 }
144 call->enabled = 1;
128 } 145 }
129 break; 146 break;
130 } 147 }
148
149 return ret;
131} 150}
132 151
133static void ftrace_clear_events(void) 152static void ftrace_clear_events(void)
@@ -406,7 +425,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
406 case 0: 425 case 0:
407 case 1: 426 case 1:
408 mutex_lock(&event_mutex); 427 mutex_lock(&event_mutex);
409 ftrace_event_enable_disable(call, val); 428 ret = ftrace_event_enable_disable(call, val);
410 mutex_unlock(&event_mutex); 429 mutex_unlock(&event_mutex);
411 break; 430 break;
412 431
@@ -416,7 +435,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
416 435
417 *ppos += cnt; 436 *ppos += cnt;
418 437
419 return cnt; 438 return ret ? ret : cnt;
420} 439}
421 440
422static ssize_t 441static ssize_t
@@ -507,7 +526,7 @@ extern char *__bad_type_size(void);
507#define FIELD(type, name) \ 526#define FIELD(type, name) \
508 sizeof(type) != sizeof(field.name) ? __bad_type_size() : \ 527 sizeof(type) != sizeof(field.name) ? __bad_type_size() : \
509 #type, "common_" #name, offsetof(typeof(field), name), \ 528 #type, "common_" #name, offsetof(typeof(field), name), \
510 sizeof(field.name) 529 sizeof(field.name), is_signed_type(type)
511 530
512static int trace_write_header(struct trace_seq *s) 531static int trace_write_header(struct trace_seq *s)
513{ 532{
@@ -515,17 +534,17 @@ static int trace_write_header(struct trace_seq *s)
515 534
516 /* struct trace_entry */ 535 /* struct trace_entry */
517 return trace_seq_printf(s, 536 return trace_seq_printf(s,
518 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" 537 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
519 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" 538 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
520 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" 539 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
521 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" 540 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
522 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" 541 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
523 "\n", 542 "\n",
524 FIELD(unsigned short, type), 543 FIELD(unsigned short, type),
525 FIELD(unsigned char, flags), 544 FIELD(unsigned char, flags),
526 FIELD(unsigned char, preempt_count), 545 FIELD(unsigned char, preempt_count),
527 FIELD(int, pid), 546 FIELD(int, pid),
528 FIELD(int, lock_depth)); 547 FIELD(int, lock_depth));
529} 548}
530 549
531static ssize_t 550static ssize_t
@@ -878,9 +897,9 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
878 "'%s/filter' entry\n", name); 897 "'%s/filter' entry\n", name);
879 } 898 }
880 899
881 entry = trace_create_file("enable", 0644, system->entry, 900 trace_create_file("enable", 0644, system->entry,
882 (void *)system->name, 901 (void *)system->name,
883 &ftrace_system_enable_fops); 902 &ftrace_system_enable_fops);
884 903
885 return system->entry; 904 return system->entry;
886} 905}
@@ -892,7 +911,6 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
892 const struct file_operations *filter, 911 const struct file_operations *filter,
893 const struct file_operations *format) 912 const struct file_operations *format)
894{ 913{
895 struct dentry *entry;
896 int ret; 914 int ret;
897 915
898 /* 916 /*
@@ -910,55 +928,76 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
910 } 928 }
911 929
912 if (call->regfunc) 930 if (call->regfunc)
913 entry = trace_create_file("enable", 0644, call->dir, call, 931 trace_create_file("enable", 0644, call->dir, call,
914 enable); 932 enable);
915 933
916 if (call->id && call->profile_enable) 934 if (call->id && call->profile_enable)
917 entry = trace_create_file("id", 0444, call->dir, call, 935 trace_create_file("id", 0444, call->dir, call,
918 id); 936 id);
919 937
920 if (call->define_fields) { 938 if (call->define_fields) {
921 ret = call->define_fields(call); 939 ret = trace_define_common_fields(call);
940 if (!ret)
941 ret = call->define_fields(call);
922 if (ret < 0) { 942 if (ret < 0) {
923 pr_warning("Could not initialize trace point" 943 pr_warning("Could not initialize trace point"
924 " events/%s\n", call->name); 944 " events/%s\n", call->name);
925 return ret; 945 return ret;
926 } 946 }
927 entry = trace_create_file("filter", 0644, call->dir, call, 947 trace_create_file("filter", 0644, call->dir, call,
928 filter); 948 filter);
929 } 949 }
930 950
931 /* A trace may not want to export its format */ 951 /* A trace may not want to export its format */
932 if (!call->show_format) 952 if (!call->show_format)
933 return 0; 953 return 0;
934 954
935 entry = trace_create_file("format", 0444, call->dir, call, 955 trace_create_file("format", 0444, call->dir, call,
936 format); 956 format);
937 957
938 return 0; 958 return 0;
939} 959}
940 960
941#define for_each_event(event, start, end) \ 961static int __trace_add_event_call(struct ftrace_event_call *call)
942 for (event = start; \ 962{
943 (unsigned long)event < (unsigned long)end; \ 963 struct dentry *d_events;
944 event++) 964 int ret;
945 965
946#ifdef CONFIG_MODULES 966 if (!call->name)
967 return -EINVAL;
947 968
948static LIST_HEAD(ftrace_module_file_list); 969 if (call->raw_init) {
970 ret = call->raw_init(call);
971 if (ret < 0) {
972 if (ret != -ENOSYS)
973 pr_warning("Could not initialize trace "
974 "events/%s\n", call->name);
975 return ret;
976 }
977 }
949 978
950/* 979 d_events = event_trace_events_dir();
951 * Modules must own their file_operations to keep up with 980 if (!d_events)
952 * reference counting. 981 return -ENOENT;
953 */ 982
954struct ftrace_module_file_ops { 983 ret = event_create_dir(call, d_events, &ftrace_event_id_fops,
955 struct list_head list; 984 &ftrace_enable_fops, &ftrace_event_filter_fops,
956 struct module *mod; 985 &ftrace_event_format_fops);
957 struct file_operations id; 986 if (!ret)
958 struct file_operations enable; 987 list_add(&call->list, &ftrace_events);
959 struct file_operations format; 988
960 struct file_operations filter; 989 return ret;
961}; 990}
991
992/* Add an additional event_call dynamically */
993int trace_add_event_call(struct ftrace_event_call *call)
994{
995 int ret;
996 mutex_lock(&event_mutex);
997 ret = __trace_add_event_call(call);
998 mutex_unlock(&event_mutex);
999 return ret;
1000}
962 1001
963static void remove_subsystem_dir(const char *name) 1002static void remove_subsystem_dir(const char *name)
964{ 1003{
@@ -986,6 +1025,53 @@ static void remove_subsystem_dir(const char *name)
986 } 1025 }
987} 1026}
988 1027
1028/*
1029 * Must be called under locking both of event_mutex and trace_event_mutex.
1030 */
1031static void __trace_remove_event_call(struct ftrace_event_call *call)
1032{
1033 ftrace_event_enable_disable(call, 0);
1034 if (call->event)
1035 __unregister_ftrace_event(call->event);
1036 debugfs_remove_recursive(call->dir);
1037 list_del(&call->list);
1038 trace_destroy_fields(call);
1039 destroy_preds(call);
1040 remove_subsystem_dir(call->system);
1041}
1042
1043/* Remove an event_call */
1044void trace_remove_event_call(struct ftrace_event_call *call)
1045{
1046 mutex_lock(&event_mutex);
1047 down_write(&trace_event_mutex);
1048 __trace_remove_event_call(call);
1049 up_write(&trace_event_mutex);
1050 mutex_unlock(&event_mutex);
1051}
1052
1053#define for_each_event(event, start, end) \
1054 for (event = start; \
1055 (unsigned long)event < (unsigned long)end; \
1056 event++)
1057
1058#ifdef CONFIG_MODULES
1059
1060static LIST_HEAD(ftrace_module_file_list);
1061
1062/*
1063 * Modules must own their file_operations to keep up with
1064 * reference counting.
1065 */
1066struct ftrace_module_file_ops {
1067 struct list_head list;
1068 struct module *mod;
1069 struct file_operations id;
1070 struct file_operations enable;
1071 struct file_operations format;
1072 struct file_operations filter;
1073};
1074
989static struct ftrace_module_file_ops * 1075static struct ftrace_module_file_ops *
990trace_create_file_ops(struct module *mod) 1076trace_create_file_ops(struct module *mod)
991{ 1077{
@@ -1043,7 +1129,7 @@ static void trace_module_add_events(struct module *mod)
1043 if (!call->name) 1129 if (!call->name)
1044 continue; 1130 continue;
1045 if (call->raw_init) { 1131 if (call->raw_init) {
1046 ret = call->raw_init(); 1132 ret = call->raw_init(call);
1047 if (ret < 0) { 1133 if (ret < 0) {
1048 if (ret != -ENOSYS) 1134 if (ret != -ENOSYS)
1049 pr_warning("Could not initialize trace " 1135 pr_warning("Could not initialize trace "
@@ -1061,10 +1147,11 @@ static void trace_module_add_events(struct module *mod)
1061 return; 1147 return;
1062 } 1148 }
1063 call->mod = mod; 1149 call->mod = mod;
1064 list_add(&call->list, &ftrace_events); 1150 ret = event_create_dir(call, d_events,
1065 event_create_dir(call, d_events, 1151 &file_ops->id, &file_ops->enable,
1066 &file_ops->id, &file_ops->enable, 1152 &file_ops->filter, &file_ops->format);
1067 &file_ops->filter, &file_ops->format); 1153 if (!ret)
1154 list_add(&call->list, &ftrace_events);
1068 } 1155 }
1069} 1156}
1070 1157
@@ -1078,14 +1165,7 @@ static void trace_module_remove_events(struct module *mod)
1078 list_for_each_entry_safe(call, p, &ftrace_events, list) { 1165 list_for_each_entry_safe(call, p, &ftrace_events, list) {
1079 if (call->mod == mod) { 1166 if (call->mod == mod) {
1080 found = true; 1167 found = true;
1081 ftrace_event_enable_disable(call, 0); 1168 __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 } 1169 }
1090 } 1170 }
1091 1171
@@ -1203,7 +1283,7 @@ static __init int event_trace_init(void)
1203 if (!call->name) 1283 if (!call->name)
1204 continue; 1284 continue;
1205 if (call->raw_init) { 1285 if (call->raw_init) {
1206 ret = call->raw_init(); 1286 ret = call->raw_init(call);
1207 if (ret < 0) { 1287 if (ret < 0) {
1208 if (ret != -ENOSYS) 1288 if (ret != -ENOSYS)
1209 pr_warning("Could not initialize trace " 1289 pr_warning("Could not initialize trace "
@@ -1211,10 +1291,12 @@ static __init int event_trace_init(void)
1211 continue; 1291 continue;
1212 } 1292 }
1213 } 1293 }
1214 list_add(&call->list, &ftrace_events); 1294 ret = event_create_dir(call, d_events, &ftrace_event_id_fops,
1215 event_create_dir(call, d_events, &ftrace_event_id_fops, 1295 &ftrace_enable_fops,
1216 &ftrace_enable_fops, &ftrace_event_filter_fops, 1296 &ftrace_event_filter_fops,
1217 &ftrace_event_format_fops); 1297 &ftrace_event_format_fops);
1298 if (!ret)
1299 list_add(&call->list, &ftrace_events);
1218 } 1300 }
1219 1301
1220 while (true) { 1302 while (true) {