Fix: perform TLS fixup in all UST entry points from each thread
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 1 Oct 2016 22:59:17 +0000 (18:59 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 3 Oct 2016 15:47:11 +0000 (11:47 -0400)
Each entry point into lttng-ust that end up taking the ust lock need to
perform a TLS fixup for each thread. Add a TLS fixup in both listener
threads, in fork and base address dump helper libs, and in app context
and tracepoint probe registration/unregistration functions, which can be
called from application threads.

Those ensure we don't take the libc dl lock within the ust lock when
performing the TLS lazy fixup.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
liblttng-ust/lttng-context-provider.c
liblttng-ust/lttng-probes.c
liblttng-ust/lttng-tracer-core.h
liblttng-ust/lttng-ust-comm.c
liblttng-ust/lttng-ust-statedump.c

index 6c067e2fecae06548a3d4495ef9477b2495a6a5b..e6749beeda6b42d4b8e0a267c1f555f18e1aaaa4 100644 (file)
@@ -67,6 +67,8 @@ int lttng_ust_context_provider_register(struct lttng_ust_context_provider *provi
        uint32_t hash;
        int ret = 0;
 
+       lttng_ust_fixup_tls();
+
        /* Provider name starts with "$app.". */
        if (strncmp("$app.", provider->name, strlen("$app.") != 0))
                return -EINVAL;
@@ -94,6 +96,8 @@ end:
 
 void lttng_ust_context_provider_unregister(struct lttng_ust_context_provider *provider)
 {
+       lttng_ust_fixup_tls();
+
        if (ust_lock())
                goto end;
        lttng_ust_context_set_session_provider(provider->name,
index bba5cd345238b25db0340c77c52ae991584a30a9..4b5259230d97d5cec6e524b0b607162a31ab8d5a 100644 (file)
@@ -194,6 +194,8 @@ int lttng_probe_register(struct lttng_probe_desc *desc)
 {
        int ret = 0;
 
+       lttng_ust_fixup_tls();
+
        /*
         * If version mismatch, don't register, but don't trigger assert
         * on caller. The version check just prints an error.
@@ -234,6 +236,8 @@ int ltt_probe_register(struct lttng_probe_desc *desc)
 
 void lttng_probe_unregister(struct lttng_probe_desc *desc)
 {
+       lttng_ust_fixup_tls();
+
        if (!check_provider_version(desc))
                return;
 
index 44aca749c6c04553702e2ecd54313657bd27b777..ba232f32acf5dc20067a41d15b496653ca1ee1a8 100644 (file)
@@ -62,5 +62,6 @@ void lttng_ust_dummy_record(struct lttng_ctx_field *field,
 void lttng_ust_dummy_get_value(struct lttng_ctx_field *field,
                struct lttng_ctx_value *value);
 int lttng_context_is_app(const char *name);
+void lttng_ust_fixup_tls(void);
 
 #endif /* _LTTNG_TRACER_CORE_H */
index 6c6eeda51a960c4b3632486faa67adc4e49b0ef0..07c1be09eb46aa2f53903ebb91f42369c290aa87 100644 (file)
@@ -388,6 +388,16 @@ void lttng_fixup_urcu_bp_tls(void)
        rcu_read_unlock();
 }
 
+void lttng_ust_fixup_tls(void)
+{
+       lttng_fixup_urcu_bp_tls();
+       lttng_fixup_ringbuffer_tls();
+       lttng_fixup_vtid_tls();
+       lttng_fixup_nest_count_tls();
+       lttng_fixup_procname_tls();
+       lttng_fixup_ust_mutex_nest_tls();
+}
+
 int lttng_get_notify_socket(void *owner)
 {
        struct sock_info *info = owner;
@@ -1295,6 +1305,8 @@ void *ust_listener_thread(void *arg)
        int sock, ret, prev_connect_failed = 0, has_waited = 0;
        long timeout;
 
+       lttng_ust_fixup_tls();
+
        /* Restart trying to connect to the session daemon */
 restart:
        if (prev_connect_failed) {
@@ -1558,12 +1570,7 @@ void __attribute__((constructor)) lttng_ust_init(void)
         * to be the dynamic linker mutex) and ust_lock, taken within
         * the ust lock.
         */
-       lttng_fixup_urcu_bp_tls();
-       lttng_fixup_ringbuffer_tls();
-       lttng_fixup_vtid_tls();
-       lttng_fixup_nest_count_tls();
-       lttng_fixup_procname_tls();
-       lttng_fixup_ust_mutex_nest_tls();
+       lttng_ust_fixup_tls();
 
        /*
         * We want precise control over the order in which we construct
@@ -1792,6 +1799,9 @@ void ust_before_fork(sigset_t *save_sigset)
        sigset_t all_sigs;
        int ret;
 
+       /* Fixup lttng-ust TLS. */
+       lttng_ust_fixup_tls();
+
        if (URCU_TLS(lttng_ust_nest_count))
                return;
        /* Disable signals */
index 4242579fa13616341c7607667d31e523d88be486..e1fbe0536d6cd3a4dadc44ef2afee4e0d41496fa 100644 (file)
@@ -315,6 +315,12 @@ int do_baddr_statedump(void *owner)
        if (getenv("LTTNG_UST_WITHOUT_BADDR_STATEDUMP"))
                return 0;
 
+       /*
+        * Fixup lttng-ust TLS when called from dlopen/dlclose
+        * instrumentation.
+        */
+       lttng_ust_fixup_tls();
+
        data.owner = owner;
        data.exec_found = 0;
        /*
This page took 0.029474 seconds and 4 git commands to generate.