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