Fix: ring buffer: RING_BUFFER_FLUSH ioctl buffer corruption
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sun, 30 Jun 2013 19:37:46 +0000 (15:37 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sun, 30 Jun 2013 21:50:47 +0000 (17:50 -0400)
commit8dfa3bb8897b8d9ac9b7ea33bebb7dad61b32d44
tree18d2de9ac06f19a1da8661001c4e03c0d27f6ac2
parent21b2893a417624ba661d0100e8ffac6de1acce40
Fix: ring buffer: RING_BUFFER_FLUSH ioctl buffer corruption

lib_ring_buffer_switch_slow() clearly states:

 * Note, however, that as a v_cmpxchg is used for some atomic
 * operations, this function must be called from the CPU which owns the
 * buffer for a ACTIVE flush.

But unfortunately, the RING_BUFFER_FLUSH ioctl does not follow these
important directives. Therefore, whenever the consumer daemon or session
daemon explicitly triggers a "flush" on a buffer, it can race with data
being written to the buffer, leading to corruption of the reserve/commit
counters, and therefore corruption of data in the buffer. It triggers
these warnings for overwrite mode buffers:

[65356.890016] WARNING: at
/home/compudj/git/lttng-modules/wrapper/ringbuffer/../../lib/ringbuffer/../../wrapper/ringbuffer/../../lib/ringbuffer/backend.h:110 lttng_event_write+0x118/0x140 [lttng_ring_buffer_client_mmap_overwrite]()

Which indicates that we are trying to write into a sub-buffer for which
we don't have exclusive access. It also causes the following warnings to
show up:

[65335.896208] ring buffer relay-overwrite-mmap, cpu 5: records were lost. Caused by:
[65335.896208]   [ 0 buffer full, 80910 nest buffer wrap-around, 0 event too big ]

Which is caused by corrupted commit counter.

Fix this by sending an IPI to the CPU owning the flushed buffer for
per-cpu synchronization. For global synchronization, no IPI is needed,
since we allow writes from remote CPUs.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lib/ringbuffer/frontend_internal.h
lib/ringbuffer/ring_buffer_frontend.c
lib/ringbuffer/ring_buffer_vfs.c
This page took 0.025879 seconds and 4 git commands to generate.