Commit | Line | Data |
---|---|---|
b7cdc182 | 1 | /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only) |
9f36eaed | 2 | * |
2fa2d39a FG |
3 | * lttng-context-callstack.c |
4 | * | |
5 | * LTTng callstack event context. | |
6 | * | |
7 | * Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
8 | * Copyright (C) 2014 Francis Giraldeau <francis.giraldeau@gmail.com> | |
9 | * | |
0bb47c89 MD |
10 | * The callstack context can be added to any kernel event. It records |
11 | * either the kernel or the userspace callstack, up to a max depth. The | |
12 | * context is a CTF sequence, such that it uses only the space required | |
13 | * for the number of callstack entries. | |
2fa2d39a | 14 | * |
0bb47c89 MD |
15 | * It allocates callstack buffers per-CPU up to 4 interrupt nesting. |
16 | * This nesting limit is the same as defined in the ring buffer. It | |
17 | * therefore uses a fixed amount of memory, proportional to the number | |
18 | * of CPUs: | |
2fa2d39a FG |
19 | * |
20 | * size = cpus * nest * depth * sizeof(unsigned long) | |
21 | * | |
3685cc80 | 22 | * Which is 4096 bytes per CPU on 64-bit host and a depth of 128. |
0bb47c89 MD |
23 | * The allocation is done at the initialization to avoid memory |
24 | * allocation overhead while tracing, using a shallow stack. | |
2fa2d39a FG |
25 | * |
26 | * The kernel callstack is recovered using save_stack_trace(), and the | |
27 | * userspace callstack uses save_stack_trace_user(). They rely on frame | |
0bb47c89 MD |
28 | * pointers. These are usually available for the kernel, but the |
29 | * compiler option -fomit-frame-pointer frequently used in popular Linux | |
30 | * distributions may cause the userspace callstack to be unreliable, and | |
31 | * is a known limitation of this approach. If frame pointers are not | |
32 | * available, it produces no error, but the callstack will be empty. We | |
33 | * still provide the feature, because it works well for runtime | |
34 | * environments having frame pointers. In the future, unwind support | |
35 | * and/or last branch record may provide a solution to this problem. | |
2fa2d39a FG |
36 | * |
37 | * The symbol name resolution is left to the trace reader. | |
38 | */ | |
39 | ||
40 | #include <linux/module.h> | |
41 | #include <linux/slab.h> | |
42 | #include <linux/sched.h> | |
43 | #include <linux/utsname.h> | |
44 | #include <linux/stacktrace.h> | |
45 | #include <linux/spinlock.h> | |
24591303 MD |
46 | #include <ringbuffer/backend.h> |
47 | #include <ringbuffer/frontend.h> | |
2df37e95 MD |
48 | #include <lttng/events.h> |
49 | #include <lttng/tracer.h> | |
50 | #include <lttng/endian.h> | |
2fa2d39a | 51 | #include "wrapper/vmalloc.h" |
2fa2d39a | 52 | |
b29c6286 MD |
53 | #ifdef CONFIG_ARCH_STACKWALK |
54 | #include "lttng-context-callstack-stackwalk-impl.h" | |
55 | #else | |
b6ee48d2 | 56 | #include "lttng-context-callstack-legacy-impl.h" |
b29c6286 | 57 | #endif |
2fa2d39a | 58 | |
437d5aa5 MD |
59 | #define NR_FIELDS 2 |
60 | ||
2fa2d39a FG |
61 | static |
62 | void field_data_free(struct field_data *fdata) | |
63 | { | |
2fa2d39a FG |
64 | if (!fdata) |
65 | return; | |
2fa2d39a FG |
66 | free_percpu(fdata->cs_percpu); |
67 | kfree(fdata); | |
68 | } | |
69 | ||
70 | static | |
0bb47c89 | 71 | struct field_data __percpu *field_data_create(enum lttng_cs_ctx_modes mode) |
2fa2d39a | 72 | { |
2fa2d39a | 73 | struct lttng_cs __percpu *cs_set; |
64cc198b | 74 | struct field_data *fdata; |
2fa2d39a | 75 | |
64cc198b | 76 | fdata = kzalloc(sizeof(*fdata), GFP_KERNEL); |
2fa2d39a FG |
77 | if (!fdata) |
78 | return NULL; | |
79 | cs_set = alloc_percpu(struct lttng_cs); | |
80 | if (!cs_set) | |
81 | goto error_alloc; | |
b5a89a3f | 82 | lttng_cs_set_init(cs_set); |
2fa2d39a | 83 | fdata->cs_percpu = cs_set; |
0bb47c89 | 84 | fdata->mode = mode; |
2fa2d39a FG |
85 | return fdata; |
86 | ||
87 | error_alloc: | |
88 | field_data_free(fdata); | |
89 | return NULL; | |
90 | } | |
91 | ||
92 | static | |
437d5aa5 | 93 | void lttng_callstack_sequence_destroy(struct lttng_kernel_ctx_field *field) |
2fa2d39a | 94 | { |
3c1a57e8 | 95 | struct field_data *fdata = field->priv; |
2fa2d39a FG |
96 | |
97 | field_data_free(fdata); | |
98 | } | |
99 | ||
437d5aa5 MD |
100 | static const struct lttng_kernel_event_field *event_fields_kernel[NR_FIELDS] = { |
101 | lttng_kernel_static_event_field("_callstack_kernel_length", | |
102 | lttng_kernel_static_type_integer_from_type(unsigned int, __BYTE_ORDER, 10), | |
103 | false, false, false), | |
104 | lttng_kernel_static_event_field("callstack_kernel", | |
105 | lttng_kernel_static_type_sequence("_callstack_kernel_length", | |
106 | lttng_kernel_static_type_integer_from_type(unsigned long, __BYTE_ORDER, 16), | |
107 | 0, none), | |
108 | false, false, false), | |
109 | }; | |
110 | ||
111 | static const struct lttng_kernel_event_field *event_fields_user[NR_FIELDS] = { | |
112 | lttng_kernel_static_event_field("_callstack_user_length", | |
113 | lttng_kernel_static_type_integer_from_type(unsigned int, __BYTE_ORDER, 10), | |
114 | false, false, false), | |
115 | lttng_kernel_static_event_field("callstack_user", | |
116 | lttng_kernel_static_type_sequence("_callstack_user_length", | |
117 | lttng_kernel_static_type_integer_from_type(unsigned long, __BYTE_ORDER, 16), | |
118 | 0, none), | |
119 | false, false, false), | |
120 | }; | |
121 | ||
122 | const struct lttng_kernel_event_field **lttng_cs_event_fields(enum lttng_cs_ctx_modes mode) | |
123 | { | |
124 | switch (mode) { | |
125 | case CALLSTACK_KERNEL: | |
126 | return event_fields_kernel; | |
127 | case CALLSTACK_USER: | |
128 | return event_fields_user; | |
129 | default: | |
130 | return NULL; | |
131 | } | |
132 | } | |
ceabb767 | 133 | |
2fa2d39a | 134 | static |
437d5aa5 | 135 | int __lttng_add_callstack_generic(struct lttng_kernel_ctx **ctx, |
0bb47c89 | 136 | enum lttng_cs_ctx_modes mode) |
2fa2d39a | 137 | { |
437d5aa5 MD |
138 | const struct lttng_kernel_event_field **event_fields; |
139 | struct lttng_kernel_ctx_field ctx_field; | |
2fa2d39a | 140 | struct field_data *fdata; |
437d5aa5 | 141 | int ret, i; |
2fa2d39a FG |
142 | |
143 | ret = init_type(mode); | |
144 | if (ret) | |
145 | return ret; | |
437d5aa5 MD |
146 | event_fields = lttng_cs_event_fields(mode); |
147 | if (!event_fields) { | |
148 | return -EINVAL; | |
ceabb767 | 149 | } |
437d5aa5 MD |
150 | for (i = 0; i < NR_FIELDS; i++) { |
151 | if (lttng_kernel_find_context(*ctx, event_fields[i]->name)) | |
152 | return -EEXIST; | |
2fa2d39a | 153 | } |
64cc198b | 154 | fdata = field_data_create(mode); |
2fa2d39a FG |
155 | if (!fdata) { |
156 | ret = -ENOMEM; | |
157 | goto error_create; | |
158 | } | |
437d5aa5 MD |
159 | memset(&ctx_field, 0, sizeof(ctx_field)); |
160 | ctx_field.event_field = event_fields[0]; | |
161 | ctx_field.get_size_arg = lttng_callstack_length_get_size; | |
162 | ctx_field.record = lttng_callstack_length_record; | |
163 | ctx_field.priv = fdata; | |
164 | ret = lttng_kernel_context_append(ctx, &ctx_field); | |
165 | if (ret) { | |
166 | ret = -ENOMEM; | |
167 | goto error_append0; | |
168 | } | |
2fa2d39a | 169 | |
437d5aa5 MD |
170 | memset(&ctx_field, 0, sizeof(ctx_field)); |
171 | ctx_field.event_field = event_fields[1]; | |
172 | ctx_field.get_size_arg = lttng_callstack_sequence_get_size; | |
173 | ctx_field.record = lttng_callstack_sequence_record; | |
174 | ctx_field.destroy = lttng_callstack_sequence_destroy; | |
175 | ctx_field.priv = fdata; | |
176 | ret = lttng_kernel_context_append(ctx, &ctx_field); | |
177 | if (ret) { | |
178 | ret = -ENOMEM; | |
179 | goto error_append1; | |
180 | } | |
2fa2d39a FG |
181 | return 0; |
182 | ||
437d5aa5 MD |
183 | error_append1: |
184 | lttng_kernel_context_remove_last(ctx); | |
185 | error_append0: | |
186 | field_data_free(fdata); | |
2fa2d39a | 187 | error_create: |
2fa2d39a FG |
188 | return ret; |
189 | } | |
190 | ||
191 | /** | |
192 | * lttng_add_callstack_to_ctx - add callstack event context | |
193 | * | |
194 | * @ctx: the lttng_ctx pointer to initialize | |
195 | * @type: the context type | |
196 | * | |
197 | * Supported callstack type supported: | |
198 | * LTTNG_KERNEL_CONTEXT_CALLSTACK_KERNEL | |
199 | * Records the callstack of the kernel | |
200 | * LTTNG_KERNEL_CONTEXT_CALLSTACK_USER | |
201 | * Records the callstack of the userspace program (from the kernel) | |
202 | * | |
203 | * Return 0 for success, or error code. | |
204 | */ | |
437d5aa5 | 205 | int lttng_add_callstack_to_ctx(struct lttng_kernel_ctx **ctx, int type) |
2fa2d39a FG |
206 | { |
207 | switch (type) { | |
606828e4 | 208 | case LTTNG_KERNEL_ABI_CONTEXT_CALLSTACK_KERNEL: |
2fa2d39a | 209 | return __lttng_add_callstack_generic(ctx, CALLSTACK_KERNEL); |
b874d3f3 | 210 | #ifdef CONFIG_X86 |
606828e4 | 211 | case LTTNG_KERNEL_ABI_CONTEXT_CALLSTACK_USER: |
2fa2d39a | 212 | return __lttng_add_callstack_generic(ctx, CALLSTACK_USER); |
b874d3f3 | 213 | #endif |
2fa2d39a FG |
214 | default: |
215 | return -EINVAL; | |
216 | } | |
217 | } | |
218 | EXPORT_SYMBOL_GPL(lttng_add_callstack_to_ctx); |