X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=libust%2Ftracepoint.c;h=6a8795b70c218498446d7b16370cfb62d484c88f;hb=8161463975e218e0833d31ab1577a7ceb9e8e9f3;hp=47d3785a1a1bede84f356cefdf45736a7d037601;hpb=10c561687fc2f7aa40380e967cf5132a656f34b7;p=ust.git diff --git a/libust/tracepoint.c b/libust/tracepoint.c index 47d3785..6a8795b 100644 --- a/libust/tracepoint.c +++ b/libust/tracepoint.c @@ -4,8 +4,8 @@ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * License as published by the Free Software Foundation; + * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -19,16 +19,17 @@ * Ported to userspace by Pierre-Marc Fournier. */ +#define _LGPL_SOURCE #include #include +#include #include #include -#include "usterr.h" - -#define _LGPL_SOURCE #include #include +#include "usterr_signal_safe.h" + //extern struct tracepoint __start___tracepoints[] __attribute__((visibility("hidden"))); //extern struct tracepoint __stop___tracepoints[] __attribute__((visibility("hidden"))); @@ -60,7 +61,7 @@ static struct cds_hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE]; */ struct tracepoint_entry { struct cds_hlist_node hlist; - struct probe *probes; + struct tracepoint_probe *probes; int refcount; /* Number of times armed. 0 if disarmed. */ char name[0]; }; @@ -70,12 +71,12 @@ struct tp_probes { //ust// struct rcu_head rcu; struct cds_list_head list; } u; - struct probe probes[0]; + struct tracepoint_probe probes[0]; }; static inline void *allocate_probes(int count) { - struct tp_probes *p = zmalloc(count * sizeof(struct probe) + struct tp_probes *p = zmalloc(count * sizeof(struct tracepoint_probe) + sizeof(struct tp_probes)); return p == NULL ? NULL : p->probes; } @@ -112,7 +113,7 @@ tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe, void *data) { int nr_probes = 0; - struct probe *old, *new; + struct tracepoint_probe *old, *new; WARN_ON(!probe); @@ -130,7 +131,7 @@ tracepoint_entry_add_probe(struct tracepoint_entry *entry, if (new == NULL) return ERR_PTR(-ENOMEM); if (old) - memcpy(new, old, nr_probes * sizeof(struct probe)); + memcpy(new, old, nr_probes * sizeof(struct tracepoint_probe)); new[nr_probes].func = probe; new[nr_probes].data = data; new[nr_probes + 1].func = NULL; @@ -145,7 +146,7 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe, void *data) { int nr_probes = 0, nr_del = 0, i; - struct probe *old, *new; + struct tracepoint_probe *old, *new; old = entry->probes; @@ -265,7 +266,7 @@ static void set_tracepoint(struct tracepoint_entry **entry, * is used. */ rcu_assign_pointer(elem->probes, (*entry)->probes); - elem->state__imv = active; + elem->state = active; } /* @@ -276,7 +277,7 @@ static void set_tracepoint(struct tracepoint_entry **entry, */ static void disable_tracepoint(struct tracepoint *elem) { - elem->state__imv = 0; + elem->state = 0; rcu_assign_pointer(elem->probes, NULL); } @@ -287,24 +288,26 @@ static void disable_tracepoint(struct tracepoint *elem) * * Updates the probe callback corresponding to a range of tracepoints. */ -void tracepoint_update_probe_range(struct tracepoint *begin, - struct tracepoint *end) +void tracepoint_update_probe_range(struct tracepoint * const *begin, + struct tracepoint * const *end) { - struct tracepoint *iter; + struct tracepoint * const *iter; struct tracepoint_entry *mark_entry; pthread_mutex_lock(&tracepoints_mutex); for (iter = begin; iter < end; iter++) { - if (!iter->name) { - disable_tracepoint(iter); + if (!*iter) + continue; /* skip dummy */ + if (!(*iter)->name) { + disable_tracepoint(*iter); continue; } - mark_entry = get_tracepoint(iter->name); + mark_entry = get_tracepoint((*iter)->name); if (mark_entry) { - set_tracepoint(&mark_entry, iter, + set_tracepoint(&mark_entry, *iter, !!mark_entry->refcount); } else { - disable_tracepoint(iter); + disable_tracepoint(*iter); } } pthread_mutex_unlock(&tracepoints_mutex); @@ -331,22 +334,19 @@ static void tracepoint_update_probes(void) //ust// __stop___tracepoints); /* tracepoints in modules. */ lib_update_tracepoints(); - /* Update immediate values */ - core_imv_update(); -//ust// module_imv_update(); } -static struct probe * +static struct tracepoint_probe * tracepoint_add_probe(const char *name, void *probe, void *data) { struct tracepoint_entry *entry; - struct probe *old; + struct tracepoint_probe *old; entry = get_tracepoint(name); if (!entry) { entry = add_tracepoint(name); if (IS_ERR(entry)) - return (struct probe *)entry; + return (struct tracepoint_probe *)entry; } old = tracepoint_entry_add_probe(entry, probe, data); if (IS_ERR(old) && !entry->refcount) @@ -355,14 +355,14 @@ tracepoint_add_probe(const char *name, void *probe, void *data) } /** - * tracepoint_probe_register - Connect a probe to a tracepoint + * __tracepoint_probe_register - Connect a probe to a tracepoint * @name: tracepoint name * @probe: probe handler * * Returns 0 if ok, error value on error. * The probe address must at least be aligned on the architecture pointer size. */ -int tracepoint_probe_register(const char *name, void *probe, void *data) +int __tracepoint_probe_register(const char *name, void *probe, void *data) { void *old; @@ -376,7 +376,6 @@ int tracepoint_probe_register(const char *name, void *probe, void *data) release_probes(old); return 0; } -//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_register); static void *tracepoint_remove_probe(const char *name, void *probe, void *data) { @@ -405,7 +404,7 @@ static void *tracepoint_remove_probe(const char *name, void *probe, void *data) * itself uses stop_machine(), which insures that every preempt disabled section * have finished. */ -int tracepoint_probe_unregister(const char *name, void *probe, void *data) +int __tracepoint_probe_unregister(const char *name, void *probe, void *data) { void *old; @@ -419,7 +418,6 @@ int tracepoint_probe_unregister(const char *name, void *probe, void *data) release_probes(old); return 0; } -//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_unregister); static CDS_LIST_HEAD(old_probes); static int need_update; @@ -547,15 +545,17 @@ int lib_get_iter_tracepoints(struct tracepoint_iter *iter) * Will return the first tracepoint in the range if the input tracepoint is * NULL. */ -int tracepoint_get_iter_range(struct tracepoint **tracepoint, - struct tracepoint *begin, struct tracepoint *end) +int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, + struct tracepoint * const *begin, struct tracepoint * const *end) { - if (!*tracepoint && begin != end) { + if (!*tracepoint && begin != end) *tracepoint = begin; - return 1; + while (*tracepoint >= begin && *tracepoint < end) { + if (!**tracepoint) + (*tracepoint)++; /* skip dummy */ + else + return 1; } - if (*tracepoint >= begin && *tracepoint < end) - return 1; return 0; } //ust// EXPORT_SYMBOL_GPL(tracepoint_get_iter_range); @@ -648,19 +648,21 @@ void tracepoint_set_new_tracepoint_cb(void (*cb)(struct tracepoint *)) new_tracepoint_cb = cb; } -static void new_tracepoints(struct tracepoint *start, struct tracepoint *end) +static void new_tracepoints(struct tracepoint * const *start, struct tracepoint * const *end) { - if(new_tracepoint_cb) { - struct tracepoint *t; - for(t=start; t < end; t++) { - new_tracepoint_cb(t); + if (new_tracepoint_cb) { + struct tracepoint * const *t; + + for(t = start; t < end; t++) { + if (*t) + new_tracepoint_cb(*t); } } } -int tracepoint_register_lib(struct tracepoint *tracepoints_start, int tracepoints_count) +int tracepoint_register_lib(struct tracepoint * const *tracepoints_start, int tracepoints_count) { - struct tracepoint_lib *pl; + struct tracepoint_lib *pl, *iter; pl = (struct tracepoint_lib *) zmalloc(sizeof(struct tracepoint_lib)); @@ -669,7 +671,20 @@ int tracepoint_register_lib(struct tracepoint *tracepoints_start, int tracepoint /* FIXME: maybe protect this with its own mutex? */ pthread_mutex_lock(&tracepoints_mutex); + /* + * We sort the libs by struct lib pointer address. + */ + cds_list_for_each_entry_reverse(iter, &libs, list) { + BUG_ON(iter == pl); /* Should never be in the list twice */ + if (iter < pl) { + /* We belong to the location right after iter. */ + cds_list_add(&pl->list, &iter->list); + goto lib_added; + } + } + /* We should be added at the head of the list */ cds_list_add(&pl->list, &libs); +lib_added: pthread_mutex_unlock(&tracepoints_mutex); new_tracepoints(tracepoints_start, tracepoints_start + tracepoints_count); @@ -677,19 +692,20 @@ int tracepoint_register_lib(struct tracepoint *tracepoints_start, int tracepoint /* FIXME: update just the loaded lib */ lib_update_tracepoints(); - DBG("just registered a tracepoints section from %p and having %d tracepoints", tracepoints_start, tracepoints_count); + /* tracepoints_count - 1: skip dummy */ + DBG("just registered a tracepoints section from %p and having %d tracepoints (minus dummy tracepoints)", tracepoints_start, tracepoints_count); return 0; } -int tracepoint_unregister_lib(struct tracepoint *tracepoints_start) +int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_start) { struct tracepoint_lib *lib; pthread_mutex_lock(&tracepoints_mutex); cds_list_for_each_entry(lib, &libs, list) { - if(lib->tracepoints_start == tracepoints_start) { + if (lib->tracepoints_start == tracepoints_start) { struct tracepoint_lib *lib2free = lib; cds_list_del(&lib->list); free(lib2free);