summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
33f8ed8)
Keep track of how many libraries use a tracepoint, and disable the
tracepoint when the number of users drops to zero.
A new reference counter is added to tracepoint_entry. This keeps track
of how many callsites use that tracepoint.
When you have libraries and/or executables sharing tracepoints, you
cannot just disable your tracepoints when the library is unregistered.
You must check that the tracepoint is not used by any other libraries
before you disable it.
Function lib_disable_tracepoints becomes unnecessary, and is removed.
Signed-off-by: Ikaheimonen, JP <jp_ikaheimonen@mentor.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
struct cds_hlist_node hlist;
struct tracepoint_probe *probes;
int refcount; /* Number of times armed. 0 if disarmed. */
struct cds_hlist_node hlist;
struct tracepoint_probe *probes;
int refcount; /* Number of times armed. 0 if disarmed. */
+ int callsite_refcount; /* how many libs use this tracepoint */
const char *signature;
char name[0];
};
const char *signature;
char name[0];
};
e->name[name_len] = '\0';
e->probes = NULL;
e->refcount = 0;
e->name[name_len] = '\0';
e->probes = NULL;
e->refcount = 0;
+ e->callsite_refcount = 0;
e->signature = signature;
cds_hlist_add_head(&e->hlist, head);
return e;
e->signature = signature;
cds_hlist_add_head(&e->hlist, head);
return e;
const char *name = tp->name;
size_t name_len = strlen(name);
uint32_t hash;
const char *name = tp->name;
size_t name_len = strlen(name);
uint32_t hash;
+ struct tracepoint_entry *tp_entry;
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);
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);
cds_hlist_add_head(&e->hlist, head);
e->tp = tp;
cds_list_add(&e->node, &lib->callsites);
cds_hlist_add_head(&e->hlist, head);
e->tp = tp;
cds_list_add(&e->node, &lib->callsites);
+
+ tp_entry = get_tracepoint(name);
+ if (!tp_entry)
+ return;
+ tp_entry->callsite_refcount++;
*/
static void remove_callsite(struct callsite_entry *e)
{
*/
static void remove_callsite(struct callsite_entry *e)
{
+ struct tracepoint_entry *tp_entry;
+
+ tp_entry = get_tracepoint(e->tp->name);
+ if (tp_entry) {
+ tp_entry->callsite_refcount--;
+ if (tp_entry->callsite_refcount == 0)
+ disable_tracepoint(e->tp);
+ }
cds_hlist_del(&e->hlist);
cds_list_del(&e->node);
free(e);
cds_hlist_del(&e->hlist);
cds_list_del(&e->node);
free(e);
-static
-void lib_disable_tracepoints(struct tracepoint_lib *lib)
-{
- struct tracepoint * const *begin;
- struct tracepoint * const *end;
- struct tracepoint * const *iter;
-
- begin = lib->tracepoints_start;
- end = lib->tracepoints_start + lib->tracepoints_count;
-
- for (iter = begin; iter < end; iter++) {
- if (!*iter)
- continue; /* skip dummy */
- disable_tracepoint(*iter);
- }
-
-}
-
int tracepoint_register_lib(struct tracepoint * const *tracepoints_start,
int tracepoints_count)
{
int tracepoint_register_lib(struct tracepoint * const *tracepoints_start,
int tracepoints_count)
{
cds_list_del(&lib->list);
/*
cds_list_del(&lib->list);
/*
- * Force tracepoint disarm for all tracepoints of this lib.
- * This takes care of destructor of library that would leave a
- * LD_PRELOAD wrapper override function enabled for tracing, but
- * the session teardown would not be able to reach the
- * tracepoint anymore to disable it.
+ * Unregistering a callsite also decreases the
+ * callsite reference count of the corresponding
+ * tracepoint, and disables the tracepoint if
+ * the reference count drops to zero.
- lib_disable_tracepoints(lib);
lib_unregister_callsites(lib);
DBG("just unregistered a tracepoints section from %p",
lib->tracepoints_start);
lib_unregister_callsites(lib);
DBG("just unregistered a tracepoints section from %p",
lib->tracepoints_start);