[dm-devel] [PATCH 5/5] dm-mpath: improve I/O schedule
Ming Lei
ming.lei at redhat.com
Fri Sep 15 16:44:56 UTC 2017
The actual I/O schedule is done in dm-mpath layer, and the
underlying I/O schedule is simply bypassed.
This patch sets underlying queue's nr_requests as its queue's
queue_depth, then we can get its queue busy feedback by simply
checking if blk_get_request() returns successfully.
In this way, dm-mpath can reports its queue busy to block layer
effectively, so I/O scheduling is improved much.
Follows the test results on lpfc*:
- fio(libaio, bs:4k, dio, queue_depth:64, 64 jobs,
over dm-mpath disk)
- system(12 cores, dual sockets, mem: 64G)
---------------------------------------
|v4.13+ |v4.13+
|+scsi_mq_perf |+scsi_mq_perf+patches
-----------------------------------------
IOPS(K) |MQ-DEADLINE |MQ-DEADLINE
------------------------------------------
read | 30.71 | 343.91
-----------------------------------------
randread | 22.98 | 17.17
------------------------------------------
write | 16.45 | 390.88
------------------------------------------
randwrite | 16.21 | 16.09
---------------------------------------
*:
1) lpfc.lpfc_lun_queue_depth=3, so that it is same with .cmd_per_lun
2) scsi_mq_perf means the patchset of 'blk-mq-sched: improve SCSI-MQ performance(V4)'[1]
3) v4.13+: top commit is 46c1e79fee41 Merge branch 'perf-urgent-for-linus'
4) the patchset 'blk-mq-sched: improve SCSI-MQ performance(V4)' focuses
on improving on SCSI-MQ, and all the test result in that coverletter was
against the raw lpfc/ib(run after 'multipath -F'), instead of dm-mpath.
5) this patchset itself doesn't depend on the scsi_mq_perf patchset[1]
[1] https://marc.info/?t=150436555700002&r=1&w=2
Signed-off-by: Ming Lei <ming.lei at redhat.com>
---
drivers/md/dm-mpath.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index f57ad8621c4c..02647386d2d9 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -39,6 +39,8 @@ struct pgpath {
struct dm_path path;
struct delayed_work activate_path;
+ unsigned old_nr_requests;
+ unsigned queue_depth;
bool is_active:1; /* Path status */
};
@@ -160,12 +162,34 @@ static struct priority_group *alloc_priority_group(void)
return pg;
}
+static void save_path_queue_depth(struct pgpath *p)
+{
+ struct request_queue *q = bdev_get_queue(p->path.dev->bdev);
+
+ p->old_nr_requests = q->nr_requests;
+ p->queue_depth = q->queue_depth;
+
+ /* one extra request for making the pipeline full */
+ if (p->queue_depth)
+ blk_update_nr_requests(q, p->queue_depth + 1);
+}
+
+static void restore_path_queue_depth(struct pgpath *p)
+{
+ struct request_queue *q = bdev_get_queue(p->path.dev->bdev);
+
+ /* nr->requests isn't changed, we restore to old value */
+ if (q->nr_requests == p->queue_depth + 1)
+ blk_update_nr_requests(q, p->old_nr_requests);
+}
+
static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti)
{
struct pgpath *pgpath, *tmp;
list_for_each_entry_safe(pgpath, tmp, pgpaths, list) {
list_del(&pgpath->list);
+ restore_path_queue_depth(pgpath);
dm_put_device(ti, pgpath->path.dev);
free_pgpath(pgpath);
}
@@ -810,6 +834,8 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps
goto bad;
}
+ save_path_queue_depth(p);
+
return p;
bad:
--
2.9.5
More information about the dm-devel
mailing list