Skip to content

Commit db29d79

Browse files
YuKuai-huaweiMike Snitzer
authored andcommitted
dm-raid: delay flushing event_work() after reconfig_mutex is released
After commit db5e653 ("md: delay choosing sync action to md_start_sync()"), md_start_sync() will hold 'reconfig_mutex', however, in order to make sure event_work is done, __md_stop() will flush workqueue with reconfig_mutex grabbed, hence if sync_work is still pending, deadlock will be triggered. Fortunately, former pacthes to fix stopping sync_thread already make sure all sync_work is done already, hence such deadlock is not possible anymore. However, in order not to cause confusions for people by this implicit dependency, delay flushing event_work to dm-raid where 'reconfig_mutex' is not held, and add some comments to emphasize that the workqueue can't be flushed with 'reconfig_mutex'. Fixes: db5e653 ("md: delay choosing sync action to md_start_sync()") Depends-on: f52f5c7 ("md: fix stopping sync thread") Signed-off-by: Yu Kuai <[email protected]> Acked-by: Xiao Ni <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent ceb6a6f commit db29d79

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

drivers/md/dm-raid.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3317,6 +3317,9 @@ static void raid_dtr(struct dm_target *ti)
33173317
mddev_lock_nointr(&rs->md);
33183318
md_stop(&rs->md);
33193319
mddev_unlock(&rs->md);
3320+
3321+
if (work_pending(&rs->md.event_work))
3322+
flush_work(&rs->md.event_work);
33203323
raid_set_free(rs);
33213324
}
33223325

drivers/md/md.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ static struct module *md_cluster_mod;
8282

8383
static DECLARE_WAIT_QUEUE_HEAD(resync_wait);
8484
static struct workqueue_struct *md_wq;
85+
86+
/*
87+
* This workqueue is used for sync_work to register new sync_thread, and for
88+
* del_work to remove rdev, and for event_work that is only set by dm-raid.
89+
*
90+
* Noted that sync_work will grab reconfig_mutex, hence never flush this
91+
* workqueue whith reconfig_mutex grabbed.
92+
*/
8593
static struct workqueue_struct *md_misc_wq;
8694
struct workqueue_struct *md_bitmap_wq;
8795

@@ -6330,9 +6338,6 @@ static void __md_stop(struct mddev *mddev)
63306338
struct md_personality *pers = mddev->pers;
63316339
md_bitmap_destroy(mddev);
63326340
mddev_detach(mddev);
6333-
/* Ensure ->event_work is done */
6334-
if (mddev->event_work.func)
6335-
flush_workqueue(md_misc_wq);
63366341
spin_lock(&mddev->lock);
63376342
mddev->pers = NULL;
63386343
spin_unlock(&mddev->lock);

0 commit comments

Comments
 (0)