struct lttng_ctx_field {
const char *name;
struct lttng_type type;
- void *callback;
+ size_t (*get_size)(size_t offset);
+ void (*record)(struct lttng_ctx_field *field,
+ struct lib_ring_buffer_ctx *ctx,
+ struct ltt_channel *chan);
union {
struct {
struct perf_event **e; /* per-cpu array */
struct ltt_channel *chan;
const struct lttng_event_desc *desc;
void *filter;
+ struct lttng_ctx *ctx;
enum lttng_kernel_instrumentation instrumentation;
union {
struct {
struct ltt_channel {
unsigned int id;
struct channel *chan; /* Channel buffers */
+ struct lttng_ctx *ctx;
/* Event ID management */
struct ltt_session *session;
struct file *file; /* File associated to channel */
struct ltt_session {
int active; /* Is trace session active ? */
+ struct lttng_ctx *ctx;
struct file *file; /* File associated to session */
struct ltt_channel *metadata; /* Metadata channel */
struct list_head chan; /* Channel list head */
return trace_clock_read64();
}
+static inline
+size_t ctx_get_size(size_t offset, struct lttng_ctx *ctx)
+{
+ int i;
+ size_t orig_offset = offset;
+
+ if (likely(!ctx))
+ return 0;
+ for (i = 0; i < ctx->nr_fields; i++)
+ offset += ctx->fields[i].get_size(offset);
+ return offset - orig_offset;
+}
+
+static inline
+void ctx_record(struct lib_ring_buffer_ctx *bufctx,
+ struct ltt_channel *chan,
+ struct lttng_ctx *ctx)
+{
+ int i;
+
+ if (likely(!ctx))
+ return;
+ for (i = 0; i < ctx->nr_fields; i++)
+ ctx->fields[i].record(&ctx->fields[i], bufctx, chan);
+}
+
/*
* record_header_size - Calculate the header size and padding necessary.
* @config: ring buffer instance configuration
struct lib_ring_buffer_ctx *ctx)
{
struct ltt_channel *ltt_chan = channel_get_private(chan);
+ struct ltt_event *event = ctx->priv;
size_t orig_offset = offset;
size_t padding;
default:
WARN_ON_ONCE(1);
}
+ offset += ctx_get_size(offset, event->ctx);
+ offset += ctx_get_size(offset, ltt_chan->ctx);
+ offset += ctx_get_size(offset, ltt_chan->session->ctx);
*pre_header_padding = padding;
return offset - orig_offset;
uint32_t event_id)
{
struct ltt_channel *ltt_chan = channel_get_private(ctx->chan);
+ struct ltt_event *event = ctx->priv;
if (unlikely(ctx->rflags))
goto slow_path;
default:
WARN_ON_ONCE(1);
}
+
+ ctx_record(ctx, ltt_chan, event->ctx);
+ ctx_record(ctx, ltt_chan, ltt_chan->ctx);
+ ctx_record(ctx, ltt_chan, ltt_chan->session->ctx);
+
return;
slow_path:
uint32_t event_id)
{
struct ltt_channel *ltt_chan = channel_get_private(ctx->chan);
+ struct ltt_event *event = ctx->priv;
switch (ltt_chan->header_type) {
case 1: /* compact */
default:
WARN_ON_ONCE(1);
}
+ ctx_record(ctx, ltt_chan, event->ctx);
+ ctx_record(ctx, ltt_chan, ltt_chan->ctx);
+ ctx_record(ctx, ltt_chan, ltt_chan->session->ctx);
}
static const struct lib_ring_buffer_config client_config;
#include "../wrapper/vmalloc.h"
#include "../ltt-tracer.h"
+static
+size_t pid_get_size(size_t offset)
+{
+ size_t size = 0;
+
+ size += lib_ring_buffer_align(offset, ltt_alignof(pid_t));
+ size += sizeof(pid_t);
+ return size;
+}
+
static
void pid_record(struct lttng_ctx_field *field,
struct lib_ring_buffer_ctx *ctx,
field->type.u.basic.integer.reverse_byte_order = 0;
field->type.u.basic.integer.base = 10;
field->type.u.basic.integer.encoding = lttng_encode_none;
- field->callback = pid_record;
+ field->get_size = pid_get_size;
+ field->record = pid_record;
wrapper_vmalloc_sync_all();
return 0;
}
return; \
__event_len = __event_get_size__##_name(__dynamic_len, _args); \
__event_align = __event_get_align__##_name(_args); \
- lib_ring_buffer_ctx_init(&ctx, __chan->chan, NULL, __event_len, \
+ lib_ring_buffer_ctx_init(&ctx, __chan->chan, __event, __event_len, \
__event_align, -1); \
__ret = __chan->ops->event_reserve(&ctx, __event->id); \
if (__ret < 0) \
if (!ACCESS_ONCE(chan->session->active))
return;
- lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL,
+ lib_ring_buffer_ctx_init(&ctx, chan->chan, event,
sizeof(payload), ltt_alignof(payload), -1);
ret = chan->ops->event_reserve(&ctx, event->id);
if (ret < 0)
if (!ACCESS_ONCE(chan->session->active))
return 0;
- lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, sizeof(data),
+ lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(data),
ltt_alignof(data), -1);
ret = chan->ops->event_reserve(&ctx, event->id);
if (ret < 0)
static DEFINE_MUTEX(perf_counter_mutex);
static LIST_HEAD(perf_counter_contexts);
+static
+size_t perf_counter_get_size(size_t offset)
+{
+ size_t size = 0;
+
+ size += lib_ring_buffer_align(offset, ltt_alignof(uint64_t));
+ size += sizeof(uint64_t);
+ return size;
+}
+
static
void perf_counter_record(struct lttng_ctx_field *field,
struct lib_ring_buffer_ctx *ctx,
field->type.u.basic.integer.reverse_byte_order = 0;
field->type.u.basic.integer.base = 10;
field->type.u.basic.integer.encoding = lttng_encode_none;
- field->callback = perf_counter_record;
+ field->get_size = perf_counter_get_size;
+ field->record = perf_counter_record;
field->u.perf_counter.e = events;
field->u.perf_counter.attr = attr;