Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

Handle kthread_create() failures properly in taskq_create(). #340

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
dweeezil committed Apr 8, 2014

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 4a0984bb5a2c56a834abb303d53210b3e67e5122
28 changes: 28 additions & 0 deletions include/sys/thread.h
Original file line number Diff line number Diff line change
@@ -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(func, data,
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 */
3 changes: 2 additions & 1 deletion module/spl/spl-debug.c
Original file line number Diff line number Diff line change
@@ -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;

2 changes: 1 addition & 1 deletion module/spl/spl-taskq.c
Original file line number Diff line number Diff line change
@@ -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);
2 changes: 1 addition & 1 deletion module/spl/spl-thread.c
Original file line number Diff line number Diff line change
@@ -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));
8 changes: 4 additions & 4 deletions module/splat/splat-condvar.c
Original file line number Diff line number Diff line change
@@ -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)) {
4 changes: 2 additions & 2 deletions module/splat/splat-rwlock.c
Original file line number Diff line number Diff line change
@@ -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)) {