1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
5 * LTTng trace/channel/event context management.
7 * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10 #include <linux/module.h>
11 #include <linux/list.h>
12 #include <linux/mutex.h>
13 #include <linux/slab.h>
14 #include <wrapper/vmalloc.h> /* for wrapper_vmalloc_sync_mappings() */
15 #include <lttng/events.h>
16 #include <lttng/tracer.h>
19 * The filter implementation requires that two consecutive "get" for the
20 * same context performed by the same thread return the same result.
24 * Static array of contexts, for $ctx filters.
26 struct lttng_ctx
*lttng_static_ctx
;
28 int lttng_find_context(struct lttng_ctx
*ctx
, const char *name
)
34 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
35 /* Skip allocated (but non-initialized) contexts */
36 if (!ctx
->fields
[i
].event_field
.name
)
38 if (!strcmp(ctx
->fields
[i
].event_field
.name
, name
))
43 EXPORT_SYMBOL_GPL(lttng_find_context
);
45 int lttng_get_context_index(struct lttng_ctx
*ctx
, const char *name
)
52 if (strncmp(name
, "$ctx.", strlen("$ctx.")) == 0) {
53 subname
= name
+ strlen("$ctx.");
57 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
58 /* Skip allocated (but non-initialized) contexts */
59 if (!ctx
->fields
[i
].event_field
.name
)
61 if (!strcmp(ctx
->fields
[i
].event_field
.name
, subname
))
66 EXPORT_SYMBOL_GPL(lttng_get_context_index
);
68 struct lttng_ctx_field
*lttng_get_context_field_from_index(struct lttng_ctx
*ctx
,
71 if (index
>= ctx
->nr_fields
)
73 return &ctx
->fields
[index
];
75 EXPORT_SYMBOL_GPL(lttng_get_context_field_from_index
);
78 * Note: as we append context information, the pointer location may change.
80 ssize_t
lttng_append_context_index(struct lttng_ctx
**ctx_p
)
82 struct lttng_ctx
*ctx
;
86 *ctx_p
= kzalloc(sizeof(struct lttng_ctx
), GFP_KERNEL
);
89 (*ctx_p
)->largest_align
= 1;
92 if (ctx
->nr_fields
+ 1 > ctx
->allocated_fields
) {
93 struct lttng_ctx_field
*new_fields
;
95 ctx
->allocated_fields
= max_t(size_t, 1, 2 * ctx
->allocated_fields
);
96 new_fields
= lttng_kvzalloc(ctx
->allocated_fields
* sizeof(struct lttng_ctx_field
), GFP_KERNEL
);
100 memcpy(new_fields
, ctx
->fields
, sizeof(*ctx
->fields
) * ctx
->nr_fields
);
101 lttng_kvfree(ctx
->fields
);
102 ctx
->fields
= new_fields
;
104 pos
= ctx
->nr_fields
++;
108 EXPORT_SYMBOL_GPL(lttng_append_context_index
);
111 * Note: as we append context information, the pointer location may change.
113 struct lttng_ctx_field
*lttng_append_context(struct lttng_ctx
**ctx_p
)
117 pos
= lttng_append_context_index(ctx_p
);
120 return &(*ctx_p
)->fields
[pos
];
122 EXPORT_SYMBOL_GPL(lttng_append_context
);
125 * lttng_context_update() should be called at least once between context
126 * modification and trace start.
128 void lttng_context_update(struct lttng_ctx
*ctx
)
131 size_t largest_align
= 8; /* in bits */
133 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
134 struct lttng_type
*type
;
135 size_t field_align
= 8;
137 type
= &ctx
->fields
[i
].event_field
.type
;
138 switch (type
->atype
) {
140 field_align
= type
->u
.integer
.alignment
;
142 case atype_array_nestable
:
144 const struct lttng_type
*nested_type
;
146 nested_type
= type
->u
.array_nestable
.elem_type
;
147 switch (nested_type
->atype
) {
149 field_align
= nested_type
->u
.integer
.alignment
;
154 case atype_array_nestable
:
155 case atype_sequence_nestable
:
156 case atype_struct_nestable
:
157 case atype_variant_nestable
:
162 field_align
= max_t(size_t, field_align
,
163 type
->u
.array_nestable
.alignment
);
166 case atype_sequence_nestable
:
168 const struct lttng_type
*nested_type
;
170 nested_type
= type
->u
.sequence_nestable
.elem_type
;
171 switch (nested_type
->atype
) {
173 field_align
= nested_type
->u
.integer
.alignment
;
179 case atype_array_nestable
:
180 case atype_sequence_nestable
:
181 case atype_struct_nestable
:
182 case atype_variant_nestable
:
187 field_align
= max_t(size_t, field_align
,
188 type
->u
.sequence_nestable
.alignment
);
194 case atype_struct_nestable
:
195 case atype_variant_nestable
:
198 case atype_enum_nestable
:
203 largest_align
= max_t(size_t, largest_align
, field_align
);
205 ctx
->largest_align
= largest_align
>> 3; /* bits to bytes */
208 /* Keep same order. */
209 void lttng_remove_context_field_index(struct lttng_ctx
**ctx_p
, size_t index
)
211 struct lttng_ctx
*ctx
= *ctx_p
;
213 WARN_ON_ONCE(ctx
->nr_fields
>= index
);
214 if (index
!= ctx
->nr_fields
- 1) {
215 memmove(&ctx
->fields
[index
], &ctx
->fields
[index
+ 1],
216 (ctx
->nr_fields
- index
- 1) * sizeof(struct lttng_ctx_field
));
218 /* Clear last item. */
219 memset(&ctx
->fields
[ctx
->nr_fields
- 1], 0, sizeof(struct lttng_ctx_field
));
222 EXPORT_SYMBOL_GPL(lttng_remove_context_field_index
);
225 * Remove last context field.
227 void lttng_remove_context_field(struct lttng_ctx
**ctx_p
,
228 struct lttng_ctx_field
*field
)
230 struct lttng_ctx
*ctx
;
234 WARN_ON_ONCE(&ctx
->fields
[ctx
->nr_fields
] != field
);
235 memset(&ctx
->fields
[ctx
->nr_fields
], 0, sizeof(struct lttng_ctx_field
));
237 EXPORT_SYMBOL_GPL(lttng_remove_context_field
);
239 void lttng_destroy_context(struct lttng_ctx
*ctx
)
245 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
246 if (ctx
->fields
[i
].destroy
)
247 ctx
->fields
[i
].destroy(&ctx
->fields
[i
]);
249 lttng_kvfree(ctx
->fields
);
253 int lttng_context_init(void)
257 ret
= lttng_add_hostname_to_ctx(<tng_static_ctx
);
259 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_hostname_to_ctx");
261 ret
= lttng_add_nice_to_ctx(<tng_static_ctx
);
263 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_nice_to_ctx");
265 ret
= lttng_add_pid_to_ctx(<tng_static_ctx
);
267 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_pid_to_ctx");
269 ret
= lttng_add_ppid_to_ctx(<tng_static_ctx
);
271 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_ppid_to_ctx");
273 ret
= lttng_add_prio_to_ctx(<tng_static_ctx
);
275 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_prio_to_ctx");
277 ret
= lttng_add_procname_to_ctx(<tng_static_ctx
);
279 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_procname_to_ctx");
281 ret
= lttng_add_tid_to_ctx(<tng_static_ctx
);
283 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_tid_to_ctx");
285 ret
= lttng_add_vppid_to_ctx(<tng_static_ctx
);
287 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_vppid_to_ctx");
289 ret
= lttng_add_vtid_to_ctx(<tng_static_ctx
);
291 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_vtid_to_ctx");
293 ret
= lttng_add_vpid_to_ctx(<tng_static_ctx
);
295 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_vpid_to_ctx");
297 ret
= lttng_add_cpu_id_to_ctx(<tng_static_ctx
);
299 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_cpu_id_to_ctx");
301 ret
= lttng_add_interruptible_to_ctx(<tng_static_ctx
);
303 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_interruptible_to_ctx");
305 ret
= lttng_add_need_reschedule_to_ctx(<tng_static_ctx
);
307 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_need_reschedule_to_ctx");
309 ret
= lttng_add_preemptible_to_ctx(<tng_static_ctx
);
310 if (ret
&& ret
!= -ENOSYS
) {
311 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_preemptible_to_ctx");
313 ret
= lttng_add_migratable_to_ctx(<tng_static_ctx
);
314 if (ret
&& ret
!= -ENOSYS
) {
315 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_migratable_to_ctx");
317 ret
= lttng_add_cgroup_ns_to_ctx(<tng_static_ctx
);
318 if (ret
&& ret
!= -ENOSYS
) {
319 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_cgroup_ns_to_ctx");
321 ret
= lttng_add_ipc_ns_to_ctx(<tng_static_ctx
);
322 if (ret
&& ret
!= -ENOSYS
) {
323 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_ipc_ns_to_ctx");
325 ret
= lttng_add_mnt_ns_to_ctx(<tng_static_ctx
);
326 if (ret
&& ret
!= -ENOSYS
) {
327 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_mnt_ns_to_ctx");
329 ret
= lttng_add_net_ns_to_ctx(<tng_static_ctx
);
330 if (ret
&& ret
!= -ENOSYS
) {
331 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_net_ns_to_ctx");
333 ret
= lttng_add_pid_ns_to_ctx(<tng_static_ctx
);
334 if (ret
&& ret
!= -ENOSYS
) {
335 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_pid_ns_to_ctx");
337 ret
= lttng_add_user_ns_to_ctx(<tng_static_ctx
);
338 if (ret
&& ret
!= -ENOSYS
) {
339 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_user_ns_to_ctx");
341 ret
= lttng_add_uts_ns_to_ctx(<tng_static_ctx
);
342 if (ret
&& ret
!= -ENOSYS
) {
343 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_uts_ns_to_ctx");
345 ret
= lttng_add_time_ns_to_ctx(<tng_static_ctx
);
346 if (ret
&& ret
!= -ENOSYS
) {
347 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_time_ns_to_ctx");
349 /* TODO: perf counters for filtering */
353 void lttng_context_exit(void)
355 lttng_destroy_context(lttng_static_ctx
);
356 lttng_static_ctx
= NULL
;