[dm-devel] [PATCH v2 2/3] md: multipath: Pass io_start_time to the path selector

Gabriel Krisman Bertazi krisman at collabora.com
Tue Apr 28 00:51:45 UTC 2020


HST need to know the IO start time in order to predict path
performance. For request-based multipath use the block layer
io_start_time, while for BIO use the dm_io start_time.

The dm_start_time_ns_from_clone function was suggested and implemented
by Mike Snitzer <snitzer at redhat.com>.

Cc: Mike Snitzer <snitzer at redhat.com>
Cc: Khazhismel Kumykov <khazhy at google.com>
Signed-off-by: Gabriel Krisman Bertazi <krisman at collabora.com>
---
 drivers/md/dm-mpath.c         | 25 +++++++++++++++----------
 drivers/md/dm-path-selector.h |  1 +
 drivers/md/dm.c               | 10 ++++++++++
 include/linux/device-mapper.h |  2 ++
 4 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 1ef4fc2e745b..7af3249948be 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -500,8 +500,9 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq,
 	struct dm_mpath_io *mpio = get_mpio(map_context);
 	struct request_queue *q;
 	struct request *clone;
-	struct path_selector_io_data io_data = {
+	struct path_selector_io_data ps_io_data = {
 		.nr_bytes = nr_bytes,
+		.io_start_time = rq->io_start_time_ns
 	};
 
 	/* Do we need to select a new pgpath? */
@@ -552,7 +553,7 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq,
 	if (pgpath->pg->ps.type->start_io)
 		pgpath->pg->ps.type->start_io(&pgpath->pg->ps,
 					      &pgpath->path,
-					      &io_data);
+					      &ps_io_data);
 	return DM_MAPIO_REMAPPED;
 }
 
@@ -568,6 +569,7 @@ static void multipath_release_clone(struct request *clone,
 		struct pgpath *pgpath = mpio->pgpath;
 		struct path_selector_io_data ps_io_data = {
 			.nr_bytes = mpio->nr_bytes,
+			.io_start_time = clone->io_start_time_ns,
 		};
 
 		if (pgpath && pgpath->pg->ps.type->end_io)
@@ -623,8 +625,9 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio,
 			       struct dm_mpath_io *mpio)
 {
 	struct pgpath *pgpath = __map_bio(m, bio);
-	struct path_selector_io_data io_data = {
+	struct path_selector_io_data ps_io_data = {
 		.nr_bytes = mpio->nr_bytes,
+		.io_start_time = dm_start_time_ns_from_clone(bio)
 	};
 
 	if (IS_ERR(pgpath))
@@ -646,7 +649,7 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio,
 	if (pgpath->pg->ps.type->start_io)
 		pgpath->pg->ps.type->start_io(&pgpath->pg->ps,
 					      &pgpath->path,
-					      &io_data);
+					      &ps_io_data);
 	return DM_MAPIO_REMAPPED;
 }
 
@@ -1627,12 +1630,13 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone,
 
 	if (pgpath) {
 		struct path_selector *ps = &pgpath->pg->ps;
-		struct path_selector_io_data io_data = {
-			.nr_bytes = mpio->nr_bytes
+		struct path_selector_io_data ps_io_data = {
+			.nr_bytes = mpio->nr_bytes,
+			.io_start_time = clone->io_start_time_ns
 		};
 
 		if (ps->type->end_io)
-			ps->type->end_io(ps, &pgpath->path, &io_data);
+			ps->type->end_io(ps, &pgpath->path, &ps_io_data);
 	}
 
 	return r;
@@ -1674,12 +1678,13 @@ static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone,
 done:
 	if (pgpath) {
 		struct path_selector *ps = &pgpath->pg->ps;
-		struct path_selector_io_data io_data = {
-			.nr_bytes = mpio->nr_bytes
+		struct path_selector_io_data ps_io_data = {
+			.nr_bytes = mpio->nr_bytes,
+			.io_start_time = dm_start_time_ns_from_clone(clone)
 		};
 
 		if (ps->type->end_io)
-			ps->type->end_io(ps, &pgpath->path, &io_data);
+			ps->type->end_io(ps, &pgpath->path, &ps_io_data);
 	}
 
 	return r;
diff --git a/drivers/md/dm-path-selector.h b/drivers/md/dm-path-selector.h
index fb582a943234..4c5fa6a2efe3 100644
--- a/drivers/md/dm-path-selector.h
+++ b/drivers/md/dm-path-selector.h
@@ -28,6 +28,7 @@ struct path_selector {
 
 struct path_selector_io_data {
 	size_t nr_bytes;
+	u64 io_start_time;
 };
 
 /* Information about a path selector type */
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index df13fdebe21f..2e0637a6de9d 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -674,6 +674,16 @@ 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;
+
+	/* FIXME: convert io->start_time from jiffies to nanoseconds */
+	return (u64)jiffies_to_msecs(io->start_time) * NSEC_PER_MSEC;
+}
+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 475668c69dbc..e2d506dd805e 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -329,6 +329,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.26.2





More information about the dm-devel mailing list