--- /dev/null
+From 263a9a6fccc9efc92f056328c105472f60273782 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2020 16:00:58 -0400
+Subject: dm: do not use waitqueue for request-based DM
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 85067747cf9888249fa11fa49ef75af5192d3988 ]
+
+Given request-based DM now uses blk-mq's blk_mq_queue_inflight() to
+determine if outstanding IO has completed (and DM has no control over
+the blk-mq state machine used to track outstanding IO) it is unsafe to
+wakeup waiter (dm_wait_for_completion) before blk-mq has cleared a
+request's state bits (e.g. MQ_RQ_IN_FLIGHT or MQ_RQ_COMPLETE). As
+such dm_wait_for_completion() could be left to wait indefinitely if no
+other requests complete.
+
+Fix this by eliminating request-based DM's use of waitqueue to wait
+for blk-mq requests to complete in dm_wait_for_completion.
+
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Depends-on: 3c94d83cb3526 ("blk-mq: change blk_mq_queue_busy() to blk_mq_queue_inflight()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Stable-dep-of: 1e1fd567d32f ("dm suspend: return -ERESTARTSYS instead of -EINTR")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-rq.c | 4 ---
+ drivers/md/dm.c | 64 ++++++++++++++++++++++++++++------------------
+ 2 files changed, 39 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
+index 6bc61927d3205..3d6ac63ee85ae 100644
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -143,10 +143,6 @@ static void rq_end_stats(struct mapped_device *md, struct request *orig)
+ */
+ static void rq_completed(struct mapped_device *md)
+ {
+- /* nudge anyone waiting on suspend queue */
+- if (unlikely(wq_has_sleeper(&md->wait)))
+- wake_up(&md->wait);
+-
+ /*
+ * dm_put() must be at the end of this function. See the comment above
+ */
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 36d21a5d09ebf..f6f5b68a6950b 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -637,28 +637,6 @@ static void free_tio(struct dm_target_io *tio)
+ bio_put(&tio->clone);
+ }
+
+-static bool md_in_flight_bios(struct mapped_device *md)
+-{
+- int cpu;
+- struct hd_struct *part = &dm_disk(md)->part0;
+- long sum = 0;
+-
+- for_each_possible_cpu(cpu) {
+- sum += part_stat_local_read_cpu(part, in_flight[0], cpu);
+- sum += part_stat_local_read_cpu(part, in_flight[1], cpu);
+- }
+-
+- return sum != 0;
+-}
+-
+-static bool md_in_flight(struct mapped_device *md)
+-{
+- if (queue_is_mq(md->queue))
+- return blk_mq_queue_inflight(md->queue);
+- else
+- return md_in_flight_bios(md);
+-}
+-
+ u64 dm_start_time_ns_from_clone(struct bio *bio)
+ {
+ struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone);
+@@ -2428,15 +2406,29 @@ void dm_put(struct mapped_device *md)
+ }
+ EXPORT_SYMBOL_GPL(dm_put);
+
+-static int dm_wait_for_completion(struct mapped_device *md, long task_state)
++static bool md_in_flight_bios(struct mapped_device *md)
++{
++ int cpu;
++ struct hd_struct *part = &dm_disk(md)->part0;
++ long sum = 0;
++
++ for_each_possible_cpu(cpu) {
++ sum += part_stat_local_read_cpu(part, in_flight[0], cpu);
++ sum += part_stat_local_read_cpu(part, in_flight[1], cpu);
++ }
++
++ return sum != 0;
++}
++
++static int dm_wait_for_bios_completion(struct mapped_device *md, long task_state)
+ {
+ int r = 0;
+ DEFINE_WAIT(wait);
+
+- while (1) {
++ while (true) {
+ prepare_to_wait(&md->wait, &wait, task_state);
+
+- if (!md_in_flight(md))
++ if (!md_in_flight_bios(md))
+ break;
+
+ if (signal_pending_state(task_state, current)) {
+@@ -2453,6 +2445,28 @@ static int dm_wait_for_completion(struct mapped_device *md, long task_state)
+ return r;
+ }
+
++static int dm_wait_for_completion(struct mapped_device *md, long task_state)
++{
++ int r = 0;
++
++ if (!queue_is_mq(md->queue))
++ return dm_wait_for_bios_completion(md, task_state);
++
++ while (true) {
++ if (!blk_mq_queue_inflight(md->queue))
++ break;
++
++ if (signal_pending_state(task_state, current)) {
++ r = -EINTR;
++ break;
++ }
++
++ msleep(5);
++ }
++
++ return r;
++}
++
+ /*
+ * Process the deferred bios
+ */
+--
+2.43.0
+
--- /dev/null
+From a82d33934515ca591b0746a08889aa2c6bfc2187 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Apr 2020 16:48:29 -0400
+Subject: dm mpath: pass IO start time to path selector
+
+From: Gabriel Krisman Bertazi <krisman@collabora.com>
+
+[ Upstream commit 087615bf3acdafd0ba7c7c9ed5286e7b7c80fe1b ]
+
+The HST path selector needs this information to perform path
+prediction. For request-based mpath, struct request's io_start_time_ns
+is used, while for bio-based, use the start_time stored in dm_io.
+
+Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Stable-dep-of: 1e1fd567d32f ("dm suspend: return -ERESTARTSYS instead of -EINTR")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-mpath.c | 9 ++++++---
+ drivers/md/dm-path-selector.h | 2 +-
+ drivers/md/dm-queue-length.c | 2 +-
+ drivers/md/dm-service-time.c | 2 +-
+ drivers/md/dm.c | 9 +++++++++
+ include/linux/device-mapper.h | 2 ++
+ 6 files changed, 20 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
+index 54ecfea2cf47b..4f6a54452b1ca 100644
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -558,7 +558,8 @@ static void multipath_release_clone(struct request *clone,
+ if (pgpath && pgpath->pg->ps.type->end_io)
+ pgpath->pg->ps.type->end_io(&pgpath->pg->ps,
+ &pgpath->path,
+- mpio->nr_bytes);
++ mpio->nr_bytes,
++ clone->io_start_time_ns);
+ }
+
+ blk_put_request(clone);
+@@ -1568,7 +1569,8 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone,
+ struct path_selector *ps = &pgpath->pg->ps;
+
+ if (ps->type->end_io)
+- ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes);
++ ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes,
++ clone->io_start_time_ns);
+ }
+
+ return r;
+@@ -1612,7 +1614,8 @@ static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone,
+ struct path_selector *ps = &pgpath->pg->ps;
+
+ if (ps->type->end_io)
+- ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes);
++ ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes,
++ dm_start_time_ns_from_clone(clone));
+ }
+
+ return r;
+diff --git a/drivers/md/dm-path-selector.h b/drivers/md/dm-path-selector.h
+index b6eb5365b1a46..c47bc0e20275b 100644
+--- a/drivers/md/dm-path-selector.h
++++ b/drivers/md/dm-path-selector.h
+@@ -74,7 +74,7 @@ struct path_selector_type {
+ int (*start_io) (struct path_selector *ps, struct dm_path *path,
+ size_t nr_bytes);
+ int (*end_io) (struct path_selector *ps, struct dm_path *path,
+- size_t nr_bytes);
++ size_t nr_bytes, u64 start_time);
+ };
+
+ /* Register a path selector */
+diff --git a/drivers/md/dm-queue-length.c b/drivers/md/dm-queue-length.c
+index 969c4f1a36336..5fd018d184187 100644
+--- a/drivers/md/dm-queue-length.c
++++ b/drivers/md/dm-queue-length.c
+@@ -227,7 +227,7 @@ static int ql_start_io(struct path_selector *ps, struct dm_path *path,
+ }
+
+ static int ql_end_io(struct path_selector *ps, struct dm_path *path,
+- size_t nr_bytes)
++ size_t nr_bytes, u64 start_time)
+ {
+ struct path_info *pi = path->pscontext;
+
+diff --git a/drivers/md/dm-service-time.c b/drivers/md/dm-service-time.c
+index f006a9005593b..9cfda665e9ebd 100644
+--- a/drivers/md/dm-service-time.c
++++ b/drivers/md/dm-service-time.c
+@@ -309,7 +309,7 @@ static int st_start_io(struct path_selector *ps, struct dm_path *path,
+ }
+
+ static int st_end_io(struct path_selector *ps, struct dm_path *path,
+- size_t nr_bytes)
++ size_t nr_bytes, u64 start_time)
+ {
+ struct path_info *pi = path->pscontext;
+
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index a7724ba45b437..36d21a5d09ebf 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -659,6 +659,15 @@ static bool md_in_flight(struct mapped_device *md)
+ return md_in_flight_bios(md);
+ }
+
++u64 dm_start_time_ns_from_clone(struct bio *bio)
++{
++ struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone);
++ struct dm_io *io = tio->io;
++
++ return jiffies_to_nsecs(io->start_time);
++}
++EXPORT_SYMBOL_GPL(dm_start_time_ns_from_clone);
++
+ static void start_io_acct(struct dm_io *io)
+ {
+ struct mapped_device *md = io->md;
+diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
+index 60631f3abddbd..b077f32043653 100644
+--- a/include/linux/device-mapper.h
++++ b/include/linux/device-mapper.h
+@@ -332,6 +332,8 @@ void *dm_per_bio_data(struct bio *bio, size_t data_size);
+ struct bio *dm_bio_from_per_bio_data(void *data, size_t data_size);
+ unsigned dm_bio_get_target_bio_nr(const struct bio *bio);
+
++u64 dm_start_time_ns_from_clone(struct bio *bio);
++
+ int dm_register_target(struct target_type *t);
+ void dm_unregister_target(struct target_type *t);
+
+--
+2.43.0
+
--- /dev/null
+From ee49ba706df738f33aac5c82b710918e96b70d75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Aug 2024 12:38:51 +0200
+Subject: dm suspend: return -ERESTARTSYS instead of -EINTR
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 1e1fd567d32fcf7544c6e09e0e5bc6c650da6e23 ]
+
+This commit changes device mapper, so that it returns -ERESTARTSYS
+instead of -EINTR when it is interrupted by a signal (so that the ioctl
+can be restarted).
+
+The manpage signal(7) says that the ioctl function should be restarted if
+the signal was handled with SA_RESTART.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index f6f5b68a6950b..3d00bb98d702b 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2432,7 +2432,7 @@ static int dm_wait_for_bios_completion(struct mapped_device *md, long task_state
+ break;
+
+ if (signal_pending_state(task_state, current)) {
+- r = -EINTR;
++ r = -ERESTARTSYS;
+ break;
+ }
+
+@@ -2457,7 +2457,7 @@ static int dm_wait_for_completion(struct mapped_device *md, long task_state)
+ break;
+
+ if (signal_pending_state(task_state, current)) {
+- r = -EINTR;
++ r = -ERESTARTSYS;
+ break;
+ }
+
+--
+2.43.0
+
gtp-pull-network-headers-in-gtp_dev_xmit.patch
block-use-unsigned-long-for-blk_validate_block_size.patch
media-solo6x10-replace-max-a-min-b-c-by-clamp-b-a-c.patch
+dm-mpath-pass-io-start-time-to-path-selector.patch
+dm-do-not-use-waitqueue-for-request-based-dm.patch
+dm-suspend-return-erestartsys-instead-of-eintr.patch