Fix: hash table cleanup call_rcu deadlock
[lttng-tools.git] / src / bin / lttng-sessiond / main.c
index 6f9834425192c3ca4b1f9f0e184071eb87f68b87..4a2bc4fdd3ebd363c6a4fb35bd4a2de3039e8cb8 100644 (file)
@@ -161,6 +161,7 @@ static pthread_t client_thread;
 static pthread_t kernel_thread;
 static pthread_t dispatch_thread;
 static pthread_t health_thread;
+static pthread_t ht_cleanup_thread;
 
 /*
  * UST registration command queue. This queue is tied with a futex and uses a N
@@ -705,9 +706,9 @@ static void *thread_manage_kernel(void *data)
 
        /*
         * This first step of the while is to clean this structure which could free
-        * non NULL pointers so zero it before the loop.
+        * non NULL pointers so initialize it before the loop.
         */
-       memset(&events, 0, sizeof(events));
+       lttng_poll_init(&events);
 
        if (testpoint(thread_manage_kernel)) {
                goto error_testpoint;
@@ -3108,9 +3109,8 @@ static void *thread_manage_health(void *data)
 
        rcu_register_thread();
 
-       /* We might hit an error path before this is set once. */
-       memset(&events, 0, sizeof(events));
-       events.epfd = -1;
+       /* We might hit an error path before this is created. */
+       lttng_poll_init(&events);
 
        /* Create unix socket */
        sock = lttcomm_create_unix_sock(health_unix_sock_path);
@@ -3226,13 +3226,17 @@ restart:
                case LTTNG_HEALTH_CONSUMER:
                        reply.ret_code = check_consumer_health();
                        break;
+               case LTTNG_HEALTH_HT_CLEANUP:
+                       reply.ret_code = health_check_state(HEALTH_TYPE_HT_CLEANUP);
+                       break;
                case LTTNG_HEALTH_ALL:
                        reply.ret_code =
                                health_check_state(HEALTH_TYPE_APP_MANAGE) &&
                                health_check_state(HEALTH_TYPE_APP_REG) &&
                                health_check_state(HEALTH_TYPE_CMD) &&
                                health_check_state(HEALTH_TYPE_KERNEL) &&
-                               check_consumer_health();
+                               check_consumer_health() &&
+                               health_check_state(HEALTH_TYPE_HT_CLEANUP);
                        break;
                default:
                        reply.ret_code = LTTNG_ERR_UND;
@@ -3277,12 +3281,6 @@ error:
                        PERROR("close");
                }
        }
-       if (new_sock >= 0) {
-               ret = close(new_sock);
-               if (ret) {
-                       PERROR("close");
-               }
-       }
 
        lttng_poll_clean(&events);
 
@@ -4300,6 +4298,11 @@ int main(int argc, char **argv)
                }
        }
 
+       /* Setup the thread ht_cleanup communication pipe. */
+       if (utils_create_pipe_cloexec(ht_cleanup_pipe) < 0) {
+               goto exit;
+       }
+
        /* Setup the thread apps communication pipe. */
        if ((ret = utils_create_pipe_cloexec(apps_cmd_pipe)) < 0) {
                goto exit;
@@ -4338,6 +4341,14 @@ int main(int argc, char **argv)
 
        write_pidfile();
 
+       /* Create thread to manage the client socket */
+       ret = pthread_create(&ht_cleanup_thread, NULL,
+                       thread_ht_cleanup, (void *) NULL);
+       if (ret != 0) {
+               PERROR("pthread_create ht_cleanup");
+               goto exit_ht_cleanup;
+       }
+
        /* Create thread to manage the client socket */
        ret = pthread_create(&health_thread, NULL,
                        thread_manage_health, (void *) NULL);
@@ -4457,6 +4468,12 @@ exit_client:
        }
 
 exit_health:
+       ret = pthread_join(ht_cleanup_thread, &status);
+       if (ret != 0) {
+               PERROR("pthread_join ht cleanup thread");
+               goto error;     /* join error, exit without cleanup */
+       }
+exit_ht_cleanup:
 exit:
        /*
         * cleanup() is called when no other thread is running.
This page took 0.026385 seconds and 5 git commands to generate.