aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-02-09 12:06:29 -0500
committerSteven Rostedt <srostedt@redhat.com>2009-02-09 12:24:58 -0500
commit34cd4998d38f9bd04f34b78a7cb0c7f1bee00bd9 (patch)
tree05fa5a4418a95119d4448fb49bd8d7d6240ed616 /kernel/trace/trace.c
parentff98781bab2735e6c89793034173e0cb5007a7e5 (diff)
tracing: clean up splice code
Ingo Molnar suggested a series of clean ups for the splice code. This patch implements those suggestions. Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c96
1 files changed, 55 insertions, 41 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 11fde0ad9cb6..d89821283b47 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2537,15 +2537,49 @@ static void tracing_spd_release_pipe(struct splice_pipe_desc *spd,
2537} 2537}
2538 2538
2539static struct pipe_buf_operations tracing_pipe_buf_ops = { 2539static struct pipe_buf_operations tracing_pipe_buf_ops = {
2540 .can_merge = 0, 2540 .can_merge = 0,
2541 .map = generic_pipe_buf_map, 2541 .map = generic_pipe_buf_map,
2542 .unmap = generic_pipe_buf_unmap, 2542 .unmap = generic_pipe_buf_unmap,
2543 .confirm = generic_pipe_buf_confirm, 2543 .confirm = generic_pipe_buf_confirm,
2544 .release = tracing_pipe_buf_release, 2544 .release = tracing_pipe_buf_release,
2545 .steal = generic_pipe_buf_steal, 2545 .steal = generic_pipe_buf_steal,
2546 .get = generic_pipe_buf_get, 2546 .get = generic_pipe_buf_get,
2547}; 2547};
2548 2548
2549static size_t
2550tracing_fill_pipe_page(struct page *pages, size_t rem,
2551 struct trace_iterator *iter)
2552{
2553 size_t count;
2554 int ret;
2555
2556 /* Seq buffer is page-sized, exactly what we need. */
2557 for (;;) {
2558 count = iter->seq.len;
2559 ret = print_trace_line(iter);
2560 count = iter->seq.len - count;
2561 if (rem < count) {
2562 rem = 0;
2563 iter->seq.len -= count;
2564 break;
2565 }
2566 if (ret == TRACE_TYPE_PARTIAL_LINE) {
2567 iter->seq.len -= count;
2568 break;
2569 }
2570
2571 trace_consume(iter);
2572 rem -= count;
2573 if (!find_next_entry_inc(iter)) {
2574 rem = 0;
2575 iter->ent = NULL;
2576 break;
2577 }
2578 }
2579
2580 return rem;
2581}
2582
2549static ssize_t tracing_splice_read_pipe(struct file *filp, 2583static ssize_t tracing_splice_read_pipe(struct file *filp,
2550 loff_t *ppos, 2584 loff_t *ppos,
2551 struct pipe_inode_info *pipe, 2585 struct pipe_inode_info *pipe,
@@ -2556,15 +2590,15 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
2556 struct partial_page partial[PIPE_BUFFERS]; 2590 struct partial_page partial[PIPE_BUFFERS];
2557 struct trace_iterator *iter = filp->private_data; 2591 struct trace_iterator *iter = filp->private_data;
2558 struct splice_pipe_desc spd = { 2592 struct splice_pipe_desc spd = {
2559 .pages = pages, 2593 .pages = pages,
2560 .partial = partial, 2594 .partial = partial,
2561 .nr_pages = 0, /* This gets updated below. */ 2595 .nr_pages = 0, /* This gets updated below. */
2562 .flags = flags, 2596 .flags = flags,
2563 .ops = &tracing_pipe_buf_ops, 2597 .ops = &tracing_pipe_buf_ops,
2564 .spd_release = tracing_spd_release_pipe, 2598 .spd_release = tracing_spd_release_pipe,
2565 }; 2599 };
2566 ssize_t ret; 2600 ssize_t ret;
2567 size_t count, rem; 2601 size_t rem;
2568 unsigned int i; 2602 unsigned int i;
2569 2603
2570 mutex_lock(&trace_types_lock); 2604 mutex_lock(&trace_types_lock);
@@ -2573,45 +2607,25 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
2573 ret = iter->trace->splice_read(iter, filp, 2607 ret = iter->trace->splice_read(iter, filp,
2574 ppos, pipe, len, flags); 2608 ppos, pipe, len, flags);
2575 if (ret) 2609 if (ret)
2576 goto out; 2610 goto out_err;
2577 } 2611 }
2578 2612
2579 ret = tracing_wait_pipe(filp); 2613 ret = tracing_wait_pipe(filp);
2580 if (ret <= 0) 2614 if (ret <= 0)
2581 goto out; 2615 goto out_err;
2582 2616
2583 if (!iter->ent && !find_next_entry_inc(iter)) { 2617 if (!iter->ent && !find_next_entry_inc(iter)) {
2584 ret = -EFAULT; 2618 ret = -EFAULT;
2585 goto out; 2619 goto out_err;
2586 } 2620 }
2587 2621
2588 /* Fill as many pages as possible. */ 2622 /* Fill as many pages as possible. */
2589 for (i = 0, rem = len; i < PIPE_BUFFERS && rem; i++) { 2623 for (i = 0, rem = len; i < PIPE_BUFFERS && rem; i++) {
2590 pages[i] = alloc_page(GFP_KERNEL); 2624 pages[i] = alloc_page(GFP_KERNEL);
2625 if (!pages[i])
2626 break;
2591 2627
2592 /* Seq buffer is page-sized, exactly what we need. */ 2628 rem = tracing_fill_pipe_page(pages[i], rem, iter);
2593 for (;;) {
2594 count = iter->seq.len;
2595 ret = print_trace_line(iter);
2596 count = iter->seq.len - count;
2597 if (rem < count) {
2598 rem = 0;
2599 iter->seq.len -= count;
2600 break;
2601 }
2602 if (ret == TRACE_TYPE_PARTIAL_LINE) {
2603 iter->seq.len -= count;
2604 break;
2605 }
2606
2607 trace_consume(iter);
2608 rem -= count;
2609 if (!find_next_entry_inc(iter)) {
2610 rem = 0;
2611 iter->ent = NULL;
2612 break;
2613 }
2614 }
2615 2629
2616 /* Copy the data into the page, so we can start over. */ 2630 /* Copy the data into the page, so we can start over. */
2617 ret = trace_seq_to_buffer(&iter->seq, 2631 ret = trace_seq_to_buffer(&iter->seq,
@@ -2633,7 +2647,7 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
2633 2647
2634 return splice_to_pipe(pipe, &spd); 2648 return splice_to_pipe(pipe, &spd);
2635 2649
2636out: 2650out_err:
2637 mutex_unlock(&trace_types_lock); 2651 mutex_unlock(&trace_types_lock);
2638 2652
2639 return ret; 2653 return ret;