aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/trace/trace.c168
-rw-r--r--kernel/trace/trace.h3
2 files changed, 147 insertions, 24 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 11ba100f9a9..aa58b7bc847 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -98,6 +98,9 @@ static inline void ftrace_enable_cpu(void)
98 98
99static cpumask_var_t __read_mostly tracing_buffer_mask; 99static cpumask_var_t __read_mostly tracing_buffer_mask;
100 100
101/* Define which cpu buffers are currently read in trace_pipe */
102static cpumask_var_t tracing_reader_cpumask;
103
101#define for_each_tracing_cpu(cpu) \ 104#define for_each_tracing_cpu(cpu) \
102 for_each_cpu(cpu, tracing_buffer_mask) 105 for_each_cpu(cpu, tracing_buffer_mask)
103 106
@@ -1195,10 +1198,25 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
1195{ 1198{
1196 struct ring_buffer *buffer = iter->tr->buffer; 1199 struct ring_buffer *buffer = iter->tr->buffer;
1197 struct trace_entry *ent, *next = NULL; 1200 struct trace_entry *ent, *next = NULL;
1201 int cpu_file = iter->cpu_file;
1198 u64 next_ts = 0, ts; 1202 u64 next_ts = 0, ts;
1199 int next_cpu = -1; 1203 int next_cpu = -1;
1200 int cpu; 1204 int cpu;
1201 1205
1206 /*
1207 * If we are in a per_cpu trace file, don't bother by iterating over
1208 * all cpu and peek directly.
1209 */
1210 if (cpu_file > TRACE_PIPE_ALL_CPU) {
1211 if (ring_buffer_empty_cpu(buffer, cpu_file))
1212 return NULL;
1213 ent = peek_next_entry(iter, cpu_file, ent_ts);
1214 if (ent_cpu)
1215 *ent_cpu = cpu_file;
1216
1217 return ent;
1218 }
1219
1202 for_each_tracing_cpu(cpu) { 1220 for_each_tracing_cpu(cpu) {
1203 1221
1204 if (ring_buffer_empty_cpu(buffer, cpu)) 1222 if (ring_buffer_empty_cpu(buffer, cpu))
@@ -1279,6 +1297,7 @@ static void *s_next(struct seq_file *m, void *v, loff_t *pos)
1279static void *s_start(struct seq_file *m, loff_t *pos) 1297static void *s_start(struct seq_file *m, loff_t *pos)
1280{ 1298{
1281 struct trace_iterator *iter = m->private; 1299 struct trace_iterator *iter = m->private;
1300 int cpu_file = iter->cpu_file;
1282 void *p = NULL; 1301 void *p = NULL;
1283 loff_t l = 0; 1302 loff_t l = 0;
1284 int cpu; 1303 int cpu;
@@ -1299,9 +1318,12 @@ static void *s_start(struct seq_file *m, loff_t *pos)
1299 1318
1300 ftrace_disable_cpu(); 1319 ftrace_disable_cpu();
1301 1320
1302 for_each_tracing_cpu(cpu) { 1321 if (cpu_file == TRACE_PIPE_ALL_CPU) {
1303 ring_buffer_iter_reset(iter->buffer_iter[cpu]); 1322 for_each_tracing_cpu(cpu)
1304 } 1323 ring_buffer_iter_reset(iter->buffer_iter[cpu]);
1324 } else
1325 ring_buffer_iter_reset(iter->buffer_iter[cpu_file]);
1326
1305 1327
1306 ftrace_enable_cpu(); 1328 ftrace_enable_cpu();
1307 1329
@@ -1653,6 +1675,7 @@ static struct seq_operations tracer_seq_ops = {
1653static struct trace_iterator * 1675static struct trace_iterator *
1654__tracing_open(struct inode *inode, struct file *file, int *ret) 1676__tracing_open(struct inode *inode, struct file *file, int *ret)
1655{ 1677{
1678 long cpu_file = (long) inode->i_private;
1656 struct trace_iterator *iter; 1679 struct trace_iterator *iter;
1657 struct seq_file *m; 1680 struct seq_file *m;
1658 int cpu; 1681 int cpu;
@@ -1672,9 +1695,10 @@ __tracing_open(struct inode *inode, struct file *file, int *ret)
1672 if (current_trace && current_trace->print_max) 1695 if (current_trace && current_trace->print_max)
1673 iter->tr = &max_tr; 1696 iter->tr = &max_tr;
1674 else 1697 else
1675 iter->tr = inode->i_private; 1698 iter->tr = &global_trace;
1676 iter->trace = current_trace; 1699 iter->trace = current_trace;
1677 iter->pos = -1; 1700 iter->pos = -1;
1701 iter->cpu_file = cpu_file;
1678 1702
1679 /* Notify the tracer early; before we stop tracing. */ 1703 /* Notify the tracer early; before we stop tracing. */
1680 if (iter->trace && iter->trace->open) 1704 if (iter->trace && iter->trace->open)
@@ -1684,14 +1708,22 @@ __tracing_open(struct inode *inode, struct file *file, int *ret)
1684 if (ring_buffer_overruns(iter->tr->buffer)) 1708 if (ring_buffer_overruns(iter->tr->buffer))
1685 iter->iter_flags |= TRACE_FILE_ANNOTATE; 1709 iter->iter_flags |= TRACE_FILE_ANNOTATE;
1686 1710
1711 if (iter->cpu_file == TRACE_PIPE_ALL_CPU) {
1712 for_each_tracing_cpu(cpu) {
1687 1713
1688 for_each_tracing_cpu(cpu) { 1714 iter->buffer_iter[cpu] =
1715 ring_buffer_read_start(iter->tr->buffer, cpu);
1689 1716
1717 if (!iter->buffer_iter[cpu])
1718 goto fail_buffer;
1719 }
1720 } else {
1721 cpu = iter->cpu_file;
1690 iter->buffer_iter[cpu] = 1722 iter->buffer_iter[cpu] =
1691 ring_buffer_read_start(iter->tr->buffer, cpu); 1723 ring_buffer_read_start(iter->tr->buffer, cpu);
1692 1724
1693 if (!iter->buffer_iter[cpu]) 1725 if (!iter->buffer_iter[cpu])
1694 goto fail_buffer; 1726 goto fail;
1695 } 1727 }
1696 1728
1697 /* TODO stop tracer */ 1729 /* TODO stop tracer */
@@ -1715,6 +1747,7 @@ __tracing_open(struct inode *inode, struct file *file, int *ret)
1715 if (iter->buffer_iter[cpu]) 1747 if (iter->buffer_iter[cpu])
1716 ring_buffer_read_finish(iter->buffer_iter[cpu]); 1748 ring_buffer_read_finish(iter->buffer_iter[cpu]);
1717 } 1749 }
1750fail:
1718 mutex_unlock(&trace_types_lock); 1751 mutex_unlock(&trace_types_lock);
1719 kfree(iter); 1752 kfree(iter);
1720 1753
@@ -2325,54 +2358,77 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf,
2325 return cnt; 2358 return cnt;
2326} 2359}
2327 2360
2328static atomic_t tracing_reader;
2329
2330static int tracing_open_pipe(struct inode *inode, struct file *filp) 2361static int tracing_open_pipe(struct inode *inode, struct file *filp)
2331{ 2362{
2363 long cpu_file = (long) inode->i_private;
2332 struct trace_iterator *iter; 2364 struct trace_iterator *iter;
2365 int ret = 0;
2333 2366
2334 if (tracing_disabled) 2367 if (tracing_disabled)
2335 return -ENODEV; 2368 return -ENODEV;
2336 2369
2337 /* We only allow for reader of the pipe */ 2370 mutex_lock(&trace_types_lock);
2338 if (atomic_inc_return(&tracing_reader) != 1) { 2371
2339 atomic_dec(&tracing_reader); 2372 /* We only allow one reader per cpu */
2340 return -EBUSY; 2373 if (cpu_file == TRACE_PIPE_ALL_CPU) {
2374 if (!cpumask_empty(tracing_reader_cpumask)) {
2375 ret = -EBUSY;
2376 goto out;
2377 }
2378 cpumask_setall(tracing_reader_cpumask);
2379 } else {
2380 if (!cpumask_test_cpu(cpu_file, tracing_reader_cpumask))
2381 cpumask_set_cpu(cpu_file, tracing_reader_cpumask);
2382 else {
2383 ret = -EBUSY;
2384 goto out;
2385 }
2341 } 2386 }
2342 2387
2343 /* create a buffer to store the information to pass to userspace */ 2388 /* create a buffer to store the information to pass to userspace */
2344 iter = kzalloc(sizeof(*iter), GFP_KERNEL); 2389 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
2345 if (!iter) 2390 if (!iter) {
2346 return -ENOMEM; 2391 ret = -ENOMEM;
2392 goto out;
2393 }
2347 2394
2348 if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) { 2395 if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) {
2349 kfree(iter); 2396 kfree(iter);
2350 return -ENOMEM; 2397 ret = -ENOMEM;
2398 goto out;
2351 } 2399 }
2352 2400
2353 mutex_lock(&trace_types_lock);
2354
2355 /* trace pipe does not show start of buffer */ 2401 /* trace pipe does not show start of buffer */
2356 cpumask_setall(iter->started); 2402 cpumask_setall(iter->started);
2357 2403
2404 iter->cpu_file = cpu_file;
2358 iter->tr = &global_trace; 2405 iter->tr = &global_trace;
2359 iter->trace = current_trace; 2406 iter->trace = current_trace;
2360 filp->private_data = iter; 2407 filp->private_data = iter;
2361 2408
2362 if (iter->trace->pipe_open) 2409 if (iter->trace->pipe_open)
2363 iter->trace->pipe_open(iter); 2410 iter->trace->pipe_open(iter);
2364 mutex_unlock(&trace_types_lock);
2365 2411
2366 return 0; 2412out:
2413 mutex_unlock(&trace_types_lock);
2414 return ret;
2367} 2415}
2368 2416
2369static int tracing_release_pipe(struct inode *inode, struct file *file) 2417static int tracing_release_pipe(struct inode *inode, struct file *file)
2370{ 2418{
2371 struct trace_iterator *iter = file->private_data; 2419 struct trace_iterator *iter = file->private_data;
2372 2420
2421 mutex_lock(&trace_types_lock);
2422
2423 if (iter->cpu_file == TRACE_PIPE_ALL_CPU)
2424 cpumask_clear(tracing_reader_cpumask);
2425 else
2426 cpumask_clear_cpu(iter->cpu_file, tracing_reader_cpumask);
2427
2428 mutex_unlock(&trace_types_lock);
2429
2373 free_cpumask_var(iter->started); 2430 free_cpumask_var(iter->started);
2374 kfree(iter); 2431 kfree(iter);
2375 atomic_dec(&tracing_reader);
2376 2432
2377 return 0; 2433 return 0;
2378} 2434}
@@ -2911,6 +2967,59 @@ struct dentry *tracing_init_dentry(void)
2911 return d_tracer; 2967 return d_tracer;
2912} 2968}
2913 2969
2970static struct dentry *d_percpu;
2971
2972struct dentry *tracing_dentry_percpu(void)
2973{
2974 static int once;
2975 struct dentry *d_tracer;
2976
2977 if (d_percpu)
2978 return d_percpu;
2979
2980 d_tracer = tracing_init_dentry();
2981
2982 if (!d_tracer)
2983 return NULL;
2984
2985 d_percpu = debugfs_create_dir("per_cpu", d_tracer);
2986
2987 if (!d_percpu && !once) {
2988 once = 1;
2989 pr_warning("Could not create debugfs directory 'per_cpu'\n");
2990 return NULL;
2991 }
2992
2993 return d_percpu;
2994}
2995
2996static void tracing_init_debugfs_percpu(long cpu)
2997{
2998 struct dentry *d_percpu = tracing_dentry_percpu();
2999 struct dentry *entry;
3000 /* strlen(trace_pipe) + MAX(log10(cpu)) + '\0' */
3001 char filename[17];
3002
3003 if (cpu > 999 || cpu < 0)
3004 return;
3005
3006 /* per cpu trace_pipe */
3007 sprintf(filename, "trace_pipe%ld", cpu);
3008
3009 entry = debugfs_create_file(filename, 0444, d_percpu,
3010 (void *) cpu, &tracing_pipe_fops);
3011 if (!entry)
3012 pr_warning("Could not create debugfs '%s' entry\n", filename);
3013
3014 /* per cpu trace */
3015 sprintf(filename, "trace%ld", cpu);
3016
3017 entry = debugfs_create_file(filename, 0444, d_percpu,
3018 (void *) cpu, &tracing_fops);
3019 if (!entry)
3020 pr_warning("Could not create debugfs '%s' entry\n", filename);
3021}
3022
2914#ifdef CONFIG_FTRACE_SELFTEST 3023#ifdef CONFIG_FTRACE_SELFTEST
2915/* Let selftest have access to static functions in this file */ 3024/* Let selftest have access to static functions in this file */
2916#include "trace_selftest.c" 3025#include "trace_selftest.c"
@@ -2920,6 +3029,7 @@ static __init int tracer_init_debugfs(void)
2920{ 3029{
2921 struct dentry *d_tracer; 3030 struct dentry *d_tracer;
2922 struct dentry *entry; 3031 struct dentry *entry;
3032 int cpu;
2923 3033
2924 d_tracer = tracing_init_dentry(); 3034 d_tracer = tracing_init_dentry();
2925 3035
@@ -2939,7 +3049,7 @@ static __init int tracer_init_debugfs(void)
2939 pr_warning("Could not create debugfs 'tracing_cpumask' entry\n"); 3049 pr_warning("Could not create debugfs 'tracing_cpumask' entry\n");
2940 3050
2941 entry = debugfs_create_file("trace", 0444, d_tracer, 3051 entry = debugfs_create_file("trace", 0444, d_tracer,
2942 &global_trace, &tracing_fops); 3052 (void *) TRACE_PIPE_ALL_CPU, &tracing_fops);
2943 if (!entry) 3053 if (!entry)
2944 pr_warning("Could not create debugfs 'trace' entry\n"); 3054 pr_warning("Could not create debugfs 'trace' entry\n");
2945 3055
@@ -2970,8 +3080,8 @@ static __init int tracer_init_debugfs(void)
2970 if (!entry) 3080 if (!entry)
2971 pr_warning("Could not create debugfs 'README' entry\n"); 3081 pr_warning("Could not create debugfs 'README' entry\n");
2972 3082
2973 entry = debugfs_create_file("trace_pipe", 0644, d_tracer, 3083 entry = debugfs_create_file("trace_pipe", 0444, d_tracer,
2974 NULL, &tracing_pipe_fops); 3084 (void *) TRACE_PIPE_ALL_CPU, &tracing_pipe_fops);
2975 if (!entry) 3085 if (!entry)
2976 pr_warning("Could not create debugfs " 3086 pr_warning("Could not create debugfs "
2977 "'trace_pipe' entry\n"); 3087 "'trace_pipe' entry\n");
@@ -2999,6 +3109,10 @@ static __init int tracer_init_debugfs(void)
2999#ifdef CONFIG_SYSPROF_TRACER 3109#ifdef CONFIG_SYSPROF_TRACER
3000 init_tracer_sysprof_debugfs(d_tracer); 3110 init_tracer_sysprof_debugfs(d_tracer);
3001#endif 3111#endif
3112
3113 for_each_tracing_cpu(cpu)
3114 tracing_init_debugfs_percpu(cpu);
3115
3002 return 0; 3116 return 0;
3003} 3117}
3004 3118
@@ -3222,8 +3336,12 @@ __init static int tracer_alloc_buffers(void)
3222 if (!alloc_cpumask_var(&tracing_cpumask, GFP_KERNEL)) 3336 if (!alloc_cpumask_var(&tracing_cpumask, GFP_KERNEL))
3223 goto out_free_buffer_mask; 3337 goto out_free_buffer_mask;
3224 3338
3339 if (!alloc_cpumask_var(&tracing_reader_cpumask, GFP_KERNEL))
3340 goto out_free_tracing_cpumask;
3341
3225 cpumask_copy(tracing_buffer_mask, cpu_possible_mask); 3342 cpumask_copy(tracing_buffer_mask, cpu_possible_mask);
3226 cpumask_copy(tracing_cpumask, cpu_all_mask); 3343 cpumask_copy(tracing_cpumask, cpu_all_mask);
3344 cpumask_clear(tracing_reader_cpumask);
3227 3345
3228 /* TODO: make the number of buffers hot pluggable with CPUS */ 3346 /* TODO: make the number of buffers hot pluggable with CPUS */
3229 global_trace.buffer = ring_buffer_alloc(trace_buf_size, 3347 global_trace.buffer = ring_buffer_alloc(trace_buf_size,
@@ -3272,6 +3390,8 @@ __init static int tracer_alloc_buffers(void)
3272 ret = 0; 3390 ret = 0;
3273 3391
3274out_free_cpumask: 3392out_free_cpumask:
3393 free_cpumask_var(tracing_reader_cpumask);
3394out_free_tracing_cpumask:
3275 free_cpumask_var(tracing_cpumask); 3395 free_cpumask_var(tracing_cpumask);
3276out_free_buffer_mask: 3396out_free_buffer_mask:
3277 free_cpumask_var(tracing_buffer_mask); 3397 free_cpumask_var(tracing_buffer_mask);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index eed732c151f..508235a39da 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -395,6 +395,8 @@ struct trace_seq {
395 unsigned int readpos; 395 unsigned int readpos;
396}; 396};
397 397
398#define TRACE_PIPE_ALL_CPU -1
399
398/* 400/*
399 * Trace iterator - used by printout routines who present trace 401 * Trace iterator - used by printout routines who present trace
400 * results to users and which routines might sleep, etc: 402 * results to users and which routines might sleep, etc:
@@ -404,6 +406,7 @@ struct trace_iterator {
404 struct tracer *trace; 406 struct tracer *trace;
405 void *private; 407 void *private;
406 struct ring_buffer_iter *buffer_iter[NR_CPUS]; 408 struct ring_buffer_iter *buffer_iter[NR_CPUS];
409 int cpu_file;
407 410
408 /* The below is zeroed out in pipe_read */ 411 /* The below is zeroed out in pipe_read */
409 struct trace_seq seq; 412 struct trace_seq seq;