Rename lttng_probe_{,un}register to lttng_kernel_probe_{,un}register
[lttng-modules.git] / src / lttng-probes.c
1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
2 *
3 * lttng-probes.c
4 *
5 * Holds LTTng probes registry.
6 *
7 * Copyright (C) 2010-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/seq_file.h>
14
15 #include <lttng/events.h>
16 #include <lttng/events-internal.h>
17
18 /*
19 * probe list is protected by sessions lock.
20 */
21 static LIST_HEAD(_probe_list);
22
23 /*
24 * List of probes registered by not yet processed.
25 */
26 static LIST_HEAD(lazy_probe_init);
27
28 /*
29 * lazy_nesting counter ensures we don't notify lazy probe registration
30 * fixup while we are performing the fixup. It is protected by the
31 * sessions lock.
32 */
33 static int lazy_nesting;
34
35 DEFINE_PER_CPU(struct lttng_dynamic_len_stack, lttng_dynamic_len_stack);
36
37 EXPORT_PER_CPU_SYMBOL_GPL(lttng_dynamic_len_stack);
38
39 /*
40 * Called under sessions lock.
41 */
42 static
43 int check_event_provider(struct lttng_kernel_probe_desc *desc)
44 {
45 int i, mismatch = 0;
46 size_t provider_name_len;
47
48 provider_name_len = strnlen(desc->provider_name,
49 LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1);
50 for (i = 0; i < desc->nr_events; i++) {
51 /*
52 * The event name needs to start with provider name + _ +
53 * one or more letter.
54 */
55 if (strncmp(desc->event_desc[i]->event_name, desc->provider_name, provider_name_len))
56 mismatch = 1;
57 else if (strlen(desc->event_desc[i]->event_name) <= provider_name_len + 1)
58 mismatch = 1;
59 else if (desc->event_desc[i]->event_name[provider_name_len] != '_')
60 mismatch = 1;
61
62 if (mismatch) {
63 printk(KERN_WARNING "LTTng: event provider mismatch: "
64 "The event name needs to start with provider "
65 "name + _ + one or more letter, "
66 "provider: %s, event name: %s\n",
67 desc->provider_name, desc->event_desc[i]->event_name);
68 return 0;
69 }
70 }
71 return 1;
72 }
73
74 /*
75 * Called under sessions lock.
76 */
77 static
78 void lttng_lazy_probe_register(struct lttng_kernel_probe_desc *desc)
79 {
80 struct lttng_kernel_probe_desc *iter;
81 struct list_head *probe_list;
82
83 /*
84 * Each provider enforce that every event name begins with the
85 * provider name. Check this in an assertion for extra
86 * carefulness. This ensures we cannot have duplicate event
87 * names across providers.
88 */
89 WARN_ON_ONCE(!check_event_provider(desc));
90
91 /*
92 * The provider ensures there are no duplicate event names.
93 * Duplicated TRACEPOINT_EVENT event names would generate a
94 * compile-time error due to duplicated symbol names.
95 */
96
97 /*
98 * We sort the providers by struct lttng_kernel_probe_desc pointer
99 * address.
100 */
101 probe_list = &_probe_list;
102 list_for_each_entry_reverse(iter, probe_list, head) {
103 BUG_ON(iter == desc); /* Should never be in the list twice */
104 if (iter < desc) {
105 /* We belong to the location right after iter. */
106 list_add(&desc->head, &iter->head);
107 goto desc_added;
108 }
109 }
110 /* We should be added at the head of the list */
111 list_add(&desc->head, probe_list);
112 desc_added:
113 pr_debug("LTTng: just registered probe %s containing %u events\n",
114 desc->provider_name, desc->nr_events);
115 }
116
117 /*
118 * Called under sessions lock.
119 */
120 static
121 void fixup_lazy_probes(void)
122 {
123 struct lttng_kernel_probe_desc *iter, *tmp;
124 int ret;
125
126 lazy_nesting++;
127 list_for_each_entry_safe(iter, tmp,
128 &lazy_probe_init, lazy_init_head) {
129 lttng_lazy_probe_register(iter);
130 iter->lazy = 0;
131 list_del(&iter->lazy_init_head);
132 }
133 ret = lttng_fix_pending_events();
134 WARN_ON_ONCE(ret);
135 ret = lttng_fix_pending_event_notifiers();
136 WARN_ON_ONCE(ret);
137 lazy_nesting--;
138 }
139
140 /*
141 * Called under sessions lock.
142 */
143 struct list_head *lttng_get_probe_list_head(void)
144 {
145 if (!lazy_nesting && !list_empty(&lazy_probe_init))
146 fixup_lazy_probes();
147 return &_probe_list;
148 }
149
150 static
151 const struct lttng_kernel_probe_desc *find_provider(const char *provider)
152 {
153 struct lttng_kernel_probe_desc *iter;
154 struct list_head *probe_list;
155
156 probe_list = lttng_get_probe_list_head();
157 list_for_each_entry(iter, probe_list, head) {
158 if (!strcmp(iter->provider_name, provider))
159 return iter;
160 }
161 return NULL;
162 }
163
164 int lttng_kernel_probe_register(struct lttng_kernel_probe_desc *desc)
165 {
166 int ret = 0;
167
168 lttng_lock_sessions();
169
170 /*
171 * Check if the provider has already been registered.
172 */
173 if (find_provider(desc->provider_name)) {
174 ret = -EEXIST;
175 goto end;
176 }
177 list_add(&desc->lazy_init_head, &lazy_probe_init);
178 desc->lazy = 1;
179 pr_debug("LTTng: adding probe %s containing %u events to lazy registration list\n",
180 desc->provider_name, desc->nr_events);
181 /*
182 * If there is at least one active session, we need to register
183 * the probe immediately, since we cannot delay event
184 * registration because they are needed ASAP.
185 */
186 if (lttng_session_active() || lttng_event_notifier_active())
187 fixup_lazy_probes();
188 end:
189 lttng_unlock_sessions();
190 return ret;
191 }
192 EXPORT_SYMBOL_GPL(lttng_kernel_probe_register);
193
194 void lttng_kernel_probe_unregister(struct lttng_kernel_probe_desc *desc)
195 {
196 lttng_lock_sessions();
197 if (!desc->lazy)
198 list_del(&desc->head);
199 else
200 list_del(&desc->lazy_init_head);
201 pr_debug("LTTng: just unregistered probe %s\n", desc->provider_name);
202 lttng_unlock_sessions();
203 }
204 EXPORT_SYMBOL_GPL(lttng_kernel_probe_unregister);
205
206 /*
207 * TODO: this is O(nr_probes * nb_events), could be faster.
208 * Called with sessions lock held.
209 */
210 static
211 const struct lttng_kernel_event_desc *find_event_desc(const char *name)
212 {
213 struct lttng_kernel_probe_desc *probe_desc;
214 int i;
215
216 list_for_each_entry(probe_desc, &_probe_list, head) {
217 for (i = 0; i < probe_desc->nr_events; i++) {
218 if (!strcmp(probe_desc->event_desc[i]->event_name, name))
219 return probe_desc->event_desc[i];
220 }
221 }
222 return NULL;
223 }
224
225 /*
226 * Called with sessions lock held.
227 */
228 const struct lttng_kernel_event_desc *lttng_event_desc_get(const char *name)
229 {
230 const struct lttng_kernel_event_desc *event_desc;
231 int ret;
232
233 event_desc = find_event_desc(name);
234 if (!event_desc)
235 return NULL;
236 ret = try_module_get(event_desc->owner);
237 WARN_ON_ONCE(!ret);
238 return event_desc;
239 }
240 EXPORT_SYMBOL_GPL(lttng_event_desc_get);
241
242 /*
243 * Called with sessions lock held.
244 */
245 void lttng_event_desc_put(const struct lttng_kernel_event_desc *event_desc)
246 {
247 module_put(event_desc->owner);
248 }
249 EXPORT_SYMBOL_GPL(lttng_event_desc_put);
250
251 static
252 void *tp_list_start(struct seq_file *m, loff_t *pos)
253 {
254 struct lttng_kernel_probe_desc *probe_desc;
255 struct list_head *probe_list;
256 int iter = 0, i;
257
258 lttng_lock_sessions();
259 probe_list = lttng_get_probe_list_head();
260 list_for_each_entry(probe_desc, probe_list, head) {
261 for (i = 0; i < probe_desc->nr_events; i++) {
262 if (iter++ >= *pos)
263 return (void *) probe_desc->event_desc[i];
264 }
265 }
266 /* End of list */
267 return NULL;
268 }
269
270 static
271 void *tp_list_next(struct seq_file *m, void *p, loff_t *ppos)
272 {
273 struct lttng_kernel_probe_desc *probe_desc;
274 struct list_head *probe_list;
275 int iter = 0, i;
276
277 (*ppos)++;
278 probe_list = lttng_get_probe_list_head();
279 list_for_each_entry(probe_desc, probe_list, head) {
280 for (i = 0; i < probe_desc->nr_events; i++) {
281 if (iter++ >= *ppos)
282 return (void *) probe_desc->event_desc[i];
283 }
284 }
285 /* End of list */
286 return NULL;
287 }
288
289 static
290 void tp_list_stop(struct seq_file *m, void *p)
291 {
292 lttng_unlock_sessions();
293 }
294
295 static
296 int tp_list_show(struct seq_file *m, void *p)
297 {
298 const struct lttng_kernel_event_desc *probe_desc = p;
299
300 seq_printf(m, "event { name = %s; };\n",
301 probe_desc->event_name);
302 return 0;
303 }
304
305 static
306 const struct seq_operations lttng_tracepoint_list_seq_ops = {
307 .start = tp_list_start,
308 .next = tp_list_next,
309 .stop = tp_list_stop,
310 .show = tp_list_show,
311 };
312
313 static
314 int lttng_tracepoint_list_open(struct inode *inode, struct file *file)
315 {
316 return seq_open(file, &lttng_tracepoint_list_seq_ops);
317 }
318
319 const struct file_operations lttng_tracepoint_list_fops = {
320 .owner = THIS_MODULE,
321 .open = lttng_tracepoint_list_open,
322 .read = seq_read,
323 .llseek = seq_lseek,
324 .release = seq_release,
325 };
326
327 int lttng_probes_init(void)
328 {
329 int cpu;
330
331 for_each_possible_cpu(cpu)
332 per_cpu_ptr(&lttng_dynamic_len_stack, cpu)->offset = 0;
333 return 0;
334 }
This page took 0.035228 seconds and 4 git commands to generate.