From: Mathieu Desnoyers Date: Sat, 1 Oct 2016 22:59:17 +0000 (-0400) Subject: Fix: perform TLS fixup in all UST entry points from each thread X-Git-Tag: v2.8.2~6 X-Git-Url: http://git.lttng.org/?p=lttng-ust.git;a=commitdiff_plain;h=a3b964ebc0510bacc9af2d729f1a68c2e3ccc95d Fix: perform TLS fixup in all UST entry points from each thread 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 --- diff --git a/liblttng-ust/lttng-context-provider.c b/liblttng-ust/lttng-context-provider.c index 6c067e2f..e6749bee 100644 --- a/liblttng-ust/lttng-context-provider.c +++ b/liblttng-ust/lttng-context-provider.c @@ -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, diff --git a/liblttng-ust/lttng-probes.c b/liblttng-ust/lttng-probes.c index bba5cd34..4b525923 100644 --- a/liblttng-ust/lttng-probes.c +++ b/liblttng-ust/lttng-probes.c @@ -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; diff --git a/liblttng-ust/lttng-tracer-core.h b/liblttng-ust/lttng-tracer-core.h index 44aca749..ba232f32 100644 --- a/liblttng-ust/lttng-tracer-core.h +++ b/liblttng-ust/lttng-tracer-core.h @@ -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 */ diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index 6c6eeda5..07c1be09 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -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 */ diff --git a/liblttng-ust/lttng-ust-statedump.c b/liblttng-ust/lttng-ust-statedump.c index 4242579f..e1fbe053 100644 --- a/liblttng-ust/lttng-ust-statedump.c +++ b/liblttng-ust/lttng-ust-statedump.c @@ -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; /*