From e56bb47c3af00db3bc9e2dea711bef4882e6ef4c Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sat, 27 May 2017 15:14:41 +0200 Subject: [PATCH] Calculate context length outside of retry loop Allow context length calculation to have side-effects which trigger event tracing by moving the calculation outside of the buffer space reservation retry loop. This also paves the way to have dynamically sized contexts in lttng-ust, which would expect to put their size of the internal stack. Note that the context length calculation is performed *after* the event payload field length calculation, so the stack needs to be used accordingly. Currently, the only dynamically sized contexts we have are provided by Java integration, which keeps its own stack. Signed-off-by: Mathieu Desnoyers --- include/lttng/ringbuffer-config.h | 3 +- liblttng-ust/lttng-ring-buffer-client.h | 67 +++++++++++++++---- .../lttng-ring-buffer-metadata-client.h | 8 ++- libringbuffer/frontend_api.h | 10 +-- libringbuffer/frontend_internal.h | 3 +- libringbuffer/ring_buffer_frontend.c | 12 ++-- 6 files changed, 77 insertions(+), 26 deletions(-) diff --git a/include/lttng/ringbuffer-config.h b/include/lttng/ringbuffer-config.h index 9ed9a34d..421a8637 100644 --- a/include/lttng/ringbuffer-config.h +++ b/include/lttng/ringbuffer-config.h @@ -57,7 +57,8 @@ struct lttng_ust_lib_ring_buffer_client_cb { size_t (*record_header_size) (const struct lttng_ust_lib_ring_buffer_config *config, struct channel *chan, size_t offset, size_t *pre_header_padding, - struct lttng_ust_lib_ring_buffer_ctx *ctx); + struct lttng_ust_lib_ring_buffer_ctx *ctx, + void *client_ctx); /* Slow path only, at subbuffer switch */ size_t (*subbuffer_header_size) (void); diff --git a/liblttng-ust/lttng-ring-buffer-client.h b/liblttng-ust/lttng-ring-buffer-client.h index 6ed06710..2f67799e 100644 --- a/liblttng-ust/lttng-ring-buffer-client.h +++ b/liblttng-ust/lttng-ring-buffer-client.h @@ -69,6 +69,10 @@ struct packet_header { } ctx; }; +struct lttng_client_ctx { + size_t packet_context_len; + size_t event_context_len; +}; static inline uint64_t lib_ring_buffer_clock_read(struct channel *chan) { @@ -76,15 +80,29 @@ static inline uint64_t lib_ring_buffer_clock_read(struct channel *chan) } static inline -size_t ctx_get_size(size_t offset, struct lttng_ctx *ctx, - enum app_ctx_mode mode) +size_t ctx_get_aligned_size(size_t offset, struct lttng_ctx *ctx, + size_t ctx_len) { - int i; size_t orig_offset = offset; if (caa_likely(!ctx)) return 0; offset += lib_ring_buffer_align(offset, ctx->largest_align); + offset += ctx_len; + return offset - orig_offset; +} + +static inline +void ctx_get_struct_size(struct lttng_ctx *ctx, size_t *ctx_len, + enum app_ctx_mode mode) +{ + int i; + size_t offset = 0; + + if (caa_likely(!ctx)) { + *ctx_len = 0; + return; + } for (i = 0; i < ctx->nr_fields; i++) { if (mode == APP_CTX_ENABLED) { offset += ctx->fields[i].get_size(&ctx->fields[i], offset); @@ -106,7 +124,7 @@ size_t ctx_get_size(size_t offset, struct lttng_ctx *ctx, } } } - return offset - orig_offset; + *ctx_len = offset; } static inline @@ -160,7 +178,8 @@ static __inline__ size_t record_header_size(const struct lttng_ust_lib_ring_buffer_config *config, struct channel *chan, size_t offset, size_t *pre_header_padding, - struct lttng_ust_lib_ring_buffer_ctx *ctx) + struct lttng_ust_lib_ring_buffer_ctx *ctx, + struct lttng_client_ctx *client_ctx) { struct lttng_channel *lttng_chan = channel_get_private(chan); struct lttng_event *event = ctx->priv; @@ -205,12 +224,16 @@ size_t record_header_size(const struct lttng_ust_lib_ring_buffer_config *config, } if (lttng_ctx) { /* 2.8+ probe ABI. */ - offset += ctx_get_size(offset, lttng_ctx->chan_ctx, APP_CTX_ENABLED); - offset += ctx_get_size(offset, lttng_ctx->event_ctx, APP_CTX_ENABLED); + offset += ctx_get_aligned_size(offset, lttng_ctx->chan_ctx, + client_ctx->packet_context_len); + offset += ctx_get_aligned_size(offset, lttng_ctx->event_ctx, + client_ctx->event_context_len); } else { /* Pre 2.8 probe ABI. */ - offset += ctx_get_size(offset, lttng_chan->ctx, APP_CTX_DISABLED); - offset += ctx_get_size(offset, event->ctx, APP_CTX_DISABLED); + offset += ctx_get_aligned_size(offset, lttng_chan->ctx, + client_ctx->packet_context_len); + offset += ctx_get_aligned_size(offset, event->ctx, + client_ctx->event_context_len); } *pre_header_padding = padding; return offset - orig_offset; @@ -379,10 +402,11 @@ static size_t client_record_header_size(const struct lttng_ust_lib_ring_buffer_config *config, struct channel *chan, size_t offset, size_t *pre_header_padding, - struct lttng_ust_lib_ring_buffer_ctx *ctx) + struct lttng_ust_lib_ring_buffer_ctx *ctx, + void *client_ctx) { return record_header_size(config, chan, offset, - pre_header_padding, ctx); + pre_header_padding, ctx, client_ctx); } /** @@ -694,8 +718,27 @@ int lttng_event_reserve(struct lttng_ust_lib_ring_buffer_ctx *ctx, uint32_t event_id) { struct lttng_channel *lttng_chan = channel_get_private(ctx->chan); + struct lttng_event *event = ctx->priv; + struct lttng_stack_ctx *lttng_ctx = ctx->priv2; + struct lttng_client_ctx client_ctx; int ret, cpu; + /* Compute internal size of context structures. */ + + if (lttng_ctx) { + /* 2.8+ probe ABI. */ + ctx_get_struct_size(lttng_ctx->chan_ctx, &client_ctx.packet_context_len, + APP_CTX_ENABLED); + ctx_get_struct_size(lttng_ctx->event_ctx, &client_ctx.event_context_len, + APP_CTX_ENABLED); + } else { + /* Pre 2.8 probe ABI. */ + ctx_get_struct_size(lttng_chan->ctx, &client_ctx.packet_context_len, + APP_CTX_DISABLED); + ctx_get_struct_size(event->ctx, &client_ctx.event_context_len, + APP_CTX_DISABLED); + } + cpu = lib_ring_buffer_get_cpu(&client_config); if (cpu < 0) return -EPERM; @@ -714,7 +757,7 @@ int lttng_event_reserve(struct lttng_ust_lib_ring_buffer_ctx *ctx, WARN_ON_ONCE(1); } - ret = lib_ring_buffer_reserve(&client_config, ctx); + ret = lib_ring_buffer_reserve(&client_config, ctx, &client_ctx); if (caa_unlikely(ret)) goto put; if (caa_likely(ctx->ctx_len diff --git a/liblttng-ust/lttng-ring-buffer-metadata-client.h b/liblttng-ust/lttng-ring-buffer-metadata-client.h index af5162f6..64940163 100644 --- a/liblttng-ust/lttng-ring-buffer-metadata-client.h +++ b/liblttng-ust/lttng-ring-buffer-metadata-client.h @@ -55,7 +55,8 @@ static inline size_t record_header_size(const struct lttng_ust_lib_ring_buffer_config *config, struct channel *chan, size_t offset, size_t *pre_header_padding, - struct lttng_ust_lib_ring_buffer_ctx *ctx) + struct lttng_ust_lib_ring_buffer_ctx *ctx, + void *client_ctx) { return 0; } @@ -72,7 +73,8 @@ static size_t client_record_header_size(const struct lttng_ust_lib_ring_buffer_config *config, struct channel *chan, size_t offset, size_t *pre_header_padding, - struct lttng_ust_lib_ring_buffer_ctx *ctx) + struct lttng_ust_lib_ring_buffer_ctx *ctx, + void *client_ctx) { return 0; } @@ -242,7 +244,7 @@ int lttng_event_reserve(struct lttng_ust_lib_ring_buffer_ctx *ctx, uint32_t even { int ret; - ret = lib_ring_buffer_reserve(&client_config, ctx); + ret = lib_ring_buffer_reserve(&client_config, ctx, NULL); if (ret) return ret; if (caa_likely(ctx->ctx_len diff --git a/libringbuffer/frontend_api.h b/libringbuffer/frontend_api.h index 14015973..bc1fd122 100644 --- a/libringbuffer/frontend_api.h +++ b/libringbuffer/frontend_api.h @@ -84,6 +84,7 @@ void lib_ring_buffer_put_cpu(const struct lttng_ust_lib_ring_buffer_config *conf static inline int lib_ring_buffer_try_reserve(const struct lttng_ust_lib_ring_buffer_config *config, struct lttng_ust_lib_ring_buffer_ctx *ctx, + void *client_ctx, unsigned long *o_begin, unsigned long *o_end, unsigned long *o_old, size_t *before_hdr_pad) { @@ -110,7 +111,7 @@ int lib_ring_buffer_try_reserve(const struct lttng_ust_lib_ring_buffer_config *c return 1; ctx->slot_size = record_header_size(config, chan, *o_begin, - before_hdr_pad, ctx); + before_hdr_pad, ctx, client_ctx); ctx->slot_size += lib_ring_buffer_align(*o_begin + ctx->slot_size, ctx->largest_align) + ctx->data_size; @@ -152,7 +153,8 @@ int lib_ring_buffer_try_reserve(const struct lttng_ust_lib_ring_buffer_config *c static inline int lib_ring_buffer_reserve(const struct lttng_ust_lib_ring_buffer_config *config, - struct lttng_ust_lib_ring_buffer_ctx *ctx) + struct lttng_ust_lib_ring_buffer_ctx *ctx, + void *client_ctx) { struct channel *chan = ctx->chan; struct lttng_ust_shm_handle *handle = ctx->handle; @@ -176,7 +178,7 @@ int lib_ring_buffer_reserve(const struct lttng_ust_lib_ring_buffer_config *confi /* * Perform retryable operations. */ - if (caa_unlikely(lib_ring_buffer_try_reserve(config, ctx, &o_begin, + if (caa_unlikely(lib_ring_buffer_try_reserve(config, ctx, client_ctx, &o_begin, &o_end, &o_old, &before_hdr_pad))) goto slow_path; @@ -207,7 +209,7 @@ int lib_ring_buffer_reserve(const struct lttng_ust_lib_ring_buffer_config *confi ctx->buf_offset = o_begin + before_hdr_pad; return 0; slow_path: - return lib_ring_buffer_reserve_slow(ctx); + return lib_ring_buffer_reserve_slow(ctx, client_ctx); } /** diff --git a/libringbuffer/frontend_internal.h b/libringbuffer/frontend_internal.h index 68aa7022..323a8df7 100644 --- a/libringbuffer/frontend_internal.h +++ b/libringbuffer/frontend_internal.h @@ -158,7 +158,8 @@ int last_tsc_overflow(const struct lttng_ust_lib_ring_buffer_config *config, #endif extern -int lib_ring_buffer_reserve_slow(struct lttng_ust_lib_ring_buffer_ctx *ctx); +int lib_ring_buffer_reserve_slow(struct lttng_ust_lib_ring_buffer_ctx *ctx, + void *client_ctx); extern void lib_ring_buffer_switch_slow(struct lttng_ust_lib_ring_buffer *buf, diff --git a/libringbuffer/ring_buffer_frontend.c b/libringbuffer/ring_buffer_frontend.c index 9ecdc157..76d6ec74 100644 --- a/libringbuffer/ring_buffer_frontend.c +++ b/libringbuffer/ring_buffer_frontend.c @@ -2060,7 +2060,8 @@ static int lib_ring_buffer_try_reserve_slow(struct lttng_ust_lib_ring_buffer *buf, struct channel *chan, struct switch_offsets *offsets, - struct lttng_ust_lib_ring_buffer_ctx *ctx) + struct lttng_ust_lib_ring_buffer_ctx *ctx, + void *client_ctx) { const struct lttng_ust_lib_ring_buffer_config *config = &chan->backend.config; struct lttng_ust_shm_handle *handle = ctx->handle; @@ -2088,7 +2089,7 @@ retry: offsets->size = config->cb.record_header_size(config, chan, offsets->begin, &offsets->pre_header_padding, - ctx); + ctx, client_ctx); offsets->size += lib_ring_buffer_align(offsets->begin + offsets->size, ctx->largest_align) @@ -2194,7 +2195,7 @@ retry: config->cb.record_header_size(config, chan, offsets->begin, &offsets->pre_header_padding, - ctx); + ctx, client_ctx); offsets->size += lib_ring_buffer_align(offsets->begin + offsets->size, ctx->largest_align) @@ -2248,7 +2249,8 @@ retry: * -EIO for other errors, else returns 0. * It will take care of sub-buffer switching. */ -int lib_ring_buffer_reserve_slow(struct lttng_ust_lib_ring_buffer_ctx *ctx) +int lib_ring_buffer_reserve_slow(struct lttng_ust_lib_ring_buffer_ctx *ctx, + void *client_ctx) { struct channel *chan = ctx->chan; struct lttng_ust_shm_handle *handle = ctx->handle; @@ -2269,7 +2271,7 @@ int lib_ring_buffer_reserve_slow(struct lttng_ust_lib_ring_buffer_ctx *ctx) do { ret = lib_ring_buffer_try_reserve_slow(buf, chan, &offsets, - ctx); + ctx, client_ctx); if (caa_unlikely(ret)) return ret; } while (caa_unlikely(v_cmpxchg(config, &buf->offset, offsets.old, -- 2.34.1