From: Mathieu Desnoyers Date: Wed, 17 May 2017 22:36:54 +0000 (-0400) Subject: Fix: thread exit vs futex wait/wakeup race X-Git-Tag: v2.10.0-rc2~56 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=5f7d3a72d099c2b62a4116e313a700a0ab8906ce;p=lttng-tools.git Fix: thread exit vs futex wait/wakeup race relayd_live_stop performs, in this order: CMM_STORE_SHARED(live_dispatch_thread_exit, 1); [A] futex_nto1_wake(&viewer_conn_queue.futex); [B] whereas thread_dispatcher does: while (!CMM_LOAD_SHARED(live_dispatch_thread_exit)) { [1] [...] futex_nto1_prepare(&viewer_conn_queue.futex); [2] [...] futex_nto1_wait(&viewer_conn_queue.futex); [3] Unfortunately, on the following sequence: [1] [A] [B] [2] [3] thread_dispatcher will end up hanging. We need to move the live_dispatch_thread_exit load between "prepare" and "wait" to fix this. There are similar scenarios with relay_thread_dispatcher, and the session daemon thread_dispatch_ust_registration, which are also fixed here. Signed-off-by: Mathieu Desnoyers Signed-off-by: Jérémie Galarneau --- diff --git a/src/bin/lttng-relayd/live.c b/src/bin/lttng-relayd/live.c index 61acafec2..f00270bea 100644 --- a/src/bin/lttng-relayd/live.c +++ b/src/bin/lttng-relayd/live.c @@ -654,12 +654,16 @@ void *thread_dispatcher(void *data) health_code_update(); - while (!CMM_LOAD_SHARED(live_dispatch_thread_exit)) { + for (;;) { health_code_update(); /* Atomically prepare the queue futex */ futex_nto1_prepare(&viewer_conn_queue.futex); + if (CMM_LOAD_SHARED(live_dispatch_thread_exit)) { + break; + } + do { health_code_update(); diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 2fcc60af0..0eb8e2825 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -977,12 +977,16 @@ static void *relay_thread_dispatcher(void *data) health_code_update(); - while (!CMM_LOAD_SHARED(dispatch_thread_exit)) { + for (;;) { health_code_update(); /* Atomically prepare the queue futex */ futex_nto1_prepare(&relay_conn_queue.futex); + if (CMM_LOAD_SHARED(dispatch_thread_exit)) { + break; + } + do { health_code_update(); diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 9b6f70cd0..e282a9c76 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -1934,12 +1934,16 @@ static void *thread_dispatch_ust_registration(void *data) DBG("[thread] Dispatch UST command started"); - while (!CMM_LOAD_SHARED(dispatch_thread_exit)) { + for (;;) { health_code_update(); /* Atomically prepare the queue futex */ futex_nto1_prepare(&ust_cmd_queue.futex); + if (CMM_LOAD_SHARED(dispatch_thread_exit)) { + break; + } + do { struct ust_app *app = NULL; ust_cmd = NULL;