Drop support for kernels < 4.4 from 'wrapper/fdtable.h'
[lttng-modules.git] / src / lttng-context.c
CommitLineData
b7cdc182 1/* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
9f36eaed 2 *
a90917c3 3 * lttng-context.c
2dccf128 4 *
2dccf128 5 * LTTng trace/channel/event context management.
17baffe2 6 *
886d51a3 7 * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2dccf128
MD
8 */
9
10#include <linux/module.h>
11#include <linux/list.h>
12#include <linux/mutex.h>
13#include <linux/slab.h>
263b6c88 14#include <wrapper/vmalloc.h> /* for wrapper_vmalloc_sync_mappings() */
2df37e95 15#include <lttng/events.h>
437d5aa5 16#include <lttng/events-internal.h>
2df37e95 17#include <lttng/tracer.h>
2dccf128 18
07dfc1d0
MD
19/*
20 * The filter implementation requires that two consecutive "get" for the
21 * same context performed by the same thread return the same result.
22 */
23
24/*
25 * Static array of contexts, for $ctx filters.
26 */
437d5aa5 27struct lttng_kernel_ctx *lttng_static_ctx;
07dfc1d0 28
437d5aa5 29int lttng_kernel_find_context(struct lttng_kernel_ctx *ctx, const char *name)
44252f0f
MD
30{
31 unsigned int i;
437d5aa5 32 const char *subname;
44252f0f 33
c02eb859
MD
34 if (!ctx)
35 return 0;
437d5aa5
MD
36 if (strncmp(name, "$ctx.", strlen("$ctx.")) == 0) {
37 subname = name + strlen("$ctx.");
38 } else {
39 subname = name;
40 }
44252f0f 41 for (i = 0; i < ctx->nr_fields; i++) {
4b58a8e4 42 /* Skip allocated (but non-initialized) contexts */
437d5aa5 43 if (!ctx->fields[i].event_field->name)
4b58a8e4 44 continue;
437d5aa5 45 if (!strcmp(ctx->fields[i].event_field->name, subname))
44252f0f
MD
46 return 1;
47 }
48 return 0;
49}
437d5aa5 50EXPORT_SYMBOL_GPL(lttng_kernel_find_context);
44252f0f 51
437d5aa5 52int lttng_kernel_get_context_index(struct lttng_kernel_ctx *ctx, const char *name)
07dfc1d0
MD
53{
54 unsigned int i;
0451bcec 55 const char *subname;
07dfc1d0
MD
56
57 if (!ctx)
58 return -1;
0451bcec
MD
59 if (strncmp(name, "$ctx.", strlen("$ctx.")) == 0) {
60 subname = name + strlen("$ctx.");
61 } else {
62 subname = name;
63 }
07dfc1d0
MD
64 for (i = 0; i < ctx->nr_fields; i++) {
65 /* Skip allocated (but non-initialized) contexts */
437d5aa5 66 if (!ctx->fields[i].event_field->name)
07dfc1d0 67 continue;
437d5aa5 68 if (!strcmp(ctx->fields[i].event_field->name, subname))
07dfc1d0
MD
69 return i;
70 }
71 return -1;
72}
437d5aa5 73EXPORT_SYMBOL_GPL(lttng_kernel_get_context_index);
07dfc1d0 74
437d5aa5 75struct lttng_kernel_ctx_field *lttng_kernel_get_context_field_from_index(struct lttng_kernel_ctx *ctx,
c02eb859
MD
76 size_t index)
77{
78 if (index >= ctx->nr_fields)
79 return NULL;
80 return &ctx->fields[index];
81}
437d5aa5 82EXPORT_SYMBOL_GPL(lttng_kernel_get_context_field_from_index);
c02eb859 83
2001023e
MD
84/*
85 * Note: as we append context information, the pointer location may change.
437d5aa5 86 * lttng_kernel_context_add_field leaves the new last context initialized to NULL.
2001023e 87 */
437d5aa5
MD
88static
89int lttng_kernel_context_add_field(struct lttng_kernel_ctx **ctx_p)
2dccf128 90{
437d5aa5 91 struct lttng_kernel_ctx *ctx;
2dccf128
MD
92
93 if (!*ctx_p) {
437d5aa5 94 *ctx_p = kzalloc(sizeof(struct lttng_kernel_ctx), GFP_KERNEL);
2dccf128 95 if (!*ctx_p)
437d5aa5 96 return -ENOMEM;
a9dd15da 97 (*ctx_p)->largest_align = 1;
2dccf128
MD
98 }
99 ctx = *ctx_p;
100 if (ctx->nr_fields + 1 > ctx->allocated_fields) {
437d5aa5 101 struct lttng_kernel_ctx_field *new_fields;
2dccf128 102
0f034e0f 103 ctx->allocated_fields = max_t(size_t, 1, 2 * ctx->allocated_fields);
437d5aa5 104 new_fields = lttng_kvzalloc(ctx->allocated_fields * sizeof(*new_fields), GFP_KERNEL);
2dccf128 105 if (!new_fields)
437d5aa5 106 return -ENOMEM;
2dccf128 107 if (ctx->fields)
77aefe99 108 memcpy(new_fields, ctx->fields, sizeof(*ctx->fields) * ctx->nr_fields);
48f5e0b5 109 lttng_kvfree(ctx->fields);
2dccf128
MD
110 ctx->fields = new_fields;
111 }
437d5aa5
MD
112 ctx->nr_fields++;
113 return 0;
c02eb859 114}
c02eb859 115
437d5aa5 116static size_t get_type_max_align(const struct lttng_kernel_type_common *type)
c02eb859 117{
437d5aa5
MD
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:
122 return CHAR_BIT;
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:
132 {
133 unsigned int i;
134 size_t field_align = 0;
135 const struct lttng_kernel_type_struct *struct_type = lttng_kernel_get_type_struct(type);
136
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),
140 field_align);
141 }
142 return field_align;
143 }
144 case lttng_kernel_type_variant:
145 /* Variants are not accounted in the overall alignment of the type they are embedded in. */
146 return 0;
147 default:
148 WARN_ON_ONCE(1);
149 return 0;
150 }
2dccf128 151}
2dccf128 152
a9dd15da
MD
153/*
154 * lttng_context_update() should be called at least once between context
155 * modification and trace start.
156 */
437d5aa5
MD
157static
158void lttng_context_update(struct lttng_kernel_ctx *ctx)
a9dd15da
MD
159{
160 int i;
161 size_t largest_align = 8; /* in bits */
162
163 for (i = 0; i < ctx->nr_fields; i++) {
a9dd15da
MD
164 size_t field_align = 8;
165
437d5aa5 166 field_align = get_type_max_align(ctx->fields[i].event_field->type);
a9dd15da
MD
167 largest_align = max_t(size_t, largest_align, field_align);
168 }
169 ctx->largest_align = largest_align >> 3; /* bits to bytes */
170}
171
437d5aa5
MD
172int lttng_kernel_context_append(struct lttng_kernel_ctx **ctx_p,
173 const struct lttng_kernel_ctx_field *f)
c02eb859 174{
437d5aa5 175 int ret;
c02eb859 176
437d5aa5
MD
177 ret = lttng_kernel_context_add_field(ctx_p);
178 if (ret)
179 return ret;
180 (*ctx_p)->fields[(*ctx_p)->nr_fields - 1] = *f;
181 lttng_context_update(*ctx_p);
182 return 0;
c02eb859 183}
c02eb859 184
437d5aa5 185void lttng_kernel_context_remove_last(struct lttng_kernel_ctx **ctx_p)
8289661d 186{
437d5aa5 187 struct lttng_kernel_ctx *ctx = *ctx_p;
8289661d 188
437d5aa5
MD
189 if (!ctx->nr_fields)
190 return;
191 memset(&ctx->fields[ctx->nr_fields - 1], 0, sizeof(struct lttng_kernel_ctx_field));
8289661d 192 ctx->nr_fields--;
437d5aa5 193 lttng_context_update(ctx);
8289661d 194}
8289661d 195
437d5aa5 196void lttng_kernel_destroy_context(struct lttng_kernel_ctx *ctx)
2dccf128
MD
197{
198 int i;
199
8070f5c0
MD
200 if (!ctx)
201 return;
9e7e4892
MD
202 for (i = 0; i < ctx->nr_fields; i++) {
203 if (ctx->fields[i].destroy)
2dc781e0 204 ctx->fields[i].destroy(ctx->fields[i].priv);
9e7e4892 205 }
48f5e0b5 206 lttng_kvfree(ctx->fields);
2dccf128
MD
207 kfree(ctx);
208}
07dfc1d0
MD
209
210int lttng_context_init(void)
211{
212 int ret;
213
f127e61e
MD
214 ret = lttng_add_hostname_to_ctx(&lttng_static_ctx);
215 if (ret) {
5a15f70c 216 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_hostname_to_ctx");
f127e61e
MD
217 }
218 ret = lttng_add_nice_to_ctx(&lttng_static_ctx);
07dfc1d0 219 if (ret) {
5a15f70c 220 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_nice_to_ctx");
07dfc1d0 221 }
07dfc1d0
MD
222 ret = lttng_add_pid_to_ctx(&lttng_static_ctx);
223 if (ret) {
5a15f70c 224 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_pid_to_ctx");
07dfc1d0 225 }
f127e61e 226 ret = lttng_add_ppid_to_ctx(&lttng_static_ctx);
07dfc1d0 227 if (ret) {
5a15f70c 228 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_ppid_to_ctx");
07dfc1d0
MD
229 }
230 ret = lttng_add_prio_to_ctx(&lttng_static_ctx);
231 if (ret) {
5a15f70c 232 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_prio_to_ctx");
07dfc1d0 233 }
f127e61e 234 ret = lttng_add_procname_to_ctx(&lttng_static_ctx);
07dfc1d0 235 if (ret) {
5a15f70c 236 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_procname_to_ctx");
07dfc1d0
MD
237 }
238 ret = lttng_add_tid_to_ctx(&lttng_static_ctx);
239 if (ret) {
5a15f70c 240 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_tid_to_ctx");
07dfc1d0 241 }
f127e61e 242 ret = lttng_add_vppid_to_ctx(&lttng_static_ctx);
07dfc1d0 243 if (ret) {
5a15f70c 244 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_vppid_to_ctx");
07dfc1d0 245 }
f127e61e 246 ret = lttng_add_vtid_to_ctx(&lttng_static_ctx);
07dfc1d0 247 if (ret) {
5a15f70c 248 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_vtid_to_ctx");
07dfc1d0 249 }
f127e61e 250 ret = lttng_add_vpid_to_ctx(&lttng_static_ctx);
07dfc1d0 251 if (ret) {
5a15f70c 252 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_vpid_to_ctx");
07dfc1d0 253 }
b3699d90
MD
254 ret = lttng_add_cpu_id_to_ctx(&lttng_static_ctx);
255 if (ret) {
5a15f70c 256 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_cpu_id_to_ctx");
b3699d90 257 }
79150a49
JD
258 ret = lttng_add_interruptible_to_ctx(&lttng_static_ctx);
259 if (ret) {
5a15f70c 260 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_interruptible_to_ctx");
79150a49
JD
261 }
262 ret = lttng_add_need_reschedule_to_ctx(&lttng_static_ctx);
263 if (ret) {
5a15f70c 264 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_need_reschedule_to_ctx");
79150a49 265 }
79150a49 266 ret = lttng_add_preemptible_to_ctx(&lttng_static_ctx);
d0e59d6f 267 if (ret && ret != -ENOSYS) {
5a15f70c 268 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_preemptible_to_ctx");
79150a49 269 }
79150a49 270 ret = lttng_add_migratable_to_ctx(&lttng_static_ctx);
d0e59d6f 271 if (ret && ret != -ENOSYS) {
5a15f70c 272 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_migratable_to_ctx");
79150a49 273 }
a6cf40a4
MJ
274 ret = lttng_add_cgroup_ns_to_ctx(&lttng_static_ctx);
275 if (ret && ret != -ENOSYS) {
5a15f70c 276 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_cgroup_ns_to_ctx");
a6cf40a4
MJ
277 }
278 ret = lttng_add_ipc_ns_to_ctx(&lttng_static_ctx);
279 if (ret && ret != -ENOSYS) {
5a15f70c 280 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_ipc_ns_to_ctx");
a6cf40a4
MJ
281 }
282 ret = lttng_add_mnt_ns_to_ctx(&lttng_static_ctx);
283 if (ret && ret != -ENOSYS) {
5a15f70c 284 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_mnt_ns_to_ctx");
a6cf40a4
MJ
285 }
286 ret = lttng_add_net_ns_to_ctx(&lttng_static_ctx);
287 if (ret && ret != -ENOSYS) {
5a15f70c 288 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_net_ns_to_ctx");
a6cf40a4
MJ
289 }
290 ret = lttng_add_pid_ns_to_ctx(&lttng_static_ctx);
291 if (ret && ret != -ENOSYS) {
5a15f70c 292 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_pid_ns_to_ctx");
a6cf40a4
MJ
293 }
294 ret = lttng_add_user_ns_to_ctx(&lttng_static_ctx);
295 if (ret && ret != -ENOSYS) {
5a15f70c 296 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_user_ns_to_ctx");
a6cf40a4
MJ
297 }
298 ret = lttng_add_uts_ns_to_ctx(&lttng_static_ctx);
299 if (ret && ret != -ENOSYS) {
5a15f70c 300 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_uts_ns_to_ctx");
a6cf40a4 301 }
876e2e92
MJ
302 ret = lttng_add_time_ns_to_ctx(&lttng_static_ctx);
303 if (ret && ret != -ENOSYS) {
5a15f70c 304 printk(KERN_WARNING "LTTng: Cannot add context lttng_add_time_ns_to_ctx");
876e2e92 305 }
f127e61e 306 /* TODO: perf counters for filtering */
07dfc1d0
MD
307 return 0;
308}
309
310void lttng_context_exit(void)
311{
437d5aa5 312 lttng_kernel_destroy_context(lttng_static_ctx);
07dfc1d0
MD
313 lttng_static_ctx = NULL;
314}
This page took 0.069834 seconds and 4 git commands to generate.