X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=liblttng-ust%2Ftracepoint.c;h=f146d382b7717955875938a1169d8436515ee043;hb=ff412fb523eeacd9f2b698ccefc4f716ace9afd0;hp=217ef4c22af2de76e8fe2990d7facc187f825386;hpb=b728d87e617189fe9898a9492a559ecf949d2348;p=lttng-ust.git diff --git a/liblttng-ust/tracepoint.c b/liblttng-ust/tracepoint.c index 217ef4c2..f146d382 100644 --- a/liblttng-ust/tracepoint.c +++ b/liblttng-ust/tracepoint.c @@ -21,26 +21,35 @@ #define _LGPL_SOURCE #include -#include -#include -#include #include #include + #include #include #include #include #include -#include +#include +#include /* for LTTNG_UST_SYM_NAME_LEN */ + +#include +#include + +#include "tracepoint-internal.h" #include "ltt-tracer-core.h" +#include "jhash.h" +#include "error.h" /* Set to 1 to enable tracepoint debug output */ static const int tracepoint_debug; static int initialized; static void (*new_tracepoint_cb)(struct tracepoint *); -/* libraries that contain tracepoints (struct tracepoint_lib) */ +/* + * libraries that contain tracepoints (struct tracepoint_lib). + * Protected by UST lock. + */ static CDS_LIST_HEAD(libs); /* @@ -53,7 +62,7 @@ static CDS_LIST_HEAD(libs); /* * Tracepoint hash table, containing the active tracepoints. - * Protected by tracepoints_mutex. + * Protected by ust lock. */ #define TRACEPOINT_HASH_BITS 6 #define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS) @@ -66,7 +75,7 @@ static int need_update; * Note about RCU : * It is used to to delay the free of multiple probes array until a quiescent * state is reached. - * Tracepoint entries modifications are protected by the tracepoints_mutex. + * Tracepoint entries modifications are protected by the ust lock. */ struct tracepoint_entry { struct cds_hlist_node hlist; @@ -82,14 +91,14 @@ struct tp_probes { struct tracepoint_probe probes[0]; }; -static inline void *allocate_probes(int count) +static void *allocate_probes(int count) { struct tp_probes *p = zmalloc(count * sizeof(struct tracepoint_probe) + sizeof(struct tp_probes)); return p == NULL ? NULL : p->probes; } -static inline void release_probes(void *old) +static void release_probes(void *old) { if (old) { struct tp_probes *tp_probes = caa_container_of(old, @@ -191,7 +200,7 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe, /* * Get tracepoint if the tracepoint is present in the tracepoint hash table. - * Must be called with tracepoints_mutex held. + * Must be called with ust lock held. * Returns NULL if not present. */ static struct tracepoint_entry *get_tracepoint(const char *name) @@ -199,11 +208,17 @@ static struct tracepoint_entry *get_tracepoint(const char *name) struct cds_hlist_head *head; struct cds_hlist_node *node; struct tracepoint_entry *e; - u32 hash = jhash(name, strlen(name), 0); + size_t name_len = strlen(name); + uint32_t hash; + if (name_len > LTTNG_UST_SYM_NAME_LEN - 1) { + WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN - 1); + name_len = LTTNG_UST_SYM_NAME_LEN - 1; + } + hash = jhash(name, name_len, 0); head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)]; cds_hlist_for_each_entry(e, node, head, hlist) { - if (!strcmp(name, e->name)) + if (!strncmp(name, e->name, LTTNG_UST_SYM_NAME_LEN - 1)) return e; } return NULL; @@ -211,19 +226,24 @@ static struct tracepoint_entry *get_tracepoint(const char *name) /* * Add the tracepoint to the tracepoint hash table. Must be called with - * tracepoints_mutex held. + * ust lock held. */ static struct tracepoint_entry *add_tracepoint(const char *name) { struct cds_hlist_head *head; struct cds_hlist_node *node; struct tracepoint_entry *e; - size_t name_len = strlen(name) + 1; - u32 hash = jhash(name, name_len-1, 0); + size_t name_len = strlen(name); + uint32_t hash; + if (name_len > LTTNG_UST_SYM_NAME_LEN - 1) { + WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN - 1); + name_len = LTTNG_UST_SYM_NAME_LEN - 1; + } + hash = jhash(name, name_len, 0); head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)]; cds_hlist_for_each_entry(e, node, head, hlist) { - if (!strcmp(name, e->name)) { + if (!strncmp(name, e->name, LTTNG_UST_SYM_NAME_LEN - 1)) { DBG("tracepoint %s busy", name); return ERR_PTR(-EEXIST); /* Already there */ } @@ -232,10 +252,11 @@ static struct tracepoint_entry *add_tracepoint(const char *name) * Using zmalloc here to allocate a variable length element. Could * cause some memory fragmentation if overused. */ - e = zmalloc(sizeof(struct tracepoint_entry) + name_len); + e = zmalloc(sizeof(struct tracepoint_entry) + name_len + 1); if (!e) return ERR_PTR(-ENOMEM); - memcpy(&e->name[0], name, name_len); + memcpy(&e->name[0], name, name_len + 1); + e->name[name_len] = '\0'; e->probes = NULL; e->refcount = 0; cds_hlist_add_head(&e->hlist, head); @@ -246,7 +267,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name) * Remove the tracepoint from the tracepoint hash table. Must be called with * ust_lock held. */ -static inline void remove_tracepoint(struct tracepoint_entry *e) +static void remove_tracepoint(struct tracepoint_entry *e) { cds_hlist_del(&e->hlist); free(e); @@ -258,7 +279,7 @@ static inline void remove_tracepoint(struct tracepoint_entry *e) static void set_tracepoint(struct tracepoint_entry **entry, struct tracepoint *elem, int active) { - WARN_ON(strcmp((*entry)->name, elem->name) != 0); + WARN_ON(strncmp((*entry)->name, elem->name, LTTNG_UST_SYM_NAME_LEN - 1) != 0); /* * rcu_assign_pointer has a cmm_smp_wmb() which makes sure that the new @@ -486,105 +507,6 @@ void tracepoint_probe_update_all(void) } } -/* - * Returns 0 if current not found. - * Returns 1 if current found. - * - * Called with tracepoint mutex held - */ -int lib_get_iter_tracepoints(struct tracepoint_iter *iter) -{ - struct tracepoint_lib *iter_lib; - int found = 0; - - cds_list_for_each_entry(iter_lib, &libs, list) { - if (iter_lib < iter->lib) - continue; - else if (iter_lib > iter->lib) - iter->tracepoint = NULL; - found = tracepoint_get_iter_range(&iter->tracepoint, - iter_lib->tracepoints_start, - iter_lib->tracepoints_start + iter_lib->tracepoints_count); - if (found) { - iter->lib = iter_lib; - break; - } - } - return found; -} - -/** - * tracepoint_get_iter_range - Get a next tracepoint iterator given a range. - * @tracepoint: current tracepoints (in), next tracepoint (out) - * @begin: beginning of the range - * @end: end of the range - * - * Returns whether a next tracepoint has been found (1) or not (0). - * Will return the first tracepoint in the range if the input tracepoint is - * NULL. - * Called with tracepoint mutex held. - */ -int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, - struct tracepoint * const *begin, struct tracepoint * const *end) -{ - if (!*tracepoint && begin != end) - *tracepoint = begin; - while (*tracepoint >= begin && *tracepoint < end) { - if (!**tracepoint) - (*tracepoint)++; /* skip dummy */ - else - return 1; - } - return 0; -} - -/* - * Called with tracepoint mutex held. - */ -static void tracepoint_get_iter(struct tracepoint_iter *iter) -{ - int found = 0; - - /* tracepoints in libs. */ - found = lib_get_iter_tracepoints(iter); - if (!found) - tracepoint_iter_reset(iter); -} - -/* - * Called with UST lock held. - */ -void tracepoint_iter_start(struct tracepoint_iter *iter) -{ - tracepoint_get_iter(iter); -} - -/* - * Called with UST lock held. - */ -void tracepoint_iter_next(struct tracepoint_iter *iter) -{ - iter->tracepoint++; - /* - * iter->tracepoint may be invalid because we blindly incremented it. - * Make sure it is valid by marshalling on the tracepoints, getting the - * tracepoints from following modules if necessary. - */ - tracepoint_get_iter(iter); -} - -/* - * Called with UST lock held. - */ -void tracepoint_iter_stop(struct tracepoint_iter *iter) -{ -} - -void tracepoint_iter_reset(struct tracepoint_iter *iter) -{ - iter->tracepoint = NULL; -} - void tracepoint_set_new_tracepoint_cb(void (*cb)(struct tracepoint *)) { new_tracepoint_cb = cb; @@ -670,3 +592,25 @@ void exit_tracepoint(void) { initialized = 0; } + +/* + * Create the wrapper symbols. + */ +#undef tp_rcu_read_lock_bp +#undef tp_rcu_read_unlock_bp +#undef tp_rcu_dereference_bp + +void tp_rcu_read_lock_bp(void) +{ + rcu_read_lock_bp(); +} + +void tp_rcu_read_unlock_bp(void) +{ + rcu_read_unlock_bp(); +} + +void *tp_rcu_dereference_sym_bp(void *p) +{ + return rcu_dereference_bp(p); +}