From: Mathieu Desnoyers Date: Wed, 17 Mar 2021 18:10:38 +0000 (-0400) Subject: Refactoring: Privatize ring buffer config header X-Git-Tag: v2.13.0-rc1~262 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=0466ac28c41336fd6d373cc8b0b26ef132225b9f;p=lttng-ust.git Refactoring: Privatize ring buffer config header The public header ringbuffer-config.h contains two distinct sets of APIs and structure declarations: - Ring buffer configuration, which should become private (moved to libringbuffer/ringbuffer-config.h), - Ring buffer context for use when writing an event record into the ring buffer. This part is moved to a new "ringbuffer-context.h" public header. Signed-off-by: Mathieu Desnoyers Change-Id: I07dae33ab5e3925dea0158058d484c49292a0bb0 --- diff --git a/include/Makefile.am b/include/Makefile.am index 0dd7cf39..8c741b06 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -21,7 +21,7 @@ nobase_include_HEADERS = \ lttng/ust-compiler.h \ lttng/ust.h \ lttng/ust-endian.h \ - lttng/ringbuffer-config.h \ + lttng/ringbuffer-context.h \ lttng/align.h \ lttng/bug.h \ lttng/ust-error.h \ diff --git a/include/lttng/ringbuffer-config.h b/include/lttng/ringbuffer-config.h deleted file mode 100644 index 00f655e5..00000000 --- a/include/lttng/ringbuffer-config.h +++ /dev/null @@ -1,372 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright (C) 2010 Mathieu Desnoyers - * - * Ring buffer configuration header. Note: after declaring the standard inline - * functions, clients should also include linux/ringbuffer/api.h. - */ - -#ifndef _LTTNG_RING_BUFFER_CONFIG_H -#define _LTTNG_RING_BUFFER_CONFIG_H - -#include -#include "lttng/ust-tracer.h" -#include -#include -#include -#include -#include "lttng/align.h" -#include - -struct lttng_ust_lib_ring_buffer; -struct lttng_ust_lib_ring_buffer_channel; -struct lttng_ust_lib_ring_buffer_config; -struct lttng_ust_lib_ring_buffer_ctx; -struct lttng_ust_shm_handle; - -/* - * Ring buffer client callbacks. Only used by slow path, never on fast path. - * For the fast path, record_header_size(), ring_buffer_clock_read() should be - * provided as inline functions too. These may simply return 0 if not used by - * the client. - */ -struct lttng_ust_lib_ring_buffer_client_cb { - /* Mandatory callbacks */ - - /* A static inline version is also required for fast path */ - uint64_t (*ring_buffer_clock_read) (struct lttng_ust_lib_ring_buffer_channel *chan); - size_t (*record_header_size) (const struct lttng_ust_lib_ring_buffer_config *config, - struct lttng_ust_lib_ring_buffer_channel *chan, - size_t offset, - size_t *pre_header_padding, - struct lttng_ust_lib_ring_buffer_ctx *ctx, - void *client_ctx); - - /* Slow path only, at subbuffer switch */ - size_t (*subbuffer_header_size) (void); - void (*buffer_begin) (struct lttng_ust_lib_ring_buffer *buf, uint64_t tsc, - unsigned int subbuf_idx, - struct lttng_ust_shm_handle *handle); - void (*buffer_end) (struct lttng_ust_lib_ring_buffer *buf, uint64_t tsc, - unsigned int subbuf_idx, unsigned long data_size, - struct lttng_ust_shm_handle *handle); - - /* Optional callbacks (can be set to NULL) */ - - /* Called at buffer creation/finalize */ - int (*buffer_create) (struct lttng_ust_lib_ring_buffer *buf, void *priv, - int cpu, const char *name, - struct lttng_ust_shm_handle *handle); - /* - * Clients should guarantee that no new reader handle can be opened - * after finalize. - */ - void (*buffer_finalize) (struct lttng_ust_lib_ring_buffer *buf, - void *priv, int cpu, - struct lttng_ust_shm_handle *handle); - - /* - * Extract header length, payload length and timestamp from event - * record. Used by buffer iterators. Timestamp is only used by channel - * iterator. - */ - void (*record_get) (const struct lttng_ust_lib_ring_buffer_config *config, - struct lttng_ust_lib_ring_buffer_channel *chan, - struct lttng_ust_lib_ring_buffer *buf, - size_t offset, size_t *header_len, - size_t *payload_len, uint64_t *timestamp, - struct lttng_ust_shm_handle *handle); - /* - * Offset and size of content size field in client. - */ - void (*content_size_field) (const struct lttng_ust_lib_ring_buffer_config *config, - size_t *offset, size_t *length); - void (*packet_size_field) (const struct lttng_ust_lib_ring_buffer_config *config, - size_t *offset, size_t *length); -}; - -/* - * Ring buffer instance configuration. - * - * Declare as "static const" within the client object to ensure the inline fast - * paths can be optimized. - * - * alloc/sync pairs: - * - * RING_BUFFER_ALLOC_PER_CPU and RING_BUFFER_SYNC_PER_CPU : - * Per-cpu buffers with per-cpu synchronization. Tracing must be performed - * with preemption disabled (lib_ring_buffer_get_cpu() and - * lib_ring_buffer_put_cpu()). - * - * RING_BUFFER_ALLOC_PER_CPU and RING_BUFFER_SYNC_GLOBAL : - * Per-cpu buffer with global synchronization. Tracing can be performed with - * preemption enabled, statistically stays on the local buffers. - * - * RING_BUFFER_ALLOC_GLOBAL and RING_BUFFER_SYNC_PER_CPU : - * Should only be used for buffers belonging to a single thread or protected - * by mutual exclusion by the client. Note that periodical sub-buffer switch - * should be disabled in this kind of configuration. - * - * RING_BUFFER_ALLOC_GLOBAL and RING_BUFFER_SYNC_GLOBAL : - * Global shared buffer with global synchronization. - * - * wakeup: - * - * RING_BUFFER_WAKEUP_BY_TIMER uses per-cpu deferrable timers to poll the - * buffers and wake up readers if data is ready. Mainly useful for tracers which - * don't want to call into the wakeup code on the tracing path. Use in - * combination with "read_timer_interval" channel_create() argument. - * - * RING_BUFFER_WAKEUP_BY_WRITER directly wakes up readers when a subbuffer is - * ready to read. Lower latencies before the reader is woken up. Mainly suitable - * for drivers. - * - * RING_BUFFER_WAKEUP_NONE does not perform any wakeup whatsoever. The client - * has the responsibility to perform wakeups. - */ -#define LTTNG_UST_RING_BUFFER_CONFIG_PADDING 20 - -enum lttng_ust_lib_ring_buffer_alloc_types { - RING_BUFFER_ALLOC_PER_CPU, - RING_BUFFER_ALLOC_GLOBAL, -}; - -enum lttng_ust_lib_ring_buffer_sync_types { - RING_BUFFER_SYNC_PER_CPU, /* Wait-free */ - RING_BUFFER_SYNC_GLOBAL, /* Lock-free */ -}; - -enum lttng_ust_lib_ring_buffer_mode_types { - RING_BUFFER_OVERWRITE = 0, /* Overwrite when buffer full */ - RING_BUFFER_DISCARD = 1, /* Discard when buffer full */ -}; - -enum lttng_ust_lib_ring_buffer_output_types { - RING_BUFFER_SPLICE, - RING_BUFFER_MMAP, - RING_BUFFER_READ, /* TODO */ - RING_BUFFER_ITERATOR, - RING_BUFFER_NONE, -}; - -enum lttng_ust_lib_ring_buffer_backend_types { - RING_BUFFER_PAGE, - RING_BUFFER_VMAP, /* TODO */ - RING_BUFFER_STATIC, /* TODO */ -}; - -enum lttng_ust_lib_ring_buffer_oops_types { - RING_BUFFER_NO_OOPS_CONSISTENCY, - RING_BUFFER_OOPS_CONSISTENCY, -}; - -enum lttng_ust_lib_ring_buffer_ipi_types { - RING_BUFFER_IPI_BARRIER, - RING_BUFFER_NO_IPI_BARRIER, -}; - -enum lttng_ust_lib_ring_buffer_wakeup_types { - RING_BUFFER_WAKEUP_BY_TIMER, /* wake up performed by timer */ - RING_BUFFER_WAKEUP_BY_WRITER, /* - * writer wakes up reader, - * not lock-free - * (takes spinlock). - */ -}; - -struct lttng_ust_lib_ring_buffer_config { - enum lttng_ust_lib_ring_buffer_alloc_types alloc; - enum lttng_ust_lib_ring_buffer_sync_types sync; - enum lttng_ust_lib_ring_buffer_mode_types mode; - enum lttng_ust_lib_ring_buffer_output_types output; - enum lttng_ust_lib_ring_buffer_backend_types backend; - enum lttng_ust_lib_ring_buffer_oops_types oops; - enum lttng_ust_lib_ring_buffer_ipi_types ipi; - enum lttng_ust_lib_ring_buffer_wakeup_types wakeup; - /* - * tsc_bits: timestamp bits saved at each record. - * 0 and 64 disable the timestamp compression scheme. - */ - unsigned int tsc_bits; - struct lttng_ust_lib_ring_buffer_client_cb cb; - /* - * client_type is used by the consumer process (which is in a - * different address space) to lookup the appropriate client - * callbacks and update the cb pointers. - */ - int client_type; - int _unused1; - const struct lttng_ust_lib_ring_buffer_client_cb *cb_ptr; - char padding[LTTNG_UST_RING_BUFFER_CONFIG_PADDING]; -}; - -/* - * ring buffer context - * - * Context passed to lib_ring_buffer_reserve(), lib_ring_buffer_commit(), - * lib_ring_buffer_try_discard_reserve(), lib_ring_buffer_align_ctx() and - * lib_ring_buffer_write(). - * - * IMPORTANT: this structure is part of the ABI between the probe and - * UST. Fields need to be only added at the end, never reordered, never - * removed. - */ -#define LTTNG_UST_RING_BUFFER_CTX_PADDING 64 -struct lttng_ust_lib_ring_buffer_ctx { - uint32_t struct_size; /* Size of this structure. */ - - /* input received by lib_ring_buffer_reserve(), saved here. */ - struct lttng_ust_lib_ring_buffer_channel *chan; /* channel */ - void *priv; /* client private data */ - struct lttng_ust_shm_handle *handle; /* shared-memory handle */ - size_t data_size; /* size of payload */ - int largest_align; /* - * alignment of the largest element - * in the payload - */ - int cpu; /* processor id */ - - /* output from lib_ring_buffer_reserve() */ - struct lttng_ust_lib_ring_buffer *buf; /* - * buffer corresponding to processor id - * for this channel - */ - size_t slot_size; /* size of the reserved slot */ - unsigned long buf_offset; /* offset following the record header */ - unsigned long pre_offset; /* - * Initial offset position _before_ - * the record is written. Positioned - * prior to record header alignment - * padding. - */ - uint64_t tsc; /* time-stamp counter value */ - unsigned int rflags; /* reservation flags */ - void *ip; /* caller ip address */ - struct lttng_ust_lib_ring_buffer_backend_pages *backend_pages; -}; - -/** - * lib_ring_buffer_ctx_init - initialize ring buffer context - * @ctx: ring buffer context to initialize - * @chan: channel - * @priv: client private data - * @data_size: size of record data payload - * @largest_align: largest alignment within data payload types - * @cpu: processor id - */ -static inline lttng_ust_notrace -void lib_ring_buffer_ctx_init(struct lttng_ust_lib_ring_buffer_ctx *ctx, - struct lttng_ust_lib_ring_buffer_channel *chan, - void *priv, size_t data_size, int largest_align, - int cpu, struct lttng_ust_shm_handle *handle); -static inline -void lib_ring_buffer_ctx_init(struct lttng_ust_lib_ring_buffer_ctx *ctx, - struct lttng_ust_lib_ring_buffer_channel *chan, - void *priv, size_t data_size, int largest_align, - int cpu, struct lttng_ust_shm_handle *handle) -{ - ctx->struct_size = sizeof(struct lttng_ust_lib_ring_buffer_ctx); - ctx->chan = chan; - ctx->priv = priv; - ctx->data_size = data_size; - ctx->largest_align = largest_align; - ctx->cpu = cpu; - ctx->rflags = 0; - ctx->handle = handle; - ctx->ip = 0; -} - -/* - * Reservation flags. - * - * RING_BUFFER_RFLAG_FULL_TSC - * - * This flag is passed to record_header_size() and to the primitive used to - * write the record header. It indicates that the full 64-bit time value is - * needed in the record header. If this flag is not set, the record header needs - * only to contain "tsc_bits" bit of time value. - * - * Reservation flags can be added by the client, starting from - * "(RING_BUFFER_FLAGS_END << 0)". It can be used to pass information from - * record_header_size() to lib_ring_buffer_write_record_header(). - */ -#define RING_BUFFER_RFLAG_FULL_TSC (1U << 0) -#define RING_BUFFER_RFLAG_END (1U << 1) - -/* - * We need to define RING_BUFFER_ALIGN_ATTR so it is known early at - * compile-time. We have to duplicate the "config->align" information and the - * definition here because config->align is used both in the slow and fast - * paths, but RING_BUFFER_ALIGN_ATTR is only available for the client code. - */ -#ifdef RING_BUFFER_ALIGN - -# define RING_BUFFER_ALIGN_ATTR /* Default arch alignment */ - -/* - * Calculate the offset needed to align the type. - * size_of_type must be non-zero. - */ -static inline lttng_ust_notrace -unsigned int lib_ring_buffer_align(size_t align_drift, size_t size_of_type); -static inline -unsigned int lib_ring_buffer_align(size_t align_drift, size_t size_of_type) -{ - return lttng_ust_offset_align(align_drift, size_of_type); -} - -#else - -# define RING_BUFFER_ALIGN_ATTR __attribute__((packed)) - -/* - * Calculate the offset needed to align the type. - * size_of_type must be non-zero. - */ -static inline lttng_ust_notrace -unsigned int lib_ring_buffer_align(size_t align_drift, size_t size_of_type); -static inline -unsigned int lib_ring_buffer_align(size_t align_drift, size_t size_of_type) -{ - return 0; -} - -#endif - -/** - * lib_ring_buffer_align_ctx - Align context offset on "alignment" - * @ctx: ring buffer context. - */ -static inline lttng_ust_notrace -void lib_ring_buffer_align_ctx(struct lttng_ust_lib_ring_buffer_ctx *ctx, - size_t alignment); -static inline -void lib_ring_buffer_align_ctx(struct lttng_ust_lib_ring_buffer_ctx *ctx, - size_t alignment) -{ - ctx->buf_offset += lib_ring_buffer_align(ctx->buf_offset, - alignment); -} - -/* - * lib_ring_buffer_check_config() returns 0 on success. - * Used internally to check for valid configurations at channel creation. - */ -static inline lttng_ust_notrace -int lib_ring_buffer_check_config(const struct lttng_ust_lib_ring_buffer_config *config, - unsigned int switch_timer_interval, - unsigned int read_timer_interval); -static inline -int lib_ring_buffer_check_config(const struct lttng_ust_lib_ring_buffer_config *config, - unsigned int switch_timer_interval, - unsigned int read_timer_interval) -{ - if (config->alloc == RING_BUFFER_ALLOC_GLOBAL - && config->sync == RING_BUFFER_SYNC_PER_CPU - && switch_timer_interval) - return -EINVAL; - return 0; -} - -#endif /* _LTTNG_RING_BUFFER_CONFIG_H */ diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h index 5d84e0b2..50cbfbbc 100644 --- a/include/lttng/ust-tracepoint-event.h +++ b/include/lttng/ust-tracepoint-event.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/liblttng-ust/lttng-context-cgroup-ns.c b/liblttng-ust/lttng-context-cgroup-ns.c index a6741fb1..65c5306c 100644 --- a/liblttng-ust/lttng-context-cgroup-ns.c +++ b/liblttng-ust/lttng-context-cgroup-ns.c @@ -14,9 +14,9 @@ #include #include #include -#include #include #include +#include #include "context-internal.h" #include "lttng-tracer-core.h" diff --git a/liblttng-ust/lttng-context-cpu-id.c b/liblttng-ust/lttng-context-cpu-id.c index cdcfe1a1..9c553828 100644 --- a/liblttng-ust/lttng-context-cpu-id.c +++ b/liblttng-ust/lttng-context-cpu-id.c @@ -18,8 +18,8 @@ #include #include #include -#include #include "../libringbuffer/getcpu.h" +#include #include "context-internal.h" diff --git a/liblttng-ust/lttng-context-ip.c b/liblttng-ust/lttng-context-ip.c index 4b32dc39..d7a65905 100644 --- a/liblttng-ust/lttng-context-ip.c +++ b/liblttng-ust/lttng-context-ip.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "context-internal.h" diff --git a/liblttng-ust/lttng-context-ipc-ns.c b/liblttng-ust/lttng-context-ipc-ns.c index d0c4ecd6..b2c5e27d 100644 --- a/liblttng-ust/lttng-context-ipc-ns.c +++ b/liblttng-ust/lttng-context-ipc-ns.c @@ -14,9 +14,9 @@ #include #include #include -#include #include #include +#include #include "context-internal.h" #include "lttng-tracer-core.h" diff --git a/liblttng-ust/lttng-context-mnt-ns.c b/liblttng-ust/lttng-context-mnt-ns.c index 3535aacb..2606ff3c 100644 --- a/liblttng-ust/lttng-context-mnt-ns.c +++ b/liblttng-ust/lttng-context-mnt-ns.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "context-internal.h" #include "ns.h" diff --git a/liblttng-ust/lttng-context-net-ns.c b/liblttng-ust/lttng-context-net-ns.c index 415c8ac3..1512fc27 100644 --- a/liblttng-ust/lttng-context-net-ns.c +++ b/liblttng-ust/lttng-context-net-ns.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/liblttng-ust/lttng-context-perf-counters.c b/liblttng-ust/lttng-context-perf-counters.c index 725f4cf1..53ff3cbc 100644 --- a/liblttng-ust/lttng-context-perf-counters.c +++ b/liblttng-ust/lttng-context-perf-counters.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/liblttng-ust/lttng-context-pid-ns.c b/liblttng-ust/lttng-context-pid-ns.c index d5c731c8..1c45d7f2 100644 --- a/liblttng-ust/lttng-context-pid-ns.c +++ b/liblttng-ust/lttng-context-pid-ns.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "context-internal.h" #include "ns.h" diff --git a/liblttng-ust/lttng-context-procname.c b/liblttng-ust/lttng-context-procname.c index 5e3f9f8a..1221298e 100644 --- a/liblttng-ust/lttng-context-procname.c +++ b/liblttng-ust/lttng-context-procname.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include "compat.h" diff --git a/liblttng-ust/lttng-context-pthread-id.c b/liblttng-ust/lttng-context-pthread-id.c index d113f595..b25dc7ae 100644 --- a/liblttng-ust/lttng-context-pthread-id.c +++ b/liblttng-ust/lttng-context-pthread-id.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include "context-internal.h" diff --git a/liblttng-ust/lttng-context-time-ns.c b/liblttng-ust/lttng-context-time-ns.c index dda556c6..6534ce72 100644 --- a/liblttng-ust/lttng-context-time-ns.c +++ b/liblttng-ust/lttng-context-time-ns.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include "lttng-tracer-core.h" diff --git a/liblttng-ust/lttng-context-user-ns.c b/liblttng-ust/lttng-context-user-ns.c index 925b77b6..ee1cf739 100644 --- a/liblttng-ust/lttng-context-user-ns.c +++ b/liblttng-ust/lttng-context-user-ns.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "context-internal.h" #include "ns.h" diff --git a/liblttng-ust/lttng-context-uts-ns.c b/liblttng-ust/lttng-context-uts-ns.c index 55a22899..e22011c9 100644 --- a/liblttng-ust/lttng-context-uts-ns.c +++ b/liblttng-ust/lttng-context-uts-ns.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/liblttng-ust/lttng-context-vegid.c b/liblttng-ust/lttng-context-vegid.c index d1a21a6e..488bfdd8 100644 --- a/liblttng-ust/lttng-context-vegid.c +++ b/liblttng-ust/lttng-context-vegid.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "context-internal.h" #include "creds.h" diff --git a/liblttng-ust/lttng-context-veuid.c b/liblttng-ust/lttng-context-veuid.c index 159eb420..22c09c82 100644 --- a/liblttng-ust/lttng-context-veuid.c +++ b/liblttng-ust/lttng-context-veuid.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "context-internal.h" #include "creds.h" diff --git a/liblttng-ust/lttng-context-vgid.c b/liblttng-ust/lttng-context-vgid.c index 5bfcd22e..a7b5dbfd 100644 --- a/liblttng-ust/lttng-context-vgid.c +++ b/liblttng-ust/lttng-context-vgid.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "context-internal.h" #include "creds.h" diff --git a/liblttng-ust/lttng-context-vpid.c b/liblttng-ust/lttng-context-vpid.c index 78e1f0ce..3594e529 100644 --- a/liblttng-ust/lttng-context-vpid.c +++ b/liblttng-ust/lttng-context-vpid.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "context-internal.h" diff --git a/liblttng-ust/lttng-context-vsgid.c b/liblttng-ust/lttng-context-vsgid.c index 16a68a5c..f49d7f79 100644 --- a/liblttng-ust/lttng-context-vsgid.c +++ b/liblttng-ust/lttng-context-vsgid.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "context-internal.h" #include "creds.h" diff --git a/liblttng-ust/lttng-context-vsuid.c b/liblttng-ust/lttng-context-vsuid.c index c7d08151..aa8f755e 100644 --- a/liblttng-ust/lttng-context-vsuid.c +++ b/liblttng-ust/lttng-context-vsuid.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "context-internal.h" #include "creds.h" diff --git a/liblttng-ust/lttng-context-vtid.c b/liblttng-ust/lttng-context-vtid.c index 432b8b0d..543e0498 100644 --- a/liblttng-ust/lttng-context-vtid.c +++ b/liblttng-ust/lttng-context-vtid.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include diff --git a/liblttng-ust/lttng-context-vuid.c b/liblttng-ust/lttng-context-vuid.c index e6f57e71..438b4222 100644 --- a/liblttng-ust/lttng-context-vuid.c +++ b/liblttng-ust/lttng-context-vuid.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "context-internal.h" #include "creds.h" diff --git a/liblttng-ust/lttng-tracer-core.h b/liblttng-ust/lttng-tracer-core.h index 3216cdc1..2ab8bc7c 100644 --- a/liblttng-ust/lttng-tracer-core.h +++ b/liblttng-ust/lttng-tracer-core.h @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include /* diff --git a/libringbuffer/Makefile.am b/libringbuffer/Makefile.am index 631a3568..46c720a5 100644 --- a/libringbuffer/Makefile.am +++ b/libringbuffer/Makefile.am @@ -12,7 +12,7 @@ libringbuffer_la_SOURCES = \ api.h mmap.h \ backend.h backend_internal.h backend_types.h \ frontend_api.h frontend.h frontend_internal.h frontend_types.h \ - nohz.h vatomic.h rb-init.h + nohz.h vatomic.h rb-init.h ringbuffer-config.h libringbuffer_la_LIBADD = \ -lrt diff --git a/libringbuffer/backend_internal.h b/libringbuffer/backend_internal.h index 60c97d42..766fde2d 100644 --- a/libringbuffer/backend_internal.h +++ b/libringbuffer/backend_internal.h @@ -14,7 +14,8 @@ #include #include -#include +#include +#include "ringbuffer-config.h" #include "backend_types.h" #include "frontend_types.h" #include "shm.h" diff --git a/libringbuffer/frontend_internal.h b/libringbuffer/frontend_internal.h index e6569b28..6e9d8be2 100644 --- a/libringbuffer/frontend_internal.h +++ b/libringbuffer/frontend_internal.h @@ -17,7 +17,8 @@ #include #include -#include +#include +#include "ringbuffer-config.h" #include "backend_types.h" #include "frontend_types.h" #include "shm.h" diff --git a/libringbuffer/frontend_types.h b/libringbuffer/frontend_types.h index 851c8da9..01fdaccf 100644 --- a/libringbuffer/frontend_types.h +++ b/libringbuffer/frontend_types.h @@ -18,7 +18,8 @@ #include #include -#include +#include +#include "ringbuffer-config.h" #include #include "backend_types.h" #include "shm_internal.h" diff --git a/libringbuffer/ring_buffer_backend.c b/libringbuffer/ring_buffer_backend.c index 3202e8d9..f1f34898 100644 --- a/libringbuffer/ring_buffer_backend.c +++ b/libringbuffer/ring_buffer_backend.c @@ -12,7 +12,8 @@ #include #include -#include +#include +#include "ringbuffer-config.h" #include "vatomic.h" #include "backend.h" #include "frontend.h" diff --git a/libringbuffer/ring_buffer_frontend.c b/libringbuffer/ring_buffer_frontend.c index bc680100..45ff7dee 100644 --- a/libringbuffer/ring_buffer_frontend.c +++ b/libringbuffer/ring_buffer_frontend.c @@ -54,7 +54,8 @@ #include #include "smp.h" -#include +#include +#include "ringbuffer-config.h" #include "vatomic.h" #include "backend.h" #include "frontend.h" diff --git a/libringbuffer/ringbuffer-config.h b/libringbuffer/ringbuffer-config.h new file mode 100644 index 00000000..1052ed6f --- /dev/null +++ b/libringbuffer/ringbuffer-config.h @@ -0,0 +1,241 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2010-2021 Mathieu Desnoyers + * + * Ring buffer configuration header. Note: after declaring the standard inline + * functions, clients should also include linux/ringbuffer/api.h. + */ + +#ifndef _LTTNG_RING_BUFFER_CONFIG_H +#define _LTTNG_RING_BUFFER_CONFIG_H + +#include +#include +#include +#include +#include +#include +#include +#include + +struct lttng_ust_lib_ring_buffer; +struct lttng_ust_lib_ring_buffer_channel; +struct lttng_ust_lib_ring_buffer_config; +struct lttng_ust_lib_ring_buffer_ctx; +struct lttng_ust_shm_handle; + +/* + * Ring buffer client callbacks. Only used by slow path, never on fast path. + * For the fast path, record_header_size(), ring_buffer_clock_read() should be + * provided as inline functions too. These may simply return 0 if not used by + * the client. + */ +struct lttng_ust_lib_ring_buffer_client_cb { + /* Mandatory callbacks */ + + /* A static inline version is also required for fast path */ + uint64_t (*ring_buffer_clock_read) (struct lttng_ust_lib_ring_buffer_channel *chan); + size_t (*record_header_size) (const struct lttng_ust_lib_ring_buffer_config *config, + struct lttng_ust_lib_ring_buffer_channel *chan, + size_t offset, + size_t *pre_header_padding, + struct lttng_ust_lib_ring_buffer_ctx *ctx, + void *client_ctx); + + /* Slow path only, at subbuffer switch */ + size_t (*subbuffer_header_size) (void); + void (*buffer_begin) (struct lttng_ust_lib_ring_buffer *buf, uint64_t tsc, + unsigned int subbuf_idx, + struct lttng_ust_shm_handle *handle); + void (*buffer_end) (struct lttng_ust_lib_ring_buffer *buf, uint64_t tsc, + unsigned int subbuf_idx, unsigned long data_size, + struct lttng_ust_shm_handle *handle); + + /* Optional callbacks (can be set to NULL) */ + + /* Called at buffer creation/finalize */ + int (*buffer_create) (struct lttng_ust_lib_ring_buffer *buf, void *priv, + int cpu, const char *name, + struct lttng_ust_shm_handle *handle); + /* + * Clients should guarantee that no new reader handle can be opened + * after finalize. + */ + void (*buffer_finalize) (struct lttng_ust_lib_ring_buffer *buf, + void *priv, int cpu, + struct lttng_ust_shm_handle *handle); + + /* + * Extract header length, payload length and timestamp from event + * record. Used by buffer iterators. Timestamp is only used by channel + * iterator. + */ + void (*record_get) (const struct lttng_ust_lib_ring_buffer_config *config, + struct lttng_ust_lib_ring_buffer_channel *chan, + struct lttng_ust_lib_ring_buffer *buf, + size_t offset, size_t *header_len, + size_t *payload_len, uint64_t *timestamp, + struct lttng_ust_shm_handle *handle); + /* + * Offset and size of content size field in client. + */ + void (*content_size_field) (const struct lttng_ust_lib_ring_buffer_config *config, + size_t *offset, size_t *length); + void (*packet_size_field) (const struct lttng_ust_lib_ring_buffer_config *config, + size_t *offset, size_t *length); +}; + +/* + * Ring buffer instance configuration. + * + * Declare as "static const" within the client object to ensure the inline fast + * paths can be optimized. + * + * alloc/sync pairs: + * + * RING_BUFFER_ALLOC_PER_CPU and RING_BUFFER_SYNC_PER_CPU : + * Per-cpu buffers with per-cpu synchronization. Tracing must be performed + * with preemption disabled (lib_ring_buffer_get_cpu() and + * lib_ring_buffer_put_cpu()). + * + * RING_BUFFER_ALLOC_PER_CPU and RING_BUFFER_SYNC_GLOBAL : + * Per-cpu buffer with global synchronization. Tracing can be performed with + * preemption enabled, statistically stays on the local buffers. + * + * RING_BUFFER_ALLOC_GLOBAL and RING_BUFFER_SYNC_PER_CPU : + * Should only be used for buffers belonging to a single thread or protected + * by mutual exclusion by the client. Note that periodical sub-buffer switch + * should be disabled in this kind of configuration. + * + * RING_BUFFER_ALLOC_GLOBAL and RING_BUFFER_SYNC_GLOBAL : + * Global shared buffer with global synchronization. + * + * wakeup: + * + * RING_BUFFER_WAKEUP_BY_TIMER uses per-cpu deferrable timers to poll the + * buffers and wake up readers if data is ready. Mainly useful for tracers which + * don't want to call into the wakeup code on the tracing path. Use in + * combination with "read_timer_interval" channel_create() argument. + * + * RING_BUFFER_WAKEUP_BY_WRITER directly wakes up readers when a subbuffer is + * ready to read. Lower latencies before the reader is woken up. Mainly suitable + * for drivers. + * + * RING_BUFFER_WAKEUP_NONE does not perform any wakeup whatsoever. The client + * has the responsibility to perform wakeups. + */ +#define LTTNG_UST_RING_BUFFER_CONFIG_PADDING 20 + +enum lttng_ust_lib_ring_buffer_alloc_types { + RING_BUFFER_ALLOC_PER_CPU, + RING_BUFFER_ALLOC_GLOBAL, +}; + +enum lttng_ust_lib_ring_buffer_sync_types { + RING_BUFFER_SYNC_PER_CPU, /* Wait-free */ + RING_BUFFER_SYNC_GLOBAL, /* Lock-free */ +}; + +enum lttng_ust_lib_ring_buffer_mode_types { + RING_BUFFER_OVERWRITE = 0, /* Overwrite when buffer full */ + RING_BUFFER_DISCARD = 1, /* Discard when buffer full */ +}; + +enum lttng_ust_lib_ring_buffer_output_types { + RING_BUFFER_SPLICE, + RING_BUFFER_MMAP, + RING_BUFFER_READ, /* TODO */ + RING_BUFFER_ITERATOR, + RING_BUFFER_NONE, +}; + +enum lttng_ust_lib_ring_buffer_backend_types { + RING_BUFFER_PAGE, + RING_BUFFER_VMAP, /* TODO */ + RING_BUFFER_STATIC, /* TODO */ +}; + +enum lttng_ust_lib_ring_buffer_oops_types { + RING_BUFFER_NO_OOPS_CONSISTENCY, + RING_BUFFER_OOPS_CONSISTENCY, +}; + +enum lttng_ust_lib_ring_buffer_ipi_types { + RING_BUFFER_IPI_BARRIER, + RING_BUFFER_NO_IPI_BARRIER, +}; + +enum lttng_ust_lib_ring_buffer_wakeup_types { + RING_BUFFER_WAKEUP_BY_TIMER, /* wake up performed by timer */ + RING_BUFFER_WAKEUP_BY_WRITER, /* + * writer wakes up reader, + * not lock-free + * (takes spinlock). + */ +}; + +struct lttng_ust_lib_ring_buffer_config { + enum lttng_ust_lib_ring_buffer_alloc_types alloc; + enum lttng_ust_lib_ring_buffer_sync_types sync; + enum lttng_ust_lib_ring_buffer_mode_types mode; + enum lttng_ust_lib_ring_buffer_output_types output; + enum lttng_ust_lib_ring_buffer_backend_types backend; + enum lttng_ust_lib_ring_buffer_oops_types oops; + enum lttng_ust_lib_ring_buffer_ipi_types ipi; + enum lttng_ust_lib_ring_buffer_wakeup_types wakeup; + /* + * tsc_bits: timestamp bits saved at each record. + * 0 and 64 disable the timestamp compression scheme. + */ + unsigned int tsc_bits; + struct lttng_ust_lib_ring_buffer_client_cb cb; + /* + * client_type is used by the consumer process (which is in a + * different address space) to lookup the appropriate client + * callbacks and update the cb pointers. + */ + int client_type; + int _unused1; + const struct lttng_ust_lib_ring_buffer_client_cb *cb_ptr; + char padding[LTTNG_UST_RING_BUFFER_CONFIG_PADDING]; +}; + +/* + * Reservation flags. + * + * RING_BUFFER_RFLAG_FULL_TSC + * + * This flag is passed to record_header_size() and to the primitive used to + * write the record header. It indicates that the full 64-bit time value is + * needed in the record header. If this flag is not set, the record header needs + * only to contain "tsc_bits" bit of time value. + * + * Reservation flags can be added by the client, starting from + * "(RING_BUFFER_FLAGS_END << 0)". It can be used to pass information from + * record_header_size() to lib_ring_buffer_write_record_header(). + */ +#define RING_BUFFER_RFLAG_FULL_TSC (1U << 0) +#define RING_BUFFER_RFLAG_END (1U << 1) + +/* + * lib_ring_buffer_check_config() returns 0 on success. + * Used internally to check for valid configurations at channel creation. + */ +static inline lttng_ust_notrace +int lib_ring_buffer_check_config(const struct lttng_ust_lib_ring_buffer_config *config, + unsigned int switch_timer_interval, + unsigned int read_timer_interval); +static inline +int lib_ring_buffer_check_config(const struct lttng_ust_lib_ring_buffer_config *config, + unsigned int switch_timer_interval, + unsigned int read_timer_interval) +{ + if (config->alloc == RING_BUFFER_ALLOC_GLOBAL + && config->sync == RING_BUFFER_SYNC_PER_CPU + && switch_timer_interval) + return -EINVAL; + return 0; +} + +#endif /* _LTTNG_RING_BUFFER_CONFIG_H */ diff --git a/tests/compile/test-app-ctx/hello.c b/tests/compile/test-app-ctx/hello.c index 20df12db..19901c7c 100644 --- a/tests/compile/test-app-ctx/hello.c +++ b/tests/compile/test-app-ctx/hello.c @@ -28,9 +28,9 @@ struct mmsghdr; #define TRACEPOINT_DEFINE #include "ust_tests_hello.h" -/* Internal header. */ #include -#include +#include +/* Internal header. */ #include static __thread unsigned int test_count;