From 4dce5a4879ae1989d091f6969b143a41ba76ba1f Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Thu, 4 May 2017 17:25:21 -0400 Subject: [PATCH] Add RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS command MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit There is no need to bump the LTTNG_MODULES_ABI_MINOR_VERSION since the multiple wildcard feature introduced as part of the 2.10 release already bumps it from 2 to 3. Signed-off-by: Jérémie Galarneau Signed-off-by: Mathieu Desnoyers --- lib/ringbuffer/frontend.h | 4 ++++ lib/ringbuffer/ring_buffer_frontend.c | 31 +++++++++++++++++++++++++++ lib/ringbuffer/ring_buffer_vfs.c | 6 ++++++ lib/ringbuffer/vfs.h | 13 +++++++++++ 4 files changed, 54 insertions(+) diff --git a/lib/ringbuffer/frontend.h b/lib/ringbuffer/frontend.h index 6ff15452..909abc2d 100644 --- a/lib/ringbuffer/frontend.h +++ b/lib/ringbuffer/frontend.h @@ -106,6 +106,10 @@ extern void lib_ring_buffer_release_read(struct lib_ring_buffer *buf); extern int lib_ring_buffer_snapshot(struct lib_ring_buffer *buf, unsigned long *consumed, unsigned long *produced); +extern int lib_ring_buffer_snapshot_sample_positions( + struct lib_ring_buffer *buf, + unsigned long *consumed, + unsigned long *produced); extern void lib_ring_buffer_move_consumer(struct lib_ring_buffer *buf, unsigned long consumed_new); diff --git a/lib/ringbuffer/ring_buffer_frontend.c b/lib/ringbuffer/ring_buffer_frontend.c index 68b62382..a477832e 100644 --- a/lib/ringbuffer/ring_buffer_frontend.c +++ b/lib/ringbuffer/ring_buffer_frontend.c @@ -1119,6 +1119,37 @@ nodata: } EXPORT_SYMBOL_GPL(lib_ring_buffer_snapshot); +/** + * Performs the same function as lib_ring_buffer_snapshot(), but the positions + * are saved regardless of whether the consumed and produced positions are + * in the same subbuffer. + * @buf: ring buffer + * @consumed: consumed byte count indicating the last position read + * @produced: produced byte count indicating the last position written + * + * This function is meant to provide information on the exact producer and + * consumer positions without regard for the "snapshot" feature. + */ +int lib_ring_buffer_snapshot_sample_positions(struct lib_ring_buffer *buf, + unsigned long *consumed, unsigned long *produced) +{ + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = &chan->backend.config; + + smp_rmb(); + *consumed = atomic_long_read(&buf->consumed); + /* + * No need to issue a memory barrier between consumed count read and + * write offset read, because consumed count can only change + * concurrently in overwrite mode, and we keep a sequence counter + * identifier derived from the write offset to check we are getting + * the same sub-buffer we are expecting (the sub-buffers are atomically + * "tagged" upon writes, tags are checked upon read). + */ + *produced = v_read(config, &buf->offset); + return 0; +} + /** * lib_ring_buffer_put_snapshot - move consumed counter forward * diff --git a/lib/ringbuffer/ring_buffer_vfs.c b/lib/ringbuffer/ring_buffer_vfs.c index 15da212d..274e976c 100644 --- a/lib/ringbuffer/ring_buffer_vfs.c +++ b/lib/ringbuffer/ring_buffer_vfs.c @@ -202,6 +202,9 @@ long lib_ring_buffer_ioctl(struct file *filp, unsigned int cmd, lib_ring_buffer_switch_remote_empty(buf); return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot, &buf->prod_snapshot); + case RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS: + return lib_ring_buffer_snapshot_sample_positions(buf, + &buf->cons_snapshot, &buf->prod_snapshot); case RING_BUFFER_SNAPSHOT_GET_CONSUMED: return put_ulong(buf->cons_snapshot, arg); case RING_BUFFER_SNAPSHOT_GET_PRODUCED: @@ -340,6 +343,9 @@ long lib_ring_buffer_compat_ioctl(struct file *filp, unsigned int cmd, lib_ring_buffer_switch_remote_empty(buf); return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot, &buf->prod_snapshot); + case RING_BUFFER_COMPAT_SNAPSHOT_SAMPLE_POSITIONS: + return lib_ring_buffer_snapshot_sample_positions(buf, + &buf->cons_snapshot, &buf->prod_snapshot); case RING_BUFFER_COMPAT_SNAPSHOT_GET_CONSUMED: return compat_put_ulong(buf->cons_snapshot, arg); case RING_BUFFER_COMPAT_SNAPSHOT_GET_PRODUCED: diff --git a/lib/ringbuffer/vfs.h b/lib/ringbuffer/vfs.h index 5444a4b2..204c57a8 100644 --- a/lib/ringbuffer/vfs.h +++ b/lib/ringbuffer/vfs.h @@ -115,6 +115,12 @@ ssize_t vfs_lib_ring_buffer_splice_read(struct file *in, loff_t *ppos, #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) +/* + * Get a snapshot of the current ring buffer producer and consumer positions, + * regardless of whether or not the two positions are contained within the same + * sub-buffer. + */ +#define RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS _IO(0xF6, 0x0E) #ifdef CONFIG_COMPAT /* Get a snapshot of the current ring buffer producer and consumer positions */ @@ -149,6 +155,13 @@ ssize_t vfs_lib_ring_buffer_splice_read(struct file *in, loff_t *ppos, #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 +/* + * Get a snapshot of the current ring buffer producer and consumer positions, + * regardless of whether or not the two positions are contained within the same + * sub-buffer. + */ +#define RING_BUFFER_COMPAT_SNAPSHOT_SAMPLE_POSITIONS \ + RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS #endif /* CONFIG_COMPAT */ #endif /* _LIB_RING_BUFFER_VFS_H */ -- 2.34.1