From 7cf44d034bdda1896f6b0c6374c90c06d45ee4fd Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 19 May 2016 20:30:07 -0400 Subject: [PATCH] Fix: don't perform extra flush on metadata channel The metadata channel requires that the LTTng client layer and the ring buffer keep a notion of the amount of data produced in the channel. This issue has been introduced recently by commit "Fix: flush empty packets on snapshot channel". Signed-off-by: Mathieu Desnoyers --- lib/ringbuffer/frontend_internal.h | 3 +++ lib/ringbuffer/ring_buffer_frontend.c | 16 +++++++--------- lib/ringbuffer/ring_buffer_vfs.c | 18 ++++++++++++++++++ lttng-abi.c | 24 ++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/lib/ringbuffer/frontend_internal.h b/lib/ringbuffer/frontend_internal.h index b13edd10..76bf20e7 100644 --- a/lib/ringbuffer/frontend_internal.h +++ b/lib/ringbuffer/frontend_internal.h @@ -159,6 +159,9 @@ void lib_ring_buffer_switch_slow(struct lib_ring_buffer *buf, extern void lib_ring_buffer_switch_remote(struct lib_ring_buffer *buf); +extern +void lib_ring_buffer_switch_remote_empty(struct lib_ring_buffer *buf); + /* Buffer write helpers */ static inline diff --git a/lib/ringbuffer/ring_buffer_frontend.c b/lib/ringbuffer/ring_buffer_frontend.c index 017d30f5..9cd62ced 100644 --- a/lib/ringbuffer/ring_buffer_frontend.c +++ b/lib/ringbuffer/ring_buffer_frontend.c @@ -904,15 +904,6 @@ 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); /* @@ -1663,6 +1654,13 @@ void lib_ring_buffer_switch_remote(struct lib_ring_buffer *buf) } EXPORT_SYMBOL_GPL(lib_ring_buffer_switch_remote); +/* Switch sub-buffer even if current sub-buffer is empty. */ +void lib_ring_buffer_switch_remote_empty(struct lib_ring_buffer *buf) +{ + _lib_ring_buffer_switch_remote(buf, SWITCH_FLUSH); +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_switch_remote_empty); + /* * Returns : * 0 if ok diff --git a/lib/ringbuffer/ring_buffer_vfs.c b/lib/ringbuffer/ring_buffer_vfs.c index f1a8bab7..15da212d 100644 --- a/lib/ringbuffer/ring_buffer_vfs.c +++ b/lib/ringbuffer/ring_buffer_vfs.c @@ -191,6 +191,15 @@ long lib_ring_buffer_ioctl(struct file *filp, unsigned int cmd, switch (cmd) { case RING_BUFFER_SNAPSHOT: + /* + * 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_empty(buf); return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot, &buf->prod_snapshot); case RING_BUFFER_SNAPSHOT_GET_CONSUMED: @@ -320,6 +329,15 @@ long lib_ring_buffer_compat_ioctl(struct file *filp, unsigned int cmd, switch (cmd) { case RING_BUFFER_COMPAT_SNAPSHOT: + /* + * 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_empty(buf); return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot, &buf->prod_snapshot); case RING_BUFFER_COMPAT_SNAPSHOT_GET_CONSUMED: diff --git a/lttng-abi.c b/lttng-abi.c index 87465189..4dd9273f 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -702,6 +702,18 @@ long lttng_metadata_ring_buffer_ioctl(struct file *filp, return put_u64(stream->version, arg); } + case RING_BUFFER_SNAPSHOT: + { + /* + * Force the buffer to quiescent so the ring buffer + * don't attempt to perform a SWITCH_FLUSH, which would + * desynchronize the client accounting of the amount of + * data available in the buffer from the ring buffer + * view. + */ + buf->quiescent = true; + break; + } default: break; } @@ -778,6 +790,18 @@ long lttng_metadata_ring_buffer_compat_ioctl(struct file *filp, return put_u64(stream->version, arg); } + case RING_BUFFER_SNAPSHOT: + { + /* + * Force the buffer to quiescent so the ring buffer + * don't attempt to perform a SWITCH_FLUSH, which would + * desynchronize the client accounting of the amount of + * data available in the buffer from the ring buffer + * view. + */ + buf->quiescent = true; + break; + } default: break; } -- 2.34.1