Split liblttng-ust into liblttng-ust and liblttng-ust-tracepoint libs
[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 pthread_mutex_lock(&tracepoint_mutex);
405 old = tracepoint_add_probe(name, probe, data);
406 if (IS_ERR(old)) {
407 ret = PTR_ERR(old);
408 goto end;
409 }
410
411 tracepoint_update_probes(); /* may update entry */
412 release_probes(old);
413 end:
414 pthread_mutex_unlock(&tracepoint_mutex);
415 return ret;
416 }
417
418 static void *tracepoint_remove_probe(const char *name, void *probe, void *data)
419 {
420 struct tracepoint_entry *entry;
421 void *old;
422
423 entry = get_tracepoint(name);
424 if (!entry)
425 return ERR_PTR(-ENOENT);
426 old = tracepoint_entry_remove_probe(entry, probe, data);
427 if (IS_ERR(old))
428 return old;
429 if (!entry->refcount)
430 remove_tracepoint(entry);
431 return old;
432 }
433
434 /**
435 * tracepoint_probe_unregister - Disconnect a probe from a tracepoint
436 * @name: tracepoint name
437 * @probe: probe function pointer
438 * @probe: probe data pointer
439 */
440 int __tracepoint_probe_unregister(const char *name, void *probe, void *data)
441 {
442 void *old;
443 int ret = 0;
444
445 pthread_mutex_lock(&tracepoint_mutex);
446 old = tracepoint_remove_probe(name, probe, data);
447 if (IS_ERR(old)) {
448 ret = PTR_ERR(old);
449 goto end;
450 }
451 tracepoint_update_probes(); /* may update entry */
452 release_probes(old);
453 end:
454 pthread_mutex_unlock(&tracepoint_mutex);
455 return ret;
456 }
457
458 static void tracepoint_add_old_probes(void *old)
459 {
460 need_update = 1;
461 if (old) {
462 struct tp_probes *tp_probes = caa_container_of(old,
463 struct tp_probes, probes[0]);
464 cds_list_add(&tp_probes->u.list, &old_probes);
465 }
466 }
467
468 /**
469 * tracepoint_probe_register_noupdate - register a probe but not connect
470 * @name: tracepoint name
471 * @probe: probe handler
472 *
473 * caller must call tracepoint_probe_update_all()
474 */
475 int tracepoint_probe_register_noupdate(const char *name, void *probe,
476 void *data)
477 {
478 void *old;
479 int ret = 0;
480
481 pthread_mutex_lock(&tracepoint_mutex);
482 old = tracepoint_add_probe(name, probe, data);
483 if (IS_ERR(old)) {
484 ret = PTR_ERR(old);
485 goto end;
486 }
487 tracepoint_add_old_probes(old);
488 end:
489 pthread_mutex_unlock(&tracepoint_mutex);
490 return ret;
491 }
492
493 /**
494 * tracepoint_probe_unregister_noupdate - remove a probe but not disconnect
495 * @name: tracepoint name
496 * @probe: probe function pointer
497 *
498 * caller must call tracepoint_probe_update_all()
499 * Called with the tracepoint mutex held.
500 */
501 int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
502 void *data)
503 {
504 void *old;
505 int ret = 0;
506
507 pthread_mutex_lock(&tracepoint_mutex);
508 old = tracepoint_remove_probe(name, probe, data);
509 if (IS_ERR(old)) {
510 ret = PTR_ERR(old);
511 goto end;
512 }
513 tracepoint_add_old_probes(old);
514 end:
515 pthread_mutex_unlock(&tracepoint_mutex);
516 return ret;
517 }
518
519 /**
520 * tracepoint_probe_update_all - update tracepoints
521 */
522 void tracepoint_probe_update_all(void)
523 {
524 CDS_LIST_HEAD(release_probes);
525 struct tp_probes *pos, *next;
526
527 pthread_mutex_lock(&tracepoint_mutex);
528 if (!need_update) {
529 goto end;
530 }
531 if (!cds_list_empty(&old_probes))
532 cds_list_replace_init(&old_probes, &release_probes);
533 need_update = 0;
534
535 tracepoint_update_probes();
536 cds_list_for_each_entry_safe(pos, next, &release_probes, u.list) {
537 cds_list_del(&pos->u.list);
538 synchronize_rcu();
539 free(pos);
540 }
541 end:
542 pthread_mutex_unlock(&tracepoint_mutex);
543 }
544
545 void tracepoint_set_new_tracepoint_cb(void (*cb)(struct tracepoint *))
546 {
547 new_tracepoint_cb = cb;
548 }
549
550 static void new_tracepoints(struct tracepoint * const *start, struct tracepoint * const *end)
551 {
552 if (new_tracepoint_cb) {
553 struct tracepoint * const *t;
554
555 for (t = start; t < end; t++) {
556 if (*t)
557 new_tracepoint_cb(*t);
558 }
559 }
560 }
561
562 static
563 void lib_disable_tracepoints(struct tracepoint * const *begin,
564 struct tracepoint * const *end)
565 {
566 struct tracepoint * const *iter;
567
568 for (iter = begin; iter < end; iter++) {
569 if (!*iter)
570 continue; /* skip dummy */
571 disable_tracepoint(*iter);
572 }
573
574 }
575
576 int tracepoint_register_lib(struct tracepoint * const *tracepoints_start,
577 int tracepoints_count)
578 {
579 struct tracepoint_lib *pl, *iter;
580
581 init_tracepoint();
582
583 pl = (struct tracepoint_lib *) zmalloc(sizeof(struct tracepoint_lib));
584
585 pl->tracepoints_start = tracepoints_start;
586 pl->tracepoints_count = tracepoints_count;
587
588 pthread_mutex_lock(&tracepoint_mutex);
589 /*
590 * We sort the libs by struct lib pointer address.
591 */
592 cds_list_for_each_entry_reverse(iter, &libs, list) {
593 BUG_ON(iter == pl); /* Should never be in the list twice */
594 if (iter < pl) {
595 /* We belong to the location right after iter. */
596 cds_list_add(&pl->list, &iter->list);
597 goto lib_added;
598 }
599 }
600 /* We should be added at the head of the list */
601 cds_list_add(&pl->list, &libs);
602 lib_added:
603 new_tracepoints(tracepoints_start, tracepoints_start + tracepoints_count);
604
605 /* TODO: update just the loaded lib */
606 lib_update_tracepoints();
607 pthread_mutex_unlock(&tracepoint_mutex);
608
609 DBG("just registered a tracepoints section from %p and having %d tracepoints",
610 tracepoints_start, tracepoints_count);
611
612 return 0;
613 }
614
615 int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_start)
616 {
617 struct tracepoint_lib *lib;
618 int tracepoints_count;
619
620 pthread_mutex_lock(&tracepoint_mutex);
621 cds_list_for_each_entry(lib, &libs, list) {
622 if (lib->tracepoints_start == tracepoints_start) {
623 struct tracepoint_lib *lib2free = lib;
624
625 cds_list_del(&lib->list);
626 tracepoints_count = lib->tracepoints_count;
627 free(lib2free);
628 goto found;
629 }
630 }
631 goto end;
632 found:
633 /*
634 * Force tracepoint disarm for all tracepoints of this lib.
635 * This takes care of destructor of library that would leave a
636 * LD_PRELOAD wrapper override function enabled for tracing, but
637 * the session teardown would not be able to reach the
638 * tracepoint anymore to disable it.
639 */
640 lib_disable_tracepoints(tracepoints_start,
641 tracepoints_start + tracepoints_count);
642 DBG("just unregistered a tracepoints section from %p",
643 tracepoints_start);
644 end:
645 pthread_mutex_unlock(&tracepoint_mutex);
646 return 0;
647 }
648
649 void init_tracepoint(void)
650 {
651 if (uatomic_xchg(&initialized, 1) == 1)
652 return;
653 init_usterr();
654 }
655
656 void exit_tracepoint(void)
657 {
658 initialized = 0;
659 }
660
661 /*
662 * Create the wrapper symbols.
663 */
664 #undef tp_rcu_read_lock_bp
665 #undef tp_rcu_read_unlock_bp
666 #undef tp_rcu_dereference_bp
667
668 void tp_rcu_read_lock_bp(void)
669 {
670 rcu_read_lock_bp();
671 }
672
673 void tp_rcu_read_unlock_bp(void)
674 {
675 rcu_read_unlock_bp();
676 }
677
678 void *tp_rcu_dereference_sym_bp(void *p)
679 {
680 return rcu_dereference_bp(p);
681 }
This page took 0.043759 seconds and 5 git commands to generate.