From 7184ef8bab0cb865c3cea9dd1a675771145df0af Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Mon, 3 Jul 2017 14:34:23 -0700 Subject: [PATCH] MD: fix sleep in atomic bioset_free() will take a mutex, so can't get called with spinlock hold. Fix: 5a85071c2cbc(md: use a separate bio_set for synchronous IO.) Cc: NeilBrown Signed-off-by: Shaohua Li --- drivers/md/md.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 092b48f8095e..66f6b928a80b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -475,6 +475,8 @@ static void mddev_delayed_delete(struct work_struct *ws); static void mddev_put(struct mddev *mddev) { + struct bio_set *bs = NULL, *sync_bs = NULL; + if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock)) return; if (!mddev->raid_disks && list_empty(&mddev->disks) && @@ -482,10 +484,8 @@ static void mddev_put(struct mddev *mddev) /* Array is not configured at all, and not held active, * so destroy it */ list_del_init(&mddev->all_mddevs); - if (mddev->bio_set) - bioset_free(mddev->bio_set); - if (mddev->sync_set) - bioset_free(mddev->sync_set); + bs = mddev->bio_set; + sync_bs = mddev->sync_set; mddev->bio_set = NULL; mddev->sync_set = NULL; if (mddev->gendisk) { @@ -500,6 +500,10 @@ static void mddev_put(struct mddev *mddev) kfree(mddev); } spin_unlock(&all_mddevs_lock); + if (bs) + bioset_free(bs); + if (sync_bs) + bioset_free(sync_bs); } static void md_safemode_timeout(unsigned long data);