From: Michael Jeanson Date: Wed, 15 Jun 2016 21:18:07 +0000 (-0400) Subject: Fix: Set thread stack size to ulimit soft value X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=commitdiff_plain;h=1a1a34b40ab10a195633b1ed5e2e9b42fdae0a78 Fix: Set thread stack size to ulimit soft value 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 Signed-off-by: Jérémie Galarneau --- diff --git a/src/bin/lttng-consumerd/lttng-consumerd.c b/src/bin/lttng-consumerd/lttng-consumerd.c index 1cc1eb9ae..1636b9c0d 100644 --- a/src/bin/lttng-consumerd/lttng-consumerd.c +++ b/src/bin/lttng-consumerd/lttng-consumerd.c @@ -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; diff --git a/src/bin/lttng-relayd/live.c b/src/bin/lttng-relayd/live.c index e2096eccd..2c3a10574 100644 --- a/src/bin/lttng-relayd/live.c +++ b/src/bin/lttng-relayd/live.c @@ -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; diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 007f95131..e8f3087b1 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -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; diff --git a/src/bin/lttng-sessiond/ht-cleanup.c b/src/bin/lttng-sessiond/ht-cleanup.c index 08bd27286..beb4e89dc 100644 --- a/src/bin/lttng-sessiond/ht-cleanup.c +++ b/src/bin/lttng-sessiond/ht-cleanup.c @@ -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"); diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 578ab2ffa..f47f73e0f 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -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(®_apps_thread, NULL, + ret = pthread_create(®_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"); diff --git a/src/common/defaults.c b/src/common/defaults.c index bd6e18351..00a026541 100644 --- a/src/common/defaults.c +++ b/src/common/defaults.c @@ -18,10 +18,18 @@ #define _LGPL_SOURCE #include #include +#include +#include +#include #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; +} diff --git a/src/common/defaults.h b/src/common/defaults.h index f05030766..178a601df 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -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 */