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.9.5~12 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=68924dc1c9ab647a8b6165e00f74593f9e3da1cf;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 9e1085f33..f9d57281e 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 919c5a96a..8a183db28 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -969,12 +969,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 0df0b1f2e..44b88f39f 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -1868,12 +1868,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;