From: Sasha Levin Date: Wed, 29 Nov 2023 19:52:11 +0000 (-0500) Subject: Fixes for 6.1 X-Git-Tag: v5.15.141~15^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a72eb2d01198bb1213bbf0b27ff3965a19917bff;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.1 Signed-off-by: Sasha Levin --- diff --git a/queue-6.1/dm-delay-fix-a-race-between-delay_presuspend-and-del.patch b/queue-6.1/dm-delay-fix-a-race-between-delay_presuspend-and-del.patch new file mode 100644 index 00000000000..440426d8c5e --- /dev/null +++ b/queue-6.1/dm-delay-fix-a-race-between-delay_presuspend-and-del.patch @@ -0,0 +1,98 @@ +From f26d1c98b5333c59bc7b8cd11a683ee5c64b6a52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Nov 2023 13:38:43 -0500 +Subject: dm-delay: fix a race between delay_presuspend and delay_bio + +From: Mikulas Patocka + +[ Upstream commit 6fc45b6ed921dc00dfb264dc08c7d67ee63d2656 ] + +In delay_presuspend, we set the atomic variable may_delay and then stop +the timer and flush pending bios. The intention here is to prevent the +delay target from re-arming the timer again. + +However, this test is racy. Suppose that one thread goes to delay_bio, +sees that dc->may_delay is one and proceeds; now, another thread executes +delay_presuspend, it sets dc->may_delay to zero, deletes the timer and +flushes pending bios. Then, the first thread continues and adds the bio to +delayed->list despite the fact that dc->may_delay is false. + +Fix this bug by changing may_delay's type from atomic_t to bool and +only access it while holding the delayed_bios_lock mutex. Note that we +don't have to grab the mutex in delay_resume because there are no bios +in flight at this point. + +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org +Signed-off-by: Mike Snitzer +Signed-off-by: Sasha Levin +--- + drivers/md/dm-delay.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c +index 02b8f4e818276..43541c8e2b43d 100644 +--- a/drivers/md/dm-delay.c ++++ b/drivers/md/dm-delay.c +@@ -30,7 +30,7 @@ struct delay_c { + struct workqueue_struct *kdelayd_wq; + struct work_struct flush_expired_bios; + struct list_head delayed_bios; +- atomic_t may_delay; ++ bool may_delay; + + struct delay_class read; + struct delay_class write; +@@ -191,7 +191,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv) + INIT_WORK(&dc->flush_expired_bios, flush_expired_bios); + INIT_LIST_HEAD(&dc->delayed_bios); + mutex_init(&dc->timer_lock); +- atomic_set(&dc->may_delay, 1); ++ dc->may_delay = true; + dc->argc = argc; + + ret = delay_class_ctr(ti, &dc->read, argv); +@@ -246,7 +246,7 @@ static int delay_bio(struct delay_c *dc, struct delay_class *c, struct bio *bio) + struct dm_delay_info *delayed; + unsigned long expires = 0; + +- if (!c->delay || !atomic_read(&dc->may_delay)) ++ if (!c->delay) + return DM_MAPIO_REMAPPED; + + delayed = dm_per_bio_data(bio, sizeof(struct dm_delay_info)); +@@ -255,6 +255,10 @@ static int delay_bio(struct delay_c *dc, struct delay_class *c, struct bio *bio) + delayed->expires = expires = jiffies + msecs_to_jiffies(c->delay); + + mutex_lock(&delayed_bios_lock); ++ if (unlikely(!dc->may_delay)) { ++ mutex_unlock(&delayed_bios_lock); ++ return DM_MAPIO_REMAPPED; ++ } + c->ops++; + list_add_tail(&delayed->list, &dc->delayed_bios); + mutex_unlock(&delayed_bios_lock); +@@ -268,7 +272,10 @@ static void delay_presuspend(struct dm_target *ti) + { + struct delay_c *dc = ti->private; + +- atomic_set(&dc->may_delay, 0); ++ mutex_lock(&delayed_bios_lock); ++ dc->may_delay = false; ++ mutex_unlock(&delayed_bios_lock); ++ + del_timer_sync(&dc->delay_timer); + flush_bios(flush_delayed_bios(dc, 1)); + } +@@ -277,7 +284,7 @@ static void delay_resume(struct dm_target *ti) + { + struct delay_c *dc = ti->private; + +- atomic_set(&dc->may_delay, 1); ++ dc->may_delay = true; + } + + static int delay_map(struct dm_target *ti, struct bio *bio) +-- +2.42.0 + diff --git a/queue-6.1/series b/queue-6.1/series index 956130a0411..ba37ae3c56d 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -53,3 +53,4 @@ ext4-make-sure-allocate-pending-entry-not-fail.patch nfsd-fix-start-of-nfs-reply-pointer-passed-to-nfsd_cache_update.patch nfsd-fix-checksum-mismatches-in-the-duplicate-reply-cache.patch arm64-dts-imx8mn-var-som-add-20ms-delay-to-ethernet-regulator-enable.patch +dm-delay-fix-a-race-between-delay_presuspend-and-del.patch