This also changes the stack size selection policy to select
the largest of:
1) default pthread stack size (dictated by libc)
2) system soft limit
3) 2 MB
This is bounded by the system's hard limit on stack size.
If this limit is smaller than 2 MB, the default size mentionned
in pthread_create(3) for Linux, we warn the user that the daemons
may be unreliable and advise bumping this limit.
Note that is is most likely possible to operate the daemons with
way less than 2MB of stack space. However, this was not
extensively tested.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
#include "align.h"
#include "error.h"
#include "align.h"
#include "error.h"
-static bool pthread_attr_init_done;
+static int pthread_attr_init_done;
static pthread_attr_t tattr;
static pthread_attr_t tattr;
-static pthread_mutex_t tattr_lock = PTHREAD_MUTEX_INITIALIZER;
LTTNG_HIDDEN
size_t default_get_channel_subbuf_size(void)
LTTNG_HIDDEN
size_t default_get_channel_subbuf_size(void)
LTTNG_HIDDEN
pthread_attr_t *default_pthread_attr(void)
{
LTTNG_HIDDEN
pthread_attr_t *default_pthread_attr(void)
{
- int ret = 0;
- size_t ptstacksize;
- struct rlimit rlim;
+ if (pthread_attr_init_done) {
+ return &tattr;
+ }
- pthread_mutex_lock(&tattr_lock);
+ WARN("Uninitializez pthread attributes, using libc defaults.");
+ return NULL;
+}
- /* Return cached value. */
- if (pthread_attr_init_done) {
- goto end;
+static void __attribute__((constructor)) init_default_pthread_attr(void)
+{
+ int ret;
+ struct rlimit rlim;
+ size_t pthread_ss, system_ss, selected_ss;
+
+ ret = pthread_attr_init(&tattr);
+ if (ret) {
+ errno = ret;
+ PERROR("pthread_attr_init");
+ goto error;
}
/* Get system stack size limits. */
ret = getrlimit(RLIMIT_STACK, &rlim);
if (ret < 0) {
PERROR("getrlimit");
}
/* Get system stack size limits. */
ret = getrlimit(RLIMIT_STACK, &rlim);
if (ret < 0) {
PERROR("getrlimit");
}
DBG("Stack size limits: soft %lld, hard %lld bytes",
(long long) rlim.rlim_cur,
(long long) rlim.rlim_max);
}
DBG("Stack size limits: soft %lld, hard %lld bytes",
(long long) rlim.rlim_cur,
(long long) rlim.rlim_max);
+ /*
+ * getrlimit() may return a stack size of "-1", meaning "unlimited".
+ * In this case, we impose a known-good default minimum value which will
+ * override the libc's default stack size if it is smaller.
+ */
+ system_ss = rlim.rlim_cur != -1 ? rlim.rlim_cur :
+ DEFAULT_LTTNG_THREAD_STACK_SIZE;
+
/* Get pthread default thread stack size. */
/* Get pthread default thread stack size. */
- ret = pthread_attr_getstacksize(&tattr, &ptstacksize);
+ ret = pthread_attr_getstacksize(&tattr, &pthread_ss);
if (ret < 0) {
PERROR("pthread_attr_getstacksize");
if (ret < 0) {
PERROR("pthread_attr_getstacksize");
- 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;
- }
+ DBG("Default pthread stack size is %zu bytes", pthread_ss);
+
+ selected_ss = max_t(size_t, pthread_ss, system_ss);
+ if (selected_ss < DEFAULT_LTTNG_THREAD_STACK_SIZE) {
+ DBG("Default stack size is too small, setting it to %zu bytes",
+ (size_t) DEFAULT_LTTNG_THREAD_STACK_SIZE);
+ selected_ss = DEFAULT_LTTNG_THREAD_STACK_SIZE;
- /* Enable cached value. */
- pthread_attr_init_done = true;
-end:
- pthread_mutex_unlock(&tattr_lock);
- return &tattr;
+ if (rlim.rlim_max >= 0 && selected_ss > rlim.rlim_max) {
+ WARN("Your system's stack size restrictions (%zu bytes) may be too low for the LTTng daemons to function properly, please set the stack size limit to at leat %zu bytes to ensure reliable operation",
+ (size_t) rlim.rlim_max, (size_t) DEFAULT_LTTNG_THREAD_STACK_SIZE);
+ selected_ss = (size_t) rlim.rlim_max;
+ }
+
+ ret = pthread_attr_setstacksize(&tattr, selected_ss);
+ if (ret < 0) {
+ PERROR("pthread_attr_setstacksize");
+ goto error_destroy;
+ }
+ pthread_attr_init_done = 1;
- pthread_mutex_unlock(&tattr_lock);
- WARN("Failed to initialize pthread attributes, using libc defaults.");
- return NULL;
+ return;
+error_destroy:
+ ret = pthread_attr_destroy(&tattr);
+ if (ret) {
+ errno = ret;
+ PERROR("pthread_attr_destroy");
+ }
+}
+
+static void __attribute__((destructor)) fini_default_pthread_attr(void)
+{
+ int ret;
+
+ if (!pthread_attr_init_done) {
+ return;
+ }
+
+ ret = pthread_attr_destroy(&tattr);
+ if (ret) {
+ errno = ret;
+ PERROR("pthread_attr_destroy");
+ }
/* Default LTTng MI XML namespace. */
#define DEFAULT_LTTNG_MI_NAMESPACE "http://lttng.org/xml/ns/lttng-mi"
/* Default LTTng MI XML namespace. */
#define DEFAULT_LTTNG_MI_NAMESPACE "http://lttng.org/xml/ns/lttng-mi"
+/* Default thread stack size; the default mandated by pthread_create(3) */
+#define DEFAULT_LTTNG_THREAD_STACK_SIZE 2097152
+
/*
* Returns the default subbuf size.
*
/*
* Returns the default subbuf size.
*