2 * SPDX-License-Identifier: LGPL-2.1-only
4 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 * LTTng UST trace/channel/event context management.
10 #include <lttng/ust-events.h>
11 #include <lttng/ust-tracer.h>
12 #include <ust-context-provider.h>
13 #include <lttng/urcu/pointer.h>
14 #include <usterr-signal-safe.h>
19 #include "tracepoint-internal.h"
21 #include "context-internal.h"
24 * The filter implementation requires that two consecutive "get" for the
25 * same context performed by the same thread return the same result.
28 int lttng_find_context(struct lttng_ctx
*ctx
, const char *name
)
33 if (strncmp(name
, "$ctx.", strlen("$ctx.")) == 0) {
34 subname
= name
+ strlen("$ctx.");
38 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
39 /* Skip allocated (but non-initialized) contexts */
40 if (!ctx
->fields
[i
].event_field
.name
)
42 if (!strcmp(ctx
->fields
[i
].event_field
.name
, subname
))
48 int lttng_get_context_index(struct lttng_ctx
*ctx
, const char *name
)
55 if (strncmp(name
, "$ctx.", strlen("$ctx.")) == 0) {
56 subname
= name
+ strlen("$ctx.");
60 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
61 /* Skip allocated (but non-initialized) contexts */
62 if (!ctx
->fields
[i
].event_field
.name
)
64 if (!strcmp(ctx
->fields
[i
].event_field
.name
, subname
))
70 static int lttng_find_context_provider(struct lttng_ctx
*ctx
, const char *name
)
74 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
75 /* Skip allocated (but non-initialized) contexts */
76 if (!ctx
->fields
[i
].event_field
.name
)
78 if (!strncmp(ctx
->fields
[i
].event_field
.name
, name
,
86 * Note: as we append context information, the pointer location may change.
88 struct lttng_ctx_field
*lttng_append_context(struct lttng_ctx
**ctx_p
)
90 struct lttng_ctx_field
*field
;
91 struct lttng_ctx
*ctx
;
94 *ctx_p
= zmalloc(sizeof(struct lttng_ctx
));
97 (*ctx_p
)->largest_align
= 1;
100 if (ctx
->nr_fields
+ 1 > ctx
->allocated_fields
) {
101 struct lttng_ctx_field
*new_fields
;
103 ctx
->allocated_fields
= max_t(size_t, 1, 2 * ctx
->allocated_fields
);
104 new_fields
= zmalloc(ctx
->allocated_fields
* sizeof(struct lttng_ctx_field
));
108 memcpy(new_fields
, ctx
->fields
, sizeof(*ctx
->fields
) * ctx
->nr_fields
);
110 ctx
->fields
= new_fields
;
112 field
= &ctx
->fields
[ctx
->nr_fields
];
117 int lttng_context_add_rcu(struct lttng_ctx
**ctx_p
,
118 const struct lttng_ctx_field
*f
)
120 struct lttng_ctx
*old_ctx
= *ctx_p
, *new_ctx
= NULL
;
121 struct lttng_ctx_field
*new_fields
= NULL
;
122 struct lttng_ctx_field
*nf
;
125 new_ctx
= zmalloc(sizeof(struct lttng_ctx
));
129 new_fields
= zmalloc(new_ctx
->allocated_fields
130 * sizeof(struct lttng_ctx_field
));
135 memcpy(new_fields
, old_ctx
->fields
,
136 sizeof(*old_ctx
->fields
) * old_ctx
->nr_fields
);
137 new_ctx
->fields
= new_fields
;
139 nf
= lttng_append_context(&new_ctx
);
146 lttng_context_update(new_ctx
);
147 lttng_ust_rcu_assign_pointer(*ctx_p
, new_ctx
);
148 lttng_ust_synchronize_trace();
150 free(old_ctx
->fields
);
157 * lttng_context_update() should be called at least once between context
158 * modification and trace start.
160 void lttng_context_update(struct lttng_ctx
*ctx
)
163 size_t largest_align
= 8; /* in bits */
165 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
166 struct lttng_type
*type
;
167 size_t field_align
= 8;
169 type
= &ctx
->fields
[i
].event_field
.type
;
170 switch (type
->atype
) {
172 field_align
= type
->u
.integer
.alignment
;
176 struct lttng_basic_type
*btype
;
178 btype
= &type
->u
.legacy
.array
.elem_type
;
179 switch (btype
->atype
) {
181 field_align
= btype
->u
.basic
.integer
.alignment
;
187 case atype_array_nestable
:
189 case atype_sequence_nestable
:
196 case atype_array_nestable
:
198 const struct lttng_type
*nested_type
;
200 nested_type
= type
->u
.array_nestable
.elem_type
;
201 switch (nested_type
->atype
) {
203 field_align
= nested_type
->u
.integer
.alignment
;
209 case atype_array_nestable
:
211 case atype_sequence_nestable
:
216 field_align
= max_t(size_t, field_align
,
217 type
->u
.array_nestable
.alignment
);
222 struct lttng_basic_type
*btype
;
224 btype
= &type
->u
.legacy
.sequence
.length_type
;
225 switch (btype
->atype
) {
227 field_align
= btype
->u
.basic
.integer
.alignment
;
232 case atype_array_nestable
:
234 case atype_sequence_nestable
:
240 btype
= &type
->u
.legacy
.sequence
.elem_type
;
241 switch (btype
->atype
) {
243 field_align
= max_t(size_t,
245 btype
->u
.basic
.integer
.alignment
);
252 case atype_array_nestable
:
254 case atype_sequence_nestable
:
261 case atype_sequence_nestable
:
263 const struct lttng_type
*nested_type
;
265 nested_type
= type
->u
.sequence_nestable
.elem_type
;
266 switch (nested_type
->atype
) {
268 field_align
= nested_type
->u
.integer
.alignment
;
275 case atype_array_nestable
:
277 case atype_sequence_nestable
:
282 field_align
= max_t(size_t, field_align
,
283 type
->u
.sequence_nestable
.alignment
);
291 case atype_enum_nestable
:
296 largest_align
= max_t(size_t, largest_align
, field_align
);
298 ctx
->largest_align
= largest_align
>> 3; /* bits to bytes */
302 * Remove last context field.
304 void lttng_remove_context_field(struct lttng_ctx
**ctx_p
,
305 struct lttng_ctx_field
*field
)
307 struct lttng_ctx
*ctx
;
311 assert(&ctx
->fields
[ctx
->nr_fields
] == field
);
312 assert(field
->field_name
== NULL
);
313 memset(&ctx
->fields
[ctx
->nr_fields
], 0, sizeof(struct lttng_ctx_field
));
316 void lttng_destroy_context(struct lttng_ctx
*ctx
)
322 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
323 if (ctx
->fields
[i
].destroy
)
324 ctx
->fields
[i
].destroy(&ctx
->fields
[i
]);
325 free(ctx
->fields
[i
].field_name
);
332 * Can be safely performed concurrently with tracing using the struct
333 * lttng_ctx. Using RCU update. Needs to match RCU read-side handling of
336 * This does not allow adding, removing, or changing typing of the
337 * contexts, since this needs to stay invariant for metadata. However,
338 * it allows updating the handlers associated with all contexts matching
339 * a provider (by name) while tracing is using it, in a way that ensures
340 * a single RCU read-side critical section see either all old, or all
343 int lttng_ust_context_set_provider_rcu(struct lttng_ctx
**_ctx
,
345 size_t (*get_size
)(struct lttng_ctx_field
*field
, size_t offset
),
346 void (*record
)(struct lttng_ctx_field
*field
,
347 struct lttng_ust_lib_ring_buffer_ctx
*ctx
,
348 struct lttng_channel
*chan
),
349 void (*get_value
)(struct lttng_ctx_field
*field
,
350 struct lttng_ctx_value
*value
))
353 struct lttng_ctx
*ctx
= *_ctx
, *new_ctx
;
354 struct lttng_ctx_field
*new_fields
;
356 if (!ctx
|| !lttng_find_context_provider(ctx
, name
))
359 * We have at least one instance of context for the provider.
361 new_ctx
= zmalloc(sizeof(*new_ctx
));
365 new_fields
= zmalloc(sizeof(*new_fields
) * ctx
->allocated_fields
);
370 memcpy(new_fields
, ctx
->fields
,
371 sizeof(*new_fields
) * ctx
->allocated_fields
);
372 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
373 if (strncmp(new_fields
[i
].event_field
.name
,
374 name
, strlen(name
)) != 0)
376 new_fields
[i
].get_size
= get_size
;
377 new_fields
[i
].record
= record
;
378 new_fields
[i
].get_value
= get_value
;
380 new_ctx
->fields
= new_fields
;
381 lttng_ust_rcu_assign_pointer(*_ctx
, new_ctx
);
382 lttng_ust_synchronize_trace();
392 int lttng_context_init_all(struct lttng_ctx
**ctx
)
396 ret
= lttng_add_pthread_id_to_ctx(ctx
);
398 WARN("Cannot add context lttng_add_pthread_id_to_ctx");
401 ret
= lttng_add_vtid_to_ctx(ctx
);
403 WARN("Cannot add context lttng_add_vtid_to_ctx");
406 ret
= lttng_add_vpid_to_ctx(ctx
);
408 WARN("Cannot add context lttng_add_vpid_to_ctx");
411 ret
= lttng_add_procname_to_ctx(ctx
);
413 WARN("Cannot add context lttng_add_procname_to_ctx");
416 ret
= lttng_add_cpu_id_to_ctx(ctx
);
418 WARN("Cannot add context lttng_add_cpu_id_to_ctx");
421 ret
= lttng_add_cgroup_ns_to_ctx(ctx
);
423 WARN("Cannot add context lttng_add_cgroup_ns_to_ctx");
426 ret
= lttng_add_ipc_ns_to_ctx(ctx
);
428 WARN("Cannot add context lttng_add_ipc_ns_to_ctx");
431 ret
= lttng_add_mnt_ns_to_ctx(ctx
);
433 WARN("Cannot add context lttng_add_mnt_ns_to_ctx");
436 ret
= lttng_add_net_ns_to_ctx(ctx
);
438 WARN("Cannot add context lttng_add_net_ns_to_ctx");
441 ret
= lttng_add_pid_ns_to_ctx(ctx
);
443 WARN("Cannot add context lttng_add_pid_ns_to_ctx");
446 ret
= lttng_add_time_ns_to_ctx(ctx
);
448 WARN("Cannot add context lttng_add_time_ns_to_ctx");
451 ret
= lttng_add_user_ns_to_ctx(ctx
);
453 WARN("Cannot add context lttng_add_user_ns_to_ctx");
456 ret
= lttng_add_uts_ns_to_ctx(ctx
);
458 WARN("Cannot add context lttng_add_uts_ns_to_ctx");
461 ret
= lttng_add_vuid_to_ctx(ctx
);
463 WARN("Cannot add context lttng_add_vuid_to_ctx");
466 ret
= lttng_add_veuid_to_ctx(ctx
);
468 WARN("Cannot add context lttng_add_veuid_to_ctx");
471 ret
= lttng_add_vsuid_to_ctx(ctx
);
473 WARN("Cannot add context lttng_add_vsuid_to_ctx");
476 ret
= lttng_add_vgid_to_ctx(ctx
);
478 WARN("Cannot add context lttng_add_vgid_to_ctx");
481 ret
= lttng_add_vegid_to_ctx(ctx
);
483 WARN("Cannot add context lttng_add_vegid_to_ctx");
486 ret
= lttng_add_vsgid_to_ctx(ctx
);
488 WARN("Cannot add context lttng_add_vsgid_to_ctx");
491 lttng_context_update(*ctx
);
495 lttng_destroy_context(*ctx
);