]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Fri, 23 Aug 2024 00:12:56 +0000 (20:12 -0400)
committerSasha Levin <sashal@kernel.org>
Fri, 23 Aug 2024 00:12:56 +0000 (20:12 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.4/dm-do-not-use-waitqueue-for-request-based-dm.patch [new file with mode: 0644]
queue-5.4/dm-mpath-pass-io-start-time-to-path-selector.patch [new file with mode: 0644]
queue-5.4/dm-suspend-return-erestartsys-instead-of-eintr.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/dm-do-not-use-waitqueue-for-request-based-dm.patch b/queue-5.4/dm-do-not-use-waitqueue-for-request-based-dm.patch
new file mode 100644 (file)
index 0000000..74f9764
--- /dev/null
@@ -0,0 +1,144 @@
+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
+
diff --git a/queue-5.4/dm-mpath-pass-io-start-time-to-path-selector.patch b/queue-5.4/dm-mpath-pass-io-start-time-to-path-selector.patch
new file mode 100644 (file)
index 0000000..c355b88
--- /dev/null
@@ -0,0 +1,135 @@
+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
+
diff --git a/queue-5.4/dm-suspend-return-erestartsys-instead-of-eintr.patch b/queue-5.4/dm-suspend-return-erestartsys-instead-of-eintr.patch
new file mode 100644 (file)
index 0000000..9561cd9
--- /dev/null
@@ -0,0 +1,48 @@
+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
+
index f504c6f4065df926a9f548ceda71d2f06c852e28..f8a9023cd69a2fd1090b5b20ca76ff065dfbaf24 100644 (file)
@@ -77,3 +77,6 @@ hrtimer-prevent-queuing-of-hrtimer-without-a-functio.patch
 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