Revert "Remove useless const qualifier"
[lttng-ust.git] / liblttng-ust / tracepoint.c
1 /*
2 * Copyright (C) 2008-2011 Mathieu Desnoyers
3 * Copyright (C) 2009 Pierre-Marc Fournier
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation;
8 * version 2.1 of the License.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 * Ported to userspace by Pierre-Marc Fournier.
20 */
21
22 #define _LGPL_SOURCE
23 #include <errno.h>
24 #include <stdint.h>
25 #include <stddef.h>
26
27 #include <urcu/arch.h>
28 #include <urcu-bp.h>
29 #include <urcu/hlist.h>
30 #include <urcu/uatomic.h>
31 #include <urcu/compiler.h>
32
33 #include <lttng/tracepoint.h>
34 #include <lttng/ust-abi.h> /* for LTTNG_UST_SYM_NAME_LEN */
35
36 #include <usterr-signal-safe.h>
37 #include <helper.h>
38
39 #include "tracepoint-internal.h"
40 #include "ltt-tracer-core.h"
41 #include "jhash.h"
42 #include "error.h"
43
44 /* Set to 1 to enable tracepoint debug output */
45 static const int tracepoint_debug;
46 static int initialized;
47 static void (*new_tracepoint_cb)(struct tracepoint *);
48
49 /*
50 * tracepoint_mutex nests inside UST mutex.
51 *
52 * Note about interaction with fork/clone: UST does not hold the
53 * tracepoint mutex across fork/clone because it is either:
54 * - nested within UST mutex, in which case holding the UST mutex across
55 * fork/clone suffice,
56 * - taken by a library constructor, which should never race with a
57 * fork/clone if the application is expected to continue running with
58 * the same memory layout (no following exec()).
59 */
60 static pthread_mutex_t tracepoint_mutex = PTHREAD_MUTEX_INITIALIZER;
61
62 /*
63 * libraries that contain tracepoints (struct tracepoint_lib).
64 * Protected by tracepoint mutex.
65 */
66 static CDS_LIST_HEAD(libs);
67
68 /*
69 * The tracepoint mutex protects the library tracepoints, the hash table, and
70 * the library list.
71 * All calls to the tracepoint API must be protected by the tracepoint mutex,
72 * excepts calls to tracepoint_register_lib and
73 * tracepoint_unregister_lib, which take the tracepoint mutex themselves.
74 */
75
76 /*
77 * Tracepoint hash table, containing the active tracepoints.
78 * Protected by tracepoint mutex.
79 */
80 #define TRACEPOINT_HASH_BITS 6
81 #define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS)
82 static struct cds_hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
83
84 static CDS_LIST_HEAD(old_probes);
85 static int need_update;
86
87 /*
88 * Note about RCU :
89 * It is used to to delay the free of multiple probes array until a quiescent
90 * state is reached.
91 * Tracepoint entries modifications are protected by the tracepoint mutex.
92 */
93 struct tracepoint_entry {
94 struct cds_hlist_node hlist;
95 struct tracepoint_probe *probes;
96 int refcount; /* Number of times armed. 0 if disarmed. */
97 char name[0];
98 };
99
100 struct tp_probes {
101 union {
102 struct cds_list_head list;
103 /* Field below only used for call_rcu scheme */
104 /* struct rcu_head head; */
105 } u;
106 struct tracepoint_probe probes[0];
107 };
108
109 static void *allocate_probes(int count)
110 {
111 struct tp_probes *p = zmalloc(count * sizeof(struct tracepoint_probe)
112 + sizeof(struct tp_probes));
113 return p == NULL ? NULL : p->probes;
114 }
115
116 static void release_probes(void *old)
117 {
118 if (old) {
119 struct tp_probes *tp_probes = caa_container_of(old,
120 struct tp_probes, probes[0]);
121 synchronize_rcu();
122 free(tp_probes);
123 }
124 }
125
126 static void debug_print_probes(struct tracepoint_entry *entry)
127 {
128 int i;
129
130 if (!tracepoint_debug || !entry->probes)
131 return;
132
133 for (i = 0; entry->probes[i].func; i++)
134 DBG("Probe %d : %p", i, entry->probes[i].func);
135 }
136
137 static void *
138 tracepoint_entry_add_probe(struct tracepoint_entry *entry,
139 void *probe, void *data)
140 {
141 int nr_probes = 0;
142 struct tracepoint_probe *old, *new;
143
144 WARN_ON(!probe);
145
146 debug_print_probes(entry);
147 old = entry->probes;
148 if (old) {
149 /* (N -> N+1), (N != 0, 1) probes */
150 for (nr_probes = 0; old[nr_probes].func; nr_probes++)
151 if (old[nr_probes].func == probe &&
152 old[nr_probes].data == data)
153 return ERR_PTR(-EEXIST);
154 }
155 /* + 2 : one for new probe, one for NULL func */
156 new = allocate_probes(nr_probes + 2);
157 if (new == NULL)
158 return ERR_PTR(-ENOMEM);
159 if (old)
160 memcpy(new, old, nr_probes * sizeof(struct tracepoint_probe));
161 new[nr_probes].func = probe;
162 new[nr_probes].data = data;
163 new[nr_probes + 1].func = NULL;
164 entry->refcount = nr_probes + 1;
165 entry->probes = new;
166 debug_print_probes(entry);
167 return old;
168 }
169
170 static void *
171 tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe,
172 void *data)
173 {
174 int nr_probes = 0, nr_del = 0, i;
175 struct tracepoint_probe *old, *new;
176
177 old = entry->probes;
178
179 if (!old)
180 return ERR_PTR(-ENOENT);
181
182 debug_print_probes(entry);
183 /* (N -> M), (N > 1, M >= 0) probes */
184 for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
185 if (!probe ||
186 (old[nr_probes].func == probe &&
187 old[nr_probes].data == data))
188 nr_del++;
189 }
190
191 if (nr_probes - nr_del == 0) {
192 /* N -> 0, (N > 1) */
193 entry->probes = NULL;
194 entry->refcount = 0;
195 debug_print_probes(entry);
196 return old;
197 } else {
198 int j = 0;
199 /* N -> M, (N > 1, M > 0) */
200 /* + 1 for NULL */
201 new = allocate_probes(nr_probes - nr_del + 1);
202 if (new == NULL)
203 return ERR_PTR(-ENOMEM);
204 for (i = 0; old[i].func; i++)
205 if (probe &&
206 (old[i].func != probe || old[i].data != data))
207 new[j++] = old[i];
208 new[nr_probes - nr_del].func = NULL;
209 entry->refcount = nr_probes - nr_del;
210 entry->probes = new;
211 }
212 debug_print_probes(entry);
213 return old;
214 }
215
216 /*
217 * Get tracepoint if the tracepoint is present in the tracepoint hash table.
218 * Must be called with tracepoint mutex held.
219 * Returns NULL if not present.
220 */
221 static struct tracepoint_entry *get_tracepoint(const char *name)
222 {
223 struct cds_hlist_head *head;
224 struct cds_hlist_node *node;
225 struct tracepoint_entry *e;
226 size_t name_len = strlen(name);
227 uint32_t hash;
228
229 if (name_len > LTTNG_UST_SYM_NAME_LEN - 1) {
230 WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN - 1);
231 name_len = LTTNG_UST_SYM_NAME_LEN - 1;
232 }
233 hash = jhash(name, name_len, 0);
234 head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
235 cds_hlist_for_each_entry(e, node, head, hlist) {
236 if (!strncmp(name, e->name, LTTNG_UST_SYM_NAME_LEN - 1))
237 return e;
238 }
239 return NULL;
240 }
241
242 /*
243 * Add the tracepoint to the tracepoint hash table. Must be called with
244 * tracepoint mutex held.
245 */
246 static struct tracepoint_entry *add_tracepoint(const char *name)
247 {
248 struct cds_hlist_head *head;
249 struct cds_hlist_node *node;
250 struct tracepoint_entry *e;
251 size_t name_len = strlen(name);
252 uint32_t hash;
253
254 if (name_len > LTTNG_UST_SYM_NAME_LEN - 1) {
255 WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN - 1);
256 name_len = LTTNG_UST_SYM_NAME_LEN - 1;
257 }
258 hash = jhash(name, name_len, 0);
259 head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
260 cds_hlist_for_each_entry(e, node, head, hlist) {
261 if (!strncmp(name, e->name, LTTNG_UST_SYM_NAME_LEN - 1)) {
262 DBG("tracepoint %s busy", name);
263 return ERR_PTR(-EEXIST); /* Already there */
264 }
265 }
266 /*
267 * Using zmalloc here to allocate a variable length element. Could
268 * cause some memory fragmentation if overused.
269 */
270 e = zmalloc(sizeof(struct tracepoint_entry) + name_len + 1);
271 if (!e)
272 return ERR_PTR(-ENOMEM);
273 memcpy(&e->name[0], name, name_len + 1);
274 e->name[name_len] = '\0';
275 e->probes = NULL;
276 e->refcount = 0;
277 cds_hlist_add_head(&e->hlist, head);
278 return e;
279 }
280
281 /*
282 * Remove the tracepoint from the tracepoint hash table. Must be called with
283 * tracepoint mutex held.
284 */
285 static void remove_tracepoint(struct tracepoint_entry *e)
286 {
287 cds_hlist_del(&e->hlist);
288 free(e);
289 }
290
291 /*
292 * Sets the probe callback corresponding to one tracepoint.
293 */
294 static void set_tracepoint(struct tracepoint_entry **entry,
295 struct tracepoint *elem, int active)
296 {
297 WARN_ON(strncmp((*entry)->name, elem->name, LTTNG_UST_SYM_NAME_LEN - 1) != 0);
298
299 /*
300 * rcu_assign_pointer has a cmm_smp_wmb() which makes sure that the new
301 * probe callbacks array is consistent before setting a pointer to it.
302 * This array is referenced by __DO_TRACE from
303 * include/linux/tracepoints.h. A matching cmm_smp_read_barrier_depends()
304 * is used.
305 */
306 rcu_assign_pointer(elem->probes, (*entry)->probes);
307 elem->state = active;
308 }
309
310 /*
311 * Disable a tracepoint and its probe callback.
312 * Note: only waiting an RCU period after setting elem->call to the empty
313 * function insures that the original callback is not used anymore. This insured
314 * by preempt_disable around the call site.
315 */
316 static void disable_tracepoint(struct tracepoint *elem)
317 {
318 elem->state = 0;
319 rcu_assign_pointer(elem->probes, NULL);
320 }
321
322 /**
323 * tracepoint_update_probe_range - Update a probe range
324 * @begin: beginning of the range
325 * @end: end of the range
326 *
327 * Updates the probe callback corresponding to a range of tracepoints.
328 */
329 static
330 void tracepoint_update_probe_range(struct tracepoint * const *begin,
331 struct tracepoint * const *end)
332 {
333 struct tracepoint * const *iter;
334 struct tracepoint_entry *mark_entry;
335
336 for (iter = begin; iter < end; iter++) {
337 if (!*iter)
338 continue; /* skip dummy */
339 if (!(*iter)->name) {
340 disable_tracepoint(*iter);
341 continue;
342 }
343 mark_entry = get_tracepoint((*iter)->name);
344 if (mark_entry) {
345 set_tracepoint(&mark_entry, *iter,
346 !!mark_entry->refcount);
347 } else {
348 disable_tracepoint(*iter);
349 }
350 }
351 }
352
353 static void lib_update_tracepoints(void)
354 {
355 struct tracepoint_lib *lib;
356
357 cds_list_for_each_entry(lib, &libs, list) {
358 tracepoint_update_probe_range(lib->tracepoints_start,
359 lib->tracepoints_start + lib->tracepoints_count);
360 }
361 }
362
363 /*
364 * Update probes, removing the faulty probes.
365 */
366 static void tracepoint_update_probes(void)
367 {
368 /* tracepoints registered from libraries and executable. */
369 lib_update_tracepoints();
370 }
371
372 static struct tracepoint_probe *
373 tracepoint_add_probe(const char *name, void *probe, void *data)
374 {
375 struct tracepoint_entry *entry;
376 struct tracepoint_probe *old;
377
378 entry = get_tracepoint(name);
379 if (!entry) {
380 entry = add_tracepoint(name);
381 if (IS_ERR(entry))
382 return (struct tracepoint_probe *)entry;
383 }
384 old = tracepoint_entry_add_probe(entry, probe, data);
385 if (IS_ERR(old) && !entry->refcount)
386 remove_tracepoint(entry);
387 return old;
388 }
389
390 /**
391 * __tracepoint_probe_register - Connect a probe to a tracepoint
392 * @name: tracepoint name
393 * @probe: probe handler
394 *
395 * Returns 0 if ok, error value on error.
396 * The probe address must at least be aligned on the architecture pointer size.
397 * Called with the tracepoint mutex held.
398 */
399 int __tracepoint_probe_register(const char *name, void *probe, void *data)
400 {
401 void *old;
402 int ret = 0;
403
404 DBG("Registering probe to tracepoint %s", name);
405
406 pthread_mutex_lock(&tracepoint_mutex);
407 old = tracepoint_add_probe(name, probe, data);
408 if (IS_ERR(old)) {
409 ret = PTR_ERR(old);
410 goto end;
411 }
412
413 tracepoint_update_probes(); /* may update entry */
414 release_probes(old);
415 end:
416 pthread_mutex_unlock(&tracepoint_mutex);
417 return ret;
418 }
419
420 static void *tracepoint_remove_probe(const char *name, void *probe, void *data)
421 {
422 struct tracepoint_entry *entry;
423 void *old;
424
425 entry = get_tracepoint(name);
426 if (!entry)
427 return ERR_PTR(-ENOENT);
428 old = tracepoint_entry_remove_probe(entry, probe, data);
429 if (IS_ERR(old))
430 return old;
431 if (!entry->refcount)
432 remove_tracepoint(entry);
433 return old;
434 }
435
436 /**
437 * tracepoint_probe_unregister - Disconnect a probe from a tracepoint
438 * @name: tracepoint name
439 * @probe: probe function pointer
440 * @probe: probe data pointer
441 */
442 int __tracepoint_probe_unregister(const char *name, void *probe, void *data)
443 {
444 void *old;
445 int ret = 0;
446
447 DBG("Un-registering probe from tracepoint %s", name);
448
449 pthread_mutex_lock(&tracepoint_mutex);
450 old = tracepoint_remove_probe(name, probe, data);
451 if (IS_ERR(old)) {
452 ret = PTR_ERR(old);
453 goto end;
454 }
455 tracepoint_update_probes(); /* may update entry */
456 release_probes(old);
457 end:
458 pthread_mutex_unlock(&tracepoint_mutex);
459 return ret;
460 }
461
462 static void tracepoint_add_old_probes(void *old)
463 {
464 need_update = 1;
465 if (old) {
466 struct tp_probes *tp_probes = caa_container_of(old,
467 struct tp_probes, probes[0]);
468 cds_list_add(&tp_probes->u.list, &old_probes);
469 }
470 }
471
472 /**
473 * tracepoint_probe_register_noupdate - register a probe but not connect
474 * @name: tracepoint name
475 * @probe: probe handler
476 *
477 * caller must call tracepoint_probe_update_all()
478 */
479 int tracepoint_probe_register_noupdate(const char *name, void *probe,
480 void *data)
481 {
482 void *old;
483 int ret = 0;
484
485 pthread_mutex_lock(&tracepoint_mutex);
486 old = tracepoint_add_probe(name, probe, data);
487 if (IS_ERR(old)) {
488 ret = PTR_ERR(old);
489 goto end;
490 }
491 tracepoint_add_old_probes(old);
492 end:
493 pthread_mutex_unlock(&tracepoint_mutex);
494 return ret;
495 }
496
497 /**
498 * tracepoint_probe_unregister_noupdate - remove a probe but not disconnect
499 * @name: tracepoint name
500 * @probe: probe function pointer
501 *
502 * caller must call tracepoint_probe_update_all()
503 * Called with the tracepoint mutex held.
504 */
505 int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
506 void *data)
507 {
508 void *old;
509 int ret = 0;
510
511 DBG("Un-registering probe from tracepoint %s", name);
512
513 pthread_mutex_lock(&tracepoint_mutex);
514 old = tracepoint_remove_probe(name, probe, data);
515 if (IS_ERR(old)) {
516 ret = PTR_ERR(old);
517 goto end;
518 }
519 tracepoint_add_old_probes(old);
520 end:
521 pthread_mutex_unlock(&tracepoint_mutex);
522 return ret;
523 }
524
525 /**
526 * tracepoint_probe_update_all - update tracepoints
527 */
528 void tracepoint_probe_update_all(void)
529 {
530 CDS_LIST_HEAD(release_probes);
531 struct tp_probes *pos, *next;
532
533 pthread_mutex_lock(&tracepoint_mutex);
534 if (!need_update) {
535 goto end;
536 }
537 if (!cds_list_empty(&old_probes))
538 cds_list_replace_init(&old_probes, &release_probes);
539 need_update = 0;
540
541 tracepoint_update_probes();
542 cds_list_for_each_entry_safe(pos, next, &release_probes, u.list) {
543 cds_list_del(&pos->u.list);
544 synchronize_rcu();
545 free(pos);
546 }
547 end:
548 pthread_mutex_unlock(&tracepoint_mutex);
549 }
550
551 void tracepoint_set_new_tracepoint_cb(void (*cb)(struct tracepoint *))
552 {
553 new_tracepoint_cb = cb;
554 }
555
556 static void new_tracepoints(struct tracepoint * const *start, struct tracepoint * const *end)
557 {
558 if (new_tracepoint_cb) {
559 struct tracepoint * const *t;
560
561 for (t = start; t < end; t++) {
562 if (*t)
563 new_tracepoint_cb(*t);
564 }
565 }
566 }
567
568 static
569 void lib_disable_tracepoints(struct tracepoint * const *begin,
570 struct tracepoint * const *end)
571 {
572 struct tracepoint * const *iter;
573
574 for (iter = begin; iter < end; iter++) {
575 if (!*iter)
576 continue; /* skip dummy */
577 disable_tracepoint(*iter);
578 }
579
580 }
581
582 int tracepoint_register_lib(struct tracepoint * const *tracepoints_start,
583 int tracepoints_count)
584 {
585 struct tracepoint_lib *pl, *iter;
586
587 init_tracepoint();
588
589 pl = (struct tracepoint_lib *) zmalloc(sizeof(struct tracepoint_lib));
590
591 pl->tracepoints_start = tracepoints_start;
592 pl->tracepoints_count = tracepoints_count;
593
594 pthread_mutex_lock(&tracepoint_mutex);
595 /*
596 * We sort the libs by struct lib pointer address.
597 */
598 cds_list_for_each_entry_reverse(iter, &libs, list) {
599 BUG_ON(iter == pl); /* Should never be in the list twice */
600 if (iter < pl) {
601 /* We belong to the location right after iter. */
602 cds_list_add(&pl->list, &iter->list);
603 goto lib_added;
604 }
605 }
606 /* We should be added at the head of the list */
607 cds_list_add(&pl->list, &libs);
608 lib_added:
609 new_tracepoints(tracepoints_start, tracepoints_start + tracepoints_count);
610
611 /* TODO: update just the loaded lib */
612 lib_update_tracepoints();
613 pthread_mutex_unlock(&tracepoint_mutex);
614
615 DBG("just registered a tracepoints section from %p and having %d tracepoints",
616 tracepoints_start, tracepoints_count);
617 if (ust_debug()) {
618 int i;
619
620 for (i = 0; i < tracepoints_count; i++) {
621 DBG("registered tracepoint: %s", tracepoints_start[i]->name);
622 }
623 }
624
625 return 0;
626 }
627
628 int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_start)
629 {
630 struct tracepoint_lib *lib;
631 int tracepoints_count;
632
633 pthread_mutex_lock(&tracepoint_mutex);
634 cds_list_for_each_entry(lib, &libs, list) {
635 if (lib->tracepoints_start == tracepoints_start) {
636 struct tracepoint_lib *lib2free = lib;
637
638 cds_list_del(&lib->list);
639 tracepoints_count = lib->tracepoints_count;
640 free(lib2free);
641 goto found;
642 }
643 }
644 goto end;
645 found:
646 /*
647 * Force tracepoint disarm for all tracepoints of this lib.
648 * This takes care of destructor of library that would leave a
649 * LD_PRELOAD wrapper override function enabled for tracing, but
650 * the session teardown would not be able to reach the
651 * tracepoint anymore to disable it.
652 */
653 lib_disable_tracepoints(tracepoints_start,
654 tracepoints_start + tracepoints_count);
655 DBG("just unregistered a tracepoints section from %p",
656 tracepoints_start);
657 end:
658 pthread_mutex_unlock(&tracepoint_mutex);
659 return 0;
660 }
661
662 void init_tracepoint(void)
663 {
664 if (uatomic_xchg(&initialized, 1) == 1)
665 return;
666 init_usterr();
667 }
668
669 void exit_tracepoint(void)
670 {
671 initialized = 0;
672 }
673
674 /*
675 * Create the wrapper symbols.
676 */
677 #undef tp_rcu_read_lock_bp
678 #undef tp_rcu_read_unlock_bp
679 #undef tp_rcu_dereference_bp
680
681 void tp_rcu_read_lock_bp(void)
682 {
683 rcu_read_lock_bp();
684 }
685
686 void tp_rcu_read_unlock_bp(void)
687 {
688 rcu_read_unlock_bp();
689 }
690
691 void *tp_rcu_dereference_sym_bp(void *p)
692 {
693 return rcu_dereference_bp(p);
694 }
This page took 0.045028 seconds and 4 git commands to generate.