]> granicus.if.org Git - zfs/commitdiff
Create threads in detached state in userspace.
authorEtienne Dechamps <etienne.dechamps@ovh.net>
Thu, 27 Sep 2012 11:31:46 +0000 (13:31 +0200)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 3 Oct 2012 20:32:48 +0000 (13:32 -0700)
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 <behlendorf1@llnl.gov>
Issue #989

cmd/ztest/ztest.c
include/sys/zfs_context.h
lib/libzpool/kernel.c

index 15f170d43fdab564d5dbd81a6a358f7fb5b4bf23..ff14c672232ceb6a5a1b8dfbb18cd808db9415dc 100644 (file)
@@ -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;
        }
 
index de8b943be5be5e93ae364501e5158dee007dc699..d8347a335fd016bb722ffad7d117370a293c3e7e 100644 (file)
@@ -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)
index 704f3d659570aec619b89177b084feca4430841f..c38efd0aad661b71bdbbd70b63d456cb1b954f69 100644 (file)
@@ -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);