aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2010-05-20 04:43:18 -0400
committerJens Axboe <jens.axboe@oracle.com>2010-05-21 15:12:40 -0400
commit35f3d14dbbc58447c61e38a162ea10add6b31dc7 (patch)
tree3e03cd540b7dcdac82195c4e76862c0ce6daaaf0 /kernel/trace/trace.c
parent3d42b3612891baecf709d93f28655a6882a65d41 (diff)
pipe: add support for shrinking and growing pipes
This patch adds F_GETPIPE_SZ and F_SETPIPE_SZ fcntl() actions for growing and shrinking the size of a pipe and adjusts pipe.c and splice.c (and relay and network splice) usage to work with these larger (or smaller) pipes. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c60
1 files changed, 36 insertions, 24 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 44f916a04065..7b155a0e6f31 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -3269,12 +3269,12 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
3269 size_t len, 3269 size_t len,
3270 unsigned int flags) 3270 unsigned int flags)
3271{ 3271{
3272 struct page *pages[PIPE_BUFFERS]; 3272 struct page *pages_def[PIPE_DEF_BUFFERS];
3273 struct partial_page partial[PIPE_BUFFERS]; 3273 struct partial_page partial_def[PIPE_DEF_BUFFERS];
3274 struct trace_iterator *iter = filp->private_data; 3274 struct trace_iterator *iter = filp->private_data;
3275 struct splice_pipe_desc spd = { 3275 struct splice_pipe_desc spd = {
3276 .pages = pages, 3276 .pages = pages_def,
3277 .partial = partial, 3277 .partial = partial_def,
3278 .nr_pages = 0, /* This gets updated below. */ 3278 .nr_pages = 0, /* This gets updated below. */
3279 .flags = flags, 3279 .flags = flags,
3280 .ops = &tracing_pipe_buf_ops, 3280 .ops = &tracing_pipe_buf_ops,
@@ -3285,6 +3285,9 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
3285 size_t rem; 3285 size_t rem;
3286 unsigned int i; 3286 unsigned int i;
3287 3287
3288 if (splice_grow_spd(pipe, &spd))
3289 return -ENOMEM;
3290
3288 /* copy the tracer to avoid using a global lock all around */ 3291 /* copy the tracer to avoid using a global lock all around */
3289 mutex_lock(&trace_types_lock); 3292 mutex_lock(&trace_types_lock);
3290 if (unlikely(old_tracer != current_trace && current_trace)) { 3293 if (unlikely(old_tracer != current_trace && current_trace)) {
@@ -3315,23 +3318,23 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
3315 trace_access_lock(iter->cpu_file); 3318 trace_access_lock(iter->cpu_file);
3316 3319
3317 /* Fill as many pages as possible. */ 3320 /* Fill as many pages as possible. */
3318 for (i = 0, rem = len; i < PIPE_BUFFERS && rem; i++) { 3321 for (i = 0, rem = len; i < pipe->buffers && rem; i++) {
3319 pages[i] = alloc_page(GFP_KERNEL); 3322 spd.pages[i] = alloc_page(GFP_KERNEL);
3320 if (!pages[i]) 3323 if (!spd.pages[i])
3321 break; 3324 break;
3322 3325
3323 rem = tracing_fill_pipe_page(rem, iter); 3326 rem = tracing_fill_pipe_page(rem, iter);
3324 3327
3325 /* Copy the data into the page, so we can start over. */ 3328 /* Copy the data into the page, so we can start over. */
3326 ret = trace_seq_to_buffer(&iter->seq, 3329 ret = trace_seq_to_buffer(&iter->seq,
3327 page_address(pages[i]), 3330 page_address(spd.pages[i]),
3328 iter->seq.len); 3331 iter->seq.len);
3329 if (ret < 0) { 3332 if (ret < 0) {
3330 __free_page(pages[i]); 3333 __free_page(spd.pages[i]);
3331 break; 3334 break;
3332 } 3335 }
3333 partial[i].offset = 0; 3336 spd.partial[i].offset = 0;
3334 partial[i].len = iter->seq.len; 3337 spd.partial[i].len = iter->seq.len;
3335 3338
3336 trace_seq_init(&iter->seq); 3339 trace_seq_init(&iter->seq);
3337 } 3340 }
@@ -3342,12 +3345,14 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
3342 3345
3343 spd.nr_pages = i; 3346 spd.nr_pages = i;
3344 3347
3345 return splice_to_pipe(pipe, &spd); 3348 ret = splice_to_pipe(pipe, &spd);
3349out:
3350 splice_shrink_spd(pipe, &spd);
3351 return ret;
3346 3352
3347out_err: 3353out_err:
3348 mutex_unlock(&iter->mutex); 3354 mutex_unlock(&iter->mutex);
3349 3355 goto out;
3350 return ret;
3351} 3356}
3352 3357
3353static ssize_t 3358static ssize_t
@@ -3746,11 +3751,11 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
3746 unsigned int flags) 3751 unsigned int flags)
3747{ 3752{
3748 struct ftrace_buffer_info *info = file->private_data; 3753 struct ftrace_buffer_info *info = file->private_data;
3749 struct partial_page partial[PIPE_BUFFERS]; 3754 struct partial_page partial_def[PIPE_DEF_BUFFERS];
3750 struct page *pages[PIPE_BUFFERS]; 3755 struct page *pages_def[PIPE_DEF_BUFFERS];
3751 struct splice_pipe_desc spd = { 3756 struct splice_pipe_desc spd = {
3752 .pages = pages, 3757 .pages = pages_def,
3753 .partial = partial, 3758 .partial = partial_def,
3754 .flags = flags, 3759 .flags = flags,
3755 .ops = &buffer_pipe_buf_ops, 3760 .ops = &buffer_pipe_buf_ops,
3756 .spd_release = buffer_spd_release, 3761 .spd_release = buffer_spd_release,
@@ -3759,22 +3764,28 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
3759 int entries, size, i; 3764 int entries, size, i;
3760 size_t ret; 3765 size_t ret;
3761 3766
3767 if (splice_grow_spd(pipe, &spd))
3768 return -ENOMEM;
3769
3762 if (*ppos & (PAGE_SIZE - 1)) { 3770 if (*ppos & (PAGE_SIZE - 1)) {
3763 WARN_ONCE(1, "Ftrace: previous read must page-align\n"); 3771 WARN_ONCE(1, "Ftrace: previous read must page-align\n");
3764 return -EINVAL; 3772 ret = -EINVAL;
3773 goto out;
3765 } 3774 }
3766 3775
3767 if (len & (PAGE_SIZE - 1)) { 3776 if (len & (PAGE_SIZE - 1)) {
3768 WARN_ONCE(1, "Ftrace: splice_read should page-align\n"); 3777 WARN_ONCE(1, "Ftrace: splice_read should page-align\n");
3769 if (len < PAGE_SIZE) 3778 if (len < PAGE_SIZE) {
3770 return -EINVAL; 3779 ret = -EINVAL;
3780 goto out;
3781 }
3771 len &= PAGE_MASK; 3782 len &= PAGE_MASK;
3772 } 3783 }
3773 3784
3774 trace_access_lock(info->cpu); 3785 trace_access_lock(info->cpu);
3775 entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu); 3786 entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu);
3776 3787
3777 for (i = 0; i < PIPE_BUFFERS && len && entries; i++, len -= PAGE_SIZE) { 3788 for (i = 0; i < pipe->buffers && len && entries; i++, len -= PAGE_SIZE) {
3778 struct page *page; 3789 struct page *page;
3779 int r; 3790 int r;
3780 3791
@@ -3829,11 +3840,12 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
3829 else 3840 else
3830 ret = 0; 3841 ret = 0;
3831 /* TODO: block */ 3842 /* TODO: block */
3832 return ret; 3843 goto out;
3833 } 3844 }
3834 3845
3835 ret = splice_to_pipe(pipe, &spd); 3846 ret = splice_to_pipe(pipe, &spd);
3836 3847 splice_shrink_spd(pipe, &spd);
3848out:
3837 return ret; 3849 return ret;
3838} 3850}
3839 3851