From b6155a916c35bfa4c4e5d49c52072e12c3daebba Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 17 May 2016 21:24:46 -0400 Subject: [PATCH] Fix: flush empty packets on snapshot channel Snapshot operation on a non-stopped stream should use a "final" flush to ensure empty packets are flushed, so we gather timestamps at the moment where the snapshot is taken. This is important for streams that have a low amount of activity. Signed-off-by: Mathieu Desnoyers --- lib/ringbuffer/ring_buffer_frontend.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/ringbuffer/ring_buffer_frontend.c b/lib/ringbuffer/ring_buffer_frontend.c index 42cf317a..708bc6d3 100644 --- a/lib/ringbuffer/ring_buffer_frontend.c +++ b/lib/ringbuffer/ring_buffer_frontend.c @@ -900,6 +900,15 @@ int lib_ring_buffer_snapshot(struct lib_ring_buffer *buf, unsigned long consumed_cur, write_offset; int finalized; + /* + * First, ensure we perform a "final" flush onto the stream. This will + * ensure we create a packet of padding if we encounter an empty + * packet. This ensures the time-stamps right before the snapshot is + * used as end of packet timestamp. + */ + if (!buf->quiescent) + _lib_ring_buffer_switch_remote(buf, SWITCH_FLUSH); + retry: finalized = ACCESS_ONCE(buf->finalized); /* @@ -1289,7 +1298,8 @@ void lib_ring_buffer_print_errors(struct channel *chan, /* * lib_ring_buffer_switch_old_start: Populate old subbuffer header. * - * Only executed when the buffer is finalized, in SWITCH_FLUSH. + * Only executed by SWITCH_FLUSH, which can be issued while tracing is active + * or at buffer finalization (destroy). */ static void lib_ring_buffer_switch_old_start(struct lib_ring_buffer *buf, @@ -1480,12 +1490,14 @@ int lib_ring_buffer_try_switch_slow(enum switch_mode mode, unsigned long sb_index, commit_count; /* - * We are performing a SWITCH_FLUSH. At this stage, there are no - * concurrent writes into the buffer. + * We are performing a SWITCH_FLUSH. There may be concurrent + * writes into the buffer if e.g. invoked while performing a + * snapshot on an active trace. * - * The client does not save any header information. Don't - * switch empty subbuffer on finalize, because it is invalid to - * deliver a completely empty subbuffer. + * If the client does not save any header information (sub-buffer + * header size == 0), don't switch empty subbuffer on finalize, + * because it is invalid to deliver a completely empty + * subbuffer. */ if (!config->cb.subbuffer_header_size()) return -1; -- 2.34.1