static kmem_cache_t *_mpio_cache;
 
+struct workqueue_struct *kmultipathd;
 static void process_queued_ios(void *data);
 static void trigger_event(void *data);
 
                bio_list_add(&m->queued_ios, bio);
                m->queue_size++;
                if (m->pg_init_required || !m->queue_io)
-                       schedule_work(&m->process_queued_ios);
+                       queue_work(kmultipathd, &m->process_queued_ios);
                pgpath = NULL;
                r = 0;
        } else if (!pgpath)
 
        m->queue_if_no_path = queue_if_no_path;
        if (!m->queue_if_no_path)
-               schedule_work(&m->process_queued_ios);
+               queue_work(kmultipathd, &m->process_queued_ios);
 
        spin_unlock_irqrestore(&m->lock, flags);
 
        if (pgpath == m->current_pgpath)
                m->current_pgpath = NULL;
 
-       schedule_work(&m->trigger_event);
+       queue_work(kmultipathd, &m->trigger_event);
 
 out:
        spin_unlock_irqrestore(&m->lock, flags);
 
        m->current_pgpath = NULL;
        if (!m->nr_valid_paths++)
-               schedule_work(&m->process_queued_ios);
+               queue_work(kmultipathd, &m->process_queued_ios);
 
-       schedule_work(&m->trigger_event);
+       queue_work(kmultipathd, &m->trigger_event);
 
 out:
        spin_unlock_irqrestore(&m->lock, flags);
 
        spin_unlock_irqrestore(&m->lock, flags);
 
-       schedule_work(&m->trigger_event);
+       queue_work(kmultipathd, &m->trigger_event);
 }
 
 /*
        }
        spin_unlock_irqrestore(&m->lock, flags);
 
-       schedule_work(&m->trigger_event);
+       queue_work(kmultipathd, &m->trigger_event);
        return 0;
 }
 
                m->current_pgpath = NULL;
                m->current_pg = NULL;
        }
-       schedule_work(&m->process_queued_ios);
+       queue_work(kmultipathd, &m->process_queued_ios);
        spin_unlock_irqrestore(&m->lock, flags);
 }
 
        bio_list_add(&m->queued_ios, bio);
        m->queue_size++;
        if (!m->queue_io)
-               schedule_work(&m->process_queued_ios);
+               queue_work(kmultipathd, &m->process_queued_ios);
        spin_unlock(&m->lock);
 
        return 1;       /* io not complete */
        spin_lock_irqsave(&m->lock, flags);
        m->suspended = 1;
        if (m->queue_if_no_path)
-               schedule_work(&m->process_queued_ios);
+               queue_work(kmultipathd, &m->process_queued_ios);
        spin_unlock_irqrestore(&m->lock, flags);
 }
 
                return -EINVAL;
        }
 
+       kmultipathd = create_workqueue("kmpathd");
+       if (!kmultipathd) {
+               DMERR("%s: failed to create workqueue kmpathd",
+                               multipath_target.name);
+               dm_unregister_target(&multipath_target);
+               kmem_cache_destroy(_mpio_cache);
+               return -ENOMEM;
+       }
+
        DMINFO("dm-multipath version %u.%u.%u loaded",
               multipath_target.version[0], multipath_target.version[1],
               multipath_target.version[2]);
 {
        int r;
 
+       destroy_workqueue(kmultipathd);
+
        r = dm_unregister_target(&multipath_target);
        if (r < 0)
                DMERR("%s: target unregister failed %d",