aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ring_buffer.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-04-30 20:49:44 -0400
committerSteven Rostedt <rostedt@goodmis.org>2009-05-05 14:25:44 -0400
commite4906eff9e6fbd2d311abcbcc53d5a531773c982 (patch)
tree05dd56b9336e7059cca3b651d542cc4b8bc2220b /kernel/trace/ring_buffer.c
parentc8d771835e18c938dae8690611d65fe98ad30f58 (diff)
ring-buffer: convert cpu buffer entries to local_t
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: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/ring_buffer.c')
-rw-r--r--kernel/trace/ring_buffer.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 26e1359fe193..c792ea893b01 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -405,7 +405,8 @@ struct ring_buffer_per_cpu {
405 unsigned long nmi_dropped; 405 unsigned long nmi_dropped;
406 unsigned long commit_overrun; 406 unsigned long commit_overrun;
407 unsigned long overrun; 407 unsigned long overrun;
408 unsigned long entries; 408 unsigned long read;
409 local_t entries;
409 u64 write_stamp; 410 u64 write_stamp;
410 u64 read_stamp; 411 u64 read_stamp;
411 atomic_t record_disabled; 412 atomic_t record_disabled;
@@ -997,7 +998,6 @@ static void rb_update_overflow(struct ring_buffer_per_cpu *cpu_buffer)
997 if (event->type_len > RINGBUF_TYPE_DATA_TYPE_LEN_MAX) 998 if (event->type_len > RINGBUF_TYPE_DATA_TYPE_LEN_MAX)
998 continue; 999 continue;
999 cpu_buffer->overrun++; 1000 cpu_buffer->overrun++;
1000 cpu_buffer->entries--;
1001 } 1001 }
1002} 1002}
1003 1003
@@ -1588,7 +1588,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_lock_reserve);
1588static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer, 1588static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer,
1589 struct ring_buffer_event *event) 1589 struct ring_buffer_event *event)
1590{ 1590{
1591 cpu_buffer->entries++; 1591 local_inc(&cpu_buffer->entries);
1592 1592
1593 /* Only process further if we own the commit */ 1593 /* Only process further if we own the commit */
1594 if (!rb_is_commit(cpu_buffer, event)) 1594 if (!rb_is_commit(cpu_buffer, event))
@@ -1722,7 +1722,7 @@ void ring_buffer_discard_commit(struct ring_buffer *buffer,
1722 * The commit is still visible by the reader, so we 1722 * The commit is still visible by the reader, so we
1723 * must increment entries. 1723 * must increment entries.
1724 */ 1724 */
1725 cpu_buffer->entries++; 1725 local_inc(&cpu_buffer->entries);
1726 out: 1726 out:
1727 /* 1727 /*
1728 * If a write came in and pushed the tail page 1728 * If a write came in and pushed the tail page
@@ -1902,7 +1902,8 @@ unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu)
1902 return 0; 1902 return 0;
1903 1903
1904 cpu_buffer = buffer->buffers[cpu]; 1904 cpu_buffer = buffer->buffers[cpu];
1905 ret = cpu_buffer->entries; 1905 ret = (local_read(&cpu_buffer->entries) - cpu_buffer->overrun)
1906 - cpu_buffer->read;
1906 1907
1907 return ret; 1908 return ret;
1908} 1909}
@@ -1985,7 +1986,8 @@ unsigned long ring_buffer_entries(struct ring_buffer *buffer)
1985 /* if you care about this being correct, lock the buffer */ 1986 /* if you care about this being correct, lock the buffer */
1986 for_each_buffer_cpu(buffer, cpu) { 1987 for_each_buffer_cpu(buffer, cpu) {
1987 cpu_buffer = buffer->buffers[cpu]; 1988 cpu_buffer = buffer->buffers[cpu];
1988 entries += cpu_buffer->entries; 1989 entries += (local_read(&cpu_buffer->entries) -
1990 cpu_buffer->overrun) - cpu_buffer->read;
1989 } 1991 }
1990 1992
1991 return entries; 1993 return entries;
@@ -2225,7 +2227,7 @@ static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer)
2225 2227
2226 if (event->type_len <= RINGBUF_TYPE_DATA_TYPE_LEN_MAX 2228 if (event->type_len <= RINGBUF_TYPE_DATA_TYPE_LEN_MAX
2227 || rb_discarded_event(event)) 2229 || rb_discarded_event(event))
2228 cpu_buffer->entries--; 2230 cpu_buffer->read++;
2229 2231
2230 rb_update_read_stamp(cpu_buffer, event); 2232 rb_update_read_stamp(cpu_buffer, event);
2231 2233
@@ -2642,7 +2644,8 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
2642 cpu_buffer->nmi_dropped = 0; 2644 cpu_buffer->nmi_dropped = 0;
2643 cpu_buffer->commit_overrun = 0; 2645 cpu_buffer->commit_overrun = 0;
2644 cpu_buffer->overrun = 0; 2646 cpu_buffer->overrun = 0;
2645 cpu_buffer->entries = 0; 2647 cpu_buffer->read = 0;
2648 local_set(&cpu_buffer->entries, 0);
2646 2649
2647 cpu_buffer->write_stamp = 0; 2650 cpu_buffer->write_stamp = 0;
2648 cpu_buffer->read_stamp = 0; 2651 cpu_buffer->read_stamp = 0;
@@ -2813,7 +2816,7 @@ static void rb_remove_entries(struct ring_buffer_per_cpu *cpu_buffer,
2813 /* Only count data entries */ 2816 /* Only count data entries */
2814 if (event->type_len > RINGBUF_TYPE_DATA_TYPE_LEN_MAX) 2817 if (event->type_len > RINGBUF_TYPE_DATA_TYPE_LEN_MAX)
2815 continue; 2818 continue;
2816 cpu_buffer->entries--; 2819 cpu_buffer->read++;
2817 } 2820 }
2818 __raw_spin_unlock(&cpu_buffer->lock); 2821 __raw_spin_unlock(&cpu_buffer->lock);
2819} 2822}