Skip to content

Commit

Permalink
Create threads in detached state in userspace.
Browse files Browse the repository at this point in the history
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.

See issue openzfs#989.
  • Loading branch information
dechamps committed Sep 27, 2012
1 parent 37abac6 commit 7a280f6
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 7 deletions.
11 changes: 7 additions & 4 deletions cmd/ztest/ztest.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions include/sys/zfs_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,15 +220,15 @@ 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)

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)
Expand Down
3 changes: 2 additions & 1 deletion lib/libzpool/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 7a280f6

Please sign in to comment.