New API: lttng_ust_init_thread() for async-signal tracing
[lttng-ust.git] / liblttng-ust / lttng-ring-buffer-client.h
CommitLineData
3d1fc7fd 1/*
c0c0989a 2 * SPDX-License-Identifier: LGPL-2.1-only
3d1fc7fd 3 *
e92f3e28
MD
4 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
c0c0989a 6 * LTTng lib ring buffer client template.
3d1fc7fd
MD
7 */
8
9af5d97a 9#include <limits.h>
b4051ad8 10#include <stddef.h>
9f3fdbc6 11#include <stdint.h>
7753d283
MJ
12
13#include <ust-events-internal.h>
0950190a 14#include <lttng/urcu/pointer.h>
ae4b659d 15#include "ust-bitfield.h"
cd61d9bf 16#include "ust-compat.h"
b728d87e 17#include "clock.h"
cbbc1cda 18#include "context-internal.h"
7dd08bec 19#include "lttng-tracer.h"
9f3fdbc6 20#include "../libringbuffer/frontend_types.h"
8936b6c0 21#include <urcu/tls-compat.h>
3d1fc7fd 22
79dfbf42
MD
23#define LTTNG_COMPACT_EVENT_BITS 5
24#define LTTNG_COMPACT_TSC_BITS 27
25
ce7352a2
MD
26enum app_ctx_mode {
27 APP_CTX_DISABLED,
28 APP_CTX_ENABLED,
29};
30
3d1fc7fd
MD
31/*
32 * Keep the natural field alignment for _each field_ within this structure if
33 * you ever add/remove a field from this header. Packed attribute is not used
34 * because gcc generates poor code on at least powerpc and mips. Don't ever
35 * let gcc add padding between the structure elements.
36 */
37
38struct packet_header {
39 /* Trace packet header */
40 uint32_t magic; /*
41 * Trace magic number.
42 * contains endianness information.
43 */
19d8b1b3 44 uint8_t uuid[LTTNG_UST_UUID_LEN];
3d1fc7fd 45 uint32_t stream_id;
2d94adc5 46 uint64_t stream_instance_id;
3d1fc7fd
MD
47
48 struct {
49 /* Stream packet context */
50 uint64_t timestamp_begin; /* Cycle count at subbuffer start */
51 uint64_t timestamp_end; /* Cycle count at subbuffer end */
0c00a107
MD
52 uint64_t content_size; /* Size of data in subbuffer */
53 uint64_t packet_size; /* Subbuffer size (include padding) */
1ff31389 54 uint64_t packet_seq_num; /* Packet sequence number */
18fc8d71 55 unsigned long events_discarded; /*
3d1fc7fd
MD
56 * Events lost in this subbuffer since
57 * the beginning of the trace.
58 * (may overflow)
59 */
3d1fc7fd
MD
60 uint32_t cpu_id; /* CPU id associated with stream */
61 uint8_t header_end; /* End of header */
62 } ctx;
63};
64
e56bb47c
MD
65struct lttng_client_ctx {
66 size_t packet_context_len;
67 size_t event_context_len;
0950190a 68 struct lttng_ust_ctx *chan_ctx;
a40b5b8c 69 struct lttng_ust_ctx *event_ctx;
e56bb47c 70};
3d1fc7fd 71
8936b6c0
MD
72/*
73 * Indexed by lib_ring_buffer_nesting_count().
74 */
75typedef struct lttng_ust_lib_ring_buffer_ctx_private private_ctx_stack_t[LIB_RING_BUFFER_MAX_NESTING];
76static DEFINE_URCU_TLS(private_ctx_stack_t, private_ctx_stack);
77
78/*
79 * Force a read (imply TLS fixup for dlopen) of TLS variables.
80 */
14e0a135 81void RING_BUFFER_MODE_TEMPLATE_TLS_FIXUP(void)
8936b6c0
MD
82{
83 asm volatile ("" : : "m" (URCU_TLS(private_ctx_stack)));
84}
85
5198080d 86static inline uint64_t lib_ring_buffer_clock_read(struct lttng_ust_lib_ring_buffer_channel *chan)
3d1fc7fd
MD
87{
88 return trace_clock_read64();
89}
90
91static inline
daacdbfc 92size_t ctx_get_aligned_size(size_t offset, struct lttng_ust_ctx *ctx,
e56bb47c 93 size_t ctx_len)
3d1fc7fd 94{
3d1fc7fd
MD
95 size_t orig_offset = offset;
96
b5a3dfa5 97 if (caa_likely(!ctx))
3d1fc7fd 98 return 0;
3b8bedd8 99 offset += lttng_ust_lib_ring_buffer_align(offset, ctx->largest_align);
e56bb47c
MD
100 offset += ctx_len;
101 return offset - orig_offset;
102}
103
104static inline
daacdbfc 105void ctx_get_struct_size(struct lttng_ust_ctx *ctx, size_t *ctx_len,
e56bb47c
MD
106 enum app_ctx_mode mode)
107{
108 int i;
109 size_t offset = 0;
110
111 if (caa_likely(!ctx)) {
112 *ctx_len = 0;
113 return;
114 }
ce7352a2
MD
115 for (i = 0; i < ctx->nr_fields; i++) {
116 if (mode == APP_CTX_ENABLED) {
daacdbfc 117 offset += ctx->fields[i]->get_size(ctx->fields[i], offset);
ce7352a2 118 } else {
daacdbfc 119 if (lttng_context_is_app(ctx->fields[i]->event_field->name)) {
ce7352a2
MD
120 /*
121 * Before UST 2.8, we cannot use the
122 * application context, because we
123 * cannot trust that the handler used
124 * for get_size is the same used for
125 * ctx_record, which would result in
126 * corrupted traces when tracing
127 * concurrently with application context
128 * register/unregister.
129 */
daacdbfc 130 offset += lttng_ust_dummy_get_size(ctx->fields[i], offset);
ce7352a2 131 } else {
daacdbfc 132 offset += ctx->fields[i]->get_size(ctx->fields[i], offset);
ce7352a2
MD
133 }
134 }
135 }
e56bb47c 136 *ctx_len = offset;
3d1fc7fd
MD
137}
138
139static inline
4cfec15c 140void ctx_record(struct lttng_ust_lib_ring_buffer_ctx *bufctx,
e7bc0ef6 141 struct lttng_ust_channel_buffer *chan,
daacdbfc 142 struct lttng_ust_ctx *ctx,
ce7352a2 143 enum app_ctx_mode mode)
3d1fc7fd
MD
144{
145 int i;
146
b5a3dfa5 147 if (caa_likely(!ctx))
3d1fc7fd 148 return;
3b8bedd8 149 lttng_ust_lib_ring_buffer_align_ctx(bufctx, ctx->largest_align);
ce7352a2
MD
150 for (i = 0; i < ctx->nr_fields; i++) {
151 if (mode == APP_CTX_ENABLED) {
daacdbfc 152 ctx->fields[i]->record(ctx->fields[i], bufctx, chan);
ce7352a2 153 } else {
daacdbfc 154 if (lttng_context_is_app(ctx->fields[i]->event_field->name)) {
ce7352a2
MD
155 /*
156 * Before UST 2.8, we cannot use the
157 * application context, because we
158 * cannot trust that the handler used
159 * for get_size is the same used for
160 * ctx_record, which would result in
161 * corrupted traces when tracing
162 * concurrently with application context
163 * register/unregister.
164 */
daacdbfc 165 lttng_ust_dummy_record(ctx->fields[i], bufctx, chan);
ce7352a2 166 } else {
daacdbfc 167 ctx->fields[i]->record(ctx->fields[i], bufctx, chan);
ce7352a2
MD
168 }
169 }
170 }
3d1fc7fd
MD
171}
172
173/*
174 * record_header_size - Calculate the header size and padding necessary.
175 * @config: ring buffer instance configuration
176 * @chan: channel
177 * @offset: offset in the write buffer
178 * @pre_header_padding: padding to add before the header (output)
179 * @ctx: reservation context
180 *
181 * Returns the event header size (including padding).
182 *
183 * The payload must itself determine its own alignment from the biggest type it
184 * contains.
185 */
186static __inline__
8ca68914 187size_t record_header_size(const struct lttng_ust_lib_ring_buffer_config *config,
5198080d
MJ
188 struct lttng_ust_lib_ring_buffer_channel *chan,
189 size_t offset,
3d1fc7fd 190 size_t *pre_header_padding,
e56bb47c
MD
191 struct lttng_ust_lib_ring_buffer_ctx *ctx,
192 struct lttng_client_ctx *client_ctx)
3d1fc7fd 193{
e7bc0ef6 194 struct lttng_ust_channel_buffer *lttng_chan = channel_get_private(chan);
3d1fc7fd
MD
195 size_t orig_offset = offset;
196 size_t padding;
197
e7bc0ef6 198 switch (lttng_chan->priv->header_type) {
3d1fc7fd 199 case 1: /* compact */
dc325c1d 200 padding = lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(uint32_t));
3d1fc7fd 201 offset += padding;
8936b6c0 202 if (!(ctx->priv->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) {
3d1fc7fd
MD
203 offset += sizeof(uint32_t); /* id and timestamp */
204 } else {
79dfbf42
MD
205 /* Minimum space taken by LTTNG_COMPACT_EVENT_BITS id */
206 offset += (LTTNG_COMPACT_EVENT_BITS + CHAR_BIT - 1) / CHAR_BIT;
3d1fc7fd 207 /* Align extended struct on largest member */
dc325c1d 208 offset += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(uint64_t));
3d1fc7fd 209 offset += sizeof(uint32_t); /* id */
dc325c1d 210 offset += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(uint64_t));
3d1fc7fd
MD
211 offset += sizeof(uint64_t); /* timestamp */
212 }
213 break;
214 case 2: /* large */
dc325c1d 215 padding = lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(uint16_t));
3d1fc7fd
MD
216 offset += padding;
217 offset += sizeof(uint16_t);
8936b6c0 218 if (!(ctx->priv->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) {
dc325c1d 219 offset += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(uint32_t));
3d1fc7fd
MD
220 offset += sizeof(uint32_t); /* timestamp */
221 } else {
222 /* Align extended struct on largest member */
dc325c1d 223 offset += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(uint64_t));
3d1fc7fd 224 offset += sizeof(uint32_t); /* id */
dc325c1d 225 offset += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(uint64_t));
3d1fc7fd
MD
226 offset += sizeof(uint64_t); /* timestamp */
227 }
228 break;
229 default:
9f3fdbc6 230 padding = 0;
3d1fc7fd
MD
231 WARN_ON_ONCE(1);
232 }
0950190a 233 offset += ctx_get_aligned_size(offset, client_ctx->chan_ctx,
2b7080aa 234 client_ctx->packet_context_len);
a40b5b8c 235 offset += ctx_get_aligned_size(offset, client_ctx->event_ctx,
2b7080aa 236 client_ctx->event_context_len);
3d1fc7fd
MD
237 *pre_header_padding = padding;
238 return offset - orig_offset;
239}
240
9f3fdbc6 241#include "../libringbuffer/api.h"
82b9bde8 242#include "lttng-rb-clients.h"
3d1fc7fd 243
9f3fdbc6 244static
7dd08bec 245void lttng_write_event_header_slow(const struct lttng_ust_lib_ring_buffer_config *config,
4cfec15c 246 struct lttng_ust_lib_ring_buffer_ctx *ctx,
0950190a 247 struct lttng_client_ctx *client_ctx,
3d1fc7fd
MD
248 uint32_t event_id);
249
250/*
7dd08bec 251 * lttng_write_event_header
3d1fc7fd
MD
252 *
253 * Writes the event header to the offset (already aligned on 32-bits).
254 *
255 * @config: ring buffer instance configuration
256 * @ctx: reservation context
257 * @event_id: event ID
258 */
259static __inline__
7dd08bec 260void lttng_write_event_header(const struct lttng_ust_lib_ring_buffer_config *config,
4cfec15c 261 struct lttng_ust_lib_ring_buffer_ctx *ctx,
0950190a 262 struct lttng_client_ctx *client_ctx,
3d1fc7fd
MD
263 uint32_t event_id)
264{
8936b6c0 265 struct lttng_ust_channel_buffer *lttng_chan = channel_get_private(ctx->priv->chan);
3d1fc7fd 266
8936b6c0 267 if (caa_unlikely(ctx->priv->rflags))
3d1fc7fd
MD
268 goto slow_path;
269
e7bc0ef6 270 switch (lttng_chan->priv->header_type) {
3d1fc7fd
MD
271 case 1: /* compact */
272 {
273 uint32_t id_time = 0;
274
79dfbf42
MD
275 bt_bitfield_write(&id_time, uint32_t,
276 0,
277 LTTNG_COMPACT_EVENT_BITS,
278 event_id);
279 bt_bitfield_write(&id_time, uint32_t,
280 LTTNG_COMPACT_EVENT_BITS,
281 LTTNG_COMPACT_TSC_BITS,
8936b6c0 282 ctx->priv->tsc);
3d1fc7fd
MD
283 lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time));
284 break;
285 }
286 case 2: /* large */
287 {
8936b6c0 288 uint32_t timestamp = (uint32_t) ctx->priv->tsc;
3d1fc7fd
MD
289 uint16_t id = event_id;
290
291 lib_ring_buffer_write(config, ctx, &id, sizeof(id));
dc325c1d 292 lttng_ust_lib_ring_buffer_align_ctx(ctx, lttng_ust_rb_alignof(uint32_t));
3d1fc7fd
MD
293 lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
294 break;
295 }
296 default:
297 WARN_ON_ONCE(1);
298 }
299
0950190a 300 ctx_record(ctx, lttng_chan, client_ctx->chan_ctx, APP_CTX_ENABLED);
a40b5b8c 301 ctx_record(ctx, lttng_chan, client_ctx->event_ctx, APP_CTX_ENABLED);
3b8bedd8 302 lttng_ust_lib_ring_buffer_align_ctx(ctx, ctx->largest_align);
3d1fc7fd
MD
303
304 return;
305
306slow_path:
0950190a 307 lttng_write_event_header_slow(config, ctx, client_ctx, event_id);
3d1fc7fd
MD
308}
309
9f3fdbc6 310static
7dd08bec 311void lttng_write_event_header_slow(const struct lttng_ust_lib_ring_buffer_config *config,
4cfec15c 312 struct lttng_ust_lib_ring_buffer_ctx *ctx,
0950190a 313 struct lttng_client_ctx *client_ctx,
3d1fc7fd
MD
314 uint32_t event_id)
315{
8936b6c0
MD
316 struct lttng_ust_lib_ring_buffer_ctx_private *ctx_private = ctx->priv;
317 struct lttng_ust_channel_buffer *lttng_chan = channel_get_private(ctx->priv->chan);
3d1fc7fd 318
e7bc0ef6 319 switch (lttng_chan->priv->header_type) {
3d1fc7fd 320 case 1: /* compact */
8936b6c0 321 if (!(ctx_private->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) {
3d1fc7fd
MD
322 uint32_t id_time = 0;
323
79dfbf42
MD
324 bt_bitfield_write(&id_time, uint32_t,
325 0,
326 LTTNG_COMPACT_EVENT_BITS,
327 event_id);
328 bt_bitfield_write(&id_time, uint32_t,
329 LTTNG_COMPACT_EVENT_BITS,
330 LTTNG_COMPACT_TSC_BITS,
8936b6c0 331 ctx_private->tsc);
3d1fc7fd
MD
332 lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time));
333 } else {
334 uint8_t id = 0;
8936b6c0 335 uint64_t timestamp = ctx_private->tsc;
3d1fc7fd 336
79dfbf42
MD
337 bt_bitfield_write(&id, uint8_t,
338 0,
339 LTTNG_COMPACT_EVENT_BITS,
340 31);
3d1fc7fd
MD
341 lib_ring_buffer_write(config, ctx, &id, sizeof(id));
342 /* Align extended struct on largest member */
dc325c1d 343 lttng_ust_lib_ring_buffer_align_ctx(ctx, lttng_ust_rb_alignof(uint64_t));
3d1fc7fd 344 lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id));
dc325c1d 345 lttng_ust_lib_ring_buffer_align_ctx(ctx, lttng_ust_rb_alignof(uint64_t));
3d1fc7fd
MD
346 lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
347 }
348 break;
349 case 2: /* large */
350 {
8936b6c0
MD
351 if (!(ctx_private->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) {
352 uint32_t timestamp = (uint32_t) ctx_private->tsc;
3d1fc7fd
MD
353 uint16_t id = event_id;
354
355 lib_ring_buffer_write(config, ctx, &id, sizeof(id));
dc325c1d 356 lttng_ust_lib_ring_buffer_align_ctx(ctx, lttng_ust_rb_alignof(uint32_t));
3d1fc7fd
MD
357 lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
358 } else {
359 uint16_t id = 65535;
8936b6c0 360 uint64_t timestamp = ctx_private->tsc;
3d1fc7fd
MD
361
362 lib_ring_buffer_write(config, ctx, &id, sizeof(id));
363 /* Align extended struct on largest member */
dc325c1d 364 lttng_ust_lib_ring_buffer_align_ctx(ctx, lttng_ust_rb_alignof(uint64_t));
3d1fc7fd 365 lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id));
dc325c1d 366 lttng_ust_lib_ring_buffer_align_ctx(ctx, lttng_ust_rb_alignof(uint64_t));
3d1fc7fd
MD
367 lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
368 }
369 break;
370 }
371 default:
372 WARN_ON_ONCE(1);
373 }
0950190a 374 ctx_record(ctx, lttng_chan, client_ctx->chan_ctx, APP_CTX_ENABLED);
a40b5b8c 375 ctx_record(ctx, lttng_chan, client_ctx->event_ctx, APP_CTX_ENABLED);
3b8bedd8 376 lttng_ust_lib_ring_buffer_align_ctx(ctx, ctx->largest_align);
3d1fc7fd
MD
377}
378
4cfec15c 379static const struct lttng_ust_lib_ring_buffer_config client_config;
3d1fc7fd 380
5198080d 381static uint64_t client_ring_buffer_clock_read(struct lttng_ust_lib_ring_buffer_channel *chan)
3d1fc7fd
MD
382{
383 return lib_ring_buffer_clock_read(chan);
384}
385
386static
4cfec15c 387size_t client_record_header_size(const struct lttng_ust_lib_ring_buffer_config *config,
5198080d
MJ
388 struct lttng_ust_lib_ring_buffer_channel *chan,
389 size_t offset,
3d1fc7fd 390 size_t *pre_header_padding,
e56bb47c
MD
391 struct lttng_ust_lib_ring_buffer_ctx *ctx,
392 void *client_ctx)
3d1fc7fd
MD
393{
394 return record_header_size(config, chan, offset,
e56bb47c 395 pre_header_padding, ctx, client_ctx);
3d1fc7fd
MD
396}
397
398/**
399 * client_packet_header_size - called on buffer-switch to a new sub-buffer
400 *
401 * Return header size without padding after the structure. Don't use packed
402 * structure because gcc generates inefficient code on some architectures
403 * (powerpc, mips..)
404 */
405static size_t client_packet_header_size(void)
406{
407 return offsetof(struct packet_header, ctx.header_end);
408}
409
23c8854a 410static void client_buffer_begin(struct lttng_ust_lib_ring_buffer *buf, uint64_t tsc,
1d498196 411 unsigned int subbuf_idx,
38fae1d3 412 struct lttng_ust_shm_handle *handle)
3d1fc7fd 413{
5198080d 414 struct lttng_ust_lib_ring_buffer_channel *chan = shmp(handle, buf->backend.chan);
3d1fc7fd
MD
415 struct packet_header *header =
416 (struct packet_header *)
417 lib_ring_buffer_offset_address(&buf->backend,
1d498196
MD
418 subbuf_idx * chan->backend.subbuf_size,
419 handle);
e7bc0ef6 420 struct lttng_ust_channel_buffer *lttng_chan = channel_get_private(chan);
1ff31389 421 uint64_t cnt = shmp_index(handle, buf->backend.buf_cnt, subbuf_idx)->seq_cnt;
3d1fc7fd 422
34daae3e
MD
423 assert(header);
424 if (!header)
425 return;
3d1fc7fd 426 header->magic = CTF_MAGIC_NUMBER;
e7bc0ef6
MD
427 memcpy(header->uuid, lttng_chan->priv->uuid, sizeof(lttng_chan->priv->uuid));
428 header->stream_id = lttng_chan->priv->id;
2d94adc5 429 header->stream_instance_id = buf->backend.cpu;
3d1fc7fd
MD
430 header->ctx.timestamp_begin = tsc;
431 header->ctx.timestamp_end = 0;
0c00a107
MD
432 header->ctx.content_size = ~0ULL; /* for debugging */
433 header->ctx.packet_size = ~0ULL;
1ff31389 434 header->ctx.packet_seq_num = chan->backend.num_subbuf * cnt + subbuf_idx;
3d1fc7fd 435 header->ctx.events_discarded = 0;
3d1fc7fd
MD
436 header->ctx.cpu_id = buf->backend.cpu;
437}
438
439/*
440 * offset is assumed to never be 0 here : never deliver a completely empty
441 * subbuffer. data_size is between 1 and subbuf_size.
442 */
23c8854a 443static void client_buffer_end(struct lttng_ust_lib_ring_buffer *buf, uint64_t tsc,
1d498196 444 unsigned int subbuf_idx, unsigned long data_size,
38fae1d3 445 struct lttng_ust_shm_handle *handle)
3d1fc7fd 446{
5198080d 447 struct lttng_ust_lib_ring_buffer_channel *chan = shmp(handle, buf->backend.chan);
3d1fc7fd
MD
448 struct packet_header *header =
449 (struct packet_header *)
450 lib_ring_buffer_offset_address(&buf->backend,
1d498196
MD
451 subbuf_idx * chan->backend.subbuf_size,
452 handle);
3d1fc7fd
MD
453 unsigned long records_lost = 0;
454
34daae3e
MD
455 assert(header);
456 if (!header)
457 return;
3d1fc7fd 458 header->ctx.timestamp_end = tsc;
b1830883
MD
459 header->ctx.content_size =
460 (uint64_t) data_size * CHAR_BIT; /* in bits */
461 header->ctx.packet_size =
b72687b8 462 (uint64_t) LTTNG_UST_PAGE_ALIGN(data_size) * CHAR_BIT; /* in bits */
04489ab4
MD
463
464 records_lost += lib_ring_buffer_get_records_lost_full(&client_config, buf);
3d1fc7fd
MD
465 records_lost += lib_ring_buffer_get_records_lost_wrap(&client_config, buf);
466 records_lost += lib_ring_buffer_get_records_lost_big(&client_config, buf);
467 header->ctx.events_discarded = records_lost;
468}
469
4cfec15c 470static int client_buffer_create(struct lttng_ust_lib_ring_buffer *buf, void *priv,
38fae1d3 471 int cpu, const char *name, struct lttng_ust_shm_handle *handle)
3d1fc7fd
MD
472{
473 return 0;
474}
475
4cfec15c 476static void client_buffer_finalize(struct lttng_ust_lib_ring_buffer *buf, void *priv, int cpu, struct lttng_ust_shm_handle *handle)
3d1fc7fd
MD
477{
478}
479
a9ff648c
MD
480static void client_content_size_field(const struct lttng_ust_lib_ring_buffer_config *config,
481 size_t *offset, size_t *length)
482{
483 *offset = offsetof(struct packet_header, ctx.content_size);
484 *length = sizeof(((struct packet_header *) NULL)->ctx.content_size);
485}
486
487static void client_packet_size_field(const struct lttng_ust_lib_ring_buffer_config *config,
488 size_t *offset, size_t *length)
489{
490 *offset = offsetof(struct packet_header, ctx.packet_size);
491 *length = sizeof(((struct packet_header *) NULL)->ctx.packet_size);
492}
493
b2f3252a
JD
494static struct packet_header *client_packet_header(struct lttng_ust_lib_ring_buffer *buf,
495 struct lttng_ust_shm_handle *handle)
496{
c4d6bd10 497 return lib_ring_buffer_read_offset_address(&buf->backend, 0, handle);
b2f3252a
JD
498}
499
500static int client_timestamp_begin(struct lttng_ust_lib_ring_buffer *buf,
07539b34 501 struct lttng_ust_lib_ring_buffer_channel *chan,
b2f3252a
JD
502 uint64_t *timestamp_begin)
503{
07539b34 504 struct lttng_ust_shm_handle *handle = chan->handle;
b2f3252a
JD
505 struct packet_header *header;
506
507 header = client_packet_header(buf, handle);
34daae3e
MD
508 if (!header)
509 return -1;
b2f3252a
JD
510 *timestamp_begin = header->ctx.timestamp_begin;
511 return 0;
512}
513
514static int client_timestamp_end(struct lttng_ust_lib_ring_buffer *buf,
07539b34 515 struct lttng_ust_lib_ring_buffer_channel *chan,
b2f3252a
JD
516 uint64_t *timestamp_end)
517{
07539b34 518 struct lttng_ust_shm_handle *handle = chan->handle;
b2f3252a
JD
519 struct packet_header *header;
520
521 header = client_packet_header(buf, handle);
34daae3e
MD
522 if (!header)
523 return -1;
b2f3252a
JD
524 *timestamp_end = header->ctx.timestamp_end;
525 return 0;
526}
527
528static int client_events_discarded(struct lttng_ust_lib_ring_buffer *buf,
07539b34 529 struct lttng_ust_lib_ring_buffer_channel *chan,
b2f3252a
JD
530 uint64_t *events_discarded)
531{
07539b34 532 struct lttng_ust_shm_handle *handle = chan->handle;
b2f3252a
JD
533 struct packet_header *header;
534
535 header = client_packet_header(buf, handle);
34daae3e
MD
536 if (!header)
537 return -1;
b2f3252a
JD
538 *events_discarded = header->ctx.events_discarded;
539 return 0;
540}
541
542static int client_content_size(struct lttng_ust_lib_ring_buffer *buf,
07539b34 543 struct lttng_ust_lib_ring_buffer_channel *chan,
b2f3252a
JD
544 uint64_t *content_size)
545{
07539b34 546 struct lttng_ust_shm_handle *handle = chan->handle;
b2f3252a
JD
547 struct packet_header *header;
548
549 header = client_packet_header(buf, handle);
34daae3e
MD
550 if (!header)
551 return -1;
b2f3252a
JD
552 *content_size = header->ctx.content_size;
553 return 0;
554}
555
556static int client_packet_size(struct lttng_ust_lib_ring_buffer *buf,
07539b34 557 struct lttng_ust_lib_ring_buffer_channel *chan,
b2f3252a
JD
558 uint64_t *packet_size)
559{
07539b34 560 struct lttng_ust_shm_handle *handle = chan->handle;
b2f3252a
JD
561 struct packet_header *header;
562
563 header = client_packet_header(buf, handle);
34daae3e
MD
564 if (!header)
565 return -1;
b2f3252a
JD
566 *packet_size = header->ctx.packet_size;
567 return 0;
568}
569
570static int client_stream_id(struct lttng_ust_lib_ring_buffer *buf,
07539b34 571 struct lttng_ust_lib_ring_buffer_channel *chan,
b2f3252a
JD
572 uint64_t *stream_id)
573{
e7bc0ef6 574 struct lttng_ust_channel_buffer *lttng_chan = channel_get_private(chan);
db95cf8b 575
e7bc0ef6 576 *stream_id = lttng_chan->priv->id;
b2f3252a 577
b2f3252a
JD
578 return 0;
579}
580
fca361e8 581static int client_current_timestamp(struct lttng_ust_lib_ring_buffer *buf,
07539b34 582 struct lttng_ust_lib_ring_buffer_channel *chan,
fca361e8
JD
583 uint64_t *ts)
584{
fca361e8
JD
585 *ts = client_ring_buffer_clock_read(chan);
586
587 return 0;
588}
589
1ff31389 590static int client_sequence_number(struct lttng_ust_lib_ring_buffer *buf,
07539b34 591 struct lttng_ust_lib_ring_buffer_channel *chan,
1ff31389
JD
592 uint64_t *seq)
593{
07539b34 594 struct lttng_ust_shm_handle *handle = chan->handle;
1ff31389
JD
595 struct packet_header *header;
596
597 header = client_packet_header(buf, handle);
3e1db88d
MD
598 if (!header)
599 return -1;
1ff31389
JD
600 *seq = header->ctx.packet_seq_num;
601 return 0;
602}
603
45a00b05 604static int client_instance_id(struct lttng_ust_lib_ring_buffer *buf,
07539b34 605 struct lttng_ust_lib_ring_buffer_channel *chan,
45a00b05
JD
606 uint64_t *id)
607{
db95cf8b 608 *id = buf->backend.cpu;
45a00b05 609
45a00b05
JD
610 return 0;
611}
612
82b9bde8
JD
613static const
614struct lttng_ust_client_lib_ring_buffer_client_cb client_cb = {
615 .parent = {
616 .ring_buffer_clock_read = client_ring_buffer_clock_read,
617 .record_header_size = client_record_header_size,
618 .subbuffer_header_size = client_packet_header_size,
619 .buffer_begin = client_buffer_begin,
620 .buffer_end = client_buffer_end,
621 .buffer_create = client_buffer_create,
622 .buffer_finalize = client_buffer_finalize,
a9ff648c
MD
623 .content_size_field = client_content_size_field,
624 .packet_size_field = client_packet_size_field,
82b9bde8 625 },
b2f3252a
JD
626 .timestamp_begin = client_timestamp_begin,
627 .timestamp_end = client_timestamp_end,
628 .events_discarded = client_events_discarded,
629 .content_size = client_content_size,
630 .packet_size = client_packet_size,
631 .stream_id = client_stream_id,
fca361e8 632 .current_timestamp = client_current_timestamp,
1ff31389 633 .sequence_number = client_sequence_number,
45a00b05 634 .instance_id = client_instance_id,
82b9bde8
JD
635};
636
4cfec15c 637static const struct lttng_ust_lib_ring_buffer_config client_config = {
3d1fc7fd
MD
638 .cb.ring_buffer_clock_read = client_ring_buffer_clock_read,
639 .cb.record_header_size = client_record_header_size,
640 .cb.subbuffer_header_size = client_packet_header_size,
641 .cb.buffer_begin = client_buffer_begin,
642 .cb.buffer_end = client_buffer_end,
643 .cb.buffer_create = client_buffer_create,
644 .cb.buffer_finalize = client_buffer_finalize,
a9ff648c
MD
645 .cb.content_size_field = client_content_size_field,
646 .cb.packet_size_field = client_packet_size_field,
3d1fc7fd 647
79dfbf42 648 .tsc_bits = LTTNG_COMPACT_TSC_BITS,
3d1fc7fd 649 .alloc = RING_BUFFER_ALLOC_PER_CPU,
5d61a504 650 .sync = RING_BUFFER_SYNC_GLOBAL,
3d1fc7fd
MD
651 .mode = RING_BUFFER_MODE_TEMPLATE,
652 .backend = RING_BUFFER_PAGE,
5d61a504 653 .output = RING_BUFFER_MMAP,
3d1fc7fd 654 .oops = RING_BUFFER_OOPS_CONSISTENCY,
5d61a504 655 .ipi = RING_BUFFER_NO_IPI_BARRIER,
34a91bdb 656 .wakeup = LTTNG_CLIENT_WAKEUP,
c1fca457 657 .client_type = LTTNG_CLIENT_TYPE,
82b9bde8
JD
658
659 .cb_ptr = &client_cb.parent,
3d1fc7fd
MD
660};
661
662static
e7bc0ef6 663struct lttng_ust_channel_buffer *_channel_create(const char *name,
a3f61e7f 664 void *buf_addr,
3d1fc7fd
MD
665 size_t subbuf_size, size_t num_subbuf,
666 unsigned int switch_timer_interval,
193183fb 667 unsigned int read_timer_interval,
6ca18e66 668 unsigned char *uuid,
a9ff648c 669 uint32_t chan_id,
b2c5f61a
MD
670 const int *stream_fds, int nr_stream_fds,
671 int64_t blocking_timeout)
3d1fc7fd 672{
f0fde1c3 673 struct lttng_ust_abi_channel_config chan_priv_init;
a3f61e7f 674 struct lttng_ust_shm_handle *handle;
e7bc0ef6 675 struct lttng_ust_channel_buffer *lttng_chan_buf;
f0fde1c3 676
e7bc0ef6
MD
677 lttng_chan_buf = lttng_ust_alloc_channel_buffer();
678 if (!lttng_chan_buf)
f0fde1c3 679 return NULL;
e7bc0ef6
MD
680 memcpy(lttng_chan_buf->priv->uuid, uuid, LTTNG_UST_UUID_LEN);
681 lttng_chan_buf->priv->id = chan_id;
a3f61e7f 682
74d81a6c
MD
683 memset(&chan_priv_init, 0, sizeof(chan_priv_init));
684 memcpy(chan_priv_init.uuid, uuid, LTTNG_UST_UUID_LEN);
6ca18e66 685 chan_priv_init.id = chan_id;
f0fde1c3 686
a3f61e7f 687 handle = channel_create(&client_config, name,
f0fde1c3
MD
688 __alignof__(struct lttng_ust_abi_channel_config),
689 sizeof(struct lttng_ust_abi_channel_config),
74d81a6c 690 &chan_priv_init,
e7bc0ef6 691 lttng_chan_buf, buf_addr, subbuf_size, num_subbuf,
a9ff648c 692 switch_timer_interval, read_timer_interval,
b2c5f61a 693 stream_fds, nr_stream_fds, blocking_timeout);
a3f61e7f 694 if (!handle)
f0fde1c3 695 goto error;
07539b34 696 lttng_chan_buf->priv->rb_chan = shmp(handle, handle->chan);
e7bc0ef6 697 return lttng_chan_buf;
f0fde1c3
MD
698
699error:
e7bc0ef6 700 lttng_ust_free_channel_common(lttng_chan_buf->parent);
f0fde1c3 701 return NULL;
3d1fc7fd
MD
702}
703
704static
e7bc0ef6 705void lttng_channel_destroy(struct lttng_ust_channel_buffer *lttng_chan_buf)
3d1fc7fd 706{
07539b34 707 channel_destroy(lttng_chan_buf->priv->rb_chan, lttng_chan_buf->priv->rb_chan->handle, 1);
e7bc0ef6 708 lttng_ust_free_channel_common(lttng_chan_buf->parent);
3d1fc7fd
MD
709}
710
711static
8936b6c0 712int lttng_event_reserve(struct lttng_ust_lib_ring_buffer_ctx *ctx)
3d1fc7fd 713{
8936b6c0 714 struct lttng_ust_event_recorder *event_recorder = ctx->client_priv;
07539b34 715 struct lttng_ust_channel_buffer *lttng_chan = event_recorder->chan;
e56bb47c 716 struct lttng_client_ctx client_ctx;
8936b6c0
MD
717 int ret, nesting;
718 struct lttng_ust_lib_ring_buffer_ctx_private *private_ctx;
719 uint32_t event_id;
3d1fc7fd 720
8936b6c0 721 event_id = event_recorder->priv->id;
0950190a 722 client_ctx.chan_ctx = lttng_ust_rcu_dereference(lttng_chan->priv->ctx);
a40b5b8c 723 client_ctx.event_ctx = lttng_ust_rcu_dereference(event_recorder->priv->ctx);
e56bb47c 724 /* Compute internal size of context structures. */
0950190a 725 ctx_get_struct_size(client_ctx.chan_ctx, &client_ctx.packet_context_len,
2b7080aa 726 APP_CTX_ENABLED);
a40b5b8c 727 ctx_get_struct_size(client_ctx.event_ctx, &client_ctx.event_context_len,
2b7080aa 728 APP_CTX_ENABLED);
e56bb47c 729
8936b6c0
MD
730 nesting = lib_ring_buffer_nesting_inc(&client_config);
731 if (nesting < 0)
3d1fc7fd 732 return -EPERM;
3d1fc7fd 733
f37bd904 734 private_ctx = &URCU_TLS(private_ctx_stack)[nesting];
8936b6c0
MD
735 memset(private_ctx, 0, sizeof(*private_ctx));
736 private_ctx->pub = ctx;
737 private_ctx->chan = lttng_chan->priv->rb_chan;
738
739 ctx->priv = private_ctx;
740
e7bc0ef6 741 switch (lttng_chan->priv->header_type) {
3d1fc7fd
MD
742 case 1: /* compact */
743 if (event_id > 30)
8936b6c0 744 private_ctx->rflags |= LTTNG_RFLAG_EXTENDED;
3d1fc7fd
MD
745 break;
746 case 2: /* large */
747 if (event_id > 65534)
8936b6c0 748 private_ctx->rflags |= LTTNG_RFLAG_EXTENDED;
3d1fc7fd
MD
749 break;
750 default:
751 WARN_ON_ONCE(1);
752 }
753
e56bb47c 754 ret = lib_ring_buffer_reserve(&client_config, ctx, &client_ctx);
630d6836 755 if (caa_unlikely(ret))
3d1fc7fd 756 goto put;
2b7080aa 757 if (lib_ring_buffer_backend_get_pages(&client_config, ctx,
8936b6c0 758 &private_ctx->backend_pages)) {
2b7080aa
MD
759 ret = -EPERM;
760 goto put;
a3492932 761 }
0950190a 762 lttng_write_event_header(&client_config, ctx, &client_ctx, event_id);
3d1fc7fd
MD
763 return 0;
764put:
7489fcb4 765 lib_ring_buffer_nesting_dec(&client_config);
3d1fc7fd
MD
766 return ret;
767}
768
769static
7dd08bec 770void lttng_event_commit(struct lttng_ust_lib_ring_buffer_ctx *ctx)
3d1fc7fd
MD
771{
772 lib_ring_buffer_commit(&client_config, ctx);
7489fcb4 773 lib_ring_buffer_nesting_dec(&client_config);
3d1fc7fd
MD
774}
775
776static
8936b6c0
MD
777void lttng_event_write(struct lttng_ust_lib_ring_buffer_ctx *ctx,
778 const void *src, size_t len, size_t alignment)
3d1fc7fd 779{
8936b6c0 780 lttng_ust_lib_ring_buffer_align_ctx(ctx, alignment);
3d1fc7fd
MD
781 lib_ring_buffer_write(&client_config, ctx, src, len);
782}
783
a44c74d9 784static
8936b6c0
MD
785void lttng_event_strcpy(struct lttng_ust_lib_ring_buffer_ctx *ctx,
786 const char *src, size_t len)
a44c74d9
MD
787{
788 lib_ring_buffer_strcpy(&client_config, ctx, src, len, '#');
789}
790
27927814 791static
879f9b0a 792void lttng_event_pstrcpy_pad(struct lttng_ust_lib_ring_buffer_ctx *ctx,
8936b6c0 793 const char *src, size_t len)
27927814 794{
879f9b0a 795 lib_ring_buffer_pstrcpy(&client_config, ctx, src, len, '\0');
27927814
MD
796}
797
3d1fc7fd 798static
07539b34 799int lttng_is_finalized(struct lttng_ust_channel_buffer *chan)
3d1fc7fd 800{
07539b34 801 struct lttng_ust_lib_ring_buffer_channel *rb_chan = chan->priv->rb_chan;
3d1fc7fd 802
07539b34 803 return lib_ring_buffer_channel_is_finalized(rb_chan);
3d1fc7fd
MD
804}
805
806static
07539b34 807int lttng_is_disabled(struct lttng_ust_channel_buffer *chan)
3d1fc7fd 808{
07539b34 809 struct lttng_ust_lib_ring_buffer_channel *rb_chan = chan->priv->rb_chan;
3d1fc7fd 810
07539b34 811 return lib_ring_buffer_channel_is_disabled(rb_chan);
3d1fc7fd
MD
812}
813
43861eab 814static
07539b34 815int lttng_flush_buffer(struct lttng_ust_channel_buffer *chan)
43861eab 816{
07539b34 817 struct lttng_ust_lib_ring_buffer_channel *rb_chan = chan->priv->rb_chan;
4cfec15c 818 struct lttng_ust_lib_ring_buffer *buf;
43861eab
MD
819 int cpu;
820
07539b34 821 for_each_channel_cpu(cpu, rb_chan) {
74d81a6c
MD
822 int shm_fd, wait_fd, wakeup_fd;
823 uint64_t memory_map_size;
43861eab 824
07539b34
MD
825 buf = channel_get_ring_buffer(&client_config, rb_chan,
826 cpu, rb_chan->handle, &shm_fd, &wait_fd,
74d81a6c 827 &wakeup_fd, &memory_map_size);
43861eab 828 lib_ring_buffer_switch(&client_config, buf,
07539b34 829 SWITCH_ACTIVE, rb_chan->handle);
43861eab
MD
830 }
831 return 0;
832}
833
7dd08bec 834static struct lttng_transport lttng_relay_transport = {
818173b9 835 .name = "relay-" RING_BUFFER_MODE_TEMPLATE_STRING "-mmap",
3d1fc7fd 836 .ops = {
14b6f891
MD
837 .struct_size = sizeof(struct lttng_ust_channel_buffer_ops),
838 .priv = __LTTNG_COMPOUND_LITERAL(struct lttng_ust_channel_buffer_ops_private, {
a880bae5
MD
839 .pub = &lttng_relay_transport.ops,
840 .channel_create = _channel_create,
841 .channel_destroy = lttng_channel_destroy,
842 .packet_avail_size = NULL, /* Would be racy anyway */
843 .is_finalized = lttng_is_finalized,
844 .is_disabled = lttng_is_disabled,
845 .flush_buffer = lttng_flush_buffer,
846 }),
7dd08bec
MD
847 .event_reserve = lttng_event_reserve,
848 .event_commit = lttng_event_commit,
849 .event_write = lttng_event_write,
a44c74d9 850 .event_strcpy = lttng_event_strcpy,
879f9b0a 851 .event_pstrcpy_pad = lttng_event_pstrcpy_pad,
3d1fc7fd 852 },
74d81a6c 853 .client_config = &client_config,
3d1fc7fd
MD
854};
855
edaa1431 856void RING_BUFFER_MODE_TEMPLATE_INIT(void)
3d1fc7fd 857{
34a91bdb
MD
858 DBG("LTT : ltt ring buffer client \"%s\" init\n",
859 "relay-" RING_BUFFER_MODE_TEMPLATE_STRING "-mmap");
7dd08bec 860 lttng_transport_register(&lttng_relay_transport);
3d1fc7fd
MD
861}
862
edaa1431 863void RING_BUFFER_MODE_TEMPLATE_EXIT(void)
3d1fc7fd 864{
34a91bdb
MD
865 DBG("LTT : ltt ring buffer client \"%s\" exit\n",
866 "relay-" RING_BUFFER_MODE_TEMPLATE_STRING "-mmap");
7dd08bec 867 lttng_transport_unregister(&lttng_relay_transport);
3d1fc7fd 868}
This page took 0.085992 seconds and 4 git commands to generate.