Merge tag 'tegra-for-3.17-dt' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra...
[cascardo/linux.git] / drivers / md / dm.c
index 437d990..32b958d 100644 (file)
@@ -54,6 +54,8 @@ static void do_deferred_remove(struct work_struct *w);
 
 static DECLARE_WORK(deferred_remove_work, do_deferred_remove);
 
+static struct workqueue_struct *deferred_remove_workqueue;
+
 /*
  * For bio-based dm.
  * One of these is allocated per bio.
@@ -276,16 +278,24 @@ static int __init local_init(void)
        if (r)
                goto out_free_rq_tio_cache;
 
+       deferred_remove_workqueue = alloc_workqueue("kdmremove", WQ_UNBOUND, 1);
+       if (!deferred_remove_workqueue) {
+               r = -ENOMEM;
+               goto out_uevent_exit;
+       }
+
        _major = major;
        r = register_blkdev(_major, _name);
        if (r < 0)
-               goto out_uevent_exit;
+               goto out_free_workqueue;
 
        if (!_major)
                _major = r;
 
        return 0;
 
+out_free_workqueue:
+       destroy_workqueue(deferred_remove_workqueue);
 out_uevent_exit:
        dm_uevent_exit();
 out_free_rq_tio_cache:
@@ -299,6 +309,7 @@ out_free_io_cache:
 static void local_exit(void)
 {
        flush_scheduled_work();
+       destroy_workqueue(deferred_remove_workqueue);
 
        kmem_cache_destroy(_rq_tio_cache);
        kmem_cache_destroy(_io_cache);
@@ -407,7 +418,7 @@ static void dm_blk_close(struct gendisk *disk, fmode_t mode)
 
        if (atomic_dec_and_test(&md->open_count) &&
            (test_bit(DMF_DEFERRED_REMOVE, &md->flags)))
-               schedule_work(&deferred_remove_work);
+               queue_work(deferred_remove_workqueue, &deferred_remove_work);
 
        dm_put(md);