From 212a7c5ffa425113159ddf0190c2b65d75c03615 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 17 May 2017 18:36:54 -0400 Subject: [PATCH] Fix: thread exit vs futex wait/wakeup race MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- src/bin/lttng-relayd/live.c | 6 +++++- src/bin/lttng-relayd/main.c | 6 +++++- src/bin/lttng-sessiond/main.c | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/bin/lttng-relayd/live.c b/src/bin/lttng-relayd/live.c index cc88032dc..ffec5977e 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 56efaae34..9c96af127 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 8527ad04c..50eead010 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -1916,12 +1916,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; -- 2.34.1