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