summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEtienne Dechamps <[email protected]>2012-09-27 13:31:46 +0200
committerBrian Behlendorf <[email protected]>2012-10-03 13:32:48 -0700
commit0aebd4f9e3223e8f1e09de7b29bba4f375db840c (patch)
tree87de1c6b6e8ba60d124a5bafe8880aa69cbff254
parent6d1d976b2c2c6b80de75a480c998466068066846 (diff)
Create threads in detached state in userspace.
Currently, thread_create(), when called in userspace, creates a joinable (i.e. not detached thread). This is the pthread default. Unfortunately, this does not reproduce kthreads behavior (kthreads are always detached). In addition, this contradicts the original Solaris code which creates userspace threads in detached mode. These joinable threads are never joined, which leads to a leakage of pthread thread objects ("zombie threads"). This in turn results in excessive ressource consumption, and possible ressource exhaustion in extreme cases (e.g. long ztest runs). This patch fixes the issue by creating userspace threads in detached mode. The only exception is ztest worker threads which are meant to be joinable. Signed-off-by: Brian Behlendorf <[email protected]> Issue #989
-rw-r--r--cmd/ztest/ztest.c11
-rw-r--r--include/sys/zfs_context.h4
-rw-r--r--lib/libzpool/kernel.c3
3 files changed, 11 insertions, 7 deletions
diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c
index 15f170d43..ff14c6722 100644
--- a/cmd/ztest/ztest.c
+++ b/cmd/ztest/ztest.c
@@ -5390,8 +5390,9 @@ ztest_run(ztest_shared_t *zs)
/*
* Create a thread to periodically resume suspended I/O.
*/
- VERIFY3P((resume_thread = thread_create(NULL, 0, ztest_resume_thread,
- spa, TS_RUN, NULL, 0, 0)), !=, NULL);
+ VERIFY3P((resume_thread = zk_thread_create(NULL, 0,
+ (thread_func_t)ztest_resume_thread, spa, TS_RUN, NULL, 0, 0,
+ PTHREAD_CREATE_JOINABLE)), !=, NULL);
/*
* Set a deadman alarm to abort() if we hang.
@@ -5437,8 +5438,10 @@ ztest_run(ztest_shared_t *zs)
if (t < zopt_datasets && ztest_dataset_open(zs, t) != 0)
return;
- VERIFY3P(thread = thread_create(NULL, 0, ztest_thread,
- (void *)(uintptr_t)t, TS_RUN, NULL, 0, 0), !=, NULL);
+ VERIFY3P(thread = zk_thread_create(NULL, 0,
+ (thread_func_t)ztest_thread,
+ (void *)(uintptr_t)t, TS_RUN, NULL, 0, 0,
+ PTHREAD_CREATE_JOINABLE), !=, NULL);
tid[t] = thread->t_tid;
}
diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h
index de8b943be..d8347a335 100644
--- a/include/sys/zfs_context.h
+++ b/include/sys/zfs_context.h
@@ -220,7 +220,7 @@ typedef struct kthread {
#define thread_exit zk_thread_exit
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
zk_thread_create(stk, stksize, (thread_func_t)func, arg, \
- len, NULL, state, pri)
+ len, NULL, state, pri, PTHREAD_CREATE_DETACHED)
#define thread_join(t) zk_thread_join(t)
#define newproc(f,a,cid,pri,ctp,pid) (ENOSYS)
@@ -228,7 +228,7 @@ extern kthread_t *zk_thread_current(void);
extern void zk_thread_exit(void);
extern kthread_t *zk_thread_create(caddr_t stk, size_t stksize,
thread_func_t func, void *arg, size_t len,
- proc_t *pp, int state, pri_t pri);
+ proc_t *pp, int state, pri_t pri, int detachstate);
extern void zk_thread_join(kt_did_t tid);
#define kpreempt_disable() ((void)0)
diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c
index 704f3d659..c38efd0aa 100644
--- a/lib/libzpool/kernel.c
+++ b/lib/libzpool/kernel.c
@@ -141,7 +141,7 @@ zk_thread_helper(void *arg)
kthread_t *
zk_thread_create(caddr_t stk, size_t stksize, thread_func_t func, void *arg,
- size_t len, proc_t *pp, int state, pri_t pri)
+ size_t len, proc_t *pp, int state, pri_t pri, int detachstate)
{
kthread_t *kt;
pthread_attr_t attr;
@@ -181,6 +181,7 @@ zk_thread_create(caddr_t stk, size_t stksize, thread_func_t func, void *arg,
VERIFY3S(pthread_attr_init(&attr), ==, 0);
VERIFY3S(pthread_attr_setstacksize(&attr, stack), ==, 0);
VERIFY3S(pthread_attr_setguardsize(&attr, PAGESIZE), ==, 0);
+ VERIFY3S(pthread_attr_setdetachstate(&attr, detachstate), ==, 0);
VERIFY3S(pthread_create(&kt->t_tid, &attr, &zk_thread_helper, kt),
==, 0);