Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'trace-fixes-3.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace

Pull tracing fixes from Steven Rostedt:
"Oleg is working on fixing a very tight race between opening a event
file and deleting that event at the same time (both must be done as
root).

I also found a bug while testing Oleg's patches which has to do with a
race with kprobes using the function tracer.

There's also a deadlock fix that was introduced with the previous
fixes"

* tag 'trace-fixes-3.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
tracing: Remove locking trace_types_lock from tracing_reset_all_online_cpus()
ftrace: Add check for NULL regs if ops has SAVE_REGS set
tracing: Kill trace_cpu struct/members
tracing: Change tracing_fops/snapshot_fops to rely on tracing_get_cpu()
tracing: Change tracing_entries_fops to rely on tracing_get_cpu()
tracing: Change tracing_stats_fops to rely on tracing_get_cpu()
tracing: Change tracing_buffers_fops to rely on tracing_get_cpu()
tracing: Change tracing_pipe_fops() to rely on tracing_get_cpu()
tracing: Introduce trace_create_cpu_file() and tracing_get_cpu()

+95 -128
+14 -4
kernel/trace/ftrace.c
··· 1441 * the hashes are freed with call_rcu_sched(). 1442 */ 1443 static int 1444 - ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip) 1445 { 1446 struct ftrace_hash *filter_hash; 1447 struct ftrace_hash *notrace_hash; 1448 int ret; 1449 1450 filter_hash = rcu_dereference_raw_notrace(ops->filter_hash); 1451 notrace_hash = rcu_dereference_raw_notrace(ops->notrace_hash); ··· 4228 # define ftrace_shutdown_sysctl() do { } while (0) 4229 4230 static inline int 4231 - ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip) 4232 { 4233 return 1; 4234 } ··· 4251 do_for_each_ftrace_op(op, ftrace_control_list) { 4252 if (!(op->flags & FTRACE_OPS_FL_STUB) && 4253 !ftrace_function_local_disabled(op) && 4254 - ftrace_ops_test(op, ip)) 4255 op->func(ip, parent_ip, op, regs); 4256 } while_for_each_ftrace_op(op); 4257 trace_recursion_clear(TRACE_CONTROL_BIT); ··· 4284 */ 4285 preempt_disable_notrace(); 4286 do_for_each_ftrace_op(op, ftrace_ops_list) { 4287 - if (ftrace_ops_test(op, ip)) 4288 op->func(ip, parent_ip, op, regs); 4289 } while_for_each_ftrace_op(op); 4290 preempt_enable_notrace();
··· 1441 * the hashes are freed with call_rcu_sched(). 1442 */ 1443 static int 1444 + ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip, void *regs) 1445 { 1446 struct ftrace_hash *filter_hash; 1447 struct ftrace_hash *notrace_hash; 1448 int ret; 1449 + 1450 + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 1451 + /* 1452 + * There's a small race when adding ops that the ftrace handler 1453 + * that wants regs, may be called without them. We can not 1454 + * allow that handler to be called if regs is NULL. 1455 + */ 1456 + if (regs == NULL && (ops->flags & FTRACE_OPS_FL_SAVE_REGS)) 1457 + return 0; 1458 + #endif 1459 1460 filter_hash = rcu_dereference_raw_notrace(ops->filter_hash); 1461 notrace_hash = rcu_dereference_raw_notrace(ops->notrace_hash); ··· 4218 # define ftrace_shutdown_sysctl() do { } while (0) 4219 4220 static inline int 4221 + ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip, void *regs) 4222 { 4223 return 1; 4224 } ··· 4241 do_for_each_ftrace_op(op, ftrace_control_list) { 4242 if (!(op->flags & FTRACE_OPS_FL_STUB) && 4243 !ftrace_function_local_disabled(op) && 4244 + ftrace_ops_test(op, ip, regs)) 4245 op->func(ip, parent_ip, op, regs); 4246 } while_for_each_ftrace_op(op); 4247 trace_recursion_clear(TRACE_CONTROL_BIT); ··· 4274 */ 4275 preempt_disable_notrace(); 4276 do_for_each_ftrace_op(op, ftrace_ops_list) { 4277 + if (ftrace_ops_test(op, ip, regs)) 4278 op->func(ip, parent_ip, op, regs); 4279 } while_for_each_ftrace_op(op); 4280 preempt_enable_notrace();
+81 -116
kernel/trace/trace.c
··· 1224 tracing_reset(&global_trace.trace_buffer, cpu); 1225 } 1226 1227 void tracing_reset_all_online_cpus(void) 1228 { 1229 struct trace_array *tr; 1230 1231 - mutex_lock(&trace_types_lock); 1232 list_for_each_entry(tr, &ftrace_trace_arrays, list) { 1233 tracing_reset_online_cpus(&tr->trace_buffer); 1234 #ifdef CONFIG_TRACER_MAX_TRACE 1235 tracing_reset_online_cpus(&tr->max_buffer); 1236 #endif 1237 } 1238 - mutex_unlock(&trace_types_lock); 1239 } 1240 1241 #define SAVED_CMDLINES 128 ··· 2842 return 0; 2843 } 2844 2845 static const struct seq_operations tracer_seq_ops = { 2846 .start = s_start, 2847 .next = s_next, ··· 2861 }; 2862 2863 static struct trace_iterator * 2864 - __tracing_open(struct trace_array *tr, struct trace_cpu *tc, 2865 - struct inode *inode, struct file *file, bool snapshot) 2866 { 2867 struct trace_iterator *iter; 2868 int cpu; 2869 ··· 2904 iter->trace_buffer = &tr->trace_buffer; 2905 iter->snapshot = snapshot; 2906 iter->pos = -1; 2907 mutex_init(&iter->mutex); 2908 - iter->cpu_file = tc->cpu; 2909 2910 /* Notify the tracer early; before we stop tracing. */ 2911 if (iter->trace && iter->trace->open) ··· 2981 filp->private_data = inode->i_private; 2982 2983 return 0; 2984 - 2985 - } 2986 - 2987 - static int tracing_open_generic_tc(struct inode *inode, struct file *filp) 2988 - { 2989 - struct trace_cpu *tc = inode->i_private; 2990 - struct trace_array *tr = tc->tr; 2991 - 2992 - if (tracing_disabled) 2993 - return -ENODEV; 2994 - 2995 - if (trace_array_get(tr) < 0) 2996 - return -ENODEV; 2997 - 2998 - filp->private_data = inode->i_private; 2999 - 3000 - return 0; 3001 - 3002 } 3003 3004 static int tracing_release(struct inode *inode, struct file *file) 3005 { 3006 struct seq_file *m = file->private_data; 3007 struct trace_iterator *iter; 3008 - struct trace_array *tr; 3009 int cpu; 3010 3011 - /* Writes do not use seq_file, need to grab tr from inode */ 3012 if (!(file->f_mode & FMODE_READ)) { 3013 - struct trace_cpu *tc = inode->i_private; 3014 - 3015 - trace_array_put(tc->tr); 3016 return 0; 3017 } 3018 3019 iter = m->private; 3020 - tr = iter->tr; 3021 - 3022 mutex_lock(&trace_types_lock); 3023 3024 for_each_tracing_cpu(cpu) { ··· 3032 return 0; 3033 } 3034 3035 - static int tracing_release_generic_tc(struct inode *inode, struct file *file) 3036 - { 3037 - struct trace_cpu *tc = inode->i_private; 3038 - struct trace_array *tr = tc->tr; 3039 - 3040 - trace_array_put(tr); 3041 - return 0; 3042 - } 3043 - 3044 static int tracing_single_release_tr(struct inode *inode, struct file *file) 3045 { 3046 struct trace_array *tr = inode->i_private; ··· 3043 3044 static int tracing_open(struct inode *inode, struct file *file) 3045 { 3046 - struct trace_cpu *tc = inode->i_private; 3047 - struct trace_array *tr = tc->tr; 3048 struct trace_iterator *iter; 3049 int ret = 0; 3050 ··· 3051 return -ENODEV; 3052 3053 /* If this file was open for write, then erase contents */ 3054 - if ((file->f_mode & FMODE_WRITE) && 3055 - (file->f_flags & O_TRUNC)) { 3056 - if (tc->cpu == RING_BUFFER_ALL_CPUS) 3057 tracing_reset_online_cpus(&tr->trace_buffer); 3058 else 3059 - tracing_reset(&tr->trace_buffer, tc->cpu); 3060 } 3061 3062 if (file->f_mode & FMODE_READ) { 3063 - iter = __tracing_open(tr, tc, inode, file, false); 3064 if (IS_ERR(iter)) 3065 ret = PTR_ERR(iter); 3066 else if (trace_flags & TRACE_ITER_LATENCY_FMT) ··· 3927 3928 static int tracing_open_pipe(struct inode *inode, struct file *filp) 3929 { 3930 - struct trace_cpu *tc = inode->i_private; 3931 - struct trace_array *tr = tc->tr; 3932 struct trace_iterator *iter; 3933 int ret = 0; 3934 ··· 3973 if (trace_clocks[tr->clock_id].in_ns) 3974 iter->iter_flags |= TRACE_FILE_TIME_IN_NS; 3975 3976 - iter->cpu_file = tc->cpu; 3977 - iter->tr = tc->tr; 3978 - iter->trace_buffer = &tc->tr->trace_buffer; 3979 mutex_init(&iter->mutex); 3980 filp->private_data = iter; 3981 ··· 3998 static int tracing_release_pipe(struct inode *inode, struct file *file) 3999 { 4000 struct trace_iterator *iter = file->private_data; 4001 - struct trace_cpu *tc = inode->i_private; 4002 - struct trace_array *tr = tc->tr; 4003 4004 mutex_lock(&trace_types_lock); 4005 ··· 4351 tracing_entries_read(struct file *filp, char __user *ubuf, 4352 size_t cnt, loff_t *ppos) 4353 { 4354 - struct trace_cpu *tc = filp->private_data; 4355 - struct trace_array *tr = tc->tr; 4356 char buf[64]; 4357 int r = 0; 4358 ssize_t ret; 4359 4360 mutex_lock(&trace_types_lock); 4361 4362 - if (tc->cpu == RING_BUFFER_ALL_CPUS) { 4363 int cpu, buf_size_same; 4364 unsigned long size; 4365 ··· 4387 } else 4388 r = sprintf(buf, "X\n"); 4389 } else 4390 - r = sprintf(buf, "%lu\n", per_cpu_ptr(tr->trace_buffer.data, tc->cpu)->entries >> 10); 4391 4392 mutex_unlock(&trace_types_lock); 4393 ··· 4399 tracing_entries_write(struct file *filp, const char __user *ubuf, 4400 size_t cnt, loff_t *ppos) 4401 { 4402 - struct trace_cpu *tc = filp->private_data; 4403 unsigned long val; 4404 int ret; 4405 ··· 4414 4415 /* value is in KB */ 4416 val <<= 10; 4417 - 4418 - ret = tracing_resize_ring_buffer(tc->tr, val, tc->cpu); 4419 if (ret < 0) 4420 return ret; 4421 ··· 4675 #ifdef CONFIG_TRACER_SNAPSHOT 4676 static int tracing_snapshot_open(struct inode *inode, struct file *file) 4677 { 4678 - struct trace_cpu *tc = inode->i_private; 4679 - struct trace_array *tr = tc->tr; 4680 struct trace_iterator *iter; 4681 struct seq_file *m; 4682 int ret = 0; ··· 4684 return -ENODEV; 4685 4686 if (file->f_mode & FMODE_READ) { 4687 - iter = __tracing_open(tr, tc, inode, file, true); 4688 if (IS_ERR(iter)) 4689 ret = PTR_ERR(iter); 4690 } else { ··· 4701 ret = 0; 4702 4703 iter->tr = tr; 4704 - iter->trace_buffer = &tc->tr->max_buffer; 4705 - iter->cpu_file = tc->cpu; 4706 m->private = iter; 4707 file->private_data = m; 4708 } ··· 4861 }; 4862 4863 static const struct file_operations tracing_entries_fops = { 4864 - .open = tracing_open_generic_tc, 4865 .read = tracing_entries_read, 4866 .write = tracing_entries_write, 4867 .llseek = generic_file_llseek, 4868 - .release = tracing_release_generic_tc, 4869 }; 4870 4871 static const struct file_operations tracing_total_entries_fops = { ··· 4917 4918 static int tracing_buffers_open(struct inode *inode, struct file *filp) 4919 { 4920 - struct trace_cpu *tc = inode->i_private; 4921 - struct trace_array *tr = tc->tr; 4922 struct ftrace_buffer_info *info; 4923 int ret; 4924 ··· 4936 mutex_lock(&trace_types_lock); 4937 4938 info->iter.tr = tr; 4939 - info->iter.cpu_file = tc->cpu; 4940 info->iter.trace = tr->current_trace; 4941 info->iter.trace_buffer = &tr->trace_buffer; 4942 info->spare = NULL; ··· 5253 tracing_stats_read(struct file *filp, char __user *ubuf, 5254 size_t count, loff_t *ppos) 5255 { 5256 - struct trace_cpu *tc = filp->private_data; 5257 - struct trace_array *tr = tc->tr; 5258 struct trace_buffer *trace_buf = &tr->trace_buffer; 5259 struct trace_seq *s; 5260 unsigned long cnt; 5261 unsigned long long t; 5262 unsigned long usec_rem; 5263 - int cpu = tc->cpu; 5264 5265 s = kmalloc(sizeof(*s), GFP_KERNEL); 5266 if (!s) ··· 5313 } 5314 5315 static const struct file_operations tracing_stats_fops = { 5316 - .open = tracing_open_generic_tc, 5317 .read = tracing_stats_read, 5318 .llseek = generic_file_llseek, 5319 - .release = tracing_release_generic_tc, 5320 }; 5321 5322 #ifdef CONFIG_DYNAMIC_FTRACE ··· 5505 return tr->percpu_dir; 5506 } 5507 5508 static void 5509 tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) 5510 { 5511 - struct trace_array_cpu *data = per_cpu_ptr(tr->trace_buffer.data, cpu); 5512 struct dentry *d_percpu = tracing_dentry_percpu(tr, cpu); 5513 struct dentry *d_cpu; 5514 char cpu_dir[30]; /* 30 characters should be more than enough */ ··· 5534 } 5535 5536 /* per cpu trace_pipe */ 5537 - trace_create_file("trace_pipe", 0444, d_cpu, 5538 - (void *)&data->trace_cpu, &tracing_pipe_fops); 5539 5540 /* per cpu trace */ 5541 - trace_create_file("trace", 0644, d_cpu, 5542 - (void *)&data->trace_cpu, &tracing_fops); 5543 5544 - trace_create_file("trace_pipe_raw", 0444, d_cpu, 5545 - (void *)&data->trace_cpu, &tracing_buffers_fops); 5546 5547 - trace_create_file("stats", 0444, d_cpu, 5548 - (void *)&data->trace_cpu, &tracing_stats_fops); 5549 5550 - trace_create_file("buffer_size_kb", 0444, d_cpu, 5551 - (void *)&data->trace_cpu, &tracing_entries_fops); 5552 5553 #ifdef CONFIG_TRACER_SNAPSHOT 5554 - trace_create_file("snapshot", 0644, d_cpu, 5555 - (void *)&data->trace_cpu, &snapshot_fops); 5556 5557 - trace_create_file("snapshot_raw", 0444, d_cpu, 5558 - (void *)&data->trace_cpu, &snapshot_raw_fops); 5559 #endif 5560 } 5561 ··· 5864 static void 5865 init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer); 5866 5867 - static void init_trace_buffers(struct trace_array *tr, struct trace_buffer *buf) 5868 - { 5869 - int cpu; 5870 - 5871 - for_each_tracing_cpu(cpu) { 5872 - memset(per_cpu_ptr(buf->data, cpu), 0, sizeof(struct trace_array_cpu)); 5873 - per_cpu_ptr(buf->data, cpu)->trace_cpu.cpu = cpu; 5874 - per_cpu_ptr(buf->data, cpu)->trace_cpu.tr = tr; 5875 - } 5876 - } 5877 - 5878 static int 5879 allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size) 5880 { ··· 5880 ring_buffer_free(buf->buffer); 5881 return -ENOMEM; 5882 } 5883 - 5884 - init_trace_buffers(tr, buf); 5885 5886 /* Allocate the first page for all buffers */ 5887 set_buffer_entries(&tr->trace_buffer, ··· 5946 5947 if (allocate_trace_buffers(tr, trace_buf_size) < 0) 5948 goto out_free_tr; 5949 - 5950 - /* Holder for file callbacks */ 5951 - tr->trace_cpu.cpu = RING_BUFFER_ALL_CPUS; 5952 - tr->trace_cpu.tr = tr; 5953 5954 tr->dir = debugfs_create_dir(name, trace_instance_dir); 5955 if (!tr->dir) ··· 6101 tr, &tracing_iter_fops); 6102 6103 trace_create_file("trace", 0644, d_tracer, 6104 - (void *)&tr->trace_cpu, &tracing_fops); 6105 6106 trace_create_file("trace_pipe", 0444, d_tracer, 6107 - (void *)&tr->trace_cpu, &tracing_pipe_fops); 6108 6109 trace_create_file("buffer_size_kb", 0644, d_tracer, 6110 - (void *)&tr->trace_cpu, &tracing_entries_fops); 6111 6112 trace_create_file("buffer_total_size_kb", 0444, d_tracer, 6113 tr, &tracing_total_entries_fops); ··· 6122 &trace_clock_fops); 6123 6124 trace_create_file("tracing_on", 0644, d_tracer, 6125 - tr, &rb_simple_fops); 6126 6127 #ifdef CONFIG_TRACER_SNAPSHOT 6128 trace_create_file("snapshot", 0644, d_tracer, 6129 - (void *)&tr->trace_cpu, &snapshot_fops); 6130 #endif 6131 6132 for_each_tracing_cpu(cpu) ··· 6419 register_die_notifier(&trace_die_notifier); 6420 6421 global_trace.flags = TRACE_ARRAY_FL_GLOBAL; 6422 - 6423 - /* Holder for file callbacks */ 6424 - global_trace.trace_cpu.cpu = RING_BUFFER_ALL_CPUS; 6425 - global_trace.trace_cpu.tr = &global_trace; 6426 6427 INIT_LIST_HEAD(&global_trace.systems); 6428 INIT_LIST_HEAD(&global_trace.events);
··· 1224 tracing_reset(&global_trace.trace_buffer, cpu); 1225 } 1226 1227 + /* Must have trace_types_lock held */ 1228 void tracing_reset_all_online_cpus(void) 1229 { 1230 struct trace_array *tr; 1231 1232 list_for_each_entry(tr, &ftrace_trace_arrays, list) { 1233 tracing_reset_online_cpus(&tr->trace_buffer); 1234 #ifdef CONFIG_TRACER_MAX_TRACE 1235 tracing_reset_online_cpus(&tr->max_buffer); 1236 #endif 1237 } 1238 } 1239 1240 #define SAVED_CMDLINES 128 ··· 2843 return 0; 2844 } 2845 2846 + /* 2847 + * Should be used after trace_array_get(), trace_types_lock 2848 + * ensures that i_cdev was already initialized. 2849 + */ 2850 + static inline int tracing_get_cpu(struct inode *inode) 2851 + { 2852 + if (inode->i_cdev) /* See trace_create_cpu_file() */ 2853 + return (long)inode->i_cdev - 1; 2854 + return RING_BUFFER_ALL_CPUS; 2855 + } 2856 + 2857 static const struct seq_operations tracer_seq_ops = { 2858 .start = s_start, 2859 .next = s_next, ··· 2851 }; 2852 2853 static struct trace_iterator * 2854 + __tracing_open(struct inode *inode, struct file *file, bool snapshot) 2855 { 2856 + struct trace_array *tr = inode->i_private; 2857 struct trace_iterator *iter; 2858 int cpu; 2859 ··· 2894 iter->trace_buffer = &tr->trace_buffer; 2895 iter->snapshot = snapshot; 2896 iter->pos = -1; 2897 + iter->cpu_file = tracing_get_cpu(inode); 2898 mutex_init(&iter->mutex); 2899 2900 /* Notify the tracer early; before we stop tracing. */ 2901 if (iter->trace && iter->trace->open) ··· 2971 filp->private_data = inode->i_private; 2972 2973 return 0; 2974 } 2975 2976 static int tracing_release(struct inode *inode, struct file *file) 2977 { 2978 + struct trace_array *tr = inode->i_private; 2979 struct seq_file *m = file->private_data; 2980 struct trace_iterator *iter; 2981 int cpu; 2982 2983 if (!(file->f_mode & FMODE_READ)) { 2984 + trace_array_put(tr); 2985 return 0; 2986 } 2987 2988 + /* Writes do not use seq_file */ 2989 iter = m->private; 2990 mutex_lock(&trace_types_lock); 2991 2992 for_each_tracing_cpu(cpu) { ··· 3044 return 0; 3045 } 3046 3047 static int tracing_single_release_tr(struct inode *inode, struct file *file) 3048 { 3049 struct trace_array *tr = inode->i_private; ··· 3064 3065 static int tracing_open(struct inode *inode, struct file *file) 3066 { 3067 + struct trace_array *tr = inode->i_private; 3068 struct trace_iterator *iter; 3069 int ret = 0; 3070 ··· 3073 return -ENODEV; 3074 3075 /* If this file was open for write, then erase contents */ 3076 + if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { 3077 + int cpu = tracing_get_cpu(inode); 3078 + 3079 + if (cpu == RING_BUFFER_ALL_CPUS) 3080 tracing_reset_online_cpus(&tr->trace_buffer); 3081 else 3082 + tracing_reset(&tr->trace_buffer, cpu); 3083 } 3084 3085 if (file->f_mode & FMODE_READ) { 3086 + iter = __tracing_open(inode, file, false); 3087 if (IS_ERR(iter)) 3088 ret = PTR_ERR(iter); 3089 else if (trace_flags & TRACE_ITER_LATENCY_FMT) ··· 3948 3949 static int tracing_open_pipe(struct inode *inode, struct file *filp) 3950 { 3951 + struct trace_array *tr = inode->i_private; 3952 struct trace_iterator *iter; 3953 int ret = 0; 3954 ··· 3995 if (trace_clocks[tr->clock_id].in_ns) 3996 iter->iter_flags |= TRACE_FILE_TIME_IN_NS; 3997 3998 + iter->tr = tr; 3999 + iter->trace_buffer = &tr->trace_buffer; 4000 + iter->cpu_file = tracing_get_cpu(inode); 4001 mutex_init(&iter->mutex); 4002 filp->private_data = iter; 4003 ··· 4020 static int tracing_release_pipe(struct inode *inode, struct file *file) 4021 { 4022 struct trace_iterator *iter = file->private_data; 4023 + struct trace_array *tr = inode->i_private; 4024 4025 mutex_lock(&trace_types_lock); 4026 ··· 4374 tracing_entries_read(struct file *filp, char __user *ubuf, 4375 size_t cnt, loff_t *ppos) 4376 { 4377 + struct inode *inode = file_inode(filp); 4378 + struct trace_array *tr = inode->i_private; 4379 + int cpu = tracing_get_cpu(inode); 4380 char buf[64]; 4381 int r = 0; 4382 ssize_t ret; 4383 4384 mutex_lock(&trace_types_lock); 4385 4386 + if (cpu == RING_BUFFER_ALL_CPUS) { 4387 int cpu, buf_size_same; 4388 unsigned long size; 4389 ··· 4409 } else 4410 r = sprintf(buf, "X\n"); 4411 } else 4412 + r = sprintf(buf, "%lu\n", per_cpu_ptr(tr->trace_buffer.data, cpu)->entries >> 10); 4413 4414 mutex_unlock(&trace_types_lock); 4415 ··· 4421 tracing_entries_write(struct file *filp, const char __user *ubuf, 4422 size_t cnt, loff_t *ppos) 4423 { 4424 + struct inode *inode = file_inode(filp); 4425 + struct trace_array *tr = inode->i_private; 4426 unsigned long val; 4427 int ret; 4428 ··· 4435 4436 /* value is in KB */ 4437 val <<= 10; 4438 + ret = tracing_resize_ring_buffer(tr, val, tracing_get_cpu(inode)); 4439 if (ret < 0) 4440 return ret; 4441 ··· 4697 #ifdef CONFIG_TRACER_SNAPSHOT 4698 static int tracing_snapshot_open(struct inode *inode, struct file *file) 4699 { 4700 + struct trace_array *tr = inode->i_private; 4701 struct trace_iterator *iter; 4702 struct seq_file *m; 4703 int ret = 0; ··· 4707 return -ENODEV; 4708 4709 if (file->f_mode & FMODE_READ) { 4710 + iter = __tracing_open(inode, file, true); 4711 if (IS_ERR(iter)) 4712 ret = PTR_ERR(iter); 4713 } else { ··· 4724 ret = 0; 4725 4726 iter->tr = tr; 4727 + iter->trace_buffer = &tr->max_buffer; 4728 + iter->cpu_file = tracing_get_cpu(inode); 4729 m->private = iter; 4730 file->private_data = m; 4731 } ··· 4884 }; 4885 4886 static const struct file_operations tracing_entries_fops = { 4887 + .open = tracing_open_generic_tr, 4888 .read = tracing_entries_read, 4889 .write = tracing_entries_write, 4890 .llseek = generic_file_llseek, 4891 + .release = tracing_release_generic_tr, 4892 }; 4893 4894 static const struct file_operations tracing_total_entries_fops = { ··· 4940 4941 static int tracing_buffers_open(struct inode *inode, struct file *filp) 4942 { 4943 + struct trace_array *tr = inode->i_private; 4944 struct ftrace_buffer_info *info; 4945 int ret; 4946 ··· 4960 mutex_lock(&trace_types_lock); 4961 4962 info->iter.tr = tr; 4963 + info->iter.cpu_file = tracing_get_cpu(inode); 4964 info->iter.trace = tr->current_trace; 4965 info->iter.trace_buffer = &tr->trace_buffer; 4966 info->spare = NULL; ··· 5277 tracing_stats_read(struct file *filp, char __user *ubuf, 5278 size_t count, loff_t *ppos) 5279 { 5280 + struct inode *inode = file_inode(filp); 5281 + struct trace_array *tr = inode->i_private; 5282 struct trace_buffer *trace_buf = &tr->trace_buffer; 5283 + int cpu = tracing_get_cpu(inode); 5284 struct trace_seq *s; 5285 unsigned long cnt; 5286 unsigned long long t; 5287 unsigned long usec_rem; 5288 5289 s = kmalloc(sizeof(*s), GFP_KERNEL); 5290 if (!s) ··· 5337 } 5338 5339 static const struct file_operations tracing_stats_fops = { 5340 + .open = tracing_open_generic_tr, 5341 .read = tracing_stats_read, 5342 .llseek = generic_file_llseek, 5343 + .release = tracing_release_generic_tr, 5344 }; 5345 5346 #ifdef CONFIG_DYNAMIC_FTRACE ··· 5529 return tr->percpu_dir; 5530 } 5531 5532 + static struct dentry * 5533 + trace_create_cpu_file(const char *name, umode_t mode, struct dentry *parent, 5534 + void *data, long cpu, const struct file_operations *fops) 5535 + { 5536 + struct dentry *ret = trace_create_file(name, mode, parent, data, fops); 5537 + 5538 + if (ret) /* See tracing_get_cpu() */ 5539 + ret->d_inode->i_cdev = (void *)(cpu + 1); 5540 + return ret; 5541 + } 5542 + 5543 static void 5544 tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) 5545 { 5546 struct dentry *d_percpu = tracing_dentry_percpu(tr, cpu); 5547 struct dentry *d_cpu; 5548 char cpu_dir[30]; /* 30 characters should be more than enough */ ··· 5548 } 5549 5550 /* per cpu trace_pipe */ 5551 + trace_create_cpu_file("trace_pipe", 0444, d_cpu, 5552 + tr, cpu, &tracing_pipe_fops); 5553 5554 /* per cpu trace */ 5555 + trace_create_cpu_file("trace", 0644, d_cpu, 5556 + tr, cpu, &tracing_fops); 5557 5558 + trace_create_cpu_file("trace_pipe_raw", 0444, d_cpu, 5559 + tr, cpu, &tracing_buffers_fops); 5560 5561 + trace_create_cpu_file("stats", 0444, d_cpu, 5562 + tr, cpu, &tracing_stats_fops); 5563 5564 + trace_create_cpu_file("buffer_size_kb", 0444, d_cpu, 5565 + tr, cpu, &tracing_entries_fops); 5566 5567 #ifdef CONFIG_TRACER_SNAPSHOT 5568 + trace_create_cpu_file("snapshot", 0644, d_cpu, 5569 + tr, cpu, &snapshot_fops); 5570 5571 + trace_create_cpu_file("snapshot_raw", 0444, d_cpu, 5572 + tr, cpu, &snapshot_raw_fops); 5573 #endif 5574 } 5575 ··· 5878 static void 5879 init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer); 5880 5881 static int 5882 allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size) 5883 { ··· 5905 ring_buffer_free(buf->buffer); 5906 return -ENOMEM; 5907 } 5908 5909 /* Allocate the first page for all buffers */ 5910 set_buffer_entries(&tr->trace_buffer, ··· 5973 5974 if (allocate_trace_buffers(tr, trace_buf_size) < 0) 5975 goto out_free_tr; 5976 5977 tr->dir = debugfs_create_dir(name, trace_instance_dir); 5978 if (!tr->dir) ··· 6132 tr, &tracing_iter_fops); 6133 6134 trace_create_file("trace", 0644, d_tracer, 6135 + tr, &tracing_fops); 6136 6137 trace_create_file("trace_pipe", 0444, d_tracer, 6138 + tr, &tracing_pipe_fops); 6139 6140 trace_create_file("buffer_size_kb", 0644, d_tracer, 6141 + tr, &tracing_entries_fops); 6142 6143 trace_create_file("buffer_total_size_kb", 0444, d_tracer, 6144 tr, &tracing_total_entries_fops); ··· 6153 &trace_clock_fops); 6154 6155 trace_create_file("tracing_on", 0644, d_tracer, 6156 + tr, &rb_simple_fops); 6157 6158 #ifdef CONFIG_TRACER_SNAPSHOT 6159 trace_create_file("snapshot", 0644, d_tracer, 6160 + tr, &snapshot_fops); 6161 #endif 6162 6163 for_each_tracing_cpu(cpu) ··· 6450 register_die_notifier(&trace_die_notifier); 6451 6452 global_trace.flags = TRACE_ARRAY_FL_GLOBAL; 6453 6454 INIT_LIST_HEAD(&global_trace.systems); 6455 INIT_LIST_HEAD(&global_trace.events);
-8
kernel/trace/trace.h
··· 130 131 struct trace_array; 132 133 - struct trace_cpu { 134 - struct trace_array *tr; 135 - struct dentry *dir; 136 - int cpu; 137 - }; 138 - 139 /* 140 * The CPU trace array - it consists of thousands of trace entries 141 * plus some other descriptor data: (for example which task started 142 * the trace, etc.) 143 */ 144 struct trace_array_cpu { 145 - struct trace_cpu trace_cpu; 146 atomic_t disabled; 147 void *buffer_page; /* ring buffer spare */ 148 ··· 189 bool allocated_snapshot; 190 #endif 191 int buffer_disabled; 192 - struct trace_cpu trace_cpu; /* place holder */ 193 #ifdef CONFIG_FTRACE_SYSCALLS 194 int sys_refcount_enter; 195 int sys_refcount_exit;
··· 130 131 struct trace_array; 132 133 /* 134 * The CPU trace array - it consists of thousands of trace entries 135 * plus some other descriptor data: (for example which task started 136 * the trace, etc.) 137 */ 138 struct trace_array_cpu { 139 atomic_t disabled; 140 void *buffer_page; /* ring buffer spare */ 141 ··· 196 bool allocated_snapshot; 197 #endif 198 int buffer_disabled; 199 #ifdef CONFIG_FTRACE_SYSCALLS 200 int sys_refcount_enter; 201 int sys_refcount_exit;