diff options
author | Benjamin Marzinski <bmarzins@redhat.com> | 2024-05-08 00:16:23 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-05-30 10:44:35 +0300 |
commit | d23afe03255dc5e3648c7da04da86237c961d740 (patch) | |
tree | dade2ff6a931463cb210c0d2e0f0c4960ff92f59 /drivers/md | |
parent | efc40e63687843fe525f1bd4c5eda854f53f33ce (diff) | |
download | linux-d23afe03255dc5e3648c7da04da86237c961d740.tar.xz |
dm-delay: fix workqueue delay_timer race
[ Upstream commit 8d24790ed08ab4e619ce58ed4a1b353ab77ffdc5 ]
delay_timer could be pending when delay_dtr() is called. It needs to be
shut down before kdelayd_wq is destroyed, so it won't try queueing more
work to kdelayd_wq while that's getting destroyed.
Also the del_timer_sync() call in delay_presuspend() doesn't protect
against the timer getting immediately rearmed by the queued call to
flush_delayed_bios(), but there's no real harm if that does happen.
timer_delete() is less work, and is basically just as likely to stop a
pointless call to flush_delayed_bios().
Fixes: 26b9f228703f ("dm: delay target")
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-delay.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c index 5eabdb06c649..eec0daa4b227 100644 --- a/drivers/md/dm-delay.c +++ b/drivers/md/dm-delay.c @@ -154,8 +154,10 @@ static void delay_dtr(struct dm_target *ti) { struct delay_c *dc = ti->private; - if (dc->kdelayd_wq) + if (dc->kdelayd_wq) { + timer_shutdown_sync(&dc->delay_timer); destroy_workqueue(dc->kdelayd_wq); + } if (dc->read.dev) dm_put_device(ti, dc->read.dev); @@ -335,7 +337,7 @@ static void delay_presuspend(struct dm_target *ti) mutex_unlock(&delayed_bios_lock); if (!delay_is_fast(dc)) - del_timer_sync(&dc->delay_timer); + timer_delete(&dc->delay_timer); flush_delayed_bios(dc, true); } |