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/events-internal.h>
17 #include <lttng/tracer.h>
20 * The filter implementation requires that two consecutive "get" for the
21 * same context performed by the same thread return the same result.
25 * Static array of contexts, for $ctx filters.
27 struct lttng_kernel_ctx
*lttng_static_ctx
;
29 int lttng_kernel_find_context(struct lttng_kernel_ctx
*ctx
, const char *name
)
36 if (strncmp(name
, "$ctx.", strlen("$ctx.")) == 0) {
37 subname
= name
+ strlen("$ctx.");
41 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
42 /* Skip allocated (but non-initialized) contexts */
43 if (!ctx
->fields
[i
].event_field
->name
)
45 if (!strcmp(ctx
->fields
[i
].event_field
->name
, subname
))
50 EXPORT_SYMBOL_GPL(lttng_kernel_find_context
);
52 int lttng_kernel_get_context_index(struct lttng_kernel_ctx
*ctx
, const char *name
)
59 if (strncmp(name
, "$ctx.", strlen("$ctx.")) == 0) {
60 subname
= name
+ strlen("$ctx.");
64 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
65 /* Skip allocated (but non-initialized) contexts */
66 if (!ctx
->fields
[i
].event_field
->name
)
68 if (!strcmp(ctx
->fields
[i
].event_field
->name
, subname
))
73 EXPORT_SYMBOL_GPL(lttng_kernel_get_context_index
);
75 struct lttng_kernel_ctx_field
*lttng_kernel_get_context_field_from_index(struct lttng_kernel_ctx
*ctx
,
78 if (index
>= ctx
->nr_fields
)
80 return &ctx
->fields
[index
];
82 EXPORT_SYMBOL_GPL(lttng_kernel_get_context_field_from_index
);
85 * Note: as we append context information, the pointer location may change.
86 * lttng_kernel_context_add_field leaves the new last context initialized to NULL.
89 int lttng_kernel_context_add_field(struct lttng_kernel_ctx
**ctx_p
)
91 struct lttng_kernel_ctx
*ctx
;
94 *ctx_p
= kzalloc(sizeof(struct lttng_kernel_ctx
), GFP_KERNEL
);
97 (*ctx_p
)->largest_align
= 1;
100 if (ctx
->nr_fields
+ 1 > ctx
->allocated_fields
) {
101 struct lttng_kernel_ctx_field
*new_fields
;
103 ctx
->allocated_fields
= max_t(size_t, 1, 2 * ctx
->allocated_fields
);
104 new_fields
= lttng_kvzalloc(ctx
->allocated_fields
* sizeof(*new_fields
), GFP_KERNEL
);
108 memcpy(new_fields
, ctx
->fields
, sizeof(*ctx
->fields
) * ctx
->nr_fields
);
109 lttng_kvfree(ctx
->fields
);
110 ctx
->fields
= new_fields
;
116 static size_t get_type_max_align(const struct lttng_kernel_type_common
*type
)
118 switch (type
->type
) {
119 case lttng_kernel_type_integer
:
120 return lttng_kernel_get_type_integer(type
)->alignment
;
121 case lttng_kernel_type_string
:
123 case lttng_kernel_type_enum
:
124 return get_type_max_align(lttng_kernel_get_type_enum(type
)->container_type
);
125 case lttng_kernel_type_array
:
126 return max_t(size_t, get_type_max_align(lttng_kernel_get_type_array(type
)->elem_type
),
127 lttng_kernel_get_type_array(type
)->alignment
);
128 case lttng_kernel_type_sequence
:
129 return max_t(size_t, get_type_max_align(lttng_kernel_get_type_sequence(type
)->elem_type
),
130 lttng_kernel_get_type_sequence(type
)->alignment
);
131 case lttng_kernel_type_struct
:
134 size_t field_align
= 0;
135 const struct lttng_kernel_type_struct
*struct_type
= lttng_kernel_get_type_struct(type
);
137 for (i
= 0; i
< struct_type
->nr_fields
; i
++) {
138 field_align
= max_t(size_t,
139 get_type_max_align(struct_type
->fields
[i
]->type
),
144 case lttng_kernel_type_variant
:
145 /* Variants are not accounted in the overall alignment of the type they are embedded in. */
154 * lttng_context_update() should be called at least once between context
155 * modification and trace start.
158 void lttng_context_update(struct lttng_kernel_ctx
*ctx
)
161 size_t largest_align
= 8; /* in bits */
163 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
164 size_t field_align
= 8;
166 field_align
= get_type_max_align(ctx
->fields
[i
].event_field
->type
);
167 largest_align
= max_t(size_t, largest_align
, field_align
);
169 ctx
->largest_align
= largest_align
>> 3; /* bits to bytes */
172 int lttng_kernel_context_append(struct lttng_kernel_ctx
**ctx_p
,
173 const struct lttng_kernel_ctx_field
*f
)
177 ret
= lttng_kernel_context_add_field(ctx_p
);
180 (*ctx_p
)->fields
[(*ctx_p
)->nr_fields
- 1] = *f
;
181 lttng_context_update(*ctx_p
);
185 void lttng_kernel_context_remove_last(struct lttng_kernel_ctx
**ctx_p
)
187 struct lttng_kernel_ctx
*ctx
= *ctx_p
;
191 memset(&ctx
->fields
[ctx
->nr_fields
- 1], 0, sizeof(struct lttng_kernel_ctx_field
));
193 lttng_context_update(ctx
);
196 void lttng_kernel_destroy_context(struct lttng_kernel_ctx
*ctx
)
202 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
203 if (ctx
->fields
[i
].destroy
)
204 ctx
->fields
[i
].destroy(ctx
->fields
[i
].priv
);
206 lttng_kvfree(ctx
->fields
);
210 int lttng_context_init(void)
214 ret
= lttng_add_hostname_to_ctx(<tng_static_ctx
);
216 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_hostname_to_ctx");
218 ret
= lttng_add_nice_to_ctx(<tng_static_ctx
);
220 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_nice_to_ctx");
222 ret
= lttng_add_pid_to_ctx(<tng_static_ctx
);
224 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_pid_to_ctx");
226 ret
= lttng_add_ppid_to_ctx(<tng_static_ctx
);
228 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_ppid_to_ctx");
230 ret
= lttng_add_prio_to_ctx(<tng_static_ctx
);
232 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_prio_to_ctx");
234 ret
= lttng_add_procname_to_ctx(<tng_static_ctx
);
236 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_procname_to_ctx");
238 ret
= lttng_add_tid_to_ctx(<tng_static_ctx
);
240 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_tid_to_ctx");
242 ret
= lttng_add_vppid_to_ctx(<tng_static_ctx
);
244 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_vppid_to_ctx");
246 ret
= lttng_add_vtid_to_ctx(<tng_static_ctx
);
248 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_vtid_to_ctx");
250 ret
= lttng_add_vpid_to_ctx(<tng_static_ctx
);
252 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_vpid_to_ctx");
254 ret
= lttng_add_cpu_id_to_ctx(<tng_static_ctx
);
256 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_cpu_id_to_ctx");
258 ret
= lttng_add_interruptible_to_ctx(<tng_static_ctx
);
260 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_interruptible_to_ctx");
262 ret
= lttng_add_need_reschedule_to_ctx(<tng_static_ctx
);
264 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_need_reschedule_to_ctx");
266 ret
= lttng_add_preemptible_to_ctx(<tng_static_ctx
);
267 if (ret
&& ret
!= -ENOSYS
) {
268 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_preemptible_to_ctx");
270 ret
= lttng_add_migratable_to_ctx(<tng_static_ctx
);
271 if (ret
&& ret
!= -ENOSYS
) {
272 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_migratable_to_ctx");
274 ret
= lttng_add_cgroup_ns_to_ctx(<tng_static_ctx
);
275 if (ret
&& ret
!= -ENOSYS
) {
276 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_cgroup_ns_to_ctx");
278 ret
= lttng_add_ipc_ns_to_ctx(<tng_static_ctx
);
279 if (ret
&& ret
!= -ENOSYS
) {
280 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_ipc_ns_to_ctx");
282 ret
= lttng_add_mnt_ns_to_ctx(<tng_static_ctx
);
283 if (ret
&& ret
!= -ENOSYS
) {
284 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_mnt_ns_to_ctx");
286 ret
= lttng_add_net_ns_to_ctx(<tng_static_ctx
);
287 if (ret
&& ret
!= -ENOSYS
) {
288 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_net_ns_to_ctx");
290 ret
= lttng_add_pid_ns_to_ctx(<tng_static_ctx
);
291 if (ret
&& ret
!= -ENOSYS
) {
292 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_pid_ns_to_ctx");
294 ret
= lttng_add_user_ns_to_ctx(<tng_static_ctx
);
295 if (ret
&& ret
!= -ENOSYS
) {
296 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_user_ns_to_ctx");
298 ret
= lttng_add_uts_ns_to_ctx(<tng_static_ctx
);
299 if (ret
&& ret
!= -ENOSYS
) {
300 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_uts_ns_to_ctx");
302 ret
= lttng_add_time_ns_to_ctx(<tng_static_ctx
);
303 if (ret
&& ret
!= -ENOSYS
) {
304 printk(KERN_WARNING
"LTTng: Cannot add context lttng_add_time_ns_to_ctx");
306 /* TODO: perf counters for filtering */
310 void lttng_context_exit(void)
312 lttng_kernel_destroy_context(lttng_static_ctx
);
313 lttng_static_ctx
= NULL
;