Calculate context length outside of retry loop
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 27 May 2017 13:14:41 +0000 (15:14 +0200)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 27 May 2017 13:23:30 +0000 (15:23 +0200)
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 <mathieu.desnoyers@efficios.com>
include/lttng/ringbuffer-config.h
liblttng-ust/lttng-ring-buffer-client.h
liblttng-ust/lttng-ring-buffer-metadata-client.h
libringbuffer/frontend_api.h
libringbuffer/frontend_internal.h
libringbuffer/ring_buffer_frontend.c

index 9ed9a34d34125a8b7bb8fc360768da1eedcafa64..421a8637c5ca8fec432f3aa219527cdba12c92b6 100644 (file)
@@ -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);
index 6ed067105d8e7fd0f8a280e3f09caa0375186836..2f67799e19feb676cb0da2b9eef26e5f74a2c0a3 100644 (file)
@@ -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
index af5162f6e8cd23d944f92555c95146205016da22..64940163d10250c4ba0e2dcbc60ee8df3f7e774d 100644 (file)
@@ -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
index 140159739feebc954f68d39b33806e3778f4ca01..bc1fd1220ba97c21da824ac326d81d4edf789a8a 100644 (file)
@@ -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);
 }
 
 /**
index 68aa70223ea5529acd3ecdf67a3c9b4057fcdb49..323a8df7f98cd7e5d3aba69302c6c291799b8bbd 100644 (file)
@@ -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,
index 9ecdc1579631339e7deb2c4bed9d9e1bb79a7d75..76d6ec746c40ade48905bcfbf0cd3c81274d812e 100644 (file)
@@ -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,
This page took 0.030172 seconds and 4 git commands to generate.