The list of contexts active for a channel can be moved to a private
structure by keeping the temporary pointer to the RCU dereferenced
context in the ring buffer client's internal context rather than within
the context shared between the probe and the ring buffer client.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: Iaf9491255d1a0940450dea613ac6e5bc0705506d
struct lttng_ust_channel_common *parent; /* Inheritance by aggregation. */
struct lttng_ust_channel_buffer_private *priv; /* Private channel buffer interface */
struct lttng_ust_channel_common *parent; /* Inheritance by aggregation. */
struct lttng_ust_channel_buffer_private *priv; /* Private channel buffer interface */
- struct lttng_ust_ctx *ctx;
struct lttng_ust_channel_ops *ops;
struct lttng_ust_lib_ring_buffer_channel *chan; /* Channel buffers */
struct lttng_ust_shm_handle *handle; /* shared-memory handle */
struct lttng_ust_channel_ops *ops;
struct lttng_ust_lib_ring_buffer_channel *chan; /* Channel buffers */
struct lttng_ust_shm_handle *handle; /* shared-memory handle */
uint32_t struct_size; /* Size of this structure */
struct lttng_ust_event_recorder *event_recorder;
uint32_t struct_size; /* Size of this structure */
struct lttng_ust_event_recorder *event_recorder;
- struct lttng_ust_ctx *chan_ctx; /* RCU dereferenced. */
struct lttng_ust_ctx *event_ctx; /* RCU dereferenced. */
/* End of base ABI. Fields below should be used after checking struct_size. */
struct lttng_ust_ctx *event_ctx; /* RCU dereferenced. */
/* End of base ABI. Fields below should be used after checking struct_size. */
memset(&__lttng_ctx, 0, sizeof(__lttng_ctx)); \
__lttng_ctx.struct_size = sizeof(struct lttng_ust_stack_ctx); \
__lttng_ctx.event_recorder = __event_recorder; \
memset(&__lttng_ctx, 0, sizeof(__lttng_ctx)); \
__lttng_ctx.struct_size = sizeof(struct lttng_ust_stack_ctx); \
__lttng_ctx.event_recorder = __event_recorder; \
- __lttng_ctx.chan_ctx = tp_rcu_dereference(__chan->ctx); \
__lttng_ctx.event_ctx = tp_rcu_dereference(__event_recorder->ctx); \
lib_ring_buffer_ctx_init(&__ctx, __chan->chan, &__lttng_ctx, __event_len, \
__event_align, -1, __chan->handle); \
__lttng_ctx.event_ctx = tp_rcu_dereference(__event_recorder->ctx); \
lib_ring_buffer_ctx_init(&__ctx, __chan->chan, &__lttng_ctx, __event_len, \
__event_align, -1, __chan->handle); \
struct lttng_ust_shm_handle *handle;
cds_list_del(<tng_chan->priv->node);
struct lttng_ust_shm_handle *handle;
cds_list_del(<tng_chan->priv->node);
- lttng_destroy_context(lttng_chan->ctx);
+ lttng_destroy_context(lttng_chan->priv->ctx);
chan = lttng_chan->chan;
handle = lttng_chan->handle;
channel_destroy(chan, handle, 0);
chan = lttng_chan->chan;
handle = lttng_chan->handle;
channel_destroy(chan, handle, 0);
/* don't change it if session stop/restart */
if (chan->header_type)
continue;
/* don't change it if session stop/restart */
if (chan->header_type)
continue;
if (ctx) {
nr_fields = ctx->nr_fields;
fields = ctx->fields;
if (ctx) {
nr_fields = ctx->nr_fields;
fields = ctx->fields;
if (ret)
abort();
cds_list_for_each_entry(chan, &session_priv->chan_head, node) {
if (ret)
abort();
cds_list_for_each_entry(chan, &session_priv->chan_head, node) {
- ret = lttng_ust_context_set_provider_rcu(&chan->pub->ctx,
+ ret = lttng_ust_context_set_provider_rcu(&chan->ctx,
name, get_size, record, get_value);
if (ret)
abort();
name, get_size, record, get_value);
if (ret)
abort();
#include <stdint.h>
#include <ust-events-internal.h>
#include <stdint.h>
#include <ust-events-internal.h>
+#include <lttng/urcu/pointer.h>
#include "ust-bitfield.h"
#include "ust-compat.h"
#include "clock.h"
#include "ust-bitfield.h"
#include "ust-compat.h"
#include "clock.h"
struct lttng_client_ctx {
size_t packet_context_len;
size_t event_context_len;
struct lttng_client_ctx {
size_t packet_context_len;
size_t event_context_len;
+ struct lttng_ust_ctx *chan_ctx;
};
static inline uint64_t lib_ring_buffer_clock_read(struct lttng_ust_lib_ring_buffer_channel *chan)
};
static inline uint64_t lib_ring_buffer_clock_read(struct lttng_ust_lib_ring_buffer_channel *chan)
padding = 0;
WARN_ON_ONCE(1);
}
padding = 0;
WARN_ON_ONCE(1);
}
- offset += ctx_get_aligned_size(offset, lttng_ctx->chan_ctx,
+ offset += ctx_get_aligned_size(offset, client_ctx->chan_ctx,
client_ctx->packet_context_len);
offset += ctx_get_aligned_size(offset, lttng_ctx->event_ctx,
client_ctx->event_context_len);
client_ctx->packet_context_len);
offset += ctx_get_aligned_size(offset, lttng_ctx->event_ctx,
client_ctx->event_context_len);
static
void lttng_write_event_header_slow(const struct lttng_ust_lib_ring_buffer_config *config,
struct lttng_ust_lib_ring_buffer_ctx *ctx,
static
void lttng_write_event_header_slow(const struct lttng_ust_lib_ring_buffer_config *config,
struct lttng_ust_lib_ring_buffer_ctx *ctx,
+ struct lttng_client_ctx *client_ctx,
static __inline__
void lttng_write_event_header(const struct lttng_ust_lib_ring_buffer_config *config,
struct lttng_ust_lib_ring_buffer_ctx *ctx,
static __inline__
void lttng_write_event_header(const struct lttng_ust_lib_ring_buffer_config *config,
struct lttng_ust_lib_ring_buffer_ctx *ctx,
+ struct lttng_client_ctx *client_ctx,
uint32_t event_id)
{
struct lttng_ust_channel_buffer *lttng_chan = channel_get_private(ctx->chan);
uint32_t event_id)
{
struct lttng_ust_channel_buffer *lttng_chan = channel_get_private(ctx->chan);
- ctx_record(ctx, lttng_chan, lttng_ctx->chan_ctx, APP_CTX_ENABLED);
+ ctx_record(ctx, lttng_chan, client_ctx->chan_ctx, APP_CTX_ENABLED);
ctx_record(ctx, lttng_chan, lttng_ctx->event_ctx, APP_CTX_ENABLED);
lib_ring_buffer_align_ctx(ctx, ctx->largest_align);
return;
slow_path:
ctx_record(ctx, lttng_chan, lttng_ctx->event_ctx, APP_CTX_ENABLED);
lib_ring_buffer_align_ctx(ctx, ctx->largest_align);
return;
slow_path:
- lttng_write_event_header_slow(config, ctx, event_id);
+ lttng_write_event_header_slow(config, ctx, client_ctx, event_id);
}
static
void lttng_write_event_header_slow(const struct lttng_ust_lib_ring_buffer_config *config,
struct lttng_ust_lib_ring_buffer_ctx *ctx,
}
static
void lttng_write_event_header_slow(const struct lttng_ust_lib_ring_buffer_config *config,
struct lttng_ust_lib_ring_buffer_ctx *ctx,
+ struct lttng_client_ctx *client_ctx,
uint32_t event_id)
{
struct lttng_ust_channel_buffer *lttng_chan = channel_get_private(ctx->chan);
uint32_t event_id)
{
struct lttng_ust_channel_buffer *lttng_chan = channel_get_private(ctx->chan);
default:
WARN_ON_ONCE(1);
}
default:
WARN_ON_ONCE(1);
}
- ctx_record(ctx, lttng_chan, lttng_ctx->chan_ctx, APP_CTX_ENABLED);
+ ctx_record(ctx, lttng_chan, client_ctx->chan_ctx, APP_CTX_ENABLED);
ctx_record(ctx, lttng_chan, lttng_ctx->event_ctx, APP_CTX_ENABLED);
lib_ring_buffer_align_ctx(ctx, ctx->largest_align);
}
ctx_record(ctx, lttng_chan, lttng_ctx->event_ctx, APP_CTX_ENABLED);
lib_ring_buffer_align_ctx(ctx, ctx->largest_align);
}
struct lttng_client_ctx client_ctx;
int ret, cpu;
struct lttng_client_ctx client_ctx;
int ret, cpu;
+ client_ctx.chan_ctx = lttng_ust_rcu_dereference(lttng_chan->priv->ctx);
/* Compute internal size of context structures. */
/* Compute internal size of context structures. */
- ctx_get_struct_size(lttng_ctx->chan_ctx, &client_ctx.packet_context_len,
+ ctx_get_struct_size(client_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);
APP_CTX_ENABLED);
ctx_get_struct_size(lttng_ctx->event_ctx, &client_ctx.event_context_len,
APP_CTX_ENABLED);
ret = -EPERM;
goto put;
}
ret = -EPERM;
goto put;
}
- lttng_write_event_header(&client_config, ctx, event_id);
+ lttng_write_event_header(&client_config, ctx, &client_ctx, event_id);
return 0;
put:
lib_ring_buffer_put_cpu(&client_config);
return 0;
put:
lib_ring_buffer_put_cpu(&client_config);
lttng_chan_buf->parent->session = session;
lttng_chan_buf->priv->parent.tstate = 1;
lttng_chan_buf->parent->session = session;
lttng_chan_buf->priv->parent.tstate = 1;
+ lttng_chan_buf->priv->ctx = NULL;
- lttng_chan_buf->ctx = NULL;
lttng_chan_buf->ops = &transport->ops;
lttng_chan_buf->chan = chan;
lttng_chan_buf->handle = channel_handle;
lttng_chan_buf->ops = &transport->ops;
lttng_chan_buf->chan = chan;
lttng_chan_buf->handle = channel_handle;
case LTTNG_UST_ABI_CONTEXT:
return lttng_abi_add_context(objd,
(struct lttng_ust_abi_context *) arg, uargs,
case LTTNG_UST_ABI_CONTEXT:
return lttng_abi_add_context(objd,
(struct lttng_ust_abi_context *) arg, uargs,
+ <tng_chan_buf->priv->ctx,
lttng_chan_buf->parent->session);
case LTTNG_UST_ABI_ENABLE:
return lttng_channel_enable(lttng_chan_buf->parent);
lttng_chan_buf->parent->session);
case LTTNG_UST_ABI_ENABLE:
return lttng_channel_enable(lttng_chan_buf->parent);
int header_type; /* 0: unset, 1: compact, 2: large */
unsigned int id; /* Channel ID */
enum lttng_ust_abi_chan_type type;
int header_type; /* 0: unset, 1: compact, 2: large */
unsigned int id; /* Channel ID */
enum lttng_ust_abi_chan_type type;
+ struct lttng_ust_ctx *ctx;
unsigned char uuid[LTTNG_UST_UUID_LEN]; /* Trace session unique ID */
};
unsigned char uuid[LTTNG_UST_UUID_LEN]; /* Trace session unique ID */
};