]> git.proxmox.com Git - mirror_spl-debian.git/commitdiff
Switch KM_SLEEP to KM_PUSHPAGE
authorBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 23 Aug 2012 22:36:28 +0000 (15:36 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 27 Aug 2012 19:00:55 +0000 (12:00 -0700)
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 <behlendorf1@llnl.gov>
include/sys/taskq.h
module/spl/spl-taskq.c
module/spl/spl-thread.c

index a5d9492f25e05590d17dade2decfabe5823505f4..a73f7703f6fc89f4a3a2c1d32870701829d5f1ae 100644 (file)
@@ -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
index e4092b8422f4a5b7db307427d834282fd9e50bac..b58eb8e947cfc79274a13548443acde1f3148b40 100644 (file)
@@ -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;
index 9f6e2237909662a1ae45fe848fb93584d8a34cf8..71e5f331d5a9c896d9d354a8bb6ec756181d79d1 100644 (file)
@@ -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);