From: Jérémie Galarneau Date: Wed, 5 Dec 2018 20:00:09 +0000 (-0500) Subject: Teardown the notification thread after the sessiond clean-up X-Git-Tag: v2.12.0-rc1~711 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=4a91420cefb94afc4a20042bdbe2564086dad3cb;p=lttng-tools.git Teardown the notification thread after the sessiond clean-up The notification thread may receive commands issued through the call_rcu thread during the destruction of some of the sessiond's data structure. This change tears down the notification thread after the clean-up has occured and the issuance of an RCU barrier. This ensures that all previously-queued call_rcu work has been performed and that any ensuing notification thread commands have been queued in return. It is safe, at that point, to queue a "quit" command in the notification thread's command queue. The notification thread's shutdown method will issue the command and wait for its completion before returning. Signed-off-by: Jérémie Galarneau --- diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 1fbfb1b05..d6bc01598 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -1353,6 +1353,7 @@ int main(int argc, char **argv) /* Queue of rotation jobs populated by the sessiond-timer. */ struct rotation_thread_timer_queue *rotation_timer_queue = NULL; struct lttng_thread *client_thread = NULL; + struct lttng_thread *notification_thread = NULL; init_kernel_workarounds(); @@ -1702,7 +1703,9 @@ int main(int argc, char **argv) } /* Create notification thread. */ - if (!launch_notification_thread(notification_thread_handle)) { + notification_thread = launch_notification_thread( + notification_thread_handle); + if (!notification_thread) { retval = -1; goto exit_notification; } @@ -1837,6 +1840,11 @@ exit_init_data: rcu_thread_online(); sessiond_cleanup(); + if (notification_thread) { + lttng_thread_shutdown(notification_thread); + lttng_thread_put(notification_thread); + } + /* * Ensure all prior call_rcu are done. call_rcu callbacks may push * hash tables to the ht_cleanup thread. Therefore, we ensure that diff --git a/src/bin/lttng-sessiond/notification-thread.c b/src/bin/lttng-sessiond/notification-thread.c index 9809e6190..b42b282e1 100644 --- a/src/bin/lttng-sessiond/notification-thread.c +++ b/src/bin/lttng-sessiond/notification-thread.c @@ -653,7 +653,8 @@ bool shutdown_notification_thread(void *thread_data) return true; } -bool launch_notification_thread(struct notification_thread_handle *handle) +struct lttng_thread *launch_notification_thread( + struct notification_thread_handle *handle) { struct lttng_thread *thread; @@ -672,8 +673,7 @@ bool launch_notification_thread(struct notification_thread_handle *handle) * (e.g. rotation thread). */ wait_until_thread_is_ready(handle); - lttng_thread_put(thread); - return true; + return thread; error: - return false; + return NULL; } diff --git a/src/bin/lttng-sessiond/notification-thread.h b/src/bin/lttng-sessiond/notification-thread.h index 525adcc6a..48b6bce3a 100644 --- a/src/bin/lttng-sessiond/notification-thread.h +++ b/src/bin/lttng-sessiond/notification-thread.h @@ -27,6 +27,7 @@ #include #include #include +#include "thread.h" struct notification_thread_handle { /* @@ -216,6 +217,7 @@ struct notification_thread_handle *notification_thread_handle_create( struct lttng_pipe *kernel_channel_monitor_pipe); void notification_thread_handle_destroy( struct notification_thread_handle *handle); -bool launch_notification_thread(struct notification_thread_handle *handle); +struct lttng_thread *launch_notification_thread( + struct notification_thread_handle *handle); #endif /* NOTIFICATION_THREAD_H */