diff options
author | Tim Chase <[email protected]> | 2014-03-26 08:29:24 -0500 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2014-04-08 12:44:42 -0700 |
commit | 17a527cb0f44cef6582583e502621541061d8817 (patch) | |
tree | 5619e8f29e0272ef6206ffa788061bdccc47d971 | |
parent | e19101e08f25708b03e5ff98a4da5756cfd709f7 (diff) |
Support post-3.13 kthread_create() semantics.
Provide spl_kthread_create() as a wrapper to the kernel's kthread_create()
to provide pre-3.13 semantics. Re-try if the call is interrupted or if it
would have returned -ENOMEM. Otherwise return NULL.
Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #339
-rw-r--r-- | include/sys/thread.h | 28 | ||||
-rw-r--r-- | module/spl/spl-debug.c | 3 | ||||
-rw-r--r-- | module/spl/spl-taskq.c | 2 | ||||
-rw-r--r-- | module/spl/spl-thread.c | 2 | ||||
-rw-r--r-- | module/splat/splat-condvar.c | 8 | ||||
-rw-r--r-- | module/splat/splat-rwlock.c | 4 |
6 files changed, 38 insertions, 9 deletions
diff --git a/include/sys/thread.h b/include/sys/thread.h index 864a74bba..f6c197255 100644 --- a/include/sys/thread.h +++ b/include/sys/thread.h @@ -60,4 +60,32 @@ extern kthread_t *__thread_create(caddr_t stk, size_t stksize, int state, pri_t pri); extern void __thread_exit(void); +/* + * spl_kthread_create - Wrapper providing pre-3.13 semantics for + * kthread_create() in which it is not killable and less likely + * to return -ENOMEM. + */ +static inline struct task_struct * +spl_kthread_create(int (*func)(void *), void *data, const char namefmt[], ...) +{ + struct task_struct *tsk; + va_list args; + + va_start(args, namefmt); + do { + tsk = kthread_create_on_node(func, data, + -1, namefmt, args); + if (IS_ERR(tsk)) { + if (signal_pending(current)) { + clear_thread_flag(TIF_SIGPENDING); + continue; + } + if (PTR_ERR(tsk) == -ENOMEM) + continue; + return (NULL); + } else + return (tsk); + } while (1); +} + #endif /* _SPL_THREAD_H */ diff --git a/module/spl/spl-debug.c b/module/spl/spl-debug.c index d450368b1..93c3f31b8 100644 --- a/module/spl/spl-debug.c +++ b/module/spl/spl-debug.c @@ -38,6 +38,7 @@ #include <linux/file_compat.h> #include <linux/swap.h> #include <sys/sysmacros.h> +#include <sys/thread.h> #include <spl-debug.h> #include <spl-trace.h> #include <spl-ctl.h> @@ -415,7 +416,7 @@ spl_debug_dumplog(int flags) spl_debug_dumplog_internal(&dp); } else { - tsk = kthread_create(spl_debug_dumplog_thread,(void *)&dp,"spl_debug"); + tsk = spl_kthread_create(spl_debug_dumplog_thread,(void *)&dp,"spl_debug"); if (tsk == NULL) return -ENOMEM; diff --git a/module/spl/spl-taskq.c b/module/spl/spl-taskq.c index 3605a0f3b..48feb1d22 100644 --- a/module/spl/spl-taskq.c +++ b/module/spl/spl-taskq.c @@ -839,7 +839,7 @@ taskq_create(const char *name, int nthreads, pri_t pri, tqt->tqt_tq = tq; tqt->tqt_id = 0; - tqt->tqt_thread = kthread_create(taskq_thread, tqt, + tqt->tqt_thread = spl_kthread_create(taskq_thread, tqt, "%s/%d", name, i); if (tqt->tqt_thread) { list_add(&tqt->tqt_thread_list, &tq->tq_thread_list); diff --git a/module/spl/spl-thread.c b/module/spl/spl-thread.c index 6b3bec509..b0fa4d795 100644 --- a/module/spl/spl-thread.c +++ b/module/spl/spl-thread.c @@ -126,7 +126,7 @@ __thread_create(caddr_t stk, size_t stksize, thread_func_t func, tp->tp_state = state; tp->tp_pri = pri; - tsk = kthread_create(thread_generic_wrapper, (void *)tp, + tsk = spl_kthread_create(thread_generic_wrapper, (void *)tp, "%s", tp->tp_name); if (IS_ERR(tsk)) { SERROR("Failed to create thread: %ld\n", PTR_ERR(tsk)); diff --git a/module/splat/splat-condvar.c b/module/splat/splat-condvar.c index 1ddde39bb..3ee2ffc9e 100644 --- a/module/splat/splat-condvar.c +++ b/module/splat/splat-condvar.c @@ -108,7 +108,7 @@ splat_condvar_test1(struct file *file, void *arg) ct[i].ct_cvp = &cv; ct[i].ct_name = SPLAT_CONDVAR_TEST1_NAME; ct[i].ct_rc = 0; - ct[i].ct_thread = kthread_create(splat_condvar_test12_thread, + ct[i].ct_thread = spl_kthread_create(splat_condvar_test12_thread, &ct[i], "%s/%d", SPLAT_CONDVAR_TEST_NAME, i); if (!IS_ERR(ct[i].ct_thread)) { @@ -173,7 +173,7 @@ splat_condvar_test2(struct file *file, void *arg) ct[i].ct_cvp = &cv; ct[i].ct_name = SPLAT_CONDVAR_TEST2_NAME; ct[i].ct_rc = 0; - ct[i].ct_thread = kthread_create(splat_condvar_test12_thread, + ct[i].ct_thread = spl_kthread_create(splat_condvar_test12_thread, &ct[i], "%s/%d", SPLAT_CONDVAR_TEST_NAME, i); if (!IS_ERR(ct[i].ct_thread)) { @@ -254,7 +254,7 @@ splat_condvar_test3(struct file *file, void *arg) ct[i].ct_cvp = &cv; ct[i].ct_name = SPLAT_CONDVAR_TEST3_NAME; ct[i].ct_rc = 0; - ct[i].ct_thread = kthread_create(splat_condvar_test34_thread, + ct[i].ct_thread = spl_kthread_create(splat_condvar_test34_thread, &ct[i], "%s/%d", SPLAT_CONDVAR_TEST_NAME, i); if (!IS_ERR(ct[i].ct_thread)) { @@ -324,7 +324,7 @@ splat_condvar_test4(struct file *file, void *arg) ct[i].ct_cvp = &cv; ct[i].ct_name = SPLAT_CONDVAR_TEST3_NAME; ct[i].ct_rc = 0; - ct[i].ct_thread = kthread_create(splat_condvar_test34_thread, + ct[i].ct_thread = spl_kthread_create(splat_condvar_test34_thread, &ct[i], "%s/%d", SPLAT_CONDVAR_TEST_NAME, i); if (!IS_ERR(ct[i].ct_thread)) { diff --git a/module/splat/splat-rwlock.c b/module/splat/splat-rwlock.c index a865fb310..6faf7d24e 100644 --- a/module/splat/splat-rwlock.c +++ b/module/splat/splat-rwlock.c @@ -215,10 +215,10 @@ splat_rwlock_test1(struct file *file, void *arg) /* The first thread will be the writer */ if (i == 0) - rwt[i].rwt_thread = kthread_create(splat_rwlock_wr_thr, + rwt[i].rwt_thread = spl_kthread_create(splat_rwlock_wr_thr, &rwt[i], "%s/%d", SPLAT_RWLOCK_TEST_NAME, i); else - rwt[i].rwt_thread = kthread_create(splat_rwlock_rd_thr, + rwt[i].rwt_thread = spl_kthread_create(splat_rwlock_rd_thr, &rwt[i], "%s/%d", SPLAT_RWLOCK_TEST_NAME, i); if (!IS_ERR(rwt[i].rwt_thread)) { |