Merge branch 'master' into for-2.6.35
[pandora-kernel.git] / kernel / trace / trace.c
index 756d728..8a76339 100644 (file)
@@ -3309,12 +3309,12 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
                                        size_t len,
                                        unsigned int flags)
 {
-       struct page *pages[PIPE_BUFFERS];
-       struct partial_page partial[PIPE_BUFFERS];
+       struct page *pages_def[PIPE_DEF_BUFFERS];
+       struct partial_page partial_def[PIPE_DEF_BUFFERS];
        struct trace_iterator *iter = filp->private_data;
        struct splice_pipe_desc spd = {
-               .pages          = pages,
-               .partial        = partial,
+               .pages          = pages_def,
+               .partial        = partial_def,
                .nr_pages       = 0, /* This gets updated below. */
                .flags          = flags,
                .ops            = &tracing_pipe_buf_ops,
@@ -3325,6 +3325,9 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
        size_t rem;
        unsigned int i;
 
+       if (splice_grow_spd(pipe, &spd))
+               return -ENOMEM;
+
        /* copy the tracer to avoid using a global lock all around */
        mutex_lock(&trace_types_lock);
        if (unlikely(old_tracer != current_trace && current_trace)) {
@@ -3355,23 +3358,23 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
        trace_access_lock(iter->cpu_file);
 
        /* Fill as many pages as possible. */
-       for (i = 0, rem = len; i < PIPE_BUFFERS && rem; i++) {
-               pages[i] = alloc_page(GFP_KERNEL);
-               if (!pages[i])
+       for (i = 0, rem = len; i < pipe->buffers && rem; i++) {
+               spd.pages[i] = alloc_page(GFP_KERNEL);
+               if (!spd.pages[i])
                        break;
 
                rem = tracing_fill_pipe_page(rem, iter);
 
                /* Copy the data into the page, so we can start over. */
                ret = trace_seq_to_buffer(&iter->seq,
-                                         page_address(pages[i]),
+                                         page_address(spd.pages[i]),
                                          iter->seq.len);
                if (ret < 0) {
-                       __free_page(pages[i]);
+                       __free_page(spd.pages[i]);
                        break;
                }
-               partial[i].offset = 0;
-               partial[i].len = iter->seq.len;
+               spd.partial[i].offset = 0;
+               spd.partial[i].len = iter->seq.len;
 
                trace_seq_init(&iter->seq);
        }
@@ -3382,12 +3385,14 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
 
        spd.nr_pages = i;
 
-       return splice_to_pipe(pipe, &spd);
+       ret = splice_to_pipe(pipe, &spd);
+out:
+       splice_shrink_spd(pipe, &spd);
+       return ret;
 
 out_err:
        mutex_unlock(&iter->mutex);
-
-       return ret;
+       goto out;
 }
 
 static ssize_t
@@ -3786,11 +3791,11 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
                            unsigned int flags)
 {
        struct ftrace_buffer_info *info = file->private_data;
-       struct partial_page partial[PIPE_BUFFERS];
-       struct page *pages[PIPE_BUFFERS];
+       struct partial_page partial_def[PIPE_DEF_BUFFERS];
+       struct page *pages_def[PIPE_DEF_BUFFERS];
        struct splice_pipe_desc spd = {
-               .pages          = pages,
-               .partial        = partial,
+               .pages          = pages_def,
+               .partial        = partial_def,
                .flags          = flags,
                .ops            = &buffer_pipe_buf_ops,
                .spd_release    = buffer_spd_release,
@@ -3799,22 +3804,28 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
        int entries, size, i;
        size_t ret;
 
+       if (splice_grow_spd(pipe, &spd))
+               return -ENOMEM;
+
        if (*ppos & (PAGE_SIZE - 1)) {
                WARN_ONCE(1, "Ftrace: previous read must page-align\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
        }
 
        if (len & (PAGE_SIZE - 1)) {
                WARN_ONCE(1, "Ftrace: splice_read should page-align\n");
-               if (len < PAGE_SIZE)
-                       return -EINVAL;
+               if (len < PAGE_SIZE) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                len &= PAGE_MASK;
        }
 
        trace_access_lock(info->cpu);
        entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu);
 
-       for (i = 0; i < PIPE_BUFFERS && len && entries; i++, len -= PAGE_SIZE) {
+       for (i = 0; i < pipe->buffers && len && entries; i++, len -= PAGE_SIZE) {
                struct page *page;
                int r;
 
@@ -3869,11 +3880,12 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
                else
                        ret = 0;
                /* TODO: block */
-               return ret;
+               goto out;
        }
 
        ret = splice_to_pipe(pipe, &spd);
-
+       splice_shrink_spd(pipe, &spd);
+out:
        return ret;
 }