diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index b3e717adbc9b480ad9bf69e2142ce44b545f3bc7..c201555b9c6c5575aede84c56929bd0c99e837a1 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -253,7 +253,6 @@ static int linear_stop (struct mddev *mddev)
 {
 	struct linear_conf *conf = mddev->private;
 
-	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
 	kfree(conf);
 	mddev->private = NULL;
 
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9f0ff718713622f13ed3af9a94ddd5c7d9bf747d..58f140bef99933b0da4a131edae3377b5da72018 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -72,6 +72,7 @@ static struct workqueue_struct *md_misc_wq;
 
 static int remove_and_add_spares(struct mddev *mddev,
 				 struct md_rdev *this);
+static void mddev_detach(struct mddev *mddev);
 
 /*
  * Default number of read corrections we'll attempt on an rdev
@@ -3372,6 +3373,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
 
 	/* Looks like we have a winner */
 	mddev_suspend(mddev);
+	mddev_detach(mddev);
 	mddev->pers->stop(mddev);
 
 	if (mddev->pers->sync_request == NULL &&
@@ -4928,18 +4930,17 @@ int md_run(struct mddev *mddev)
 		       (unsigned long long)mddev->array_sectors / 2,
 		       (unsigned long long)mddev->pers->size(mddev, 0, 0) / 2);
 		err = -EINVAL;
-		mddev->pers->stop(mddev);
 	}
 	if (err == 0 && mddev->pers->sync_request &&
 	    (mddev->bitmap_info.file || mddev->bitmap_info.offset)) {
 		err = bitmap_create(mddev);
-		if (err) {
+		if (err)
 			printk(KERN_ERR "%s: failed to create bitmap (%d)\n",
 			       mdname(mddev), err);
-			mddev->pers->stop(mddev);
-		}
 	}
 	if (err) {
+		mddev_detach(mddev);
+		mddev->pers->stop(mddev);
 		module_put(mddev->pers->owner);
 		mddev->pers = NULL;
 		bitmap_destroy(mddev);
@@ -5112,9 +5113,30 @@ void md_stop_writes(struct mddev *mddev)
 }
 EXPORT_SYMBOL_GPL(md_stop_writes);
 
+static void mddev_detach(struct mddev *mddev)
+{
+	struct bitmap *bitmap = mddev->bitmap;
+	/* wait for behind writes to complete */
+	if (bitmap && atomic_read(&bitmap->behind_writes) > 0) {
+		printk(KERN_INFO "md:%s: behind writes in progress - waiting to stop.\n",
+		       mdname(mddev));
+		/* need to kick something here to make sure I/O goes? */
+		wait_event(bitmap->behind_wait,
+			   atomic_read(&bitmap->behind_writes) == 0);
+	}
+	if (mddev->pers->quiesce) {
+		mddev->pers->quiesce(mddev, 1);
+		mddev->pers->quiesce(mddev, 0);
+	}
+	md_unregister_thread(&mddev->thread);
+	if (mddev->queue)
+		blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
+}
+
 static void __md_stop(struct mddev *mddev)
 {
 	mddev->ready = 0;
+	mddev_detach(mddev);
 	mddev->pers->stop(mddev);
 	if (mddev->pers->sync_request && mddev->to_remove == NULL)
 		mddev->to_remove = &md_redundancy_group;
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index fedb1b31877db4c72373d2c2137fdf2051350744..9fe34453835b1b06056bbb731becf858b528e8dd 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -504,8 +504,6 @@ static int multipath_stop (struct mddev *mddev)
 {
 	struct mpconf *conf = mddev->private;
 
-	md_unregister_thread(&mddev->thread);
-	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
 	mempool_destroy(conf->pool);
 	kfree(conf->multipaths);
 	kfree(conf);
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 3770c9675b1748b2b2db5a434144fcea1a096952..01dfca94b66343edaffe3ecb96a562d9fa4e742b 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -477,7 +477,6 @@ static int raid0_stop(struct mddev *mddev)
 {
 	struct r0conf *conf = mddev->private;
 
-	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
 	kfree(conf->strip_zone);
 	kfree(conf->devlist);
 	kfree(conf);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 45c512a4b75d8e56b73cd4a24d25af6053e3459e..fccea0b39808592c99f524af0b37b0ce66e4bd6d 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2954,29 +2954,17 @@ static int run(struct mddev *mddev)
 	}
 
 	ret =  md_integrity_register(mddev);
-	if (ret)
+	if (ret) {
+		md_unregister_thread(&mddev->thread);
 		stop(mddev);
+	}
 	return ret;
 }
 
 static int stop(struct mddev *mddev)
 {
 	struct r1conf *conf = mddev->private;
-	struct bitmap *bitmap = mddev->bitmap;
-
-	/* wait for behind writes to complete */
-	if (bitmap && atomic_read(&bitmap->behind_writes) > 0) {
-		printk(KERN_INFO "md/raid1:%s: behind writes in progress - waiting to stop.\n",
-		       mdname(mddev));
-		/* need to kick something here to make sure I/O goes? */
-		wait_event(bitmap->behind_wait,
-			   atomic_read(&bitmap->behind_writes) == 0);
-	}
-
-	freeze_array(conf, 0);
-	unfreeze_array(conf);
 
-	md_unregister_thread(&mddev->thread);
 	if (conf->r1bio_pool)
 		mempool_destroy(conf->r1bio_pool);
 	kfree(conf->mirrors);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 407c81a820f4b38865f24e3097f991d55ca0647f..654fdae906aa20c3b12431d2fe741724839c7299 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3802,14 +3802,6 @@ static int stop(struct mddev *mddev)
 {
 	struct r10conf *conf = mddev->private;
 
-	raise_barrier(conf, 0);
-	lower_barrier(conf);
-
-	md_unregister_thread(&mddev->thread);
-	if (mddev->queue)
-		/* the unplug fn references 'conf'*/
-		blk_sync_queue(mddev->queue);
-
 	if (conf->r10bio_pool)
 		mempool_destroy(conf->r10bio_pool);
 	safe_put_page(conf->tmppage);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 2d4a2cc85eb2e62a891d2f35d90e0c9e3c7cf468..48252607764777c128f06552ea97f7270af3bce7 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -6317,7 +6317,6 @@ static int stop(struct mddev *mddev)
 {
 	struct r5conf *conf = mddev->private;
 
-	md_unregister_thread(&mddev->thread);
 	free_conf(conf);
 	mddev->private = NULL;
 	mddev->to_remove = &raid5_attrs_group;