summaryrefslogtreecommitdiff
path: root/multipathd
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2009-03-13 15:55:14 -0500
committerChristophe Varoqui <christophe.varoqui@free.fr>2009-04-03 23:55:33 +0200
commit058013c2527bed13f7b3dadc752260dbd9efc62f (patch)
tree05cca12a0bc18069dcfc714dcec5a62e7b6b208a /multipathd
parent2275a916feb7430c93c9686479775353100fc876 (diff)
downloadmultipath-tools-058013c2527bed13f7b3dadc752260dbd9efc62f.tar.gz
multipath-tools-058013c2527bed13f7b3dadc752260dbd9efc62f.tar.bz2
multipath-tools-058013c2527bed13f7b3dadc752260dbd9efc62f.zip
set pthread stack size to at least PTHREAD_STACK_MIN
Setting the stacksize too small just causes pthread_attr_setstacksize() to fail, leaving you with the default stack size. On some architectures, the default stacksize is large, like 10Mb. Since you start one waiter thread per multipath device, every 100 devices eats up 1Gb of memory. The other problem is that when I actually read the pthread_attr_init man page (it can fail. who knew?), I saw that it can fail with ENOMEM. Also, that it had a function to free it, and that the result of reinitializing an attr that hadn't been freed was undefined. Clearly, this function wasn't intended to be called over and over without ever freeing the attr, which is how we've been using it in multipathd. So, in the spirit of writing code to the interface, instead of to how it appears to be currently implemented, how about this.
Diffstat (limited to 'multipathd')
-rw-r--r--multipathd/main.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/multipathd/main.c b/multipathd/main.c
index a5b61e6..f5e3e38 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -14,6 +14,7 @@
#include <errno.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <limits.h>
/*
* libcheckers
@@ -1275,17 +1276,47 @@ set_oom_adj (int val)
fclose(fp);
}
+void
+setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached)
+{
+ if (pthread_attr_init(attr)) {
+ fprintf(stderr, "can't initialize thread attr: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+ if (stacksize < PTHREAD_STACK_MIN)
+ stacksize = PTHREAD_STACK_MIN;
+
+ if (pthread_attr_setstacksize(attr, stacksize)) {
+ fprintf(stderr, "can't set thread stack size to %lu: %s\n",
+ (unsigned long)stacksize, strerror(errno));
+ exit(1);
+ }
+ if (detached && pthread_attr_setdetachstate(attr,
+ PTHREAD_CREATE_DETACHED)) {
+ fprintf(stderr, "can't set thread to detached: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+}
+
static int
child (void * param)
{
pthread_t check_thr, uevent_thr, uxlsnr_thr;
- pthread_attr_t attr;
+ pthread_attr_t log_attr, misc_attr;
struct vectors * vecs;
mlockall(MCL_CURRENT | MCL_FUTURE);
- if (logsink)
- log_thread_start();
+ setup_thread_attr(&misc_attr, 64 * 1024, 1);
+ setup_thread_attr(&waiter_attr, 32 * 1024, 1);
+
+ if (logsink) {
+ setup_thread_attr(&log_attr, 64 * 1024, 0);
+ log_thread_start(&log_attr);
+ pthread_attr_destroy(&log_attr);
+ }
condlog(2, "--------start up--------");
condlog(2, "read " DEFAULT_CONFIGFILE);
@@ -1356,13 +1387,10 @@ child (void * param)
/*
* start threads
*/
- pthread_attr_init(&attr);
- pthread_attr_setstacksize(&attr, 64 * 1024);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- pthread_create(&check_thr, &attr, checkerloop, vecs);
- pthread_create(&uevent_thr, &attr, ueventloop, vecs);
- pthread_create(&uxlsnr_thr, &attr, uxlsnrloop, vecs);
+ pthread_create(&check_thr, &misc_attr, checkerloop, vecs);
+ pthread_create(&uevent_thr, &misc_attr, ueventloop, vecs);
+ pthread_create(&uxlsnr_thr, &misc_attr, uxlsnrloop, vecs);
+ pthread_attr_destroy(&misc_attr);
pthread_cond_wait(&exit_cond, &exit_mutex);