Rename lttng_probe_{,un}register to lttng_kernel_probe_{,un}register
[lttng-modules.git] / src / lttng-probes.c
... / ...
CommitLineData
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 */
21static LIST_HEAD(_probe_list);
22
23/*
24 * List of probes registered by not yet processed.
25 */
26static 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 */
33static int lazy_nesting;
34
35DEFINE_PER_CPU(struct lttng_dynamic_len_stack, lttng_dynamic_len_stack);
36
37EXPORT_PER_CPU_SYMBOL_GPL(lttng_dynamic_len_stack);
38
39/*
40 * Called under sessions lock.
41 */
42static
43int 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 */
77static
78void 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);
112desc_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 */
120static
121void 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 */
143struct 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
150static
151const 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
164int 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();
188end:
189 lttng_unlock_sessions();
190 return ret;
191}
192EXPORT_SYMBOL_GPL(lttng_kernel_probe_register);
193
194void 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}
204EXPORT_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 */
210static
211const 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 */
228const 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}
240EXPORT_SYMBOL_GPL(lttng_event_desc_get);
241
242/*
243 * Called with sessions lock held.
244 */
245void lttng_event_desc_put(const struct lttng_kernel_event_desc *event_desc)
246{
247 module_put(event_desc->owner);
248}
249EXPORT_SYMBOL_GPL(lttng_event_desc_put);
250
251static
252void *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
270static
271void *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
289static
290void tp_list_stop(struct seq_file *m, void *p)
291{
292 lttng_unlock_sessions();
293}
294
295static
296int 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
305static
306const 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
313static
314int lttng_tracepoint_list_open(struct inode *inode, struct file *file)
315{
316 return seq_open(file, &lttng_tracepoint_list_seq_ops);
317}
318
319const 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
327int 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.023573 seconds and 4 git commands to generate.