Fix: Set thread stack size to ulimit soft value
authorMichael Jeanson <mjeanson@efficios.com>
Wed, 15 Jun 2016 21:18:07 +0000 (17:18 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 29 Jun 2016 23:29:53 +0000 (19:29 -0400)
Some libc don't honor the limit set for the stack size and use their own
empirically chosen static value. Detect this behavior by checking if the
current stack size is smally than the soft limit and in that case set
the pthread stack size to soft limit value.

Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/bin/lttng-consumerd/lttng-consumerd.c
src/bin/lttng-relayd/live.c
src/bin/lttng-relayd/main.c
src/bin/lttng-sessiond/ht-cleanup.c
src/bin/lttng-sessiond/main.c
src/common/defaults.c
src/common/defaults.h

index 1cc1eb9ae567c5a957bbf4d0704a2805337050f8..1636b9c0d22777798ff220df010c4bc5ca6c9634 100644 (file)
@@ -492,7 +492,7 @@ int main(int argc, char **argv)
        }
 
        /* Create thread to manage the client socket */
-       ret = pthread_create(&health_thread, NULL,
+       ret = pthread_create(&health_thread, default_pthread_attr(),
                        thread_manage_health, (void *) NULL);
        if (ret) {
                errno = ret;
@@ -511,7 +511,7 @@ int main(int argc, char **argv)
        cmm_smp_mb();   /* Read ready before following operations */
 
        /* Create thread to manage channels */
-       ret = pthread_create(&channel_thread, NULL,
+       ret = pthread_create(&channel_thread, default_pthread_attr(),
                        consumer_thread_channel_poll,
                        (void *) ctx);
        if (ret) {
@@ -522,7 +522,7 @@ int main(int argc, char **argv)
        }
 
        /* Create thread to manage the polling/writing of trace metadata */
-       ret = pthread_create(&metadata_thread, NULL,
+       ret = pthread_create(&metadata_thread, default_pthread_attr(),
                        consumer_thread_metadata_poll,
                        (void *) ctx);
        if (ret) {
@@ -533,8 +533,8 @@ int main(int argc, char **argv)
        }
 
        /* Create thread to manage the polling/writing of trace data */
-       ret = pthread_create(&data_thread, NULL, consumer_thread_data_poll,
-                       (void *) ctx);
+       ret = pthread_create(&data_thread, default_pthread_attr(),
+                       consumer_thread_data_poll, (void *) ctx);
        if (ret) {
                errno = ret;
                PERROR("pthread_create");
@@ -543,7 +543,7 @@ int main(int argc, char **argv)
        }
 
        /* Create the thread to manage the receive of fd */
-       ret = pthread_create(&sessiond_thread, NULL,
+       ret = pthread_create(&sessiond_thread, default_pthread_attr(),
                        consumer_thread_sessiond_poll,
                        (void *) ctx);
        if (ret) {
@@ -557,7 +557,7 @@ int main(int argc, char **argv)
         * Create the thread to manage the UST metadata periodic timer and
         * live timer.
         */
-       ret = pthread_create(&metadata_timer_thread, NULL,
+       ret = pthread_create(&metadata_timer_thread, default_pthread_attr(),
                        consumer_timer_thread, (void *) ctx);
        if (ret) {
                errno = ret;
index e2096eccd3897b5a500ebaabbe8ea5ecfac1cd90..2c3a10574b5499c6a4a8585f3a22e5eac05562bc 100644 (file)
@@ -2186,7 +2186,7 @@ int relayd_live_create(struct lttng_uri *uri)
        }
 
        /* Setup the dispatcher thread */
-       ret = pthread_create(&live_dispatcher_thread, NULL,
+       ret = pthread_create(&live_dispatcher_thread, default_pthread_attr(),
                        thread_dispatcher, (void *) NULL);
        if (ret) {
                errno = ret;
@@ -2196,7 +2196,7 @@ int relayd_live_create(struct lttng_uri *uri)
        }
 
        /* Setup the worker thread */
-       ret = pthread_create(&live_worker_thread, NULL,
+       ret = pthread_create(&live_worker_thread, default_pthread_attr(),
                        thread_worker, NULL);
        if (ret) {
                errno = ret;
@@ -2206,7 +2206,7 @@ int relayd_live_create(struct lttng_uri *uri)
        }
 
        /* Setup the listener thread */
-       ret = pthread_create(&live_listener_thread, NULL,
+       ret = pthread_create(&live_listener_thread, default_pthread_attr(),
                        thread_listener, (void *) NULL);
        if (ret) {
                errno = ret;
index 007f9513158d20aed0d89941f34e6f598e0606b9..e8f3087b11bd95e966be7e4e5c9dcf9ad1eb5a1e 100644 (file)
@@ -2778,7 +2778,6 @@ int main(int argc, char **argv)
                }
        }
 
-
        /* Initialize thread health monitoring */
        health_relayd = health_app_create(NR_HEALTH_RELAYD_TYPES);
        if (!health_relayd) {
@@ -2834,7 +2833,7 @@ int main(int argc, char **argv)
        }
 
        /* Create thread to manage the client socket */
-       ret = pthread_create(&health_thread, NULL,
+       ret = pthread_create(&health_thread, default_pthread_attr(),
                        thread_manage_health, (void *) NULL);
        if (ret) {
                errno = ret;
@@ -2844,7 +2843,7 @@ int main(int argc, char **argv)
        }
 
        /* Setup the dispatcher thread */
-       ret = pthread_create(&dispatcher_thread, NULL,
+       ret = pthread_create(&dispatcher_thread, default_pthread_attr(),
                        relay_thread_dispatcher, (void *) NULL);
        if (ret) {
                errno = ret;
@@ -2854,7 +2853,7 @@ int main(int argc, char **argv)
        }
 
        /* Setup the worker thread */
-       ret = pthread_create(&worker_thread, NULL,
+       ret = pthread_create(&worker_thread, default_pthread_attr(),
                        relay_thread_worker, NULL);
        if (ret) {
                errno = ret;
@@ -2864,7 +2863,7 @@ int main(int argc, char **argv)
        }
 
        /* Setup the listener thread */
-       ret = pthread_create(&listener_thread, NULL,
+       ret = pthread_create(&listener_thread, default_pthread_attr(),
                        relay_thread_listener, (void *) NULL);
        if (ret) {
                errno = ret;
index 08bd27286763835b499088896d4884301a35f26f..beb4e89dc8e71eff082cef0350a87e5f98eb14b0 100644 (file)
@@ -239,7 +239,8 @@ int init_ht_cleanup_thread(pthread_t *thread)
                goto error_quit_pipe;
        }
 
-       ret = pthread_create(thread, NULL, thread_ht_cleanup, NULL);
+       ret = pthread_create(thread, default_pthread_attr(), thread_ht_cleanup,
+                       NULL);
        if (ret) {
                errno = ret;
                PERROR("pthread_create ht_cleanup");
index 578ab2ffad92329b584c5494e5b51135635e5c1f..f47f73e0f2d3128bc8d95898eebc80ad7b1a901e 100644 (file)
@@ -2366,8 +2366,8 @@ static int spawn_consumer_thread(struct consumer_data *consumer_data)
                goto error;
        }
 
-       ret = pthread_create(&consumer_data->thread, NULL, thread_manage_consumer,
-                       consumer_data);
+       ret = pthread_create(&consumer_data->thread, default_pthread_attr(),
+                       thread_manage_consumer, consumer_data);
        if (ret) {
                errno = ret;
                PERROR("pthread_create consumer");
@@ -5980,7 +5980,7 @@ int main(int argc, char **argv)
        load_info->path = opt_load_session_path;
 
        /* Create health-check thread */
-       ret = pthread_create(&health_thread, NULL,
+       ret = pthread_create(&health_thread, default_pthread_attr(),
                        thread_manage_health, (void *) NULL);
        if (ret) {
                errno = ret;
@@ -5990,7 +5990,7 @@ int main(int argc, char **argv)
        }
 
        /* Create thread to manage the client socket */
-       ret = pthread_create(&client_thread, NULL,
+       ret = pthread_create(&client_thread, default_pthread_attr(),
                        thread_manage_clients, (void *) NULL);
        if (ret) {
                errno = ret;
@@ -6000,7 +6000,7 @@ int main(int argc, char **argv)
        }
 
        /* Create thread to dispatch registration */
-       ret = pthread_create(&dispatch_thread, NULL,
+       ret = pthread_create(&dispatch_thread, default_pthread_attr(),
                        thread_dispatch_ust_registration, (void *) NULL);
        if (ret) {
                errno = ret;
@@ -6010,7 +6010,7 @@ int main(int argc, char **argv)
        }
 
        /* Create thread to manage application registration. */
-       ret = pthread_create(&reg_apps_thread, NULL,
+       ret = pthread_create(&reg_apps_thread, default_pthread_attr(),
                        thread_registration_apps, (void *) NULL);
        if (ret) {
                errno = ret;
@@ -6020,7 +6020,7 @@ int main(int argc, char **argv)
        }
 
        /* Create thread to manage application socket */
-       ret = pthread_create(&apps_thread, NULL,
+       ret = pthread_create(&apps_thread, default_pthread_attr(),
                        thread_manage_apps, (void *) NULL);
        if (ret) {
                errno = ret;
@@ -6030,7 +6030,7 @@ int main(int argc, char **argv)
        }
 
        /* Create thread to manage application notify socket */
-       ret = pthread_create(&apps_notify_thread, NULL,
+       ret = pthread_create(&apps_notify_thread, default_pthread_attr(),
                        ust_thread_manage_notify, (void *) NULL);
        if (ret) {
                errno = ret;
@@ -6040,7 +6040,7 @@ int main(int argc, char **argv)
        }
 
        /* Create agent registration thread. */
-       ret = pthread_create(&agent_reg_thread, NULL,
+       ret = pthread_create(&agent_reg_thread, default_pthread_attr(),
                        agent_thread_manage_registration, (void *) NULL);
        if (ret) {
                errno = ret;
@@ -6052,7 +6052,7 @@ int main(int argc, char **argv)
        /* Don't start this thread if kernel tracing is not requested nor root */
        if (is_root && !opt_no_kernel) {
                /* Create kernel thread to manage kernel event */
-               ret = pthread_create(&kernel_thread, NULL,
+               ret = pthread_create(&kernel_thread, default_pthread_attr(),
                                thread_manage_kernel, (void *) NULL);
                if (ret) {
                        errno = ret;
@@ -6063,8 +6063,8 @@ int main(int argc, char **argv)
        }
 
        /* Create session loading thread. */
-       ret = pthread_create(&load_session_thread, NULL, thread_load_session,
-                       load_info);
+       ret = pthread_create(&load_session_thread, default_pthread_attr(),
+                       thread_load_session, load_info);
        if (ret) {
                errno = ret;
                PERROR("pthread_create load_session_thread");
index bd6e18351bc0e05ee0821e08139729cecac439f3..00a0265414baaf693a0eb687e8ce05b9a8f23907 100644 (file)
 #define _LGPL_SOURCE
 #include <stddef.h>
 #include <unistd.h>
+#include <stdbool.h>
+#include <sys/resource.h>
+#include <pthread.h>
 
 #include "defaults.h"
 #include "macros.h"
 #include "align.h"
+#include "error.h"
+
+static bool pthread_attr_init_done;
+static pthread_attr_t tattr;
+static pthread_mutex_t tattr_lock = PTHREAD_MUTEX_INITIALIZER;
 
 LTTNG_HIDDEN
 size_t default_get_channel_subbuf_size(void)
@@ -52,3 +60,59 @@ size_t default_get_ust_uid_channel_subbuf_size(void)
 {
        return max(DEFAULT_UST_UID_CHANNEL_SUBBUF_SIZE, PAGE_SIZE);
 }
+
+LTTNG_HIDDEN
+pthread_attr_t *default_pthread_attr(void)
+{
+       int ret = 0;
+       size_t ptstacksize;
+       struct rlimit rlim;
+
+       pthread_mutex_lock(&tattr_lock);
+
+       /* Return cached value. */
+       if (pthread_attr_init_done) {
+               goto end;
+       }
+
+       /* Get system stack size limits. */
+       ret = getrlimit(RLIMIT_STACK, &rlim);
+       if (ret < 0) {
+               PERROR("getrlimit");
+               goto error;
+       }
+       DBG("Stack size limits: soft %lld, hard %lld bytes",
+                       (long long) rlim.rlim_cur,
+                       (long long) rlim.rlim_max);
+
+       /* Get pthread default thread stack size. */
+       ret = pthread_attr_getstacksize(&tattr, &ptstacksize);
+       if (ret < 0) {
+               PERROR("pthread_attr_getstacksize");
+               goto error;
+       }
+       DBG("Default pthread stack size is %zu bytes", ptstacksize);
+
+       /* Check if the default pthread stack size honors ulimits. */
+       if (ptstacksize < rlim.rlim_cur) {
+               DBG("Your libc doesn't honor stack size limits, setting thread stack size to soft limit (%lld bytes)",
+                               (long long) rlim.rlim_cur);
+
+               /* Create pthread_attr_t struct with ulimit stack size. */
+               ret = pthread_attr_setstacksize(&tattr, rlim.rlim_cur);
+               if (ret < 0) {
+                       PERROR("pthread_attr_setstacksize");
+                       goto error;
+               }
+       }
+
+       /* Enable cached value. */
+       pthread_attr_init_done = true;
+end:
+       pthread_mutex_unlock(&tattr_lock);
+       return &tattr;
+error:
+       pthread_mutex_unlock(&tattr_lock);
+       WARN("Failed to initialize pthread attributes, using libc defaults.");
+       return NULL;
+}
index f05030766a77be8dae7452e4fdaae94205378d79..178a601dfde3b38c619a421642564aefd078ac7a 100644 (file)
@@ -354,4 +354,16 @@ size_t default_get_ust_pid_channel_subbuf_size(void);
 LTTNG_HIDDEN
 size_t default_get_ust_uid_channel_subbuf_size(void);
 
+/*
+ * Get the default pthread_attr to use on thread creation.
+ *
+ * Some libc, such as musl, don't honor the limit set for the stack size and use
+ * their own empirically chosen static value. This function checks if the
+ * current stack size is smaller than the stack size limit and if so returns a
+ * pthread_attr_t pointer where the thread stack size is set to the soft stack
+ * size limit.
+ */
+LTTNG_HIDDEN
+pthread_attr_t *default_pthread_attr(void);
+
 #endif /* _DEFAULTS_H */
This page took 0.042206 seconds and 4 git commands to generate.