diff mbox series

[v4.19] dm: fix mempool NULL pointer race when completing IO

Message ID alpine.LRH.2.02.2205031639140.11434@file01.intranet.prod.int.rdu2.redhat.com
State New
Headers show
Series [v4.19] dm: fix mempool NULL pointer race when completing IO | expand

Commit Message

Mikulas Patocka May 3, 2022, 8:39 p.m. UTC
This is backport of the patch d208b89401e0 ("dm: fix mempool NULL pointer
race when completing IO") for the kernel 4.19.

The bugs fixed by this patch can cause random crashing when reloading dm
table, so it is eligible for stable backport.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Reviewed-by: Mike Snitzer <snitzer@kernel.org>

---
 drivers/md/dm.c |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)
diff mbox series

Patch

Index: linux-stable/drivers/md/dm.c
===================================================================
--- linux-stable.orig/drivers/md/dm.c	2022-04-30 20:13:27.000000000 +0200
+++ linux-stable/drivers/md/dm.c	2022-04-30 20:13:55.000000000 +0200
@@ -631,21 +631,20 @@  static void start_io_acct(struct dm_io *
 				    false, 0, &io->stats_aux);
 }
 
-static void end_io_acct(struct dm_io *io)
+static void end_io_acct(struct mapped_device *md, struct bio *bio,
+			unsigned long start_time, struct dm_stats_aux *stats_aux)
 {
-	struct mapped_device *md = io->md;
-	struct bio *bio = io->orig_bio;
-	unsigned long duration = jiffies - io->start_time;
+	unsigned long duration = jiffies - start_time;
 	int pending;
 	int rw = bio_data_dir(bio);
 
 	generic_end_io_acct(md->queue, bio_op(bio), &dm_disk(md)->part0,
-			    io->start_time);
+			    start_time);
 
 	if (unlikely(dm_stats_used(&md->stats)))
 		dm_stats_account_io(&md->stats, bio_data_dir(bio),
 				    bio->bi_iter.bi_sector, bio_sectors(bio),
-				    true, duration, &io->stats_aux);
+				    true, duration, stats_aux);
 
 	/*
 	 * After this is decremented the bio must not be touched if it is
@@ -872,6 +871,8 @@  static void dec_pending(struct dm_io *io
 	blk_status_t io_error;
 	struct bio *bio;
 	struct mapped_device *md = io->md;
+	unsigned long start_time = 0;
+	struct dm_stats_aux stats_aux;
 
 	/* Push-back supersedes any I/O errors */
 	if (unlikely(error)) {
@@ -898,8 +899,10 @@  static void dec_pending(struct dm_io *io
 
 		io_error = io->status;
 		bio = io->orig_bio;
-		end_io_acct(io);
+		start_time = io->start_time;
+		stats_aux = io->stats_aux;
 		free_io(md, io);
+		end_io_acct(md, bio, start_time, &stats_aux);
 
 		if (io_error == BLK_STS_DM_REQUEUE)
 			return;