1. 08 8月, 2009 1 次提交
  2. 06 8月, 2009 3 次提交
    • R
      ring-buffer: Fix advance of reader in rb_buffer_peek() · 469535a5
      Robert Richter 提交于
      When calling rb_buffer_peek() from ring_buffer_consume() and a
      padding event is returned, the function rb_advance_reader() is
      called twice. This may lead to missing samples or under high
      workloads to the warning below. This patch fixes this. If a padding
      event is returned by rb_buffer_peek() it will be consumed by the
      calling function now.
      
      Also, I simplified some code in ring_buffer_consume().
      
      ------------[ cut here ]------------
      WARNING: at /dev/shm/.source/linux/kernel/trace/ring_buffer.c:2289 rb_advance_reader+0x2e/0xc5()
      Hardware name: Anaheim
      Modules linked in:
      Pid: 29, comm: events/2 Tainted: G        W  2.6.31-rc3-oprofile-x86_64-standard-00059-g5050dc2 #1
      Call Trace:
      [<ffffffff8106776f>] ? rb_advance_reader+0x2e/0xc5
      [<ffffffff81039ffe>] warn_slowpath_common+0x77/0x8f
      [<ffffffff8103a025>] warn_slowpath_null+0xf/0x11
      [<ffffffff8106776f>] rb_advance_reader+0x2e/0xc5
      [<ffffffff81068bda>] ring_buffer_consume+0xa0/0xd2
      [<ffffffff81326933>] op_cpu_buffer_read_entry+0x21/0x9e
      [<ffffffff810be3af>] ? __find_get_block+0x4b/0x165
      [<ffffffff8132749b>] sync_buffer+0xa5/0x401
      [<ffffffff810be3af>] ? __find_get_block+0x4b/0x165
      [<ffffffff81326c1b>] ? wq_sync_buffer+0x0/0x78
      [<ffffffff81326c76>] wq_sync_buffer+0x5b/0x78
      [<ffffffff8104aa30>] worker_thread+0x113/0x1ac
      [<ffffffff8104dd95>] ? autoremove_wake_function+0x0/0x38
      [<ffffffff8104a91d>] ? worker_thread+0x0/0x1ac
      [<ffffffff8104dc9a>] kthread+0x88/0x92
      [<ffffffff8100bdba>] child_rip+0xa/0x20
      [<ffffffff8104dc12>] ? kthread+0x0/0x92
      [<ffffffff8100bdb0>] ? child_rip+0x0/0x20
      ---[ end trace f561c0a58fcc89bd ]---
      
      Cc: Steven Rostedt <rostedt@goodmis.org>
      Cc: <stable@kernel.org>
      Signed-off-by: NRobert Richter <robert.richter@amd.com>
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      469535a5
    • S
      ring-buffer: do not disable ring buffer on oops_in_progress · 464e85eb
      Steven Rostedt 提交于
      The commit:
      
        commit e0fdace1
        Author: David Miller <davem@davemloft.net>
        Date:   Fri Aug 1 01:11:22 2008 -0700
      
          debug_locks: set oops_in_progress if we will log messages.
      
          Otherwise lock debugging messages on runqueue locks can deadlock the
          system due to the wakeups performed by printk().
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      
      Will permanently set oops_in_progress on any lockdep failure.
      When this triggers it will cause any read from the ring buffer to
      permanently disable the ring buffer (not to mention no locking of
      printk).
      
      This patch removes the check. It keeps the print in NMI which makes
      sense. This is probably OK, since the ring buffer should not cause
      something to set oops_in_progress anyway.
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      464e85eb
    • S
      ring-buffer: fix check of try_to_discard result · 0f2541d2
      Steven Rostedt 提交于
      The function ring_buffer_discard_commit inversed the code path
      of the result of try_to_discard. It should skip incrementing the
      entry counter if try_to_discard succeeded. But instead, it increments
      the entry conder if it succeeded to discard, and does not increment
      it if it fails.
      
      The result of this bug is that filtering will make the stat counters
      incorrect.
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      0f2541d2
  3. 25 6月, 2009 1 次提交
    • P
      ring-buffer: Make it generally available · 1155de47
      Paul Mundt 提交于
      In hunting down the cause for the hwlat_detector ring buffer spew in
      my failed -next builds it became obvious that folks are now treating
      ring_buffer as something that is generic independent of tracing and thus,
      suitable for public driver consumption.
      
      Given that there are only a few minor areas in ring_buffer that have any
      reliance on CONFIG_TRACING or CONFIG_FUNCTION_TRACER, provide stubs for
      those and make it generally available.
      Signed-off-by: NPaul Mundt <lethal@linux-sh.org>
      Cc: Jon Masters <jcm@jonmasters.org>
      Cc: Steven Rostedt <rostedt@goodmis.org>
      LKML-Reference: <20090625053012.GB19944@linux-sh.org>
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      1155de47
  4. 18 6月, 2009 4 次提交
    • S
      ring-buffer: do not grab locks in nmi · 8d707e8e
      Steven Rostedt 提交于
      If ftrace_dump_on_oops is set, and an NMI detects a lockup, then it
      will need to read from the ring buffer. But the read side of the
      ring buffer still takes locks. This patch adds a check on the read
      side that if it is in an NMI, then it will disable the ring buffer
      and not take any locks.
      
      Reads can still happen on a disabled ring buffer.
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      8d707e8e
    • S
      ring-buffer: add locks around rb_per_cpu_empty · d4788207
      Steven Rostedt 提交于
      The checking of whether the buffer is empty or not needs to be serialized
      among the readers. Add the reader spin lock around it.
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      d4788207
    • S
      ring-buffer: check for less than two in size allocation · 5f78abee
      Steven Rostedt 提交于
      The ring buffer must have at least two pages allocated for the
      reader page swap to work.
      
      The page count check will miss the case of a zero size passed in.
      Even though a zero size ring buffer would probably fail an allocation,
      making the min size check for less than two instead of equal to one makes
      the code a bit more robust.
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      5f78abee
    • S
      ring-buffer: remove useless compile check for buffer_page size · 0dcd4d6c
      Steven Rostedt 提交于
      The original version of the ring buffer had a hack to map the
      page struct that held the pages of the buffer to also be the structure
      that the ring buffer would keep the pages in a link list.
      
      This overlap of the page struct was very dangerous and that hack was
      removed a while ago.
      
      But there was a check to make sure the buffer_page never became bigger
      than the page struct, and would fail the compile if it did. The
      check was only meaningful when we had the hack. Now that we have separate
      allocated descriptors for the buffer pages, we can remove this check.
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      0dcd4d6c
  5. 17 6月, 2009 4 次提交
    • S
      ring-buffer: remove useless warn on check · c6a9d7b5
      Steven Rostedt 提交于
      A check if "write > BUF_PAGE_SIZE" is done right after a
      
      	if (write > BUF_PAGE_SIZE)
      		return ...;
      
      Thus the check is actually testing the compiler and not the
      kernel. This is useless, remove it.
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      c6a9d7b5
    • S
      ring-buffer: use BUF_PAGE_HDR_SIZE in calculating index · 22f470f8
      Steven Rostedt 提交于
      The index of the event is found by masking PAGE_MASK to it and
      subtracting the header size. Currently the header size is calculate
      by PAGE_SIZE - BUF_PAGE_SIZE, when we already have a macro
      BUF_PAGE_HDR_SIZE to define it.
      
      If we want to change BUF_PAGE_SIZE to something less than filling
      the rest of the page (this is done for debugging), then we break
      the algorithm to find the index.
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      22f470f8
    • S
      ring-buffer: use commit counters for commit pointer accounting · fa743953
      Steven Rostedt 提交于
      The ring buffer is made up of three sets of pointers.
      
      The head page pointer, which points to the next page for the reader to
      get.
      
      The commit pointer and commit index, which points to the page and index
      of the last committed write respectively.
      
      The tail pointer and tail index, which points to the page and the index
      of the last reserved data respectively (non committed).
      
      The commit pointer is only moved forward by the outer most writer.
      If a nested writer comes in, it will not move the pointer forward.
      
      The current implementation has a flaw. It assumes that the outer most
      writer successfully reserved data. There's a small race window where
      the outer most writer could find the tail pointer, but a nested
      writer could come in (via interrupt) and move the tail forward, and
      even the commit forward.
      
      The outer writer would not realized the commit moved forward and the
      accounting will break.
      
      This patch changes the design to use counters in the per cpu buffers
      to keep track of commits. The counters are incremented at the start
      of the commit, and decremented at the end. If the end commit counter
      is 1, then it moves the commit pointers. A loop is made to check for
      races between checking and moving the commit pointers. Only the outer
      commit should move the pointers anyway.
      
      The test of knowing if a reserve is equal to the last commit update
      is still needed to know for time keeping. The time code is much less
      racey than the commit updates.
      
      This change not only solves the mentioned race, but also makes the
      code simpler.
      
      [ Impact: fix commit race and simplify code ]
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      fa743953
    • S
      ring-buffer: remove unused variable · 263294f3
      Steven Rostedt 提交于
      Fix the compiler error:
      
      kernel/trace/ring_buffer.c: In function 'rb_move_tail':
      kernel/trace/ring_buffer.c:1236: warning: unused variable 'event'
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      263294f3
  6. 15 6月, 2009 3 次提交
  7. 10 6月, 2009 1 次提交
  8. 09 6月, 2009 1 次提交
    • P
      ring-buffer: pass in lockdep class key for reader_lock · 1f8a6a10
      Peter Zijlstra 提交于
      On Sun, 7 Jun 2009, Ingo Molnar wrote:
      > Testing tracer sched_switch: <6>Starting ring buffer hammer
      > PASSED
      > Testing tracer sysprof: PASSED
      > Testing tracer function: PASSED
      > Testing tracer irqsoff:
      > =============================================
      > PASSED
      > Testing tracer preemptoff: PASSED
      > Testing tracer preemptirqsoff: [ INFO: possible recursive locking detected ]
      > PASSED
      > Testing tracer branch: 2.6.30-rc8-tip-01972-ge5b9078-dirty #5760
      > ---------------------------------------------
      > rb_consumer/431 is trying to acquire lock:
      >  (&cpu_buffer->reader_lock){......}, at: [<c109eef7>] ring_buffer_reset_cpu+0x37/0x70
      >
      > but task is already holding lock:
      >  (&cpu_buffer->reader_lock){......}, at: [<c10a019e>] ring_buffer_consume+0x7e/0xc0
      >
      > other info that might help us debug this:
      > 1 lock held by rb_consumer/431:
      >  #0:  (&cpu_buffer->reader_lock){......}, at: [<c10a019e>] ring_buffer_consume+0x7e/0xc0
      
      The ring buffer is a generic structure, and can be used outside of
      ftrace. If ftrace traces within the use of the ring buffer, it can produce
      false positives with lockdep.
      
      This patch passes in a static lock key into the allocation of the ring
      buffer, so that different ring buffers will have their own lock class.
      Reported-by: NIngo Molnar <mingo@elte.hu>
      Signed-off-by: NPeter Zijlstra <a.p.zijlstra@chello.nl>
      LKML-Reference: <1244477919.13761.9042.camel@twins>
      
      [ store key in ring buffer descriptor ]
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      1f8a6a10
  9. 03 6月, 2009 3 次提交
    • S
      ring-buffer: discard timestamps that are at the start of the buffer · ea05b57c
      Steven Rostedt 提交于
      Every buffer page in the ring buffer includes its own time stamp.
      When an event is recorded to the ring buffer with a delta time greater
      than what can be held in the event header, a time stamp event is created.
      
      If the the create timestamp falls over to the next buffer page, it is
      redundant because the buffer page holds a full time stamp. This patch
      will try to discard the time stamp when it falls to the start of the
      next page.
      
      This change also fixes a issues with disarding events. If most events are
      discarded, timestamps will start to creep into the ring buffer. If we
      do not discard the timestamps then they can fill up the ring buffer over
      time and waste space.
      
      This change will keep time stamps from filling up over another page. If
      something is recorded in the buffer page, and the rest is filtered, then
      the time stamps can only fill up to the end of the page.
      
      [ Impact: prevent time stamps from filling ring buffer ]
      Reported-by: NTim Bird <tim.bird@am.sony.com>
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      ea05b57c
    • S
      ring-buffer: try to discard unneeded timestamps · edd813bf
      Steven Rostedt 提交于
      There are times that a race may happen that we add a timestamp in a
      nested write. This timestamp would just contain a zero delta and serves
      no purpose.
      
      Now that we have a way to discard events, this patch will try to discard
      the timestamp instead of just wasting the space in the ring buffer.
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      edd813bf
    • T
      ring-buffer: fix bug in ring_buffer_discard_commit · a2023556
      Tim Bird 提交于
      There's a bug in ring_buffer_discard_commit.  The wrong
      pointer is being compared in order to check if the event
      can be freed from the buffer rather than discarded
      (i.e. marked as PAD).
      
      I noticed this when I was working on duration filtering.
      The bug is not deadly - it just results in lots of wasted
      space in the buffer.  All filtered events are left in
      the buffer and marked as discarded, rather than being
      removed from the buffer to make space for other events.
      
      Unfortunately, when I fixed this bug, I got errors doing a
      filtered function trace.  Multiple TIME_EXTEND
      events pile up in the buffer, and trigger the
      following loop overage warning in rb_iter_peek():
      
      again:
      	...
      	if (RB_WARN_ON(cpu_buffer, ++nr_loops > 10))
      		return NULL;
      
      I'm not sure what the best way is to fix this. I don't
      know if I should extend the loop threshhold, or if I should
      make the test more complex (ignore TIME_EXTEND
      events), or just get rid of this loop check completely.
      
      Note that if I implement a workaround for this, then I
      see another problem from rb_advance_iter().  I haven't
      tracked that one down yet.
      
      In general, it seems like the case of removing filtered
      events has not been working properly, and so some assumptions
      about buffer invariant conditions need to be revisited.
      
      Here's the patch for the simple fix:
      
      Compare correct pointer for checking if an event can be
      freed rather than left as discarded in the buffer.
      Signed-off-by: NTim Bird <tim.bird@am.sony.com>
      LKML-Reference: <4A25BE9E.5090909@am.sony.com>
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      a2023556
  10. 12 5月, 2009 5 次提交
  11. 08 5月, 2009 1 次提交
  12. 07 5月, 2009 2 次提交
    • S
      ring-buffer: make moving the tail page a separate function · 6634ff26
      Steven Rostedt 提交于
      Ingo Molnar thought the code would be cleaner if we used a function call
      instead of a goto for moving the tail page. After implementing this,
      it seems that gcc still inlines the result and the output is pretty much
      the same. Since this is considered a cleaner approach, might as well
      implement it.
      
      [ Impact: code clean up ]
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      6634ff26
    • S
      ring-buffer: remove unneeded conditional in rb_reserve_next · 8e7abf1c
      Steven Rostedt 提交于
      The code in __rb_reserve_next checks on page overflow if it is the
      original commiter and then resets the page back to the original
      setting.  Although this is fine, and the code is correct, it is
      a bit fragil. Some experimental work I did breaks it easily.
      
      The better and more robust solution is to have all commiters that
      overflow the page, simply subtract what they added.
      
      [ Impact: more robust ring buffer account management ]
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      8e7abf1c
  13. 06 5月, 2009 7 次提交
    • S
      ring-buffer: move big if statement down · aa20ae84
      Steven Rostedt 提交于
      In the hot path of the ring buffer "__rb_reserve_next" there's a big
      if statement that does not even return back to the work flow.
      
      	code;
      
      	if (cross to next page) {
      
      		[ lots of code ]
      
      		return;
      	}
      
      	more code;
      
      The condition is even the unlikely path, although we do not denote it
      with an unlikely because gcc is fine with it. The condition is true when
      the write crosses a page boundary, and we need to start at a new page.
      
      Having this if statement makes it hard to read, but calling another
      function to do the work is also not appropriate, because we are using a lot
      of variables that were set before the if statement, and we do not want to
      send them as parameters.
      
      This patch changes it to a goto:
      
      	code;
      
      	if (cross to next page)
      		goto next_page;
      
      	more code;
      
      	return;
      
      next_page:
      
      	[ lots of code]
      
      This makes the code easier to understand, and a bit more obvious.
      
      The output from gcc is practically identical. For some reason, gcc decided
      to use different registers when I switched it to a goto. But other than that,
      the logic is the same.
      
      [ Impact: easier to read code ]
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      aa20ae84
    • S
      ring-buffer: disable writers when resetting buffers · 41ede23e
      Steven Rostedt 提交于
      As a precaution, it is best to disable writing to the ring buffers
      when reseting them.
      
      [ Impact: prevent weird things if write happens during reset ]
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      41ede23e
    • S
      ring-buffer: have read page swap increment counter with page entries · afbab76a
      Steven Rostedt 提交于
      In the swap page ring buffer code that is used by the ftrace splice code,
      we scan the page to increment the counter of entries read.
      
      With the number of entries already in the page we simply need to add it.
      
      [ Impact: speed up reading page from ring buffer ]
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      afbab76a
    • S
      ring-buffer: record page entries in buffer page descriptor · 778c55d4
      Steven Rostedt 提交于
      Currently, when the ring buffer writer overflows the buffer and must
      write over non consumed data, we increment the overrun counter by
      reading the entries on the page we are about to overwrite. This reads
      the entries one by one.
      
      This is not very effecient. This patch adds another entry counter
      into each buffer page descriptor that keeps track of the number of
      entries on the page. Now on overwrite, the overrun counter simply
      needs to add the number of entries that is on the page it is about
      to overwrite.
      
      [ Impact: speed up of ring buffer in overwrite mode ]
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      778c55d4
    • S
      ring-buffer: convert cpu buffer entries to local_t · e4906eff
      Steven Rostedt 提交于
      The entries counter in cpu buffer is not atomic. It can be updated by
      other interrupts or from another CPU (readers).
      
      But making entries into "atomic_t" causes an atomic operation that can
      hurt performance. Instead we convert it to a local_t that will increment
      a counter with a local CPU atomic operation (if the arch supports it).
      
      Instead of fighting with readers and overwrites that decrement the counter,
      I added a "read" counter. Every time a reader reads an entry it is
      incremented.
      
      We already have a overrun counter and with that, the entries counter and
      the read counter, we can calculate the total number of entries in the
      buffer with:
      
        (entries - overrun) - read
      
      As long as the total number of entries in the ring buffer is less than
      the word size, this will work. But since the entries counter was previously
      a long, this is no different than what we had before.
      
      Thanks to Andrew Morton for pointing out in the first version that
      atomic_t does not replace unsigned long. I switched to atomic_long_t
      even though it is signed. A negative count is most likely a bug.
      
      [ Impact: keep accurate count of cpu buffer entries ]
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      e4906eff
    • S
      ring-buffer: add counters for commit overrun and nmi dropped entries · f0d2c681
      Steven Rostedt 提交于
      The WARN_ON in the ring buffer when a commit is preempted and the
      buffer is filled by preceding writes can happen in normal operations.
      The WARN_ON makes it look like a bug, not to mention, because
      it does not stop tracing and calls printk which can also recurse, this
      is prone to deadlock (the WARN_ON is not in a position to recurse).
      
      This patch removes the WARN_ON and replaces it with a counter that
      can be retrieved by a tracer. This counter is called commit_overrun.
      
      While at it, I added a nmi_dropped counter to count any time an NMI entry
      is dropped because the NMI could not take the spinlock.
      
      [ Impact: prevent deadlock by printing normal case warning ]
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      f0d2c681
    • S
      ring-buffer: export symbols · d6ce96da
      Steven Rostedt 提交于
      I'm adding a module to do a series of tests on the ring buffer as well
      as benchmarks. This module needs to have more of the ring buffer API
      exported. There's nothing wrong with reading the ring buffer from a
      module.
      
      [ Impact: allow modules to read pages from the ring buffer ]
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      d6ce96da
  14. 29 4月, 2009 1 次提交
  15. 24 4月, 2009 1 次提交
  16. 21 4月, 2009 2 次提交
    • S
      ring-buffer: only warn on wrap if buffer is bigger than two pages · 3554228d
      Steven Rostedt 提交于
      On boot up, to save memory, ftrace allocates the minimum buffer
      which is two pages. Ftrace also goes through a series of tests
      (when configured) on boot up. These tests can fill up a page within
      a single interrupt.
      
      The ring buffer also has a WARN_ON when it detects that the buffer was
      completely filled within a single commit (other commits are allowed to
      be nested).
      
      Combine the small buffer on start up, with the tests that can fill more
      than a single page within an interrupt, this can trigger the WARN_ON.
      
      This patch makes the WARN_ON only happen when the ring buffer consists
      of more than two pages.
      
      [ Impact: prevent false WARN_ON in ftrace startup tests ]
      Reported-by: NIngo Molnar <mingo@elte.hu>
      LKML-Reference: <20090421094616.GA14561@elte.hu>
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      3554228d
    • S
      tracing: use recursive counter over irq level · aa18efb2
      Steven Rostedt 提交于
      Althought using the irq level (hardirq_count, softirq_count and in_nmi)
      was nice to detect bad recursion right away, but since the counters are
      not atomically updated with respect to the interrupts, the function tracer
      might trigger the test from an interrupt handler before the hardirq_count
      is updated. This will trigger a false warning.
      
      This patch converts the recursive detection to a simple counter.
      If the depth is greater than 16 then the recursive detection will trigger.
      16 is more than enough for any nested interrupts.
      
      [ Impact: fix false positive trace recursion detection ]
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      aa18efb2