Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 30 May 2010 19:35:01 +0000 (12:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 30 May 2010 19:35:01 +0000 (12:35 -0700)
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  perf tui: Fix last use_browser problem related to .perfconfig
  perf symbols: Add the build id cache to the vmlinux path
  perf tui: Reset use_browser if stdout is not a tty
  ring-buffer: Move zeroing out excess in page to ring buffer code
  ring-buffer: Reset "real_end" when page is filled

1  2 
kernel/trace/trace.c

diff --combined kernel/trace/trace.c
index 55e48511d7c8ea8292b70dbd7cbcec43dc0c10b1,95d0b1a28f93848a0ff5beaf667faeb9e4892062..086d3631680505f20d0820371c50b43f4056e316
@@@ -3310,12 -3310,12 +3310,12 @@@ static ssize_t tracing_splice_read_pipe
                                        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,
        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)) {
        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);
        }
  
        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
@@@ -3666,7 -3661,6 +3666,6 @@@ tracing_buffers_read(struct file *filp
                     size_t count, loff_t *ppos)
  {
        struct ftrace_buffer_info *info = filp->private_data;
-       unsigned int pos;
        ssize_t ret;
        size_t size;
  
        if (ret < 0)
                return 0;
  
-       pos = ring_buffer_page_len(info->spare);
-       if (pos < PAGE_SIZE)
-               memset(info->spare + pos, 0, PAGE_SIZE - pos);
  read:
        size = PAGE_SIZE - info->read;
        if (size > count)
@@@ -3792,11 -3781,11 +3786,11 @@@ tracing_buffers_splice_read(struct fil
                            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,
        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;
  
                else
                        ret = 0;
                /* TODO: block */
 -              return ret;
 +              goto out;
        }
  
        ret = splice_to_pipe(pipe, &spd);
 -
 +      splice_shrink_spd(pipe, &spd);
 +out:
        return ret;
  }