diff options
Diffstat (limited to 'kernel/trace/trace.c')
| -rw-r--r-- | kernel/trace/trace.c | 227 |
1 files changed, 102 insertions, 125 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0cd500bffd9b..882ec1dd1515 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -1224,18 +1224,17 @@ void tracing_reset_current(int cpu) | |||
| 1224 | tracing_reset(&global_trace.trace_buffer, cpu); | 1224 | tracing_reset(&global_trace.trace_buffer, cpu); |
| 1225 | } | 1225 | } |
| 1226 | 1226 | ||
| 1227 | /* Must have trace_types_lock held */ | ||
| 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 | ||
| @@ -4366,15 +4351,16 @@ static ssize_t | |||
| 4366 | tracing_entries_read(struct file *filp, char __user *ubuf, | 4351 | tracing_entries_read(struct file *filp, char __user *ubuf, |
| 4367 | size_t cnt, loff_t *ppos) | 4352 | size_t cnt, loff_t *ppos) |
| 4368 | { | 4353 | { |
| 4369 | struct trace_cpu *tc = filp->private_data; | 4354 | struct inode *inode = file_inode(filp); |
| 4370 | struct trace_array *tr = tc->tr; | 4355 | struct trace_array *tr = inode->i_private; |
| 4356 | int cpu = tracing_get_cpu(inode); | ||
| 4371 | char buf[64]; | 4357 | char buf[64]; |
| 4372 | int r = 0; | 4358 | int r = 0; |
| 4373 | ssize_t ret; | 4359 | ssize_t ret; |
| 4374 | 4360 | ||
| 4375 | mutex_lock(&trace_types_lock); | 4361 | mutex_lock(&trace_types_lock); |
| 4376 | 4362 | ||
| 4377 | if (tc->cpu == RING_BUFFER_ALL_CPUS) { | 4363 | if (cpu == RING_BUFFER_ALL_CPUS) { |
| 4378 | int cpu, buf_size_same; | 4364 | int cpu, buf_size_same; |
| 4379 | unsigned long size; | 4365 | unsigned long size; |
| 4380 | 4366 | ||
| @@ -4401,7 +4387,7 @@ tracing_entries_read(struct file *filp, char __user *ubuf, | |||
| 4401 | } else | 4387 | } else |
| 4402 | r = sprintf(buf, "X\n"); | 4388 | r = sprintf(buf, "X\n"); |
| 4403 | } else | 4389 | } else |
| 4404 | r = sprintf(buf, "%lu\n", per_cpu_ptr(tr->trace_buffer.data, tc->cpu)->entries >> 10); | 4390 | r = sprintf(buf, "%lu\n", per_cpu_ptr(tr->trace_buffer.data, cpu)->entries >> 10); |
| 4405 | 4391 | ||
| 4406 | mutex_unlock(&trace_types_lock); | 4392 | mutex_unlock(&trace_types_lock); |
| 4407 | 4393 | ||
| @@ -4413,7 +4399,8 @@ static ssize_t | |||
| 4413 | tracing_entries_write(struct file *filp, const char __user *ubuf, | 4399 | tracing_entries_write(struct file *filp, const char __user *ubuf, |
| 4414 | size_t cnt, loff_t *ppos) | 4400 | size_t cnt, loff_t *ppos) |
| 4415 | { | 4401 | { |
| 4416 | struct trace_cpu *tc = filp->private_data; | 4402 | struct inode *inode = file_inode(filp); |
| 4403 | struct trace_array *tr = inode->i_private; | ||
| 4417 | unsigned long val; | 4404 | unsigned long val; |
| 4418 | int ret; | 4405 | int ret; |
| 4419 | 4406 | ||
| @@ -4427,8 +4414,7 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, | |||
| 4427 | 4414 | ||
| 4428 | /* value is in KB */ | 4415 | /* value is in KB */ |
| 4429 | val <<= 10; | 4416 | val <<= 10; |
| 4430 | 4417 | 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) | 4418 | if (ret < 0) |
| 4433 | return ret; | 4419 | return ret; |
| 4434 | 4420 | ||
| @@ -4689,8 +4675,7 @@ struct ftrace_buffer_info { | |||
| 4689 | #ifdef CONFIG_TRACER_SNAPSHOT | 4675 | #ifdef CONFIG_TRACER_SNAPSHOT |
| 4690 | static int tracing_snapshot_open(struct inode *inode, struct file *file) | 4676 | static int tracing_snapshot_open(struct inode *inode, struct file *file) |
| 4691 | { | 4677 | { |
| 4692 | struct trace_cpu *tc = inode->i_private; | 4678 | struct trace_array *tr = inode->i_private; |
| 4693 | struct trace_array *tr = tc->tr; | ||
| 4694 | struct trace_iterator *iter; | 4679 | struct trace_iterator *iter; |
| 4695 | struct seq_file *m; | 4680 | struct seq_file *m; |
| 4696 | int ret = 0; | 4681 | int ret = 0; |
| @@ -4699,26 +4684,29 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file) | |||
| 4699 | return -ENODEV; | 4684 | return -ENODEV; |
| 4700 | 4685 | ||
| 4701 | if (file->f_mode & FMODE_READ) { | 4686 | if (file->f_mode & FMODE_READ) { |
| 4702 | iter = __tracing_open(tr, tc, inode, file, true); | 4687 | iter = __tracing_open(inode, file, true); |
| 4703 | if (IS_ERR(iter)) | 4688 | if (IS_ERR(iter)) |
| 4704 | ret = PTR_ERR(iter); | 4689 | ret = PTR_ERR(iter); |
| 4705 | } else { | 4690 | } else { |
| 4706 | /* Writes still need the seq_file to hold the private data */ | 4691 | /* Writes still need the seq_file to hold the private data */ |
| 4692 | ret = -ENOMEM; | ||
| 4707 | m = kzalloc(sizeof(*m), GFP_KERNEL); | 4693 | m = kzalloc(sizeof(*m), GFP_KERNEL); |
| 4708 | if (!m) | 4694 | if (!m) |
| 4709 | return -ENOMEM; | 4695 | goto out; |
| 4710 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); | 4696 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); |
| 4711 | if (!iter) { | 4697 | if (!iter) { |
| 4712 | kfree(m); | 4698 | kfree(m); |
| 4713 | return -ENOMEM; | 4699 | goto out; |
| 4714 | } | 4700 | } |
| 4701 | ret = 0; | ||
| 4702 | |||
| 4715 | iter->tr = tr; | 4703 | iter->tr = tr; |
| 4716 | iter->trace_buffer = &tc->tr->max_buffer; | 4704 | iter->trace_buffer = &tr->max_buffer; |
| 4717 | iter->cpu_file = tc->cpu; | 4705 | iter->cpu_file = tracing_get_cpu(inode); |
| 4718 | m->private = iter; | 4706 | m->private = iter; |
| 4719 | file->private_data = m; | 4707 | file->private_data = m; |
| 4720 | } | 4708 | } |
| 4721 | 4709 | out: | |
| 4722 | if (ret < 0) | 4710 | if (ret < 0) |
| 4723 | trace_array_put(tr); | 4711 | trace_array_put(tr); |
| 4724 | 4712 | ||
| @@ -4873,11 +4861,11 @@ static const struct file_operations tracing_pipe_fops = { | |||
| 4873 | }; | 4861 | }; |
| 4874 | 4862 | ||
| 4875 | static const struct file_operations tracing_entries_fops = { | 4863 | static const struct file_operations tracing_entries_fops = { |
| 4876 | .open = tracing_open_generic_tc, | 4864 | .open = tracing_open_generic_tr, |
| 4877 | .read = tracing_entries_read, | 4865 | .read = tracing_entries_read, |
| 4878 | .write = tracing_entries_write, | 4866 | .write = tracing_entries_write, |
| 4879 | .llseek = generic_file_llseek, | 4867 | .llseek = generic_file_llseek, |
| 4880 | .release = tracing_release_generic_tc, | 4868 | .release = tracing_release_generic_tr, |
| 4881 | }; | 4869 | }; |
| 4882 | 4870 | ||
| 4883 | static const struct file_operations tracing_total_entries_fops = { | 4871 | static const struct file_operations tracing_total_entries_fops = { |
| @@ -4929,8 +4917,7 @@ static const struct file_operations snapshot_raw_fops = { | |||
| 4929 | 4917 | ||
| 4930 | static int tracing_buffers_open(struct inode *inode, struct file *filp) | 4918 | static int tracing_buffers_open(struct inode *inode, struct file *filp) |
| 4931 | { | 4919 | { |
| 4932 | struct trace_cpu *tc = inode->i_private; | 4920 | struct trace_array *tr = inode->i_private; |
| 4933 | struct trace_array *tr = tc->tr; | ||
| 4934 | struct ftrace_buffer_info *info; | 4921 | struct ftrace_buffer_info *info; |
| 4935 | int ret; | 4922 | int ret; |
| 4936 | 4923 | ||
| @@ -4948,10 +4935,8 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp) | |||
| 4948 | 4935 | ||
| 4949 | mutex_lock(&trace_types_lock); | 4936 | mutex_lock(&trace_types_lock); |
| 4950 | 4937 | ||
| 4951 | tr->ref++; | ||
| 4952 | |||
| 4953 | info->iter.tr = tr; | 4938 | info->iter.tr = tr; |
| 4954 | info->iter.cpu_file = tc->cpu; | 4939 | info->iter.cpu_file = tracing_get_cpu(inode); |
| 4955 | info->iter.trace = tr->current_trace; | 4940 | info->iter.trace = tr->current_trace; |
| 4956 | info->iter.trace_buffer = &tr->trace_buffer; | 4941 | info->iter.trace_buffer = &tr->trace_buffer; |
| 4957 | info->spare = NULL; | 4942 | info->spare = NULL; |
| @@ -5268,14 +5253,14 @@ static ssize_t | |||
| 5268 | tracing_stats_read(struct file *filp, char __user *ubuf, | 5253 | tracing_stats_read(struct file *filp, char __user *ubuf, |
| 5269 | size_t count, loff_t *ppos) | 5254 | size_t count, loff_t *ppos) |
| 5270 | { | 5255 | { |
| 5271 | struct trace_cpu *tc = filp->private_data; | 5256 | struct inode *inode = file_inode(filp); |
| 5272 | struct trace_array *tr = tc->tr; | 5257 | struct trace_array *tr = inode->i_private; |
| 5273 | struct trace_buffer *trace_buf = &tr->trace_buffer; | 5258 | struct trace_buffer *trace_buf = &tr->trace_buffer; |
| 5259 | int cpu = tracing_get_cpu(inode); | ||
| 5274 | struct trace_seq *s; | 5260 | struct trace_seq *s; |
| 5275 | unsigned long cnt; | 5261 | unsigned long cnt; |
| 5276 | unsigned long long t; | 5262 | unsigned long long t; |
| 5277 | unsigned long usec_rem; | 5263 | unsigned long usec_rem; |
| 5278 | int cpu = tc->cpu; | ||
| 5279 | 5264 | ||
| 5280 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 5265 | s = kmalloc(sizeof(*s), GFP_KERNEL); |
| 5281 | if (!s) | 5266 | if (!s) |
| @@ -5328,9 +5313,10 @@ tracing_stats_read(struct file *filp, char __user *ubuf, | |||
| 5328 | } | 5313 | } |
| 5329 | 5314 | ||
| 5330 | static const struct file_operations tracing_stats_fops = { | 5315 | static const struct file_operations tracing_stats_fops = { |
| 5331 | .open = tracing_open_generic, | 5316 | .open = tracing_open_generic_tr, |
| 5332 | .read = tracing_stats_read, | 5317 | .read = tracing_stats_read, |
| 5333 | .llseek = generic_file_llseek, | 5318 | .llseek = generic_file_llseek, |
| 5319 | .release = tracing_release_generic_tr, | ||
| 5334 | }; | 5320 | }; |
| 5335 | 5321 | ||
| 5336 | #ifdef CONFIG_DYNAMIC_FTRACE | 5322 | #ifdef CONFIG_DYNAMIC_FTRACE |
| @@ -5519,10 +5505,20 @@ static struct dentry *tracing_dentry_percpu(struct trace_array *tr, int cpu) | |||
| 5519 | return tr->percpu_dir; | 5505 | return tr->percpu_dir; |
| 5520 | } | 5506 | } |
| 5521 | 5507 | ||
| 5508 | static struct dentry * | ||
| 5509 | trace_create_cpu_file(const char *name, umode_t mode, struct dentry *parent, | ||
| 5510 | void *data, long cpu, const struct file_operations *fops) | ||
| 5511 | { | ||
| 5512 | struct dentry *ret = trace_create_file(name, mode, parent, data, fops); | ||
| 5513 | |||
| 5514 | if (ret) /* See tracing_get_cpu() */ | ||
| 5515 | ret->d_inode->i_cdev = (void *)(cpu + 1); | ||
| 5516 | return ret; | ||
| 5517 | } | ||
| 5518 | |||
| 5522 | static void | 5519 | static void |
| 5523 | tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) | 5520 | tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) |
| 5524 | { | 5521 | { |
| 5525 | struct trace_array_cpu *data = per_cpu_ptr(tr->trace_buffer.data, cpu); | ||
| 5526 | struct dentry *d_percpu = tracing_dentry_percpu(tr, cpu); | 5522 | struct dentry *d_percpu = tracing_dentry_percpu(tr, cpu); |
| 5527 | struct dentry *d_cpu; | 5523 | struct dentry *d_cpu; |
| 5528 | char cpu_dir[30]; /* 30 characters should be more than enough */ | 5524 | char cpu_dir[30]; /* 30 characters should be more than enough */ |
| @@ -5538,28 +5534,28 @@ tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) | |||
| 5538 | } | 5534 | } |
| 5539 | 5535 | ||
| 5540 | /* per cpu trace_pipe */ | 5536 | /* per cpu trace_pipe */ |
| 5541 | trace_create_file("trace_pipe", 0444, d_cpu, | 5537 | trace_create_cpu_file("trace_pipe", 0444, d_cpu, |
| 5542 | (void *)&data->trace_cpu, &tracing_pipe_fops); | 5538 | tr, cpu, &tracing_pipe_fops); |
| 5543 | 5539 | ||
| 5544 | /* per cpu trace */ | 5540 | /* per cpu trace */ |
| 5545 | trace_create_file("trace", 0644, d_cpu, | 5541 | trace_create_cpu_file("trace", 0644, d_cpu, |
| 5546 | (void *)&data->trace_cpu, &tracing_fops); | 5542 | tr, cpu, &tracing_fops); |
| 5547 | 5543 | ||
| 5548 | trace_create_file("trace_pipe_raw", 0444, d_cpu, | 5544 | trace_create_cpu_file("trace_pipe_raw", 0444, d_cpu, |
| 5549 | (void *)&data->trace_cpu, &tracing_buffers_fops); | 5545 | tr, cpu, &tracing_buffers_fops); |
| 5550 | 5546 | ||
| 5551 | trace_create_file("stats", 0444, d_cpu, | 5547 | trace_create_cpu_file("stats", 0444, d_cpu, |
| 5552 | (void *)&data->trace_cpu, &tracing_stats_fops); | 5548 | tr, cpu, &tracing_stats_fops); |
| 5553 | 5549 | ||
| 5554 | trace_create_file("buffer_size_kb", 0444, d_cpu, | 5550 | trace_create_cpu_file("buffer_size_kb", 0444, d_cpu, |
| 5555 | (void *)&data->trace_cpu, &tracing_entries_fops); | 5551 | tr, cpu, &tracing_entries_fops); |
| 5556 | 5552 | ||
| 5557 | #ifdef CONFIG_TRACER_SNAPSHOT | 5553 | #ifdef CONFIG_TRACER_SNAPSHOT |
| 5558 | trace_create_file("snapshot", 0644, d_cpu, | 5554 | trace_create_cpu_file("snapshot", 0644, d_cpu, |
| 5559 | (void *)&data->trace_cpu, &snapshot_fops); | 5555 | tr, cpu, &snapshot_fops); |
| 5560 | 5556 | ||
| 5561 | trace_create_file("snapshot_raw", 0444, d_cpu, | 5557 | trace_create_cpu_file("snapshot_raw", 0444, d_cpu, |
| 5562 | (void *)&data->trace_cpu, &snapshot_raw_fops); | 5558 | tr, cpu, &snapshot_raw_fops); |
| 5563 | #endif | 5559 | #endif |
| 5564 | } | 5560 | } |
| 5565 | 5561 | ||
| @@ -5868,17 +5864,6 @@ struct dentry *trace_instance_dir; | |||
| 5868 | static void | 5864 | static void |
| 5869 | init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer); | 5865 | init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer); |
| 5870 | 5866 | ||
| 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 | 5867 | static int |
| 5883 | allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size) | 5868 | allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size) |
| 5884 | { | 5869 | { |
| @@ -5896,8 +5881,6 @@ allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size | |||
| 5896 | return -ENOMEM; | 5881 | return -ENOMEM; |
| 5897 | } | 5882 | } |
| 5898 | 5883 | ||
| 5899 | init_trace_buffers(tr, buf); | ||
| 5900 | |||
| 5901 | /* Allocate the first page for all buffers */ | 5884 | /* Allocate the first page for all buffers */ |
| 5902 | set_buffer_entries(&tr->trace_buffer, | 5885 | set_buffer_entries(&tr->trace_buffer, |
| 5903 | ring_buffer_size(tr->trace_buffer.buffer, 0)); | 5886 | ring_buffer_size(tr->trace_buffer.buffer, 0)); |
| @@ -5964,17 +5947,15 @@ static int new_instance_create(const char *name) | |||
| 5964 | if (allocate_trace_buffers(tr, trace_buf_size) < 0) | 5947 | if (allocate_trace_buffers(tr, trace_buf_size) < 0) |
| 5965 | goto out_free_tr; | 5948 | goto out_free_tr; |
| 5966 | 5949 | ||
| 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); | 5950 | tr->dir = debugfs_create_dir(name, trace_instance_dir); |
| 5972 | if (!tr->dir) | 5951 | if (!tr->dir) |
| 5973 | goto out_free_tr; | 5952 | goto out_free_tr; |
| 5974 | 5953 | ||
| 5975 | ret = event_trace_add_tracer(tr->dir, tr); | 5954 | ret = event_trace_add_tracer(tr->dir, tr); |
| 5976 | if (ret) | 5955 | if (ret) { |
| 5956 | debugfs_remove_recursive(tr->dir); | ||
| 5977 | goto out_free_tr; | 5957 | goto out_free_tr; |
| 5958 | } | ||
| 5978 | 5959 | ||
| 5979 | init_tracer_debugfs(tr, tr->dir); | 5960 | init_tracer_debugfs(tr, tr->dir); |
| 5980 | 5961 | ||
| @@ -6120,13 +6101,13 @@ init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer) | |||
| 6120 | tr, &tracing_iter_fops); | 6101 | tr, &tracing_iter_fops); |
| 6121 | 6102 | ||
| 6122 | trace_create_file("trace", 0644, d_tracer, | 6103 | trace_create_file("trace", 0644, d_tracer, |
| 6123 | (void *)&tr->trace_cpu, &tracing_fops); | 6104 | tr, &tracing_fops); |
| 6124 | 6105 | ||
| 6125 | trace_create_file("trace_pipe", 0444, d_tracer, | 6106 | trace_create_file("trace_pipe", 0444, d_tracer, |
| 6126 | (void *)&tr->trace_cpu, &tracing_pipe_fops); | 6107 | tr, &tracing_pipe_fops); |
| 6127 | 6108 | ||
| 6128 | trace_create_file("buffer_size_kb", 0644, d_tracer, | 6109 | trace_create_file("buffer_size_kb", 0644, d_tracer, |
| 6129 | (void *)&tr->trace_cpu, &tracing_entries_fops); | 6110 | tr, &tracing_entries_fops); |
| 6130 | 6111 | ||
| 6131 | trace_create_file("buffer_total_size_kb", 0444, d_tracer, | 6112 | trace_create_file("buffer_total_size_kb", 0444, d_tracer, |
| 6132 | tr, &tracing_total_entries_fops); | 6113 | tr, &tracing_total_entries_fops); |
| @@ -6141,11 +6122,11 @@ init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer) | |||
| 6141 | &trace_clock_fops); | 6122 | &trace_clock_fops); |
| 6142 | 6123 | ||
| 6143 | trace_create_file("tracing_on", 0644, d_tracer, | 6124 | trace_create_file("tracing_on", 0644, d_tracer, |
| 6144 | tr, &rb_simple_fops); | 6125 | tr, &rb_simple_fops); |
| 6145 | 6126 | ||
| 6146 | #ifdef CONFIG_TRACER_SNAPSHOT | 6127 | #ifdef CONFIG_TRACER_SNAPSHOT |
| 6147 | trace_create_file("snapshot", 0644, d_tracer, | 6128 | trace_create_file("snapshot", 0644, d_tracer, |
| 6148 | (void *)&tr->trace_cpu, &snapshot_fops); | 6129 | tr, &snapshot_fops); |
| 6149 | #endif | 6130 | #endif |
| 6150 | 6131 | ||
| 6151 | for_each_tracing_cpu(cpu) | 6132 | for_each_tracing_cpu(cpu) |
| @@ -6439,10 +6420,6 @@ __init static int tracer_alloc_buffers(void) | |||
| 6439 | 6420 | ||
| 6440 | global_trace.flags = TRACE_ARRAY_FL_GLOBAL; | 6421 | global_trace.flags = TRACE_ARRAY_FL_GLOBAL; |
| 6441 | 6422 | ||
| 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); | 6423 | INIT_LIST_HEAD(&global_trace.systems); |
| 6447 | INIT_LIST_HEAD(&global_trace.events); | 6424 | INIT_LIST_HEAD(&global_trace.events); |
| 6448 | list_add(&global_trace.list, &ftrace_trace_arrays); | 6425 | list_add(&global_trace.list, &ftrace_trace_arrays); |
