Skip to content

Commit

Permalink
Fix: add "flush empty" ioctl for stream intersection
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
compudj committed May 11, 2017
1 parent 6140ad9 commit c6f0546
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 2 deletions.
2 changes: 2 additions & 0 deletions lib/ringbuffer/frontend_internal.h
Expand Up @@ -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 */

Expand Down
8 changes: 8 additions & 0 deletions lib/ringbuffer/ring_buffer_frontend.c
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions lib/ringbuffer/ring_buffer_vfs.c
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
9 changes: 7 additions & 2 deletions lib/ringbuffer/vfs.h
Expand Up @@ -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)
Expand All @@ -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 */
Expand Down Expand Up @@ -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
Expand All @@ -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 */
2 changes: 2 additions & 0 deletions lttng-abi.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit c6f0546

Please sign in to comment.