@@ -180,6 +180,7 @@ unsigned long ring_buffer_overrun_cpu(struct trace_buffer *buffer, int cpu);
unsigned long ring_buffer_commit_overrun_cpu(struct trace_buffer *buffer, int cpu);
unsigned long ring_buffer_dropped_events_cpu(struct trace_buffer *buffer, int cpu);
unsigned long ring_buffer_read_events_cpu(struct trace_buffer *buffer, int cpu);
+unsigned long ring_buffer_writer_loops(struct trace_buffer *buffer, int cpu);
u64 ring_buffer_time_stamp(struct trace_buffer *buffer);
void ring_buffer_normalize_time_stamp(struct trace_buffer *buffer,
@@ -474,6 +474,7 @@ struct ring_buffer_per_cpu {
local_t pages_touched;
local_t pages_lost;
local_t pages_read;
+ local_t writer_loops;
long last_pages_touch;
size_t shortest_full;
unsigned long read;
@@ -3483,8 +3484,10 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
/*B*/ rb_time_set(&cpu_buffer->before_stamp, info->ts);
- /*C*/ if (!local_try_cmpxchg(&tail_page->write, &w, w + info->length))
+ /*C*/ if (!local_try_cmpxchg(&tail_page->write, &w, w + info->length)) {
+ local_inc(&cpu_buffer->writer_loops);
goto again;
+ }
/* Set write to the start of this event */
write = w & RB_WRITE_MASK;
@@ -4062,6 +4065,22 @@ u64 ring_buffer_oldest_event_ts(struct trace_buffer *buffer, int cpu)
}
EXPORT_SYMBOL_GPL(ring_buffer_oldest_event_ts);
+/**
+ * ring_buffer_writer_loops - get the number of times writer failed cmpxchg
+ * @buffer: The ring buffer
+ * @cpu: The per CPU buffer to read from.
+ */
+unsigned long ring_buffer_writer_loops(struct trace_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+
+ if (!cpumask_test_cpu(cpu, buffer->cpumask))
+ return 0;
+
+ cpu_buffer = buffer->buffers[cpu];
+ return local_read(&cpu_buffer->writer_loops);
+}
+
/**
* ring_buffer_bytes_cpu - get the number of bytes unconsumed in a cpu buffer
* @buffer: The ring buffer
@@ -5145,6 +5164,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
local_set(&cpu_buffer->pages_touched, 0);
local_set(&cpu_buffer->pages_lost, 0);
local_set(&cpu_buffer->pages_read, 0);
+ local_set(&cpu_buffer->writer_loops, 0);
cpu_buffer->last_pages_touch = 0;
cpu_buffer->shortest_full = 0;
cpu_buffer->read = 0;
@@ -8670,6 +8670,9 @@ tracing_stats_read(struct file *filp, char __user *ubuf,
cnt = ring_buffer_read_events_cpu(trace_buf->buffer, cpu);
trace_seq_printf(s, "read events: %ld\n", cnt);
+ cnt = ring_buffer_writer_loops(trace_buf->buffer, cpu);
+ trace_seq_printf(s, "writer loops: %ld\n", cnt);
+
count = simple_read_from_buffer(ubuf, count, ppos,
s->buffer, trace_seq_used(s));