X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=libust%2Fmarker.c;h=0c85cc3997f0d8669473c91055b7582ea4ad4f7c;hb=86699c2035dd69428706ade2d6dfb150ada757cb;hp=ef6f029ac65a2dc75ccb6d84a69c823f74c6af20;hpb=dc2848112a55ee60632491148089cc60984f683d;p=ust.git diff --git a/libust/marker.c b/libust/marker.c index ef6f029..0c85cc3 100644 --- a/libust/marker.c +++ b/libust/marker.c @@ -20,8 +20,9 @@ #include #define _LGPL_SOURCE #include +#include -#include +#include #include #include "usterr.h" @@ -49,12 +50,12 @@ static LIST_HEAD(libs); void lock_markers(void) { - mutex_lock(&markers_mutex); + pthread_mutex_lock(&markers_mutex); } void unlock_markers(void) { - mutex_unlock(&markers_mutex); + pthread_mutex_unlock(&markers_mutex); } /* @@ -234,7 +235,7 @@ static notrace void marker_probe_cb_noarg(const struct marker *mdata, static void free_old_closure(struct rcu_head *head) { - struct marker_entry *entry = container_of(head, + struct marker_entry *entry = _ust_container_of(head, struct marker_entry, rcu); free(entry->oldptr); /* Make sure we free the data before setting the pending flag to 0 */ @@ -427,10 +428,10 @@ static struct marker_entry *add_marker(const char *channel, const char *name, } } /* - * Using malloc here to allocate a variable length element. Could + * Using zmalloc here to allocate a variable length element. Could * cause some memory fragmentation if overused. */ - e = malloc(sizeof(struct marker_entry) + e = zmalloc(sizeof(struct marker_entry) + channel_len + name_len + format_len); if (!e) return ERR_PTR(-ENOMEM); @@ -438,7 +439,7 @@ static struct marker_entry *add_marker(const char *channel, const char *name, e->name = &e->channel[channel_len]; memcpy(e->name, name, name_len); if (format) { - e->format = &e->name[channel_len + name_len]; + e->format = &e->name[name_len]; memcpy(e->format, format, format_len); if (strcmp(e->format, MARK_NOARGS) == 0) e->call = marker_probe_cb_noarg; @@ -528,7 +529,7 @@ static int set_marker(struct marker_entry *entry, struct marker *elem, if (entry->format) { if (strcmp(entry->format, elem->format) != 0) { - DBG("Format mismatch for probe %s (%s), marker (%s)", + ERR("Format mismatch for probe %s (%s), marker (%s)", entry->name, entry->format, elem->format); @@ -576,36 +577,36 @@ static int set_marker(struct marker_entry *entry, struct marker *elem, smp_wmb(); elem->ptype = entry->ptype; -//ust// if (elem->tp_name && (active ^ _imv_read(elem->state))) { -//ust// WARN_ON(!elem->tp_cb); -//ust// /* -//ust// * It is ok to directly call the probe registration because type -//ust// * checking has been done in the __trace_mark_tp() macro. -//ust// */ -//ust// -//ust// if (active) { -//ust// /* -//ust// * try_module_get should always succeed because we hold -//ust// * markers_mutex to get the tp_cb address. -//ust// */ + if (elem->tp_name && (active ^ _imv_read(elem->state))) { + WARN_ON(!elem->tp_cb); + /* + * It is ok to directly call the probe registration because type + * checking has been done in the __trace_mark_tp() macro. + */ + + if (active) { + /* + * try_module_get should always succeed because we hold + * markers_mutex to get the tp_cb address. + */ //ust// ret = try_module_get(__module_text_address( //ust// (unsigned long)elem->tp_cb)); //ust// BUG_ON(!ret); -//ust// ret = tracepoint_probe_register_noupdate( -//ust// elem->tp_name, -//ust// elem->tp_cb); -//ust// } else { -//ust// ret = tracepoint_probe_unregister_noupdate( -//ust// elem->tp_name, -//ust// elem->tp_cb); -//ust// /* -//ust// * tracepoint_probe_update_all() must be called -//ust// * before the module containing tp_cb is unloaded. -//ust// */ + ret = tracepoint_probe_register_noupdate( + elem->tp_name, + elem->tp_cb); + } else { + ret = tracepoint_probe_unregister_noupdate( + elem->tp_name, + elem->tp_cb); + /* + * tracepoint_probe_update_all() must be called + * before the module containing tp_cb is unloaded. + */ //ust// module_put(__module_text_address( //ust// (unsigned long)elem->tp_cb)); -//ust// } -//ust// } + } + } elem->state__imv = active; return ret; @@ -619,24 +620,24 @@ static int set_marker(struct marker_entry *entry, struct marker *elem, */ static void disable_marker(struct marker *elem) { -//ust// int ret; -//ust// -//ust// /* leave "call" as is. It is known statically. */ -//ust// if (elem->tp_name && _imv_read(elem->state)) { -//ust// WARN_ON(!elem->tp_cb); -//ust// /* -//ust// * It is ok to directly call the probe registration because type -//ust// * checking has been done in the __trace_mark_tp() macro. -//ust// */ -//ust// ret = tracepoint_probe_unregister_noupdate(elem->tp_name, -//ust// elem->tp_cb); -//ust// WARN_ON(ret); -//ust// /* -//ust// * tracepoint_probe_update_all() must be called -//ust// * before the module containing tp_cb is unloaded. -//ust// */ + int ret; + + /* leave "call" as is. It is known statically. */ + if (elem->tp_name && _imv_read(elem->state)) { + WARN_ON(!elem->tp_cb); + /* + * It is ok to directly call the probe registration because type + * checking has been done in the __trace_mark_tp() macro. + */ + ret = tracepoint_probe_unregister_noupdate(elem->tp_name, + elem->tp_cb); + WARN_ON(ret); + /* + * tracepoint_probe_update_all() must be called + * before the module containing tp_cb is unloaded. + */ //ust// module_put(__module_text_address((unsigned long)elem->tp_cb)); -//ust// } + } elem->state__imv = 0; elem->single.func = __mark_empty_function; /* Update the function before setting the ptype */ @@ -660,9 +661,9 @@ int is_marker_enabled(const char *channel, const char *name) { struct marker_entry *entry; - mutex_lock(&markers_mutex); + pthread_mutex_lock(&markers_mutex); entry = get_marker(channel, name); - mutex_unlock(&markers_mutex); + pthread_mutex_unlock(&markers_mutex); return entry && !!entry->refcount; } @@ -680,7 +681,7 @@ void marker_update_probe_range(struct marker *begin, struct marker *iter; struct marker_entry *mark_entry; - mutex_lock(&markers_mutex); + pthread_mutex_lock(&markers_mutex); for (iter = begin; iter < end; iter++) { mark_entry = get_marker(iter->channel, iter->name); if (mark_entry) { @@ -706,7 +707,7 @@ void marker_update_probe_range(struct marker *begin, disable_marker(iter); } } - mutex_unlock(&markers_mutex); + pthread_mutex_unlock(&markers_mutex); } static void lib_update_markers(void) @@ -714,11 +715,11 @@ static void lib_update_markers(void) struct lib *lib; /* FIXME: we should probably take a mutex here on libs */ -//ust// mutex_lock(&module_mutex); +//ust// pthread_mutex_lock(&module_mutex); list_for_each_entry(lib, &libs, list) marker_update_probe_range(lib->markers_start, lib->markers_start + lib->markers_count); -//ust// mutex_unlock(&module_mutex); +//ust// pthread_mutex_unlock(&module_mutex); } /* @@ -745,7 +746,7 @@ static void marker_update_probes(void) /* Markers in modules. */ //ust// module_update_markers(); lib_update_markers(); -//ust// tracepoint_probe_update_all(); + tracepoint_probe_update_all(); /* Update immediate values */ core_imv_update(); //ust// module_imv_update(); /* FIXME: need to port for libs? */ @@ -773,7 +774,7 @@ int marker_probe_register(const char *channel, const char *name, struct marker_probe_closure *old; int first_probe = 0; - mutex_lock(&markers_mutex); + pthread_mutex_lock(&markers_mutex); entry = get_marker(channel, name); if (!entry) { first_probe = 1; @@ -824,12 +825,12 @@ int marker_probe_register(const char *channel, const char *name, else goto end; } - mutex_unlock(&markers_mutex); + pthread_mutex_unlock(&markers_mutex); /* Activate marker if necessary */ marker_update_probes(); - mutex_lock(&markers_mutex); + pthread_mutex_lock(&markers_mutex); entry = get_marker(channel, name); if (!entry) goto end; @@ -850,7 +851,7 @@ error_remove_marker: ret_err = remove_marker(channel, name); WARN_ON(ret_err); end: - mutex_unlock(&markers_mutex); + pthread_mutex_unlock(&markers_mutex); return ret; } //ust// EXPORT_SYMBOL_GPL(marker_probe_register); @@ -875,18 +876,18 @@ int marker_probe_unregister(const char *channel, const char *name, struct marker_probe_closure *old; int ret = -ENOENT; - mutex_lock(&markers_mutex); + pthread_mutex_lock(&markers_mutex); entry = get_marker(channel, name); if (!entry) goto end; //ust// if (entry->rcu_pending) //ust// rcu_barrier_sched(); old = marker_entry_remove_probe(entry, probe, probe_private); - mutex_unlock(&markers_mutex); + pthread_mutex_unlock(&markers_mutex); marker_update_probes(); - mutex_lock(&markers_mutex); + pthread_mutex_lock(&markers_mutex); entry = get_marker(channel, name); if (!entry) goto end; @@ -901,7 +902,7 @@ int marker_probe_unregister(const char *channel, const char *name, remove_marker(channel, name); /* Ignore busy error message */ ret = 0; end: - mutex_unlock(&markers_mutex); + pthread_mutex_unlock(&markers_mutex); return ret; } //ust// EXPORT_SYMBOL_GPL(marker_probe_unregister); @@ -958,7 +959,7 @@ int marker_probe_unregister_private_data(marker_probe_func *probe, struct marker_probe_closure *old; char *channel = NULL, *name = NULL; - mutex_lock(&markers_mutex); + pthread_mutex_lock(&markers_mutex); entry = get_marker_from_private_data(probe, probe_private); if (!entry) { ret = -ENOENT; @@ -969,11 +970,11 @@ int marker_probe_unregister_private_data(marker_probe_func *probe, old = marker_entry_remove_probe(entry, NULL, probe_private); channel = strdup(entry->channel); name = strdup(entry->name); - mutex_unlock(&markers_mutex); + pthread_mutex_unlock(&markers_mutex); marker_update_probes(); - mutex_lock(&markers_mutex); + pthread_mutex_lock(&markers_mutex); entry = get_marker(channel, name); if (!entry) goto end; @@ -988,7 +989,7 @@ int marker_probe_unregister_private_data(marker_probe_func *probe, /* Ignore busy error message */ remove_marker(channel, name); end: - mutex_unlock(&markers_mutex); + pthread_mutex_unlock(&markers_mutex); free(channel); free(name); return ret; @@ -1084,7 +1085,7 @@ int lib_get_iter_markers(struct marker_iter *iter) struct lib *iter_lib; int found = 0; -//ust// mutex_lock(&module_mutex); +//ust// pthread_mutex_lock(&module_mutex); list_for_each_entry(iter_lib, &libs, list) { if (iter_lib < iter->lib) continue; @@ -1098,7 +1099,7 @@ int lib_get_iter_markers(struct marker_iter *iter) break; } } -//ust// mutex_unlock(&module_mutex); +//ust// pthread_mutex_unlock(&module_mutex); return found; } @@ -1202,8 +1203,8 @@ static void free_user_marker(char __user *state, struct hlist_head *head) //ust// struct hlist_node *pos; //ust// struct marker_entry *entry; //ust// -//ust// mutex_lock(&markers_mutex); -//ust// mutex_lock(¤t->group_leader->user_markers_mutex); +//ust// pthread_mutex_lock(&markers_mutex); +//ust// pthread_mutex_lock(¤t->group_leader->user_markers_mutex); //ust// if (strcmp(current->comm, "testprog") == 0) //ust// DBG("do update pending for testprog"); //ust// hlist_for_each_entry(umark, pos, @@ -1230,8 +1231,8 @@ static void free_user_marker(char __user *state, struct hlist_head *head) //ust// } //ust// } //ust// clear_thread_flag(TIF_MARKER_PENDING); -//ust// mutex_unlock(¤t->group_leader->user_markers_mutex); -//ust// mutex_unlock(&markers_mutex); +//ust// pthread_mutex_unlock(¤t->group_leader->user_markers_mutex); +//ust// pthread_mutex_unlock(&markers_mutex); //ust// } /* @@ -1245,15 +1246,15 @@ void exit_user_markers(struct task_struct *p) struct hlist_node *pos, *n; if (thread_group_leader(p)) { - mutex_lock(&markers_mutex); - mutex_lock(&p->user_markers_mutex); + pthread_mutex_lock(&markers_mutex); + pthread_mutex_lock(&p->user_markers_mutex); hlist_for_each_entry_safe(umark, pos, n, &p->user_markers, hlist) free(umark); INIT_HLIST_HEAD(&p->user_markers); p->user_markers_sequence++; - mutex_unlock(&p->user_markers_mutex); - mutex_unlock(&markers_mutex); + pthread_mutex_unlock(&p->user_markers_mutex); + pthread_mutex_unlock(&markers_mutex); } } @@ -1261,9 +1262,9 @@ int is_marker_enabled(const char *channel, const char *name) { struct marker_entry *entry; - mutex_lock(&markers_mutex); + pthread_mutex_lock(&markers_mutex); entry = get_marker(channel, name); - mutex_unlock(&markers_mutex); + pthread_mutex_unlock(&markers_mutex); return entry && !!entry->refcount; } @@ -1309,7 +1310,7 @@ void ltt_dump_marker_state(struct ust_trace *trace) struct hlist_node *node; unsigned int i; - mutex_lock(&markers_mutex); + pthread_mutex_lock(&markers_mutex); call_data.trace = trace; call_data.serializer = NULL; @@ -1337,7 +1338,7 @@ void ltt_dump_marker_state(struct ust_trace *trace) entry->format); } } - mutex_unlock(&markers_mutex); + pthread_mutex_unlock(&markers_mutex); } //ust// EXPORT_SYMBOL_GPL(ltt_dump_marker_state); @@ -1362,7 +1363,7 @@ int marker_register_lib(struct marker *markers_start, int markers_count) { struct lib *pl; - pl = (struct lib *) malloc(sizeof(struct lib)); + pl = (struct lib *) zmalloc(sizeof(struct lib)); pl->markers_start = markers_start; pl->markers_count = markers_count; @@ -1382,11 +1383,28 @@ int marker_register_lib(struct marker *markers_start, int markers_count) return 0; } -int marker_unregister_lib(struct marker *markers_start, int markers_count) +int marker_unregister_lib(struct marker *markers_start) { + struct lib *lib; + /*FIXME: implement; but before implementing, marker_register_lib must have appropriate locking. */ + lock_markers(); + + /* FIXME: we should probably take a mutex here on libs */ +//ust// pthread_mutex_lock(&module_mutex); + list_for_each_entry(lib, &libs, list) { + if(lib->markers_start == markers_start) { + struct lib *lib2free = lib; + list_del(&lib->list); + free(lib2free); + break; + } + } + + unlock_markers(); + return 0; } @@ -1396,7 +1414,11 @@ void __attribute__((constructor)) init_markers(void) { if(!initialized) { marker_register_lib(__start___markers, (((long)__stop___markers)-((long)__start___markers))/sizeof(struct marker)); - //DBG("markers_start: %p, markers_stop: %p\n", __start___markers, __stop___markers); initialized = 1; } } + +void __attribute__((constructor)) destroy_markers(void) +{ + marker_unregister_lib(__start___markers); +}