diff options
Diffstat (limited to 'kernel/trace')
-rw-r--r-- | kernel/trace/blktrace.c | 12 | ||||
-rw-r--r-- | kernel/trace/ftrace.c | 36 | ||||
-rw-r--r-- | kernel/trace/ring_buffer.c | 15 | ||||
-rw-r--r-- | kernel/trace/trace.c | 25 | ||||
-rw-r--r-- | kernel/trace/trace.h | 4 | ||||
-rw-r--r-- | kernel/trace/trace_event_profile.c | 2 | ||||
-rw-r--r-- | kernel/trace/trace_events.c | 4 | ||||
-rw-r--r-- | kernel/trace/trace_events_filter.c | 20 | ||||
-rw-r--r-- | kernel/trace/trace_functions_graph.c | 11 | ||||
-rw-r--r-- | kernel/trace/trace_printk.c | 2 | ||||
-rw-r--r-- | kernel/trace/trace_stack.c | 7 | ||||
-rw-r--r-- | kernel/trace/trace_stat.c | 34 |
12 files changed, 96 insertions, 76 deletions
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 1090b0aed9ba..7a34cb563fec 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
@@ -267,8 +267,8 @@ static void blk_trace_free(struct blk_trace *bt) | |||
267 | { | 267 | { |
268 | debugfs_remove(bt->msg_file); | 268 | debugfs_remove(bt->msg_file); |
269 | debugfs_remove(bt->dropped_file); | 269 | debugfs_remove(bt->dropped_file); |
270 | debugfs_remove(bt->dir); | ||
271 | relay_close(bt->rchan); | 270 | relay_close(bt->rchan); |
271 | debugfs_remove(bt->dir); | ||
272 | free_percpu(bt->sequence); | 272 | free_percpu(bt->sequence); |
273 | free_percpu(bt->msg_data); | 273 | free_percpu(bt->msg_data); |
274 | kfree(bt); | 274 | kfree(bt); |
@@ -378,18 +378,8 @@ static int blk_subbuf_start_callback(struct rchan_buf *buf, void *subbuf, | |||
378 | 378 | ||
379 | static int blk_remove_buf_file_callback(struct dentry *dentry) | 379 | static int blk_remove_buf_file_callback(struct dentry *dentry) |
380 | { | 380 | { |
381 | struct dentry *parent = dentry->d_parent; | ||
382 | debugfs_remove(dentry); | 381 | debugfs_remove(dentry); |
383 | 382 | ||
384 | /* | ||
385 | * this will fail for all but the last file, but that is ok. what we | ||
386 | * care about is the top level buts->name directory going away, when | ||
387 | * the last trace file is gone. Then we don't have to rmdir() that | ||
388 | * manually on trace stop, so it nicely solves the issue with | ||
389 | * force killing of running traces. | ||
390 | */ | ||
391 | |||
392 | debugfs_remove(parent); | ||
393 | return 0; | 383 | return 0; |
394 | } | 384 | } |
395 | 385 | ||
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 4521c77d1a1a..25edd5cc5935 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -1662,7 +1662,7 @@ ftrace_regex_open(struct inode *inode, struct file *file, int enable) | |||
1662 | 1662 | ||
1663 | mutex_lock(&ftrace_regex_lock); | 1663 | mutex_lock(&ftrace_regex_lock); |
1664 | if ((file->f_mode & FMODE_WRITE) && | 1664 | if ((file->f_mode & FMODE_WRITE) && |
1665 | !(file->f_flags & O_APPEND)) | 1665 | (file->f_flags & O_TRUNC)) |
1666 | ftrace_filter_reset(enable); | 1666 | ftrace_filter_reset(enable); |
1667 | 1667 | ||
1668 | if (file->f_mode & FMODE_READ) { | 1668 | if (file->f_mode & FMODE_READ) { |
@@ -2278,7 +2278,11 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, | |||
2278 | read++; | 2278 | read++; |
2279 | cnt--; | 2279 | cnt--; |
2280 | 2280 | ||
2281 | if (!(iter->flags & ~FTRACE_ITER_CONT)) { | 2281 | /* |
2282 | * If the parser haven't finished with the last write, | ||
2283 | * continue reading the user input without skipping spaces. | ||
2284 | */ | ||
2285 | if (!(iter->flags & FTRACE_ITER_CONT)) { | ||
2282 | /* skip white space */ | 2286 | /* skip white space */ |
2283 | while (cnt && isspace(ch)) { | 2287 | while (cnt && isspace(ch)) { |
2284 | ret = get_user(ch, ubuf++); | 2288 | ret = get_user(ch, ubuf++); |
@@ -2288,8 +2292,9 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, | |||
2288 | cnt--; | 2292 | cnt--; |
2289 | } | 2293 | } |
2290 | 2294 | ||
2295 | /* only spaces were written */ | ||
2291 | if (isspace(ch)) { | 2296 | if (isspace(ch)) { |
2292 | file->f_pos += read; | 2297 | *ppos += read; |
2293 | ret = read; | 2298 | ret = read; |
2294 | goto out; | 2299 | goto out; |
2295 | } | 2300 | } |
@@ -2319,12 +2324,12 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, | |||
2319 | if (ret) | 2324 | if (ret) |
2320 | goto out; | 2325 | goto out; |
2321 | iter->buffer_idx = 0; | 2326 | iter->buffer_idx = 0; |
2322 | } else | 2327 | } else { |
2323 | iter->flags |= FTRACE_ITER_CONT; | 2328 | iter->flags |= FTRACE_ITER_CONT; |
2329 | iter->buffer[iter->buffer_idx++] = ch; | ||
2330 | } | ||
2324 | 2331 | ||
2325 | 2332 | *ppos += read; | |
2326 | file->f_pos += read; | ||
2327 | |||
2328 | ret = read; | 2333 | ret = read; |
2329 | out: | 2334 | out: |
2330 | mutex_unlock(&ftrace_regex_lock); | 2335 | mutex_unlock(&ftrace_regex_lock); |
@@ -2577,7 +2582,7 @@ ftrace_graph_open(struct inode *inode, struct file *file) | |||
2577 | 2582 | ||
2578 | mutex_lock(&graph_lock); | 2583 | mutex_lock(&graph_lock); |
2579 | if ((file->f_mode & FMODE_WRITE) && | 2584 | if ((file->f_mode & FMODE_WRITE) && |
2580 | !(file->f_flags & O_APPEND)) { | 2585 | (file->f_flags & O_TRUNC)) { |
2581 | ftrace_graph_count = 0; | 2586 | ftrace_graph_count = 0; |
2582 | memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs)); | 2587 | memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs)); |
2583 | } | 2588 | } |
@@ -2596,6 +2601,14 @@ ftrace_graph_open(struct inode *inode, struct file *file) | |||
2596 | } | 2601 | } |
2597 | 2602 | ||
2598 | static int | 2603 | static int |
2604 | ftrace_graph_release(struct inode *inode, struct file *file) | ||
2605 | { | ||
2606 | if (file->f_mode & FMODE_READ) | ||
2607 | seq_release(inode, file); | ||
2608 | return 0; | ||
2609 | } | ||
2610 | |||
2611 | static int | ||
2599 | ftrace_set_func(unsigned long *array, int *idx, char *buffer) | 2612 | ftrace_set_func(unsigned long *array, int *idx, char *buffer) |
2600 | { | 2613 | { |
2601 | struct dyn_ftrace *rec; | 2614 | struct dyn_ftrace *rec; |
@@ -2724,9 +2737,10 @@ ftrace_graph_write(struct file *file, const char __user *ubuf, | |||
2724 | } | 2737 | } |
2725 | 2738 | ||
2726 | static const struct file_operations ftrace_graph_fops = { | 2739 | static const struct file_operations ftrace_graph_fops = { |
2727 | .open = ftrace_graph_open, | 2740 | .open = ftrace_graph_open, |
2728 | .read = seq_read, | 2741 | .read = seq_read, |
2729 | .write = ftrace_graph_write, | 2742 | .write = ftrace_graph_write, |
2743 | .release = ftrace_graph_release, | ||
2730 | }; | 2744 | }; |
2731 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 2745 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
2732 | 2746 | ||
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index bf27bb7a63e2..a330513d96ce 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -735,6 +735,7 @@ ring_buffer_free(struct ring_buffer *buffer) | |||
735 | 735 | ||
736 | put_online_cpus(); | 736 | put_online_cpus(); |
737 | 737 | ||
738 | kfree(buffer->buffers); | ||
738 | free_cpumask_var(buffer->cpumask); | 739 | free_cpumask_var(buffer->cpumask); |
739 | 740 | ||
740 | kfree(buffer); | 741 | kfree(buffer); |
@@ -1785,7 +1786,7 @@ void ring_buffer_discard_commit(struct ring_buffer *buffer, | |||
1785 | */ | 1786 | */ |
1786 | RB_WARN_ON(buffer, !local_read(&cpu_buffer->committing)); | 1787 | RB_WARN_ON(buffer, !local_read(&cpu_buffer->committing)); |
1787 | 1788 | ||
1788 | if (!rb_try_to_discard(cpu_buffer, event)) | 1789 | if (rb_try_to_discard(cpu_buffer, event)) |
1789 | goto out; | 1790 | goto out; |
1790 | 1791 | ||
1791 | /* | 1792 | /* |
@@ -2383,7 +2384,6 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts) | |||
2383 | * the box. Return the padding, and we will release | 2384 | * the box. Return the padding, and we will release |
2384 | * the current locks, and try again. | 2385 | * the current locks, and try again. |
2385 | */ | 2386 | */ |
2386 | rb_advance_reader(cpu_buffer); | ||
2387 | return event; | 2387 | return event; |
2388 | 2388 | ||
2389 | case RINGBUF_TYPE_TIME_EXTEND: | 2389 | case RINGBUF_TYPE_TIME_EXTEND: |
@@ -2486,7 +2486,7 @@ static inline int rb_ok_to_lock(void) | |||
2486 | * buffer too. A one time deal is all you get from reading | 2486 | * buffer too. A one time deal is all you get from reading |
2487 | * the ring buffer from an NMI. | 2487 | * the ring buffer from an NMI. |
2488 | */ | 2488 | */ |
2489 | if (likely(!in_nmi() && !oops_in_progress)) | 2489 | if (likely(!in_nmi())) |
2490 | return 1; | 2490 | return 1; |
2491 | 2491 | ||
2492 | tracing_off_permanent(); | 2492 | tracing_off_permanent(); |
@@ -2519,6 +2519,8 @@ ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts) | |||
2519 | if (dolock) | 2519 | if (dolock) |
2520 | spin_lock(&cpu_buffer->reader_lock); | 2520 | spin_lock(&cpu_buffer->reader_lock); |
2521 | event = rb_buffer_peek(buffer, cpu, ts); | 2521 | event = rb_buffer_peek(buffer, cpu, ts); |
2522 | if (event && event->type_len == RINGBUF_TYPE_PADDING) | ||
2523 | rb_advance_reader(cpu_buffer); | ||
2522 | if (dolock) | 2524 | if (dolock) |
2523 | spin_unlock(&cpu_buffer->reader_lock); | 2525 | spin_unlock(&cpu_buffer->reader_lock); |
2524 | local_irq_restore(flags); | 2526 | local_irq_restore(flags); |
@@ -2590,12 +2592,9 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts) | |||
2590 | spin_lock(&cpu_buffer->reader_lock); | 2592 | spin_lock(&cpu_buffer->reader_lock); |
2591 | 2593 | ||
2592 | event = rb_buffer_peek(buffer, cpu, ts); | 2594 | event = rb_buffer_peek(buffer, cpu, ts); |
2593 | if (!event) | 2595 | if (event) |
2594 | goto out_unlock; | 2596 | rb_advance_reader(cpu_buffer); |
2595 | |||
2596 | rb_advance_reader(cpu_buffer); | ||
2597 | 2597 | ||
2598 | out_unlock: | ||
2599 | if (dolock) | 2598 | if (dolock) |
2600 | spin_unlock(&cpu_buffer->reader_lock); | 2599 | spin_unlock(&cpu_buffer->reader_lock); |
2601 | local_irq_restore(flags); | 2600 | local_irq_restore(flags); |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8bc8d8afea6a..8c358395d338 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -848,6 +848,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, | |||
848 | ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | | 848 | ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | |
849 | (need_resched() ? TRACE_FLAG_NEED_RESCHED : 0); | 849 | (need_resched() ? TRACE_FLAG_NEED_RESCHED : 0); |
850 | } | 850 | } |
851 | EXPORT_SYMBOL_GPL(tracing_generic_entry_update); | ||
851 | 852 | ||
852 | struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr, | 853 | struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr, |
853 | int type, | 854 | int type, |
@@ -2031,7 +2032,7 @@ static int tracing_open(struct inode *inode, struct file *file) | |||
2031 | 2032 | ||
2032 | /* If this file was open for write, then erase contents */ | 2033 | /* If this file was open for write, then erase contents */ |
2033 | if ((file->f_mode & FMODE_WRITE) && | 2034 | if ((file->f_mode & FMODE_WRITE) && |
2034 | !(file->f_flags & O_APPEND)) { | 2035 | (file->f_flags & O_TRUNC)) { |
2035 | long cpu = (long) inode->i_private; | 2036 | long cpu = (long) inode->i_private; |
2036 | 2037 | ||
2037 | if (cpu == TRACE_PIPE_ALL_CPU) | 2038 | if (cpu == TRACE_PIPE_ALL_CPU) |
@@ -3085,7 +3086,8 @@ tracing_fill_pipe_page(size_t rem, struct trace_iterator *iter) | |||
3085 | break; | 3086 | break; |
3086 | } | 3087 | } |
3087 | 3088 | ||
3088 | trace_consume(iter); | 3089 | if (ret != TRACE_TYPE_NO_CONSUME) |
3090 | trace_consume(iter); | ||
3089 | rem -= count; | 3091 | rem -= count; |
3090 | if (!find_next_entry_inc(iter)) { | 3092 | if (!find_next_entry_inc(iter)) { |
3091 | rem = 0; | 3093 | rem = 0; |
@@ -3894,17 +3896,9 @@ trace_options_core_write(struct file *filp, const char __user *ubuf, size_t cnt, | |||
3894 | if (ret < 0) | 3896 | if (ret < 0) |
3895 | return ret; | 3897 | return ret; |
3896 | 3898 | ||
3897 | switch (val) { | 3899 | if (val != 0 && val != 1) |
3898 | case 0: | ||
3899 | trace_flags &= ~(1 << index); | ||
3900 | break; | ||
3901 | case 1: | ||
3902 | trace_flags |= 1 << index; | ||
3903 | break; | ||
3904 | |||
3905 | default: | ||
3906 | return -EINVAL; | 3900 | return -EINVAL; |
3907 | } | 3901 | set_tracer_flags(1 << index, val); |
3908 | 3902 | ||
3909 | *ppos += cnt; | 3903 | *ppos += cnt; |
3910 | 3904 | ||
@@ -4233,8 +4227,11 @@ static void __ftrace_dump(bool disable_tracing) | |||
4233 | iter.pos = -1; | 4227 | iter.pos = -1; |
4234 | 4228 | ||
4235 | if (find_next_entry_inc(&iter) != NULL) { | 4229 | if (find_next_entry_inc(&iter) != NULL) { |
4236 | print_trace_line(&iter); | 4230 | int ret; |
4237 | trace_consume(&iter); | 4231 | |
4232 | ret = print_trace_line(&iter); | ||
4233 | if (ret != TRACE_TYPE_NO_CONSUME) | ||
4234 | trace_consume(&iter); | ||
4238 | } | 4235 | } |
4239 | 4236 | ||
4240 | trace_printk_seq(&iter.seq); | 4237 | trace_printk_seq(&iter.seq); |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 3548ae5cc780..8b9f4f6e9559 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -438,10 +438,6 @@ struct trace_entry *tracing_get_trace_entry(struct trace_array *tr, | |||
438 | struct trace_entry *trace_find_next_entry(struct trace_iterator *iter, | 438 | struct trace_entry *trace_find_next_entry(struct trace_iterator *iter, |
439 | int *ent_cpu, u64 *ent_ts); | 439 | int *ent_cpu, u64 *ent_ts); |
440 | 440 | ||
441 | void tracing_generic_entry_update(struct trace_entry *entry, | ||
442 | unsigned long flags, | ||
443 | int pc); | ||
444 | |||
445 | void default_wait_pipe(struct trace_iterator *iter); | 441 | void default_wait_pipe(struct trace_iterator *iter); |
446 | void poll_wait_pipe(struct trace_iterator *iter); | 442 | void poll_wait_pipe(struct trace_iterator *iter); |
447 | 443 | ||
diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c index 5b5895afecfe..11ba5bb4ed0a 100644 --- a/kernel/trace/trace_event_profile.c +++ b/kernel/trace/trace_event_profile.c | |||
@@ -14,7 +14,7 @@ int ftrace_profile_enable(int event_id) | |||
14 | 14 | ||
15 | mutex_lock(&event_mutex); | 15 | mutex_lock(&event_mutex); |
16 | list_for_each_entry(event, &ftrace_events, list) { | 16 | list_for_each_entry(event, &ftrace_events, list) { |
17 | if (event->id == event_id) { | 17 | if (event->id == event_id && event->profile_enable) { |
18 | ret = event->profile_enable(event); | 18 | ret = event->profile_enable(event); |
19 | break; | 19 | break; |
20 | } | 20 | } |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 53c8fd376a88..e75276a49cf5 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -376,7 +376,7 @@ ftrace_event_seq_open(struct inode *inode, struct file *file) | |||
376 | const struct seq_operations *seq_ops; | 376 | const struct seq_operations *seq_ops; |
377 | 377 | ||
378 | if ((file->f_mode & FMODE_WRITE) && | 378 | if ((file->f_mode & FMODE_WRITE) && |
379 | !(file->f_flags & O_APPEND)) | 379 | (file->f_flags & O_TRUNC)) |
380 | ftrace_clear_events(); | 380 | ftrace_clear_events(); |
381 | 381 | ||
382 | seq_ops = inode->i_private; | 382 | seq_ops = inode->i_private; |
@@ -940,7 +940,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, | |||
940 | entry = trace_create_file("enable", 0644, call->dir, call, | 940 | entry = trace_create_file("enable", 0644, call->dir, call, |
941 | enable); | 941 | enable); |
942 | 942 | ||
943 | if (call->id) | 943 | if (call->id && call->profile_enable) |
944 | entry = trace_create_file("id", 0444, call->dir, call, | 944 | entry = trace_create_file("id", 0444, call->dir, call, |
945 | id); | 945 | id); |
946 | 946 | ||
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 936c621bbf46..f32dc9d1ea7b 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
@@ -624,9 +624,6 @@ static int filter_add_subsystem_pred(struct filter_parse_state *ps, | |||
624 | return -ENOSPC; | 624 | return -ENOSPC; |
625 | } | 625 | } |
626 | 626 | ||
627 | filter->preds[filter->n_preds] = pred; | ||
628 | filter->n_preds++; | ||
629 | |||
630 | list_for_each_entry(call, &ftrace_events, list) { | 627 | list_for_each_entry(call, &ftrace_events, list) { |
631 | 628 | ||
632 | if (!call->define_fields) | 629 | if (!call->define_fields) |
@@ -643,6 +640,9 @@ static int filter_add_subsystem_pred(struct filter_parse_state *ps, | |||
643 | } | 640 | } |
644 | replace_filter_string(call->filter, filter_string); | 641 | replace_filter_string(call->filter, filter_string); |
645 | } | 642 | } |
643 | |||
644 | filter->preds[filter->n_preds] = pred; | ||
645 | filter->n_preds++; | ||
646 | out: | 646 | out: |
647 | return err; | 647 | return err; |
648 | } | 648 | } |
@@ -1029,12 +1029,17 @@ static int replace_preds(struct event_subsystem *system, | |||
1029 | 1029 | ||
1030 | if (elt->op == OP_AND || elt->op == OP_OR) { | 1030 | if (elt->op == OP_AND || elt->op == OP_OR) { |
1031 | pred = create_logical_pred(elt->op); | 1031 | pred = create_logical_pred(elt->op); |
1032 | if (!pred) | ||
1033 | return -ENOMEM; | ||
1032 | if (call) { | 1034 | if (call) { |
1033 | err = filter_add_pred(ps, call, pred); | 1035 | err = filter_add_pred(ps, call, pred); |
1034 | filter_free_pred(pred); | 1036 | filter_free_pred(pred); |
1035 | } else | 1037 | } else { |
1036 | err = filter_add_subsystem_pred(ps, system, | 1038 | err = filter_add_subsystem_pred(ps, system, |
1037 | pred, filter_string); | 1039 | pred, filter_string); |
1040 | if (err) | ||
1041 | filter_free_pred(pred); | ||
1042 | } | ||
1038 | if (err) | 1043 | if (err) |
1039 | return err; | 1044 | return err; |
1040 | 1045 | ||
@@ -1048,12 +1053,17 @@ static int replace_preds(struct event_subsystem *system, | |||
1048 | } | 1053 | } |
1049 | 1054 | ||
1050 | pred = create_pred(elt->op, operand1, operand2); | 1055 | pred = create_pred(elt->op, operand1, operand2); |
1056 | if (!pred) | ||
1057 | return -ENOMEM; | ||
1051 | if (call) { | 1058 | if (call) { |
1052 | err = filter_add_pred(ps, call, pred); | 1059 | err = filter_add_pred(ps, call, pred); |
1053 | filter_free_pred(pred); | 1060 | filter_free_pred(pred); |
1054 | } else | 1061 | } else { |
1055 | err = filter_add_subsystem_pred(ps, system, pred, | 1062 | err = filter_add_subsystem_pred(ps, system, pred, |
1056 | filter_string); | 1063 | filter_string); |
1064 | if (err) | ||
1065 | filter_free_pred(pred); | ||
1066 | } | ||
1057 | if (err) | 1067 | if (err) |
1058 | return err; | 1068 | return err; |
1059 | 1069 | ||
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index d2249abafb53..420ec3487579 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c | |||
@@ -843,9 +843,16 @@ print_graph_function(struct trace_iterator *iter) | |||
843 | 843 | ||
844 | switch (entry->type) { | 844 | switch (entry->type) { |
845 | case TRACE_GRAPH_ENT: { | 845 | case TRACE_GRAPH_ENT: { |
846 | struct ftrace_graph_ent_entry *field; | 846 | /* |
847 | * print_graph_entry() may consume the current event, | ||
848 | * thus @field may become invalid, so we need to save it. | ||
849 | * sizeof(struct ftrace_graph_ent_entry) is very small, | ||
850 | * it can be safely saved at the stack. | ||
851 | */ | ||
852 | struct ftrace_graph_ent_entry *field, saved; | ||
847 | trace_assign_type(field, entry); | 853 | trace_assign_type(field, entry); |
848 | return print_graph_entry(field, s, iter); | 854 | saved = *field; |
855 | return print_graph_entry(&saved, s, iter); | ||
849 | } | 856 | } |
850 | case TRACE_GRAPH_RET: { | 857 | case TRACE_GRAPH_RET: { |
851 | struct ftrace_graph_ret_entry *field; | 858 | struct ftrace_graph_ret_entry *field; |
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c index 7b6278110827..687699d365ae 100644 --- a/kernel/trace/trace_printk.c +++ b/kernel/trace/trace_printk.c | |||
@@ -176,7 +176,7 @@ static int t_show(struct seq_file *m, void *v) | |||
176 | const char *str = *fmt; | 176 | const char *str = *fmt; |
177 | int i; | 177 | int i; |
178 | 178 | ||
179 | seq_printf(m, "0x%lx : \"", (unsigned long)fmt); | 179 | seq_printf(m, "0x%lx : \"", *(unsigned long *)fmt); |
180 | 180 | ||
181 | /* | 181 | /* |
182 | * Tabs and new lines need to be converted. | 182 | * Tabs and new lines need to be converted. |
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index e644af910124..6a2a9d484cd6 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c | |||
@@ -301,17 +301,14 @@ static const struct seq_operations stack_trace_seq_ops = { | |||
301 | 301 | ||
302 | static int stack_trace_open(struct inode *inode, struct file *file) | 302 | static int stack_trace_open(struct inode *inode, struct file *file) |
303 | { | 303 | { |
304 | int ret; | 304 | return seq_open(file, &stack_trace_seq_ops); |
305 | |||
306 | ret = seq_open(file, &stack_trace_seq_ops); | ||
307 | |||
308 | return ret; | ||
309 | } | 305 | } |
310 | 306 | ||
311 | static const struct file_operations stack_trace_fops = { | 307 | static const struct file_operations stack_trace_fops = { |
312 | .open = stack_trace_open, | 308 | .open = stack_trace_open, |
313 | .read = seq_read, | 309 | .read = seq_read, |
314 | .llseek = seq_lseek, | 310 | .llseek = seq_lseek, |
311 | .release = seq_release, | ||
315 | }; | 312 | }; |
316 | 313 | ||
317 | int | 314 | int |
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c index e66f5e493342..aea321c82fa0 100644 --- a/kernel/trace/trace_stat.c +++ b/kernel/trace/trace_stat.c | |||
@@ -73,7 +73,7 @@ static struct rb_node *release_next(struct rb_node *node) | |||
73 | } | 73 | } |
74 | } | 74 | } |
75 | 75 | ||
76 | static void reset_stat_session(struct stat_session *session) | 76 | static void __reset_stat_session(struct stat_session *session) |
77 | { | 77 | { |
78 | struct rb_node *node = session->stat_root.rb_node; | 78 | struct rb_node *node = session->stat_root.rb_node; |
79 | 79 | ||
@@ -83,10 +83,17 @@ static void reset_stat_session(struct stat_session *session) | |||
83 | session->stat_root = RB_ROOT; | 83 | session->stat_root = RB_ROOT; |
84 | } | 84 | } |
85 | 85 | ||
86 | static void reset_stat_session(struct stat_session *session) | ||
87 | { | ||
88 | mutex_lock(&session->stat_mutex); | ||
89 | __reset_stat_session(session); | ||
90 | mutex_unlock(&session->stat_mutex); | ||
91 | } | ||
92 | |||
86 | static void destroy_session(struct stat_session *session) | 93 | static void destroy_session(struct stat_session *session) |
87 | { | 94 | { |
88 | debugfs_remove(session->file); | 95 | debugfs_remove(session->file); |
89 | reset_stat_session(session); | 96 | __reset_stat_session(session); |
90 | mutex_destroy(&session->stat_mutex); | 97 | mutex_destroy(&session->stat_mutex); |
91 | kfree(session); | 98 | kfree(session); |
92 | } | 99 | } |
@@ -150,7 +157,7 @@ static int stat_seq_init(struct stat_session *session) | |||
150 | int i; | 157 | int i; |
151 | 158 | ||
152 | mutex_lock(&session->stat_mutex); | 159 | mutex_lock(&session->stat_mutex); |
153 | reset_stat_session(session); | 160 | __reset_stat_session(session); |
154 | 161 | ||
155 | if (!ts->stat_cmp) | 162 | if (!ts->stat_cmp) |
156 | ts->stat_cmp = dummy_cmp; | 163 | ts->stat_cmp = dummy_cmp; |
@@ -183,7 +190,7 @@ exit: | |||
183 | return ret; | 190 | return ret; |
184 | 191 | ||
185 | exit_free_rbtree: | 192 | exit_free_rbtree: |
186 | reset_stat_session(session); | 193 | __reset_stat_session(session); |
187 | mutex_unlock(&session->stat_mutex); | 194 | mutex_unlock(&session->stat_mutex); |
188 | return ret; | 195 | return ret; |
189 | } | 196 | } |
@@ -250,16 +257,21 @@ static const struct seq_operations trace_stat_seq_ops = { | |||
250 | static int tracing_stat_open(struct inode *inode, struct file *file) | 257 | static int tracing_stat_open(struct inode *inode, struct file *file) |
251 | { | 258 | { |
252 | int ret; | 259 | int ret; |
253 | 260 | struct seq_file *m; | |
254 | struct stat_session *session = inode->i_private; | 261 | struct stat_session *session = inode->i_private; |
255 | 262 | ||
263 | ret = stat_seq_init(session); | ||
264 | if (ret) | ||
265 | return ret; | ||
266 | |||
256 | ret = seq_open(file, &trace_stat_seq_ops); | 267 | ret = seq_open(file, &trace_stat_seq_ops); |
257 | if (!ret) { | 268 | if (ret) { |
258 | struct seq_file *m = file->private_data; | 269 | reset_stat_session(session); |
259 | m->private = session; | 270 | return ret; |
260 | ret = stat_seq_init(session); | ||
261 | } | 271 | } |
262 | 272 | ||
273 | m = file->private_data; | ||
274 | m->private = session; | ||
263 | return ret; | 275 | return ret; |
264 | } | 276 | } |
265 | 277 | ||
@@ -270,11 +282,9 @@ static int tracing_stat_release(struct inode *i, struct file *f) | |||
270 | { | 282 | { |
271 | struct stat_session *session = i->i_private; | 283 | struct stat_session *session = i->i_private; |
272 | 284 | ||
273 | mutex_lock(&session->stat_mutex); | ||
274 | reset_stat_session(session); | 285 | reset_stat_session(session); |
275 | mutex_unlock(&session->stat_mutex); | ||
276 | 286 | ||
277 | return 0; | 287 | return seq_release(i, f); |
278 | } | 288 | } |
279 | 289 | ||
280 | static const struct file_operations tracing_stat_fops = { | 290 | static const struct file_operations tracing_stat_fops = { |