diff options
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 75 |
1 files changed, 41 insertions, 34 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 756d7283318b..086d36316805 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -1936,7 +1936,7 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter) | |||
1936 | } | 1936 | } |
1937 | 1937 | ||
1938 | if (event) | 1938 | if (event) |
1939 | return event->trace(iter, sym_flags); | 1939 | return event->funcs->trace(iter, sym_flags, event); |
1940 | 1940 | ||
1941 | if (!trace_seq_printf(s, "Unknown type %d\n", entry->type)) | 1941 | if (!trace_seq_printf(s, "Unknown type %d\n", entry->type)) |
1942 | goto partial; | 1942 | goto partial; |
@@ -1962,7 +1962,7 @@ static enum print_line_t print_raw_fmt(struct trace_iterator *iter) | |||
1962 | 1962 | ||
1963 | event = ftrace_find_event(entry->type); | 1963 | event = ftrace_find_event(entry->type); |
1964 | if (event) | 1964 | if (event) |
1965 | return event->raw(iter, 0); | 1965 | return event->funcs->raw(iter, 0, event); |
1966 | 1966 | ||
1967 | if (!trace_seq_printf(s, "%d ?\n", entry->type)) | 1967 | if (!trace_seq_printf(s, "%d ?\n", entry->type)) |
1968 | goto partial; | 1968 | goto partial; |
@@ -1989,7 +1989,7 @@ static enum print_line_t print_hex_fmt(struct trace_iterator *iter) | |||
1989 | 1989 | ||
1990 | event = ftrace_find_event(entry->type); | 1990 | event = ftrace_find_event(entry->type); |
1991 | if (event) { | 1991 | if (event) { |
1992 | enum print_line_t ret = event->hex(iter, 0); | 1992 | enum print_line_t ret = event->funcs->hex(iter, 0, event); |
1993 | if (ret != TRACE_TYPE_HANDLED) | 1993 | if (ret != TRACE_TYPE_HANDLED) |
1994 | return ret; | 1994 | return ret; |
1995 | } | 1995 | } |
@@ -2014,7 +2014,8 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter) | |||
2014 | } | 2014 | } |
2015 | 2015 | ||
2016 | event = ftrace_find_event(entry->type); | 2016 | event = ftrace_find_event(entry->type); |
2017 | return event ? event->binary(iter, 0) : TRACE_TYPE_HANDLED; | 2017 | return event ? event->funcs->binary(iter, 0, event) : |
2018 | TRACE_TYPE_HANDLED; | ||
2018 | } | 2019 | } |
2019 | 2020 | ||
2020 | int trace_empty(struct trace_iterator *iter) | 2021 | int trace_empty(struct trace_iterator *iter) |
@@ -3309,12 +3310,12 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, | |||
3309 | size_t len, | 3310 | size_t len, |
3310 | unsigned int flags) | 3311 | unsigned int flags) |
3311 | { | 3312 | { |
3312 | struct page *pages[PIPE_BUFFERS]; | 3313 | struct page *pages_def[PIPE_DEF_BUFFERS]; |
3313 | struct partial_page partial[PIPE_BUFFERS]; | 3314 | struct partial_page partial_def[PIPE_DEF_BUFFERS]; |
3314 | struct trace_iterator *iter = filp->private_data; | 3315 | struct trace_iterator *iter = filp->private_data; |
3315 | struct splice_pipe_desc spd = { | 3316 | struct splice_pipe_desc spd = { |
3316 | .pages = pages, | 3317 | .pages = pages_def, |
3317 | .partial = partial, | 3318 | .partial = partial_def, |
3318 | .nr_pages = 0, /* This gets updated below. */ | 3319 | .nr_pages = 0, /* This gets updated below. */ |
3319 | .flags = flags, | 3320 | .flags = flags, |
3320 | .ops = &tracing_pipe_buf_ops, | 3321 | .ops = &tracing_pipe_buf_ops, |
@@ -3325,6 +3326,9 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, | |||
3325 | size_t rem; | 3326 | size_t rem; |
3326 | unsigned int i; | 3327 | unsigned int i; |
3327 | 3328 | ||
3329 | if (splice_grow_spd(pipe, &spd)) | ||
3330 | return -ENOMEM; | ||
3331 | |||
3328 | /* copy the tracer to avoid using a global lock all around */ | 3332 | /* copy the tracer to avoid using a global lock all around */ |
3329 | mutex_lock(&trace_types_lock); | 3333 | mutex_lock(&trace_types_lock); |
3330 | if (unlikely(old_tracer != current_trace && current_trace)) { | 3334 | if (unlikely(old_tracer != current_trace && current_trace)) { |
@@ -3355,23 +3359,23 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, | |||
3355 | trace_access_lock(iter->cpu_file); | 3359 | trace_access_lock(iter->cpu_file); |
3356 | 3360 | ||
3357 | /* Fill as many pages as possible. */ | 3361 | /* Fill as many pages as possible. */ |
3358 | for (i = 0, rem = len; i < PIPE_BUFFERS && rem; i++) { | 3362 | for (i = 0, rem = len; i < pipe->buffers && rem; i++) { |
3359 | pages[i] = alloc_page(GFP_KERNEL); | 3363 | spd.pages[i] = alloc_page(GFP_KERNEL); |
3360 | if (!pages[i]) | 3364 | if (!spd.pages[i]) |
3361 | break; | 3365 | break; |
3362 | 3366 | ||
3363 | rem = tracing_fill_pipe_page(rem, iter); | 3367 | rem = tracing_fill_pipe_page(rem, iter); |
3364 | 3368 | ||
3365 | /* Copy the data into the page, so we can start over. */ | 3369 | /* Copy the data into the page, so we can start over. */ |
3366 | ret = trace_seq_to_buffer(&iter->seq, | 3370 | ret = trace_seq_to_buffer(&iter->seq, |
3367 | page_address(pages[i]), | 3371 | page_address(spd.pages[i]), |
3368 | iter->seq.len); | 3372 | iter->seq.len); |
3369 | if (ret < 0) { | 3373 | if (ret < 0) { |
3370 | __free_page(pages[i]); | 3374 | __free_page(spd.pages[i]); |
3371 | break; | 3375 | break; |
3372 | } | 3376 | } |
3373 | partial[i].offset = 0; | 3377 | spd.partial[i].offset = 0; |
3374 | partial[i].len = iter->seq.len; | 3378 | spd.partial[i].len = iter->seq.len; |
3375 | 3379 | ||
3376 | trace_seq_init(&iter->seq); | 3380 | trace_seq_init(&iter->seq); |
3377 | } | 3381 | } |
@@ -3382,12 +3386,14 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, | |||
3382 | 3386 | ||
3383 | spd.nr_pages = i; | 3387 | spd.nr_pages = i; |
3384 | 3388 | ||
3385 | return splice_to_pipe(pipe, &spd); | 3389 | ret = splice_to_pipe(pipe, &spd); |
3390 | out: | ||
3391 | splice_shrink_spd(pipe, &spd); | ||
3392 | return ret; | ||
3386 | 3393 | ||
3387 | out_err: | 3394 | out_err: |
3388 | mutex_unlock(&iter->mutex); | 3395 | mutex_unlock(&iter->mutex); |
3389 | 3396 | goto out; | |
3390 | return ret; | ||
3391 | } | 3397 | } |
3392 | 3398 | ||
3393 | static ssize_t | 3399 | static ssize_t |
@@ -3660,7 +3666,6 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, | |||
3660 | size_t count, loff_t *ppos) | 3666 | size_t count, loff_t *ppos) |
3661 | { | 3667 | { |
3662 | struct ftrace_buffer_info *info = filp->private_data; | 3668 | struct ftrace_buffer_info *info = filp->private_data; |
3663 | unsigned int pos; | ||
3664 | ssize_t ret; | 3669 | ssize_t ret; |
3665 | size_t size; | 3670 | size_t size; |
3666 | 3671 | ||
@@ -3687,11 +3692,6 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, | |||
3687 | if (ret < 0) | 3692 | if (ret < 0) |
3688 | return 0; | 3693 | return 0; |
3689 | 3694 | ||
3690 | pos = ring_buffer_page_len(info->spare); | ||
3691 | |||
3692 | if (pos < PAGE_SIZE) | ||
3693 | memset(info->spare + pos, 0, PAGE_SIZE - pos); | ||
3694 | |||
3695 | read: | 3695 | read: |
3696 | size = PAGE_SIZE - info->read; | 3696 | size = PAGE_SIZE - info->read; |
3697 | if (size > count) | 3697 | if (size > count) |
@@ -3786,11 +3786,11 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
3786 | unsigned int flags) | 3786 | unsigned int flags) |
3787 | { | 3787 | { |
3788 | struct ftrace_buffer_info *info = file->private_data; | 3788 | struct ftrace_buffer_info *info = file->private_data; |
3789 | struct partial_page partial[PIPE_BUFFERS]; | 3789 | struct partial_page partial_def[PIPE_DEF_BUFFERS]; |
3790 | struct page *pages[PIPE_BUFFERS]; | 3790 | struct page *pages_def[PIPE_DEF_BUFFERS]; |
3791 | struct splice_pipe_desc spd = { | 3791 | struct splice_pipe_desc spd = { |
3792 | .pages = pages, | 3792 | .pages = pages_def, |
3793 | .partial = partial, | 3793 | .partial = partial_def, |
3794 | .flags = flags, | 3794 | .flags = flags, |
3795 | .ops = &buffer_pipe_buf_ops, | 3795 | .ops = &buffer_pipe_buf_ops, |
3796 | .spd_release = buffer_spd_release, | 3796 | .spd_release = buffer_spd_release, |
@@ -3799,22 +3799,28 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
3799 | int entries, size, i; | 3799 | int entries, size, i; |
3800 | size_t ret; | 3800 | size_t ret; |
3801 | 3801 | ||
3802 | if (splice_grow_spd(pipe, &spd)) | ||
3803 | return -ENOMEM; | ||
3804 | |||
3802 | if (*ppos & (PAGE_SIZE - 1)) { | 3805 | if (*ppos & (PAGE_SIZE - 1)) { |
3803 | WARN_ONCE(1, "Ftrace: previous read must page-align\n"); | 3806 | WARN_ONCE(1, "Ftrace: previous read must page-align\n"); |
3804 | return -EINVAL; | 3807 | ret = -EINVAL; |
3808 | goto out; | ||
3805 | } | 3809 | } |
3806 | 3810 | ||
3807 | if (len & (PAGE_SIZE - 1)) { | 3811 | if (len & (PAGE_SIZE - 1)) { |
3808 | WARN_ONCE(1, "Ftrace: splice_read should page-align\n"); | 3812 | WARN_ONCE(1, "Ftrace: splice_read should page-align\n"); |
3809 | if (len < PAGE_SIZE) | 3813 | if (len < PAGE_SIZE) { |
3810 | return -EINVAL; | 3814 | ret = -EINVAL; |
3815 | goto out; | ||
3816 | } | ||
3811 | len &= PAGE_MASK; | 3817 | len &= PAGE_MASK; |
3812 | } | 3818 | } |
3813 | 3819 | ||
3814 | trace_access_lock(info->cpu); | 3820 | trace_access_lock(info->cpu); |
3815 | entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu); | 3821 | entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu); |
3816 | 3822 | ||
3817 | for (i = 0; i < PIPE_BUFFERS && len && entries; i++, len -= PAGE_SIZE) { | 3823 | for (i = 0; i < pipe->buffers && len && entries; i++, len -= PAGE_SIZE) { |
3818 | struct page *page; | 3824 | struct page *page; |
3819 | int r; | 3825 | int r; |
3820 | 3826 | ||
@@ -3869,11 +3875,12 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
3869 | else | 3875 | else |
3870 | ret = 0; | 3876 | ret = 0; |
3871 | /* TODO: block */ | 3877 | /* TODO: block */ |
3872 | return ret; | 3878 | goto out; |
3873 | } | 3879 | } |
3874 | 3880 | ||
3875 | ret = splice_to_pipe(pipe, &spd); | 3881 | ret = splice_to_pipe(pipe, &spd); |
3876 | 3882 | splice_shrink_spd(pipe, &spd); | |
3883 | out: | ||
3877 | return ret; | 3884 | return ret; |
3878 | } | 3885 | } |
3879 | 3886 | ||