Fix: add "flush empty" ioctl for stream intersection
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 11 May 2017 20:50:50 +0000 (16:50 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 11 May 2017 21:47:52 +0000 (17:47 -0400)
Changing the behavior of the "snapshot" lttng command to implicitly do a
buffer "flush" (even when current packet is empty) had unwanted
side-effects: for instance, the snapshot ABI is used by the live timer
to grab the buffer positions, and we don't want to generate useless
empty packets in that scenario.

Therefore, add the "flush empty" behavior as a new ioctl to the ring
buffer. This allows lttng-tools to perform buffer flush (even for empty
packets) when it needs to. Given that this new ioctl is added within
stable branches as well, lttng-tools always need to handle "-ENOSYS"
gracefully.

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
lib/ringbuffer/vfs.h
lttng-abi.c

index 3a229ff8f9b6e73d16fcb60e4b7124728033d01f..f143ecae462df68f2823387962ea27388ed1f603 100644 (file)
@@ -167,6 +167,8 @@ void lib_ring_buffer_check_deliver_slow(const struct lib_ring_buffer_config *con
 
 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 */
 
index 8257dcc63867410291d2dd7bf07ab176449edc3b..3d2e400dc437ae0cbe66cb299021c6cb8483b53c 100644 (file)
@@ -1861,12 +1861,20 @@ static void _lib_ring_buffer_switch_remote(struct lib_ring_buffer *buf,
        put_online_cpus();
 }
 
+/* Switch sub-buffer if current sub-buffer is non-empty. */
 void lib_ring_buffer_switch_remote(struct lib_ring_buffer *buf)
 {
        _lib_ring_buffer_switch_remote(buf, SWITCH_ACTIVE);
 }
 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
index b4e18aaf9a9557f56ccc6704f177dac6421e508e..97be835655a8c0f665526f8471aa1030e140b561 100644 (file)
@@ -273,6 +273,9 @@ long lib_ring_buffer_ioctl(struct file *filp, unsigned int cmd,
        case RING_BUFFER_FLUSH:
                lib_ring_buffer_switch_remote(buf);
                return 0;
+       case RING_BUFFER_FLUSH_EMPTY:
+               lib_ring_buffer_switch_remote_empty(buf);
+               return 0;
        default:
                return -ENOIOCTLCMD;
        }
@@ -421,6 +424,9 @@ long lib_ring_buffer_compat_ioctl(struct file *filp, unsigned int cmd,
        case RING_BUFFER_COMPAT_FLUSH:
                lib_ring_buffer_switch_remote(buf);
                return 0;
+       case RING_BUFFER_COMPAT_FLUSH_EMPTY:
+               lib_ring_buffer_switch_remote_empty(buf);
+               return 0;
        default:
                return -ENOIOCTLCMD;
        }
index 204c57a81f6e9c11e968c1609c675551c02cb791..b2e5b1c84810a606b4368a84673bc8dca410ccb6 100644 (file)
@@ -111,7 +111,7 @@ ssize_t vfs_lib_ring_buffer_splice_read(struct file *in, loff_t *ppos,
 #define RING_BUFFER_GET_MMAP_LEN               _IOR(0xF6, 0x0A, unsigned long)
 /* returns the offset of the subbuffer belonging to the mmap reader. */
 #define RING_BUFFER_GET_MMAP_READ_OFFSET       _IOR(0xF6, 0x0B, unsigned long)
-/* flush the current sub-buffer */
+/* Flush the current sub-buffer, if non-empty. */
 #define RING_BUFFER_FLUSH                      _IO(0xF6, 0x0C)
 /* Get the current version of the metadata cache (after a get_next). */
 #define RING_BUFFER_GET_METADATA_VERSION       _IOR(0xF6, 0x0D, uint64_t)
@@ -121,6 +121,8 @@ ssize_t vfs_lib_ring_buffer_splice_read(struct file *in, loff_t *ppos,
  * sub-buffer.
  */
 #define RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS  _IO(0xF6, 0x0E)
+/* Flush the current sub-buffer, even if empty. */
+#define RING_BUFFER_FLUSH_EMPTY                        _IO(0xF6, 0x0F)
 
 #ifdef CONFIG_COMPAT
 /* Get a snapshot of the current ring buffer producer and consumer positions */
@@ -151,7 +153,7 @@ ssize_t vfs_lib_ring_buffer_splice_read(struct file *in, loff_t *ppos,
 #define RING_BUFFER_COMPAT_GET_MMAP_LEN                _IOR(0xF6, 0x0A, compat_ulong_t)
 /* returns the offset of the subbuffer belonging to the mmap reader. */
 #define RING_BUFFER_COMPAT_GET_MMAP_READ_OFFSET        _IOR(0xF6, 0x0B, compat_ulong_t)
-/* flush the current sub-buffer */
+/* Flush the current sub-buffer, if non-empty. */
 #define RING_BUFFER_COMPAT_FLUSH               RING_BUFFER_FLUSH
 /* Get the current version of the metadata cache (after a get_next). */
 #define RING_BUFFER_COMPAT_GET_METADATA_VERSION        RING_BUFFER_GET_METADATA_VERSION
@@ -162,6 +164,9 @@ ssize_t vfs_lib_ring_buffer_splice_read(struct file *in, loff_t *ppos,
  */
 #define RING_BUFFER_COMPAT_SNAPSHOT_SAMPLE_POSITIONS   \
        RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS
+/* Flush the current sub-buffer, even if empty. */
+#define RING_BUFFER_COMPAT_FLUSH_EMPTY                 \
+       RING_BUFFER_FLUSH_EMPTY
 #endif /* CONFIG_COMPAT */
 
 #endif /* _LIB_RING_BUFFER_VFS_H */
index ab1e832b6ca6d2688a7cace9667615f33d4fe304..77e5e9859e7f51099964f4002b932faf98531984 100644 (file)
@@ -684,6 +684,7 @@ long lttng_metadata_ring_buffer_ioctl(struct file *filp,
                 */
                return -ENOSYS;
        }
+       case RING_BUFFER_FLUSH_EMPTY:   /* Fall-through. */
        case RING_BUFFER_FLUSH:
        {
                struct lttng_metadata_stream *stream = filp->private_data;
@@ -760,6 +761,7 @@ long lttng_metadata_ring_buffer_compat_ioctl(struct file *filp,
                 */
                return -ENOSYS;
        }
+       case RING_BUFFER_FLUSH_EMPTY:   /* Fall-through. */
        case RING_BUFFER_FLUSH:
        {
                struct lttng_metadata_stream *stream = filp->private_data;
This page took 0.029104 seconds and 4 git commands to generate.