Skip to content

Commit 4ce97db

Browse files
Josef Bacikrostedt
authored andcommitted
trace: Fix epoll hang when we race with new entries
Epoll on trace_pipe can sometimes hang in a weird case. If the ring buffer is empty when we set waiters_pending but an event shows up exactly at that moment we can miss being woken up by the ring buffers irq work. Since ring_buffer_empty() is inherently racey we will sometimes think that the buffer is not empty. So we don't get woken up and we don't think there are any events even though there were some ready when we added the watch, which makes us hang. This patch fixes this by making sure that we are actually on the wait list before we set waiters_pending, and add a memory barrier to make sure ring_buffer_empty() is going to be correct. Link: http://lkml.kernel.org/p/[email protected] Cc: [email protected] # 3.10+ Cc: Martin Lau <[email protected]> Signed-off-by: Josef Bacik <[email protected]> Signed-off-by: Steven Rostedt <[email protected]>
1 parent 39b5552 commit 4ce97db

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

kernel/trace/ring_buffer.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,8 +626,22 @@ int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,
626626
work = &cpu_buffer->irq_work;
627627
}
628628

629-
work->waiters_pending = true;
630629
poll_wait(filp, &work->waiters, poll_table);
630+
work->waiters_pending = true;
631+
/*
632+
* There's a tight race between setting the waiters_pending and
633+
* checking if the ring buffer is empty. Once the waiters_pending bit
634+
* is set, the next event will wake the task up, but we can get stuck
635+
* if there's only a single event in.
636+
*
637+
* FIXME: Ideally, we need a memory barrier on the writer side as well,
638+
* but adding a memory barrier to all events will cause too much of a
639+
* performance hit in the fast path. We only need a memory barrier when
640+
* the buffer goes from empty to having content. But as this race is
641+
* extremely small, and it's not a problem if another event comes in, we
642+
* will fix it later.
643+
*/
644+
smp_mb();
631645

632646
if ((cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) ||
633647
(cpu != RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu(buffer, cpu)))

0 commit comments

Comments
 (0)