aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/trace/trace.h3
-rw-r--r--kernel/trace/trace_events.c55
2 files changed, 54 insertions, 4 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 2c3cba59552d..c7fbf93f1b7c 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -226,6 +226,9 @@ extern struct list_head ftrace_trace_arrays;
226 226
227extern struct mutex trace_types_lock; 227extern struct mutex trace_types_lock;
228 228
229extern int trace_array_get(struct trace_array *tr);
230extern void trace_array_put(struct trace_array *tr);
231
229/* 232/*
230 * The global tracer (top) should be the first trace array added, 233 * The global tracer (top) should be the first trace array added,
231 * but we check the flag anyway. 234 * but we check the flag anyway.
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 35c6f23c71b2..920e08fb53b3 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -410,6 +410,35 @@ static void put_system(struct ftrace_subsystem_dir *dir)
410} 410}
411 411
412/* 412/*
413 * Open and update trace_array ref count.
414 * Must have the current trace_array passed to it.
415 */
416static int tracing_open_generic_file(struct inode *inode, struct file *filp)
417{
418 struct ftrace_event_file *file = inode->i_private;
419 struct trace_array *tr = file->tr;
420 int ret;
421
422 if (trace_array_get(tr) < 0)
423 return -ENODEV;
424
425 ret = tracing_open_generic(inode, filp);
426 if (ret < 0)
427 trace_array_put(tr);
428 return ret;
429}
430
431static int tracing_release_generic_file(struct inode *inode, struct file *filp)
432{
433 struct ftrace_event_file *file = inode->i_private;
434 struct trace_array *tr = file->tr;
435
436 trace_array_put(tr);
437
438 return 0;
439}
440
441/*
413 * __ftrace_set_clr_event(NULL, NULL, NULL, set) will set/unset all events. 442 * __ftrace_set_clr_event(NULL, NULL, NULL, set) will set/unset all events.
414 */ 443 */
415static int __ftrace_set_clr_event(struct trace_array *tr, const char *match, 444static int __ftrace_set_clr_event(struct trace_array *tr, const char *match,
@@ -1032,9 +1061,17 @@ static int subsystem_open(struct inode *inode, struct file *filp)
1032 /* Some versions of gcc think dir can be uninitialized here */ 1061 /* Some versions of gcc think dir can be uninitialized here */
1033 WARN_ON(!dir); 1062 WARN_ON(!dir);
1034 1063
1064 /* Still need to increment the ref count of the system */
1065 if (trace_array_get(tr) < 0) {
1066 put_system(dir);
1067 return -ENODEV;
1068 }
1069
1035 ret = tracing_open_generic(inode, filp); 1070 ret = tracing_open_generic(inode, filp);
1036 if (ret < 0) 1071 if (ret < 0) {
1072 trace_array_put(tr);
1037 put_system(dir); 1073 put_system(dir);
1074 }
1038 1075
1039 return ret; 1076 return ret;
1040} 1077}
@@ -1045,16 +1082,23 @@ static int system_tr_open(struct inode *inode, struct file *filp)
1045 struct trace_array *tr = inode->i_private; 1082 struct trace_array *tr = inode->i_private;
1046 int ret; 1083 int ret;
1047 1084
1085 if (trace_array_get(tr) < 0)
1086 return -ENODEV;
1087
1048 /* Make a temporary dir that has no system but points to tr */ 1088 /* Make a temporary dir that has no system but points to tr */
1049 dir = kzalloc(sizeof(*dir), GFP_KERNEL); 1089 dir = kzalloc(sizeof(*dir), GFP_KERNEL);
1050 if (!dir) 1090 if (!dir) {
1091 trace_array_put(tr);
1051 return -ENOMEM; 1092 return -ENOMEM;
1093 }
1052 1094
1053 dir->tr = tr; 1095 dir->tr = tr;
1054 1096
1055 ret = tracing_open_generic(inode, filp); 1097 ret = tracing_open_generic(inode, filp);
1056 if (ret < 0) 1098 if (ret < 0) {
1099 trace_array_put(tr);
1057 kfree(dir); 1100 kfree(dir);
1101 }
1058 1102
1059 filp->private_data = dir; 1103 filp->private_data = dir;
1060 1104
@@ -1065,6 +1109,8 @@ static int subsystem_release(struct inode *inode, struct file *file)
1065{ 1109{
1066 struct ftrace_subsystem_dir *dir = file->private_data; 1110 struct ftrace_subsystem_dir *dir = file->private_data;
1067 1111
1112 trace_array_put(dir->tr);
1113
1068 /* 1114 /*
1069 * If dir->subsystem is NULL, then this is a temporary 1115 * If dir->subsystem is NULL, then this is a temporary
1070 * descriptor that was made for a trace_array to enable 1116 * descriptor that was made for a trace_array to enable
@@ -1192,9 +1238,10 @@ static const struct file_operations ftrace_set_event_fops = {
1192}; 1238};
1193 1239
1194static const struct file_operations ftrace_enable_fops = { 1240static const struct file_operations ftrace_enable_fops = {
1195 .open = tracing_open_generic, 1241 .open = tracing_open_generic_file,
1196 .read = event_enable_read, 1242 .read = event_enable_read,
1197 .write = event_enable_write, 1243 .write = event_enable_write,
1244 .release = tracing_release_generic_file,
1198 .llseek = default_llseek, 1245 .llseek = default_llseek,
1199}; 1246};
1200 1247