Fix: timer_expire_entry changed in 4.19.312
[lttng-modules.git] / lttng-context.c
1 /* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
2 *
3 * lttng-context.c
4 *
5 * LTTng trace/channel/event context management.
6 *
7 * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 */
9
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_all() */
15 #include <lttng-events.h>
16 #include <lttng-tracer.h>
17
18 /*
19 * The filter implementation requires that two consecutive "get" for the
20 * same context performed by the same thread return the same result.
21 */
22
23 /*
24 * Static array of contexts, for $ctx filters.
25 */
26 struct lttng_ctx *lttng_static_ctx;
27
28 int lttng_find_context(struct lttng_ctx *ctx, const char *name)
29 {
30 unsigned int i;
31
32 for (i = 0; i < ctx->nr_fields; i++) {
33 /* Skip allocated (but non-initialized) contexts */
34 if (!ctx->fields[i].event_field.name)
35 continue;
36 if (!strcmp(ctx->fields[i].event_field.name, name))
37 return 1;
38 }
39 return 0;
40 }
41 EXPORT_SYMBOL_GPL(lttng_find_context);
42
43 int lttng_get_context_index(struct lttng_ctx *ctx, const char *name)
44 {
45 unsigned int i;
46 const char *subname;
47
48 if (!ctx)
49 return -1;
50 if (strncmp(name, "$ctx.", strlen("$ctx.")) == 0) {
51 subname = name + strlen("$ctx.");
52 } else {
53 subname = name;
54 }
55 for (i = 0; i < ctx->nr_fields; i++) {
56 /* Skip allocated (but non-initialized) contexts */
57 if (!ctx->fields[i].event_field.name)
58 continue;
59 if (!strcmp(ctx->fields[i].event_field.name, subname))
60 return i;
61 }
62 return -1;
63 }
64 EXPORT_SYMBOL_GPL(lttng_get_context_index);
65
66 /*
67 * Note: as we append context information, the pointer location may change.
68 */
69 struct lttng_ctx_field *lttng_append_context(struct lttng_ctx **ctx_p)
70 {
71 struct lttng_ctx_field *field;
72 struct lttng_ctx *ctx;
73
74 if (!*ctx_p) {
75 *ctx_p = kzalloc(sizeof(struct lttng_ctx), GFP_KERNEL);
76 if (!*ctx_p)
77 return NULL;
78 (*ctx_p)->largest_align = 1;
79 }
80 ctx = *ctx_p;
81 if (ctx->nr_fields + 1 > ctx->allocated_fields) {
82 struct lttng_ctx_field *new_fields;
83
84 ctx->allocated_fields = max_t(size_t, 1, 2 * ctx->allocated_fields);
85 new_fields = lttng_kvzalloc(ctx->allocated_fields * sizeof(struct lttng_ctx_field), GFP_KERNEL);
86 if (!new_fields)
87 return NULL;
88 if (ctx->fields)
89 memcpy(new_fields, ctx->fields, sizeof(*ctx->fields) * ctx->nr_fields);
90 lttng_kvfree(ctx->fields);
91 ctx->fields = new_fields;
92 }
93 field = &ctx->fields[ctx->nr_fields];
94 ctx->nr_fields++;
95 return field;
96 }
97 EXPORT_SYMBOL_GPL(lttng_append_context);
98
99 /*
100 * lttng_context_update() should be called at least once between context
101 * modification and trace start.
102 */
103 void lttng_context_update(struct lttng_ctx *ctx)
104 {
105 int i;
106 size_t largest_align = 8; /* in bits */
107
108 for (i = 0; i < ctx->nr_fields; i++) {
109 struct lttng_type *type;
110 size_t field_align = 8;
111
112 type = &ctx->fields[i].event_field.type;
113 switch (type->atype) {
114 case atype_integer:
115 field_align = type->u.basic.integer.alignment;
116 break;
117 case atype_array:
118 case atype_array_bitfield:
119 {
120 struct lttng_basic_type *btype;
121
122 btype = &type->u.array.elem_type;
123 switch (btype->atype) {
124 case atype_integer:
125 field_align = btype->u.basic.integer.alignment;
126 break;
127 case atype_string:
128 break;
129
130 case atype_array:
131 case atype_sequence:
132 case atype_array_bitfield:
133 case atype_sequence_bitfield:
134 case atype_struct:
135 case atype_array_compound:
136 case atype_sequence_compound:
137 case atype_variant:
138 default:
139 WARN_ON_ONCE(1);
140 break;
141 }
142 break;
143 }
144 case atype_sequence:
145 case atype_sequence_bitfield:
146 {
147 struct lttng_basic_type *btype;
148
149 btype = &type->u.sequence.length_type;
150 switch (btype->atype) {
151 case atype_integer:
152 field_align = btype->u.basic.integer.alignment;
153 break;
154
155 case atype_string:
156 case atype_array:
157 case atype_sequence:
158 case atype_array_bitfield:
159 case atype_sequence_bitfield:
160 case atype_struct:
161 case atype_array_compound:
162 case atype_sequence_compound:
163 case atype_variant:
164 default:
165 WARN_ON_ONCE(1);
166 break;
167 }
168
169 btype = &type->u.sequence.elem_type;
170 switch (btype->atype) {
171 case atype_integer:
172 field_align = max_t(size_t,
173 field_align,
174 btype->u.basic.integer.alignment);
175 break;
176
177 case atype_string:
178 break;
179
180 case atype_array:
181 case atype_sequence:
182 case atype_array_bitfield:
183 case atype_sequence_bitfield:
184 case atype_struct:
185 case atype_array_compound:
186 case atype_sequence_compound:
187 case atype_variant:
188 default:
189 WARN_ON_ONCE(1);
190 break;
191 }
192 break;
193 }
194 case atype_string:
195 break;
196
197 case atype_struct:
198 case atype_array_compound:
199 case atype_sequence_compound:
200 case atype_variant:
201 break;
202
203 case atype_enum:
204 default:
205 WARN_ON_ONCE(1);
206 break;
207 }
208 largest_align = max_t(size_t, largest_align, field_align);
209 }
210 ctx->largest_align = largest_align >> 3; /* bits to bytes */
211 }
212
213 /*
214 * Remove last context field.
215 */
216 void lttng_remove_context_field(struct lttng_ctx **ctx_p,
217 struct lttng_ctx_field *field)
218 {
219 struct lttng_ctx *ctx;
220
221 ctx = *ctx_p;
222 ctx->nr_fields--;
223 WARN_ON_ONCE(&ctx->fields[ctx->nr_fields] != field);
224 memset(&ctx->fields[ctx->nr_fields], 0, sizeof(struct lttng_ctx_field));
225 }
226 EXPORT_SYMBOL_GPL(lttng_remove_context_field);
227
228 void lttng_destroy_context(struct lttng_ctx *ctx)
229 {
230 int i;
231
232 if (!ctx)
233 return;
234 for (i = 0; i < ctx->nr_fields; i++) {
235 if (ctx->fields[i].destroy)
236 ctx->fields[i].destroy(&ctx->fields[i]);
237 }
238 lttng_kvfree(ctx->fields);
239 kfree(ctx);
240 }
241
242 int lttng_context_init(void)
243 {
244 int ret;
245
246 ret = lttng_add_hostname_to_ctx(&lttng_static_ctx);
247 if (ret) {
248 printk(KERN_WARNING "Cannot add context lttng_add_hostname_to_ctx");
249 }
250 ret = lttng_add_nice_to_ctx(&lttng_static_ctx);
251 if (ret) {
252 printk(KERN_WARNING "Cannot add context lttng_add_nice_to_ctx");
253 }
254 ret = lttng_add_pid_to_ctx(&lttng_static_ctx);
255 if (ret) {
256 printk(KERN_WARNING "Cannot add context lttng_add_pid_to_ctx");
257 }
258 ret = lttng_add_ppid_to_ctx(&lttng_static_ctx);
259 if (ret) {
260 printk(KERN_WARNING "Cannot add context lttng_add_ppid_to_ctx");
261 }
262 ret = lttng_add_prio_to_ctx(&lttng_static_ctx);
263 if (ret) {
264 printk(KERN_WARNING "Cannot add context lttng_add_prio_to_ctx");
265 }
266 ret = lttng_add_procname_to_ctx(&lttng_static_ctx);
267 if (ret) {
268 printk(KERN_WARNING "Cannot add context lttng_add_procname_to_ctx");
269 }
270 ret = lttng_add_tid_to_ctx(&lttng_static_ctx);
271 if (ret) {
272 printk(KERN_WARNING "Cannot add context lttng_add_tid_to_ctx");
273 }
274 ret = lttng_add_vppid_to_ctx(&lttng_static_ctx);
275 if (ret) {
276 printk(KERN_WARNING "Cannot add context lttng_add_vppid_to_ctx");
277 }
278 ret = lttng_add_vtid_to_ctx(&lttng_static_ctx);
279 if (ret) {
280 printk(KERN_WARNING "Cannot add context lttng_add_vtid_to_ctx");
281 }
282 ret = lttng_add_vpid_to_ctx(&lttng_static_ctx);
283 if (ret) {
284 printk(KERN_WARNING "Cannot add context lttng_add_vpid_to_ctx");
285 }
286 ret = lttng_add_cpu_id_to_ctx(&lttng_static_ctx);
287 if (ret) {
288 printk(KERN_WARNING "Cannot add context lttng_add_cpu_id_to_ctx");
289 }
290 ret = lttng_add_interruptible_to_ctx(&lttng_static_ctx);
291 if (ret) {
292 printk(KERN_WARNING "Cannot add context lttng_add_interruptible_to_ctx");
293 }
294 ret = lttng_add_need_reschedule_to_ctx(&lttng_static_ctx);
295 if (ret) {
296 printk(KERN_WARNING "Cannot add context lttng_add_need_reschedule_to_ctx");
297 }
298 ret = lttng_add_preemptible_to_ctx(&lttng_static_ctx);
299 if (ret && ret != -ENOSYS) {
300 printk(KERN_WARNING "Cannot add context lttng_add_preemptible_to_ctx");
301 }
302 ret = lttng_add_migratable_to_ctx(&lttng_static_ctx);
303 if (ret && ret != -ENOSYS) {
304 printk(KERN_WARNING "Cannot add context lttng_add_migratable_to_ctx");
305 }
306 /* TODO: perf counters for filtering */
307 return 0;
308 }
309
310 void lttng_context_exit(void)
311 {
312 lttng_destroy_context(lttng_static_ctx);
313 lttng_static_ctx = NULL;
314 }
This page took 0.034254 seconds and 4 git commands to generate.