From cd5ca4b2f86a606aa6ed68341a3672fdde1c9856 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 23 Aug 2012 15:36:28 -0700 Subject: [PATCH] Switch KM_SLEEP to KM_PUSHPAGE Under certain circumstances the following functions may be called in a context where KM_SLEEP is unsafe and can result in a deadlocked system. To avoid this problem the unconditional KM_SLEEPs are converted to KM_PUSHPAGEs. This will prevent them from attempting to initiate any I/O during direct reclaim. Signed-off-by: Brian Behlendorf --- include/sys/taskq.h | 1 + module/spl/spl-taskq.c | 8 +++----- module/spl/spl-thread.c | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/sys/taskq.h b/include/sys/taskq.h index a5d9492..a73f770 100644 --- a/include/sys/taskq.h +++ b/include/sys/taskq.h @@ -62,6 +62,7 @@ typedef struct taskq_ent { */ #define TQ_SLEEP KM_SLEEP #define TQ_NOSLEEP KM_NOSLEEP +#define TQ_PUSHPAGE KM_PUSHPAGE #define TQ_NOQUEUE 0x01000000 #define TQ_NOALLOC 0x02000000 #define TQ_NEW 0x04000000 diff --git a/module/spl/spl-taskq.c b/module/spl/spl-taskq.c index e4092b8..b58eb8e 100644 --- a/module/spl/spl-taskq.c +++ b/module/spl/spl-taskq.c @@ -50,8 +50,6 @@ task_alloc(taskq_t *tq, uint_t flags) SENTRY; ASSERT(tq); - ASSERT(flags & (TQ_SLEEP | TQ_NOSLEEP)); /* One set */ - ASSERT(!((flags & TQ_SLEEP) && (flags & TQ_NOSLEEP))); /* Not both */ ASSERT(spin_is_locked(&tq->tq_lock)); retry: /* Acquire taskq_ent_t's from free list if available */ @@ -554,7 +552,7 @@ __taskq_create(const char *name, int nthreads, pri_t pri, nthreads = MAX((num_online_cpus() * nthreads) / 100, 1); } - tq = kmem_alloc(sizeof(*tq), KM_SLEEP); + tq = kmem_alloc(sizeof(*tq), KM_PUSHPAGE); if (tq == NULL) SRETURN(NULL); @@ -580,12 +578,12 @@ __taskq_create(const char *name, int nthreads, pri_t pri, if (flags & TASKQ_PREPOPULATE) for (i = 0; i < minalloc; i++) - task_done(tq, task_alloc(tq, TQ_SLEEP | TQ_NEW)); + task_done(tq, task_alloc(tq, TQ_PUSHPAGE | TQ_NEW)); spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); for (i = 0; i < nthreads; i++) { - tqt = kmem_alloc(sizeof(*tqt), KM_SLEEP); + tqt = kmem_alloc(sizeof(*tqt), KM_PUSHPAGE); INIT_LIST_HEAD(&tqt->tqt_thread_list); INIT_LIST_HEAD(&tqt->tqt_active_list); tqt->tqt_tq = tq; diff --git a/module/spl/spl-thread.c b/module/spl/spl-thread.c index 9f6e223..71e5f33 100644 --- a/module/spl/spl-thread.c +++ b/module/spl/spl-thread.c @@ -98,14 +98,14 @@ __thread_create(caddr_t stk, size_t stksize, thread_func_t func, /* Variable stack size unsupported */ ASSERT(stk == NULL); - tp = kmem_alloc(sizeof(thread_priv_t), KM_SLEEP); + tp = kmem_alloc(sizeof(thread_priv_t), KM_PUSHPAGE); if (tp == NULL) SRETURN(NULL); tp->tp_magic = TP_MAGIC; tp->tp_name_size = strlen(name) + 1; - tp->tp_name = kmem_alloc(tp->tp_name_size, KM_SLEEP); + tp->tp_name = kmem_alloc(tp->tp_name_size, KM_PUSHPAGE); if (tp->tp_name == NULL) { kmem_free(tp, sizeof(thread_priv_t)); SRETURN(NULL); -- 2.40.0