diff options
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 254 |
1 files changed, 116 insertions, 138 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0cd500bffd9b..496f94d57698 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -243,20 +243,25 @@ int filter_current_check_discard(struct ring_buffer *buffer, | |||
243 | } | 243 | } |
244 | EXPORT_SYMBOL_GPL(filter_current_check_discard); | 244 | EXPORT_SYMBOL_GPL(filter_current_check_discard); |
245 | 245 | ||
246 | cycle_t ftrace_now(int cpu) | 246 | cycle_t buffer_ftrace_now(struct trace_buffer *buf, int cpu) |
247 | { | 247 | { |
248 | u64 ts; | 248 | u64 ts; |
249 | 249 | ||
250 | /* Early boot up does not have a buffer yet */ | 250 | /* Early boot up does not have a buffer yet */ |
251 | if (!global_trace.trace_buffer.buffer) | 251 | if (!buf->buffer) |
252 | return trace_clock_local(); | 252 | return trace_clock_local(); |
253 | 253 | ||
254 | ts = ring_buffer_time_stamp(global_trace.trace_buffer.buffer, cpu); | 254 | ts = ring_buffer_time_stamp(buf->buffer, cpu); |
255 | ring_buffer_normalize_time_stamp(global_trace.trace_buffer.buffer, cpu, &ts); | 255 | ring_buffer_normalize_time_stamp(buf->buffer, cpu, &ts); |
256 | 256 | ||
257 | return ts; | 257 | return ts; |
258 | } | 258 | } |
259 | 259 | ||
260 | cycle_t ftrace_now(int cpu) | ||
261 | { | ||
262 | return buffer_ftrace_now(&global_trace.trace_buffer, cpu); | ||
263 | } | ||
264 | |||
260 | /** | 265 | /** |
261 | * tracing_is_enabled - Show if global_trace has been disabled | 266 | * tracing_is_enabled - Show if global_trace has been disabled |
262 | * | 267 | * |
@@ -1211,7 +1216,7 @@ void tracing_reset_online_cpus(struct trace_buffer *buf) | |||
1211 | /* Make sure all commits have finished */ | 1216 | /* Make sure all commits have finished */ |
1212 | synchronize_sched(); | 1217 | synchronize_sched(); |
1213 | 1218 | ||
1214 | buf->time_start = ftrace_now(buf->cpu); | 1219 | buf->time_start = buffer_ftrace_now(buf, buf->cpu); |
1215 | 1220 | ||
1216 | for_each_online_cpu(cpu) | 1221 | for_each_online_cpu(cpu) |
1217 | ring_buffer_reset_cpu(buffer, cpu); | 1222 | ring_buffer_reset_cpu(buffer, cpu); |
@@ -1219,23 +1224,17 @@ void tracing_reset_online_cpus(struct trace_buffer *buf) | |||
1219 | ring_buffer_record_enable(buffer); | 1224 | ring_buffer_record_enable(buffer); |
1220 | } | 1225 | } |
1221 | 1226 | ||
1222 | void tracing_reset_current(int cpu) | 1227 | /* Must have trace_types_lock held */ |
1223 | { | ||
1224 | tracing_reset(&global_trace.trace_buffer, cpu); | ||
1225 | } | ||
1226 | |||
1227 | void tracing_reset_all_online_cpus(void) | 1228 | void tracing_reset_all_online_cpus(void) |
1228 | { | 1229 | { |
1229 | struct trace_array *tr; | 1230 | struct trace_array *tr; |
1230 | 1231 | ||
1231 | mutex_lock(&trace_types_lock); | ||
1232 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { | 1232 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { |
1233 | tracing_reset_online_cpus(&tr->trace_buffer); | 1233 | tracing_reset_online_cpus(&tr->trace_buffer); |
1234 | #ifdef CONFIG_TRACER_MAX_TRACE | 1234 | #ifdef CONFIG_TRACER_MAX_TRACE |
1235 | tracing_reset_online_cpus(&tr->max_buffer); | 1235 | tracing_reset_online_cpus(&tr->max_buffer); |
1236 | #endif | 1236 | #endif |
1237 | } | 1237 | } |
1238 | mutex_unlock(&trace_types_lock); | ||
1239 | } | 1238 | } |
1240 | 1239 | ||
1241 | #define SAVED_CMDLINES 128 | 1240 | #define SAVED_CMDLINES 128 |
@@ -2843,6 +2842,17 @@ static int s_show(struct seq_file *m, void *v) | |||
2843 | return 0; | 2842 | return 0; |
2844 | } | 2843 | } |
2845 | 2844 | ||
2845 | /* | ||
2846 | * Should be used after trace_array_get(), trace_types_lock | ||
2847 | * ensures that i_cdev was already initialized. | ||
2848 | */ | ||
2849 | static inline int tracing_get_cpu(struct inode *inode) | ||
2850 | { | ||
2851 | if (inode->i_cdev) /* See trace_create_cpu_file() */ | ||
2852 | return (long)inode->i_cdev - 1; | ||
2853 | return RING_BUFFER_ALL_CPUS; | ||
2854 | } | ||
2855 | |||
2846 | static const struct seq_operations tracer_seq_ops = { | 2856 | static const struct seq_operations tracer_seq_ops = { |
2847 | .start = s_start, | 2857 | .start = s_start, |
2848 | .next = s_next, | 2858 | .next = s_next, |
@@ -2851,9 +2861,9 @@ static const struct seq_operations tracer_seq_ops = { | |||
2851 | }; | 2861 | }; |
2852 | 2862 | ||
2853 | static struct trace_iterator * | 2863 | static struct trace_iterator * |
2854 | __tracing_open(struct trace_array *tr, struct trace_cpu *tc, | 2864 | __tracing_open(struct inode *inode, struct file *file, bool snapshot) |
2855 | struct inode *inode, struct file *file, bool snapshot) | ||
2856 | { | 2865 | { |
2866 | struct trace_array *tr = inode->i_private; | ||
2857 | struct trace_iterator *iter; | 2867 | struct trace_iterator *iter; |
2858 | int cpu; | 2868 | int cpu; |
2859 | 2869 | ||
@@ -2894,8 +2904,8 @@ __tracing_open(struct trace_array *tr, struct trace_cpu *tc, | |||
2894 | iter->trace_buffer = &tr->trace_buffer; | 2904 | iter->trace_buffer = &tr->trace_buffer; |
2895 | iter->snapshot = snapshot; | 2905 | iter->snapshot = snapshot; |
2896 | iter->pos = -1; | 2906 | iter->pos = -1; |
2907 | iter->cpu_file = tracing_get_cpu(inode); | ||
2897 | mutex_init(&iter->mutex); | 2908 | mutex_init(&iter->mutex); |
2898 | iter->cpu_file = tc->cpu; | ||
2899 | 2909 | ||
2900 | /* Notify the tracer early; before we stop tracing. */ | 2910 | /* Notify the tracer early; before we stop tracing. */ |
2901 | if (iter->trace && iter->trace->open) | 2911 | if (iter->trace && iter->trace->open) |
@@ -2971,45 +2981,22 @@ static int tracing_open_generic_tr(struct inode *inode, struct file *filp) | |||
2971 | filp->private_data = inode->i_private; | 2981 | filp->private_data = inode->i_private; |
2972 | 2982 | ||
2973 | return 0; | 2983 | return 0; |
2974 | |||
2975 | } | ||
2976 | |||
2977 | static int tracing_open_generic_tc(struct inode *inode, struct file *filp) | ||
2978 | { | ||
2979 | struct trace_cpu *tc = inode->i_private; | ||
2980 | struct trace_array *tr = tc->tr; | ||
2981 | |||
2982 | if (tracing_disabled) | ||
2983 | return -ENODEV; | ||
2984 | |||
2985 | if (trace_array_get(tr) < 0) | ||
2986 | return -ENODEV; | ||
2987 | |||
2988 | filp->private_data = inode->i_private; | ||
2989 | |||
2990 | return 0; | ||
2991 | |||
2992 | } | 2984 | } |
2993 | 2985 | ||
2994 | static int tracing_release(struct inode *inode, struct file *file) | 2986 | static int tracing_release(struct inode *inode, struct file *file) |
2995 | { | 2987 | { |
2988 | struct trace_array *tr = inode->i_private; | ||
2996 | struct seq_file *m = file->private_data; | 2989 | struct seq_file *m = file->private_data; |
2997 | struct trace_iterator *iter; | 2990 | struct trace_iterator *iter; |
2998 | struct trace_array *tr; | ||
2999 | int cpu; | 2991 | int cpu; |
3000 | 2992 | ||
3001 | /* Writes do not use seq_file, need to grab tr from inode */ | ||
3002 | if (!(file->f_mode & FMODE_READ)) { | 2993 | if (!(file->f_mode & FMODE_READ)) { |
3003 | struct trace_cpu *tc = inode->i_private; | 2994 | trace_array_put(tr); |
3004 | |||
3005 | trace_array_put(tc->tr); | ||
3006 | return 0; | 2995 | return 0; |
3007 | } | 2996 | } |
3008 | 2997 | ||
2998 | /* Writes do not use seq_file */ | ||
3009 | iter = m->private; | 2999 | iter = m->private; |
3010 | tr = iter->tr; | ||
3011 | trace_array_put(tr); | ||
3012 | |||
3013 | mutex_lock(&trace_types_lock); | 3000 | mutex_lock(&trace_types_lock); |
3014 | 3001 | ||
3015 | for_each_tracing_cpu(cpu) { | 3002 | for_each_tracing_cpu(cpu) { |
@@ -3023,6 +3010,9 @@ static int tracing_release(struct inode *inode, struct file *file) | |||
3023 | if (!iter->snapshot) | 3010 | if (!iter->snapshot) |
3024 | /* reenable tracing if it was previously enabled */ | 3011 | /* reenable tracing if it was previously enabled */ |
3025 | tracing_start_tr(tr); | 3012 | tracing_start_tr(tr); |
3013 | |||
3014 | __trace_array_put(tr); | ||
3015 | |||
3026 | mutex_unlock(&trace_types_lock); | 3016 | mutex_unlock(&trace_types_lock); |
3027 | 3017 | ||
3028 | mutex_destroy(&iter->mutex); | 3018 | mutex_destroy(&iter->mutex); |
@@ -3042,15 +3032,6 @@ static int tracing_release_generic_tr(struct inode *inode, struct file *file) | |||
3042 | return 0; | 3032 | return 0; |
3043 | } | 3033 | } |
3044 | 3034 | ||
3045 | static int tracing_release_generic_tc(struct inode *inode, struct file *file) | ||
3046 | { | ||
3047 | struct trace_cpu *tc = inode->i_private; | ||
3048 | struct trace_array *tr = tc->tr; | ||
3049 | |||
3050 | trace_array_put(tr); | ||
3051 | return 0; | ||
3052 | } | ||
3053 | |||
3054 | static int tracing_single_release_tr(struct inode *inode, struct file *file) | 3035 | static int tracing_single_release_tr(struct inode *inode, struct file *file) |
3055 | { | 3036 | { |
3056 | struct trace_array *tr = inode->i_private; | 3037 | struct trace_array *tr = inode->i_private; |
@@ -3062,8 +3043,7 @@ static int tracing_single_release_tr(struct inode *inode, struct file *file) | |||
3062 | 3043 | ||
3063 | static int tracing_open(struct inode *inode, struct file *file) | 3044 | static int tracing_open(struct inode *inode, struct file *file) |
3064 | { | 3045 | { |
3065 | struct trace_cpu *tc = inode->i_private; | 3046 | struct trace_array *tr = inode->i_private; |
3066 | struct trace_array *tr = tc->tr; | ||
3067 | struct trace_iterator *iter; | 3047 | struct trace_iterator *iter; |
3068 | int ret = 0; | 3048 | int ret = 0; |
3069 | 3049 | ||
@@ -3071,16 +3051,17 @@ static int tracing_open(struct inode *inode, struct file *file) | |||
3071 | return -ENODEV; | 3051 | return -ENODEV; |
3072 | 3052 | ||
3073 | /* If this file was open for write, then erase contents */ | 3053 | /* If this file was open for write, then erase contents */ |
3074 | if ((file->f_mode & FMODE_WRITE) && | 3054 | if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { |
3075 | (file->f_flags & O_TRUNC)) { | 3055 | int cpu = tracing_get_cpu(inode); |
3076 | if (tc->cpu == RING_BUFFER_ALL_CPUS) | 3056 | |
3057 | if (cpu == RING_BUFFER_ALL_CPUS) | ||
3077 | tracing_reset_online_cpus(&tr->trace_buffer); | 3058 | tracing_reset_online_cpus(&tr->trace_buffer); |
3078 | else | 3059 | else |
3079 | tracing_reset(&tr->trace_buffer, tc->cpu); | 3060 | tracing_reset(&tr->trace_buffer, cpu); |
3080 | } | 3061 | } |
3081 | 3062 | ||
3082 | if (file->f_mode & FMODE_READ) { | 3063 | if (file->f_mode & FMODE_READ) { |
3083 | iter = __tracing_open(tr, tc, inode, file, false); | 3064 | iter = __tracing_open(inode, file, false); |
3084 | if (IS_ERR(iter)) | 3065 | if (IS_ERR(iter)) |
3085 | ret = PTR_ERR(iter); | 3066 | ret = PTR_ERR(iter); |
3086 | else if (trace_flags & TRACE_ITER_LATENCY_FMT) | 3067 | else if (trace_flags & TRACE_ITER_LATENCY_FMT) |
@@ -3447,6 +3428,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, | |||
3447 | static int tracing_trace_options_open(struct inode *inode, struct file *file) | 3428 | static int tracing_trace_options_open(struct inode *inode, struct file *file) |
3448 | { | 3429 | { |
3449 | struct trace_array *tr = inode->i_private; | 3430 | struct trace_array *tr = inode->i_private; |
3431 | int ret; | ||
3450 | 3432 | ||
3451 | if (tracing_disabled) | 3433 | if (tracing_disabled) |
3452 | return -ENODEV; | 3434 | return -ENODEV; |
@@ -3454,7 +3436,11 @@ static int tracing_trace_options_open(struct inode *inode, struct file *file) | |||
3454 | if (trace_array_get(tr) < 0) | 3436 | if (trace_array_get(tr) < 0) |
3455 | return -ENODEV; | 3437 | return -ENODEV; |
3456 | 3438 | ||
3457 | return single_open(file, tracing_trace_options_show, inode->i_private); | 3439 | ret = single_open(file, tracing_trace_options_show, inode->i_private); |
3440 | if (ret < 0) | ||
3441 | trace_array_put(tr); | ||
3442 | |||
3443 | return ret; | ||
3458 | } | 3444 | } |
3459 | 3445 | ||
3460 | static const struct file_operations tracing_iter_fops = { | 3446 | static const struct file_operations tracing_iter_fops = { |
@@ -3537,14 +3523,14 @@ static const char readme_msg[] = | |||
3537 | "\n snapshot\t\t- Like 'trace' but shows the content of the static snapshot buffer\n" | 3523 | "\n snapshot\t\t- Like 'trace' but shows the content of the static snapshot buffer\n" |
3538 | "\t\t\t Read the contents for more information\n" | 3524 | "\t\t\t Read the contents for more information\n" |
3539 | #endif | 3525 | #endif |
3540 | #ifdef CONFIG_STACKTRACE | 3526 | #ifdef CONFIG_STACK_TRACER |
3541 | " stack_trace\t\t- Shows the max stack trace when active\n" | 3527 | " stack_trace\t\t- Shows the max stack trace when active\n" |
3542 | " stack_max_size\t- Shows current max stack size that was traced\n" | 3528 | " stack_max_size\t- Shows current max stack size that was traced\n" |
3543 | "\t\t\t Write into this file to reset the max size (trigger a new trace)\n" | 3529 | "\t\t\t Write into this file to reset the max size (trigger a new trace)\n" |
3544 | #ifdef CONFIG_DYNAMIC_FTRACE | 3530 | #ifdef CONFIG_DYNAMIC_FTRACE |
3545 | " stack_trace_filter\t- Like set_ftrace_filter but limits what stack_trace traces\n" | 3531 | " stack_trace_filter\t- Like set_ftrace_filter but limits what stack_trace traces\n" |
3546 | #endif | 3532 | #endif |
3547 | #endif /* CONFIG_STACKTRACE */ | 3533 | #endif /* CONFIG_STACK_TRACER */ |
3548 | ; | 3534 | ; |
3549 | 3535 | ||
3550 | static ssize_t | 3536 | static ssize_t |
@@ -3941,8 +3927,7 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf, | |||
3941 | 3927 | ||
3942 | static int tracing_open_pipe(struct inode *inode, struct file *filp) | 3928 | static int tracing_open_pipe(struct inode *inode, struct file *filp) |
3943 | { | 3929 | { |
3944 | struct trace_cpu *tc = inode->i_private; | 3930 | struct trace_array *tr = inode->i_private; |
3945 | struct trace_array *tr = tc->tr; | ||
3946 | struct trace_iterator *iter; | 3931 | struct trace_iterator *iter; |
3947 | int ret = 0; | 3932 | int ret = 0; |
3948 | 3933 | ||
@@ -3958,6 +3943,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) | |||
3958 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); | 3943 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); |
3959 | if (!iter) { | 3944 | if (!iter) { |
3960 | ret = -ENOMEM; | 3945 | ret = -ENOMEM; |
3946 | __trace_array_put(tr); | ||
3961 | goto out; | 3947 | goto out; |
3962 | } | 3948 | } |
3963 | 3949 | ||
@@ -3987,9 +3973,9 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) | |||
3987 | if (trace_clocks[tr->clock_id].in_ns) | 3973 | if (trace_clocks[tr->clock_id].in_ns) |
3988 | iter->iter_flags |= TRACE_FILE_TIME_IN_NS; | 3974 | iter->iter_flags |= TRACE_FILE_TIME_IN_NS; |
3989 | 3975 | ||
3990 | iter->cpu_file = tc->cpu; | 3976 | iter->tr = tr; |
3991 | iter->tr = tc->tr; | 3977 | iter->trace_buffer = &tr->trace_buffer; |
3992 | iter->trace_buffer = &tc->tr->trace_buffer; | 3978 | iter->cpu_file = tracing_get_cpu(inode); |
3993 | mutex_init(&iter->mutex); | 3979 | mutex_init(&iter->mutex); |
3994 | filp->private_data = iter; | 3980 | filp->private_data = iter; |
3995 | 3981 | ||
@@ -4012,8 +3998,7 @@ fail: | |||
4012 | static int tracing_release_pipe(struct inode *inode, struct file *file) | 3998 | static int tracing_release_pipe(struct inode *inode, struct file *file) |
4013 | { | 3999 | { |
4014 | struct trace_iterator *iter = file->private_data; | 4000 | struct trace_iterator *iter = file->private_data; |
4015 | struct trace_cpu *tc = inode->i_private; | 4001 | struct trace_array *tr = inode->i_private; |
4016 | struct trace_array *tr = tc->tr; | ||
4017 | 4002 | ||
4018 | mutex_lock(&trace_types_lock); | 4003 | mutex_lock(&trace_types_lock); |
4019 | 4004 | ||
@@ -4166,6 +4151,7 @@ waitagain: | |||
4166 | memset(&iter->seq, 0, | 4151 | memset(&iter->seq, 0, |
4167 | sizeof(struct trace_iterator) - | 4152 | sizeof(struct trace_iterator) - |
4168 | offsetof(struct trace_iterator, seq)); | 4153 | offsetof(struct trace_iterator, seq)); |
4154 | cpumask_clear(iter->started); | ||
4169 | iter->pos = -1; | 4155 | iter->pos = -1; |
4170 | 4156 | ||
4171 | trace_event_read_lock(); | 4157 | trace_event_read_lock(); |
@@ -4366,15 +4352,16 @@ static ssize_t | |||
4366 | tracing_entries_read(struct file *filp, char __user *ubuf, | 4352 | tracing_entries_read(struct file *filp, char __user *ubuf, |
4367 | size_t cnt, loff_t *ppos) | 4353 | size_t cnt, loff_t *ppos) |
4368 | { | 4354 | { |
4369 | struct trace_cpu *tc = filp->private_data; | 4355 | struct inode *inode = file_inode(filp); |
4370 | struct trace_array *tr = tc->tr; | 4356 | struct trace_array *tr = inode->i_private; |
4357 | int cpu = tracing_get_cpu(inode); | ||
4371 | char buf[64]; | 4358 | char buf[64]; |
4372 | int r = 0; | 4359 | int r = 0; |
4373 | ssize_t ret; | 4360 | ssize_t ret; |
4374 | 4361 | ||
4375 | mutex_lock(&trace_types_lock); | 4362 | mutex_lock(&trace_types_lock); |
4376 | 4363 | ||
4377 | if (tc->cpu == RING_BUFFER_ALL_CPUS) { | 4364 | if (cpu == RING_BUFFER_ALL_CPUS) { |
4378 | int cpu, buf_size_same; | 4365 | int cpu, buf_size_same; |
4379 | unsigned long size; | 4366 | unsigned long size; |
4380 | 4367 | ||
@@ -4401,7 +4388,7 @@ tracing_entries_read(struct file *filp, char __user *ubuf, | |||
4401 | } else | 4388 | } else |
4402 | r = sprintf(buf, "X\n"); | 4389 | r = sprintf(buf, "X\n"); |
4403 | } else | 4390 | } else |
4404 | r = sprintf(buf, "%lu\n", per_cpu_ptr(tr->trace_buffer.data, tc->cpu)->entries >> 10); | 4391 | r = sprintf(buf, "%lu\n", per_cpu_ptr(tr->trace_buffer.data, cpu)->entries >> 10); |
4405 | 4392 | ||
4406 | mutex_unlock(&trace_types_lock); | 4393 | mutex_unlock(&trace_types_lock); |
4407 | 4394 | ||
@@ -4413,7 +4400,8 @@ static ssize_t | |||
4413 | tracing_entries_write(struct file *filp, const char __user *ubuf, | 4400 | tracing_entries_write(struct file *filp, const char __user *ubuf, |
4414 | size_t cnt, loff_t *ppos) | 4401 | size_t cnt, loff_t *ppos) |
4415 | { | 4402 | { |
4416 | struct trace_cpu *tc = filp->private_data; | 4403 | struct inode *inode = file_inode(filp); |
4404 | struct trace_array *tr = inode->i_private; | ||
4417 | unsigned long val; | 4405 | unsigned long val; |
4418 | int ret; | 4406 | int ret; |
4419 | 4407 | ||
@@ -4427,8 +4415,7 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, | |||
4427 | 4415 | ||
4428 | /* value is in KB */ | 4416 | /* value is in KB */ |
4429 | val <<= 10; | 4417 | val <<= 10; |
4430 | 4418 | ret = tracing_resize_ring_buffer(tr, val, tracing_get_cpu(inode)); | |
4431 | ret = tracing_resize_ring_buffer(tc->tr, val, tc->cpu); | ||
4432 | if (ret < 0) | 4419 | if (ret < 0) |
4433 | return ret; | 4420 | return ret; |
4434 | 4421 | ||
@@ -4482,7 +4469,7 @@ tracing_free_buffer_release(struct inode *inode, struct file *filp) | |||
4482 | 4469 | ||
4483 | /* disable tracing ? */ | 4470 | /* disable tracing ? */ |
4484 | if (trace_flags & TRACE_ITER_STOP_ON_FREE) | 4471 | if (trace_flags & TRACE_ITER_STOP_ON_FREE) |
4485 | tracing_off(); | 4472 | tracer_tracing_off(tr); |
4486 | /* resize the ring buffer to 0 */ | 4473 | /* resize the ring buffer to 0 */ |
4487 | tracing_resize_ring_buffer(tr, 0, RING_BUFFER_ALL_CPUS); | 4474 | tracing_resize_ring_buffer(tr, 0, RING_BUFFER_ALL_CPUS); |
4488 | 4475 | ||
@@ -4647,12 +4634,12 @@ static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf, | |||
4647 | * New clock may not be consistent with the previous clock. | 4634 | * New clock may not be consistent with the previous clock. |
4648 | * Reset the buffer so that it doesn't have incomparable timestamps. | 4635 | * Reset the buffer so that it doesn't have incomparable timestamps. |
4649 | */ | 4636 | */ |
4650 | tracing_reset_online_cpus(&global_trace.trace_buffer); | 4637 | tracing_reset_online_cpus(&tr->trace_buffer); |
4651 | 4638 | ||
4652 | #ifdef CONFIG_TRACER_MAX_TRACE | 4639 | #ifdef CONFIG_TRACER_MAX_TRACE |
4653 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer) | 4640 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer) |
4654 | ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func); | 4641 | ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func); |
4655 | tracing_reset_online_cpus(&global_trace.max_buffer); | 4642 | tracing_reset_online_cpus(&tr->max_buffer); |
4656 | #endif | 4643 | #endif |
4657 | 4644 | ||
4658 | mutex_unlock(&trace_types_lock); | 4645 | mutex_unlock(&trace_types_lock); |
@@ -4689,8 +4676,7 @@ struct ftrace_buffer_info { | |||
4689 | #ifdef CONFIG_TRACER_SNAPSHOT | 4676 | #ifdef CONFIG_TRACER_SNAPSHOT |
4690 | static int tracing_snapshot_open(struct inode *inode, struct file *file) | 4677 | static int tracing_snapshot_open(struct inode *inode, struct file *file) |
4691 | { | 4678 | { |
4692 | struct trace_cpu *tc = inode->i_private; | 4679 | struct trace_array *tr = inode->i_private; |
4693 | struct trace_array *tr = tc->tr; | ||
4694 | struct trace_iterator *iter; | 4680 | struct trace_iterator *iter; |
4695 | struct seq_file *m; | 4681 | struct seq_file *m; |
4696 | int ret = 0; | 4682 | int ret = 0; |
@@ -4699,26 +4685,29 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file) | |||
4699 | return -ENODEV; | 4685 | return -ENODEV; |
4700 | 4686 | ||
4701 | if (file->f_mode & FMODE_READ) { | 4687 | if (file->f_mode & FMODE_READ) { |
4702 | iter = __tracing_open(tr, tc, inode, file, true); | 4688 | iter = __tracing_open(inode, file, true); |
4703 | if (IS_ERR(iter)) | 4689 | if (IS_ERR(iter)) |
4704 | ret = PTR_ERR(iter); | 4690 | ret = PTR_ERR(iter); |
4705 | } else { | 4691 | } else { |
4706 | /* Writes still need the seq_file to hold the private data */ | 4692 | /* Writes still need the seq_file to hold the private data */ |
4693 | ret = -ENOMEM; | ||
4707 | m = kzalloc(sizeof(*m), GFP_KERNEL); | 4694 | m = kzalloc(sizeof(*m), GFP_KERNEL); |
4708 | if (!m) | 4695 | if (!m) |
4709 | return -ENOMEM; | 4696 | goto out; |
4710 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); | 4697 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); |
4711 | if (!iter) { | 4698 | if (!iter) { |
4712 | kfree(m); | 4699 | kfree(m); |
4713 | return -ENOMEM; | 4700 | goto out; |
4714 | } | 4701 | } |
4702 | ret = 0; | ||
4703 | |||
4715 | iter->tr = tr; | 4704 | iter->tr = tr; |
4716 | iter->trace_buffer = &tc->tr->max_buffer; | 4705 | iter->trace_buffer = &tr->max_buffer; |
4717 | iter->cpu_file = tc->cpu; | 4706 | iter->cpu_file = tracing_get_cpu(inode); |
4718 | m->private = iter; | 4707 | m->private = iter; |
4719 | file->private_data = m; | 4708 | file->private_data = m; |
4720 | } | 4709 | } |
4721 | 4710 | out: | |
4722 | if (ret < 0) | 4711 | if (ret < 0) |
4723 | trace_array_put(tr); | 4712 | trace_array_put(tr); |
4724 | 4713 | ||
@@ -4873,11 +4862,11 @@ static const struct file_operations tracing_pipe_fops = { | |||
4873 | }; | 4862 | }; |
4874 | 4863 | ||
4875 | static const struct file_operations tracing_entries_fops = { | 4864 | static const struct file_operations tracing_entries_fops = { |
4876 | .open = tracing_open_generic_tc, | 4865 | .open = tracing_open_generic_tr, |
4877 | .read = tracing_entries_read, | 4866 | .read = tracing_entries_read, |
4878 | .write = tracing_entries_write, | 4867 | .write = tracing_entries_write, |
4879 | .llseek = generic_file_llseek, | 4868 | .llseek = generic_file_llseek, |
4880 | .release = tracing_release_generic_tc, | 4869 | .release = tracing_release_generic_tr, |
4881 | }; | 4870 | }; |
4882 | 4871 | ||
4883 | static const struct file_operations tracing_total_entries_fops = { | 4872 | static const struct file_operations tracing_total_entries_fops = { |
@@ -4929,8 +4918,7 @@ static const struct file_operations snapshot_raw_fops = { | |||
4929 | 4918 | ||
4930 | static int tracing_buffers_open(struct inode *inode, struct file *filp) | 4919 | static int tracing_buffers_open(struct inode *inode, struct file *filp) |
4931 | { | 4920 | { |
4932 | struct trace_cpu *tc = inode->i_private; | 4921 | struct trace_array *tr = inode->i_private; |
4933 | struct trace_array *tr = tc->tr; | ||
4934 | struct ftrace_buffer_info *info; | 4922 | struct ftrace_buffer_info *info; |
4935 | int ret; | 4923 | int ret; |
4936 | 4924 | ||
@@ -4948,10 +4936,8 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp) | |||
4948 | 4936 | ||
4949 | mutex_lock(&trace_types_lock); | 4937 | mutex_lock(&trace_types_lock); |
4950 | 4938 | ||
4951 | tr->ref++; | ||
4952 | |||
4953 | info->iter.tr = tr; | 4939 | info->iter.tr = tr; |
4954 | info->iter.cpu_file = tc->cpu; | 4940 | info->iter.cpu_file = tracing_get_cpu(inode); |
4955 | info->iter.trace = tr->current_trace; | 4941 | info->iter.trace = tr->current_trace; |
4956 | info->iter.trace_buffer = &tr->trace_buffer; | 4942 | info->iter.trace_buffer = &tr->trace_buffer; |
4957 | info->spare = NULL; | 4943 | info->spare = NULL; |
@@ -5268,14 +5254,14 @@ static ssize_t | |||
5268 | tracing_stats_read(struct file *filp, char __user *ubuf, | 5254 | tracing_stats_read(struct file *filp, char __user *ubuf, |
5269 | size_t count, loff_t *ppos) | 5255 | size_t count, loff_t *ppos) |
5270 | { | 5256 | { |
5271 | struct trace_cpu *tc = filp->private_data; | 5257 | struct inode *inode = file_inode(filp); |
5272 | struct trace_array *tr = tc->tr; | 5258 | struct trace_array *tr = inode->i_private; |
5273 | struct trace_buffer *trace_buf = &tr->trace_buffer; | 5259 | struct trace_buffer *trace_buf = &tr->trace_buffer; |
5260 | int cpu = tracing_get_cpu(inode); | ||
5274 | struct trace_seq *s; | 5261 | struct trace_seq *s; |
5275 | unsigned long cnt; | 5262 | unsigned long cnt; |
5276 | unsigned long long t; | 5263 | unsigned long long t; |
5277 | unsigned long usec_rem; | 5264 | unsigned long usec_rem; |
5278 | int cpu = tc->cpu; | ||
5279 | 5265 | ||
5280 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 5266 | s = kmalloc(sizeof(*s), GFP_KERNEL); |
5281 | if (!s) | 5267 | if (!s) |
@@ -5328,9 +5314,10 @@ tracing_stats_read(struct file *filp, char __user *ubuf, | |||
5328 | } | 5314 | } |
5329 | 5315 | ||
5330 | static const struct file_operations tracing_stats_fops = { | 5316 | static const struct file_operations tracing_stats_fops = { |
5331 | .open = tracing_open_generic, | 5317 | .open = tracing_open_generic_tr, |
5332 | .read = tracing_stats_read, | 5318 | .read = tracing_stats_read, |
5333 | .llseek = generic_file_llseek, | 5319 | .llseek = generic_file_llseek, |
5320 | .release = tracing_release_generic_tr, | ||
5334 | }; | 5321 | }; |
5335 | 5322 | ||
5336 | #ifdef CONFIG_DYNAMIC_FTRACE | 5323 | #ifdef CONFIG_DYNAMIC_FTRACE |
@@ -5519,10 +5506,20 @@ static struct dentry *tracing_dentry_percpu(struct trace_array *tr, int cpu) | |||
5519 | return tr->percpu_dir; | 5506 | return tr->percpu_dir; |
5520 | } | 5507 | } |
5521 | 5508 | ||
5509 | static struct dentry * | ||
5510 | trace_create_cpu_file(const char *name, umode_t mode, struct dentry *parent, | ||
5511 | void *data, long cpu, const struct file_operations *fops) | ||
5512 | { | ||
5513 | struct dentry *ret = trace_create_file(name, mode, parent, data, fops); | ||
5514 | |||
5515 | if (ret) /* See tracing_get_cpu() */ | ||
5516 | ret->d_inode->i_cdev = (void *)(cpu + 1); | ||
5517 | return ret; | ||
5518 | } | ||
5519 | |||
5522 | static void | 5520 | static void |
5523 | tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) | 5521 | tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) |
5524 | { | 5522 | { |
5525 | struct trace_array_cpu *data = per_cpu_ptr(tr->trace_buffer.data, cpu); | ||
5526 | struct dentry *d_percpu = tracing_dentry_percpu(tr, cpu); | 5523 | struct dentry *d_percpu = tracing_dentry_percpu(tr, cpu); |
5527 | struct dentry *d_cpu; | 5524 | struct dentry *d_cpu; |
5528 | char cpu_dir[30]; /* 30 characters should be more than enough */ | 5525 | char cpu_dir[30]; /* 30 characters should be more than enough */ |
@@ -5538,28 +5535,28 @@ tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) | |||
5538 | } | 5535 | } |
5539 | 5536 | ||
5540 | /* per cpu trace_pipe */ | 5537 | /* per cpu trace_pipe */ |
5541 | trace_create_file("trace_pipe", 0444, d_cpu, | 5538 | trace_create_cpu_file("trace_pipe", 0444, d_cpu, |
5542 | (void *)&data->trace_cpu, &tracing_pipe_fops); | 5539 | tr, cpu, &tracing_pipe_fops); |
5543 | 5540 | ||
5544 | /* per cpu trace */ | 5541 | /* per cpu trace */ |
5545 | trace_create_file("trace", 0644, d_cpu, | 5542 | trace_create_cpu_file("trace", 0644, d_cpu, |
5546 | (void *)&data->trace_cpu, &tracing_fops); | 5543 | tr, cpu, &tracing_fops); |
5547 | 5544 | ||
5548 | trace_create_file("trace_pipe_raw", 0444, d_cpu, | 5545 | trace_create_cpu_file("trace_pipe_raw", 0444, d_cpu, |
5549 | (void *)&data->trace_cpu, &tracing_buffers_fops); | 5546 | tr, cpu, &tracing_buffers_fops); |
5550 | 5547 | ||
5551 | trace_create_file("stats", 0444, d_cpu, | 5548 | trace_create_cpu_file("stats", 0444, d_cpu, |
5552 | (void *)&data->trace_cpu, &tracing_stats_fops); | 5549 | tr, cpu, &tracing_stats_fops); |
5553 | 5550 | ||
5554 | trace_create_file("buffer_size_kb", 0444, d_cpu, | 5551 | trace_create_cpu_file("buffer_size_kb", 0444, d_cpu, |
5555 | (void *)&data->trace_cpu, &tracing_entries_fops); | 5552 | tr, cpu, &tracing_entries_fops); |
5556 | 5553 | ||
5557 | #ifdef CONFIG_TRACER_SNAPSHOT | 5554 | #ifdef CONFIG_TRACER_SNAPSHOT |
5558 | trace_create_file("snapshot", 0644, d_cpu, | 5555 | trace_create_cpu_file("snapshot", 0644, d_cpu, |
5559 | (void *)&data->trace_cpu, &snapshot_fops); | 5556 | tr, cpu, &snapshot_fops); |
5560 | 5557 | ||
5561 | trace_create_file("snapshot_raw", 0444, d_cpu, | 5558 | trace_create_cpu_file("snapshot_raw", 0444, d_cpu, |
5562 | (void *)&data->trace_cpu, &snapshot_raw_fops); | 5559 | tr, cpu, &snapshot_raw_fops); |
5563 | #endif | 5560 | #endif |
5564 | } | 5561 | } |
5565 | 5562 | ||
@@ -5868,17 +5865,6 @@ struct dentry *trace_instance_dir; | |||
5868 | static void | 5865 | static void |
5869 | init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer); | 5866 | init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer); |
5870 | 5867 | ||
5871 | static void init_trace_buffers(struct trace_array *tr, struct trace_buffer *buf) | ||
5872 | { | ||
5873 | int cpu; | ||
5874 | |||
5875 | for_each_tracing_cpu(cpu) { | ||
5876 | memset(per_cpu_ptr(buf->data, cpu), 0, sizeof(struct trace_array_cpu)); | ||
5877 | per_cpu_ptr(buf->data, cpu)->trace_cpu.cpu = cpu; | ||
5878 | per_cpu_ptr(buf->data, cpu)->trace_cpu.tr = tr; | ||
5879 | } | ||
5880 | } | ||
5881 | |||
5882 | static int | 5868 | static int |
5883 | allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size) | 5869 | allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size) |
5884 | { | 5870 | { |
@@ -5896,8 +5882,6 @@ allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size | |||
5896 | return -ENOMEM; | 5882 | return -ENOMEM; |
5897 | } | 5883 | } |
5898 | 5884 | ||
5899 | init_trace_buffers(tr, buf); | ||
5900 | |||
5901 | /* Allocate the first page for all buffers */ | 5885 | /* Allocate the first page for all buffers */ |
5902 | set_buffer_entries(&tr->trace_buffer, | 5886 | set_buffer_entries(&tr->trace_buffer, |
5903 | ring_buffer_size(tr->trace_buffer.buffer, 0)); | 5887 | ring_buffer_size(tr->trace_buffer.buffer, 0)); |
@@ -5964,17 +5948,15 @@ static int new_instance_create(const char *name) | |||
5964 | if (allocate_trace_buffers(tr, trace_buf_size) < 0) | 5948 | if (allocate_trace_buffers(tr, trace_buf_size) < 0) |
5965 | goto out_free_tr; | 5949 | goto out_free_tr; |
5966 | 5950 | ||
5967 | /* Holder for file callbacks */ | ||
5968 | tr->trace_cpu.cpu = RING_BUFFER_ALL_CPUS; | ||
5969 | tr->trace_cpu.tr = tr; | ||
5970 | |||
5971 | tr->dir = debugfs_create_dir(name, trace_instance_dir); | 5951 | tr->dir = debugfs_create_dir(name, trace_instance_dir); |
5972 | if (!tr->dir) | 5952 | if (!tr->dir) |
5973 | goto out_free_tr; | 5953 | goto out_free_tr; |
5974 | 5954 | ||
5975 | ret = event_trace_add_tracer(tr->dir, tr); | 5955 | ret = event_trace_add_tracer(tr->dir, tr); |
5976 | if (ret) | 5956 | if (ret) { |
5957 | debugfs_remove_recursive(tr->dir); | ||
5977 | goto out_free_tr; | 5958 | goto out_free_tr; |
5959 | } | ||
5978 | 5960 | ||
5979 | init_tracer_debugfs(tr, tr->dir); | 5961 | init_tracer_debugfs(tr, tr->dir); |
5980 | 5962 | ||
@@ -6120,13 +6102,13 @@ init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer) | |||
6120 | tr, &tracing_iter_fops); | 6102 | tr, &tracing_iter_fops); |
6121 | 6103 | ||
6122 | trace_create_file("trace", 0644, d_tracer, | 6104 | trace_create_file("trace", 0644, d_tracer, |
6123 | (void *)&tr->trace_cpu, &tracing_fops); | 6105 | tr, &tracing_fops); |
6124 | 6106 | ||
6125 | trace_create_file("trace_pipe", 0444, d_tracer, | 6107 | trace_create_file("trace_pipe", 0444, d_tracer, |
6126 | (void *)&tr->trace_cpu, &tracing_pipe_fops); | 6108 | tr, &tracing_pipe_fops); |
6127 | 6109 | ||
6128 | trace_create_file("buffer_size_kb", 0644, d_tracer, | 6110 | trace_create_file("buffer_size_kb", 0644, d_tracer, |
6129 | (void *)&tr->trace_cpu, &tracing_entries_fops); | 6111 | tr, &tracing_entries_fops); |
6130 | 6112 | ||
6131 | trace_create_file("buffer_total_size_kb", 0444, d_tracer, | 6113 | trace_create_file("buffer_total_size_kb", 0444, d_tracer, |
6132 | tr, &tracing_total_entries_fops); | 6114 | tr, &tracing_total_entries_fops); |
@@ -6141,11 +6123,11 @@ init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer) | |||
6141 | &trace_clock_fops); | 6123 | &trace_clock_fops); |
6142 | 6124 | ||
6143 | trace_create_file("tracing_on", 0644, d_tracer, | 6125 | trace_create_file("tracing_on", 0644, d_tracer, |
6144 | tr, &rb_simple_fops); | 6126 | tr, &rb_simple_fops); |
6145 | 6127 | ||
6146 | #ifdef CONFIG_TRACER_SNAPSHOT | 6128 | #ifdef CONFIG_TRACER_SNAPSHOT |
6147 | trace_create_file("snapshot", 0644, d_tracer, | 6129 | trace_create_file("snapshot", 0644, d_tracer, |
6148 | (void *)&tr->trace_cpu, &snapshot_fops); | 6130 | tr, &snapshot_fops); |
6149 | #endif | 6131 | #endif |
6150 | 6132 | ||
6151 | for_each_tracing_cpu(cpu) | 6133 | for_each_tracing_cpu(cpu) |
@@ -6439,10 +6421,6 @@ __init static int tracer_alloc_buffers(void) | |||
6439 | 6421 | ||
6440 | global_trace.flags = TRACE_ARRAY_FL_GLOBAL; | 6422 | global_trace.flags = TRACE_ARRAY_FL_GLOBAL; |
6441 | 6423 | ||
6442 | /* Holder for file callbacks */ | ||
6443 | global_trace.trace_cpu.cpu = RING_BUFFER_ALL_CPUS; | ||
6444 | global_trace.trace_cpu.tr = &global_trace; | ||
6445 | |||
6446 | INIT_LIST_HEAD(&global_trace.systems); | 6424 | INIT_LIST_HEAD(&global_trace.systems); |
6447 | INIT_LIST_HEAD(&global_trace.events); | 6425 | INIT_LIST_HEAD(&global_trace.events); |
6448 | list_add(&global_trace.list, &ftrace_trace_arrays); | 6426 | list_add(&global_trace.list, &ftrace_trace_arrays); |