Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1742589 > unrolled thread
| Started by | Ming Lei <ming.lei@redhat.com> |
|---|---|
| First post | 2017-09-30 12:30 +0200 |
| Last post | 2017-09-30 12:40 +0200 |
| Articles | 4 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH V5 00/14] blk-mq-sched: improve sequential I/O performance(part 1) Ming Lei <ming.lei@redhat.com> - 2017-09-30 12:30 +0200
[PATCH V5 6/7] blk-mq-sched: improve dispatching from sw queue Ming Lei <ming.lei@redhat.com> - 2017-09-30 12:30 +0200
[PATCH V5 2/7] blk-mq-sched: fix scheduler bad performance Ming Lei <ming.lei@redhat.com> - 2017-09-30 12:30 +0200
Re: [PATCH V5 00/14] blk-mq-sched: improve sequential I/O performance(part 1) Ming Lei <ming.lei@redhat.com> - 2017-09-30 12:40 +0200
| From | Ming Lei <ming.lei@redhat.com> |
|---|---|
| Date | 2017-09-30 12:30 +0200 |
| Subject | [PATCH V5 00/14] blk-mq-sched: improve sequential I/O performance(part 1) |
| Message-ID | <uvnbX-2Ra-5@gated-at.bofh.it> |
Hi Jens,
In Red Hat internal storage test wrt. blk-mq scheduler, we
found that I/O performance is much bad with mq-deadline, especially
about sequential I/O on some multi-queue SCSI devcies(lpfc, qla2xxx,
SRP...)
Turns out one big issue causes the performance regression: requests
are still dequeued from sw queue/scheduler queue even when ldd's
queue is busy, so I/O merge becomes quite difficult to make, then
sequential IO degrades a lot.
This issue becomes one of mains reasons for reverting default SCSI_MQ
in V4.13.
The 1st patch takes direct issue in blk_mq_request_bypass_insert(),
then we can improve dm-mpath's performance in part 2, which will
be posted out soon.
The 2nd six patches improve this situation, and brings back
some performance loss.
With this change, SCSI-MQ sequential I/O performance is
improved much, Paolo reported that mq-deadline performance
improved much[2] in his dbench test wrt V2. Also performanc
improvement on lpfc/qla2xx was observed with V1.[1]
Please consider it for V4.15.
[1] http://marc.info/?l=linux-block&m=150151989915776&w=2
[2] https://marc.info/?l=linux-block&m=150217980602843&w=2
V5:
- address some comments from Omar
- add Tested-by & Reveiewed-by tag
- use direct issue for blk_mq_request_bypass_insert(), and
start to consider to improve sequential I/O for dm-mpath
- only include part 1(the original patch 1 ~ 6), as suggested
by Omar
V4:
- add Reviewed-by tag
- some trival change: typo fix in commit log or comment,
variable name, no actual functional change
V3:
- totally round robin for picking req from ctx, as suggested
by Bart
- remove one local variable in __sbitmap_for_each_set()
- drop patches of single dispatch list, which can improve
performance on mq-deadline, but cause a bit degrade on
none because all hctxs need to be checked after ->dispatch
is flushed. Will post it again once it is mature.
- rebase on v4.13-rc6 with block for-next
V2:
- dequeue request from sw queues in round roubin's style
as suggested by Bart, and introduces one helper in sbitmap
for this purpose
- improve bio merge via hash table from sw queue
- add comments about using DISPATCH_BUSY state in lockless way,
simplifying handling on busy state,
- hold ctx->lock when clearing ctx busy bit as suggested
by Bart
Ming Lei (7):
blk-mq: issue rq directly in blk_mq_request_bypass_insert()
blk-mq-sched: fix scheduler bad performance
sbitmap: introduce __sbitmap_for_each_set()
blk-mq: introduce blk_mq_dequeue_from_ctx()
blk-mq-sched: move actual dispatching into one helper
blk-mq-sched: improve dispatching from sw queue
blk-mq-sched: don't dequeue request until all in ->dispatch are
flushed
block/blk-core.c | 3 +-
block/blk-mq-debugfs.c | 1 +
block/blk-mq-sched.c | 104 ++++++++++++++++++++++++++++++++++++-------
block/blk-mq.c | 114 +++++++++++++++++++++++++++++++++++++++---------
block/blk-mq.h | 4 +-
drivers/md/dm-rq.c | 2 +-
include/linux/blk-mq.h | 3 ++
include/linux/sbitmap.h | 64 +++++++++++++++++++--------
8 files changed, 238 insertions(+), 57 deletions(-)
--
2.9.5
[toc] | [next] | [standalone]
| From | Ming Lei <ming.lei@redhat.com> |
|---|---|
| Date | 2017-09-30 12:30 +0200 |
| Subject | [PATCH V5 6/7] blk-mq-sched: improve dispatching from sw queue |
| Message-ID | <uvnbX-2Ra-19@gated-at.bofh.it> |
| In reply to | #1742589 |
SCSI devices use host-wide tagset, and the shared
driver tag space is often quite big. Meantime
there is also queue depth for each lun(.cmd_per_lun),
which is often small.
So lots of requests may stay in sw queue, and we
always flush all belonging to same hw queue and
dispatch them all to driver, unfortunately it is
easy to cause queue busy because of the small
per-lun queue depth. Once these requests are flushed
out, they have to stay in hctx->dispatch, and no bio
merge can participate into these requests, and
sequential IO performance is hurted.
This patch improves dispatching from sw queue when
there is per-request-queue queue depth by taking
request one by one from sw queue, just like the way
of IO scheduler.
Reviewed-by: Omar Sandoval <osandov@fb.com>
Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Tested-by: Tom Nguyen <tom81094@gmail.com>
Tested-by: Paolo Valente <paolo.valente@linaro.org>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
block/blk-mq-sched.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++--
include/linux/blk-mq.h | 2 ++
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index 538f363f39ca..3ba112d9dc15 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -105,6 +105,42 @@ static void blk_mq_do_dispatch_sched(struct request_queue *q,
} while (blk_mq_dispatch_rq_list(q, &rq_list));
}
+static struct blk_mq_ctx *blk_mq_next_ctx(struct blk_mq_hw_ctx *hctx,
+ struct blk_mq_ctx *ctx)
+{
+ unsigned idx = ctx->index_hw;
+
+ if (++idx == hctx->nr_ctx)
+ idx = 0;
+
+ return hctx->ctxs[idx];
+}
+
+static void blk_mq_do_dispatch_ctx(struct request_queue *q,
+ struct blk_mq_hw_ctx *hctx)
+{
+ LIST_HEAD(rq_list);
+ struct blk_mq_ctx *ctx = READ_ONCE(hctx->dispatch_from);
+ bool dispatched;
+
+ do {
+ struct request *rq;
+
+ rq = blk_mq_dequeue_from_ctx(hctx, ctx);
+ if (!rq)
+ break;
+ list_add(&rq->queuelist, &rq_list);
+
+ /* round robin for fair dispatch */
+ ctx = blk_mq_next_ctx(hctx, rq->mq_ctx);
+
+ dispatched = blk_mq_dispatch_rq_list(q, &rq_list);
+ } while (dispatched);
+
+ if (!dispatched)
+ WRITE_ONCE(hctx->dispatch_from, ctx);
+}
+
void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx)
{
struct request_queue *q = hctx->queue;
@@ -142,18 +178,31 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx)
if (!list_empty(&rq_list)) {
blk_mq_sched_mark_restart_hctx(hctx);
do_sched_dispatch = blk_mq_dispatch_rq_list(q, &rq_list);
- } else if (!has_sched_dispatch) {
+ } else if (!has_sched_dispatch && !q->queue_depth) {
+ /*
+ * If there is no per-request_queue depth, we
+ * flush all requests in this hw queue, otherwise
+ * pick up request one by one from sw queue for
+ * avoiding to mess up I/O merge when dispatch
+ * run out of resource, which can be triggered
+ * easily by per-request_queue queue depth
+ */
blk_mq_flush_busy_ctxs(hctx, &rq_list);
blk_mq_dispatch_rq_list(q, &rq_list);
}
+ if (!do_sched_dispatch)
+ return;
+
/*
* We want to dispatch from the scheduler if there was nothing
* on the dispatch list or we were able to dispatch from the
* dispatch list.
*/
- if (do_sched_dispatch && has_sched_dispatch)
+ if (has_sched_dispatch)
blk_mq_do_dispatch_sched(q, e, hctx);
+ else
+ blk_mq_do_dispatch_ctx(q, hctx);
}
bool blk_mq_sched_try_merge(struct request_queue *q, struct bio *bio,
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 2747469cedaf..fccabe00fb55 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -30,6 +30,8 @@ struct blk_mq_hw_ctx {
struct sbitmap ctx_map;
+ struct blk_mq_ctx *dispatch_from;
+
struct blk_mq_ctx **ctxs;
unsigned int nr_ctx;
--
2.9.5
[toc] | [prev] | [next] | [standalone]
| From | Ming Lei <ming.lei@redhat.com> |
|---|---|
| Date | 2017-09-30 12:30 +0200 |
| Subject | [PATCH V5 2/7] blk-mq-sched: fix scheduler bad performance |
| Message-ID | <uvnbX-2Ra-21@gated-at.bofh.it> |
| In reply to | #1742589 |
When hw queue is busy, we shouldn't take requests from
scheduler queue any more, otherwise it is difficult to do
IO merge.
This patch fixes the awful IO performance on some
SCSI devices(lpfc, qla2xxx, ...) when mq-deadline/kyber
is used by not taking requests if hw queue is busy.
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Tested-by: Tom Nguyen <tom81094@gmail.com>
Tested-by: Paolo Valente <paolo.valente@linaro.org>
Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
block/blk-mq-sched.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index 4ab69435708c..eca011fdfa0e 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -94,7 +94,7 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx)
struct request_queue *q = hctx->queue;
struct elevator_queue *e = q->elevator;
const bool has_sched_dispatch = e && e->type->ops.mq.dispatch_request;
- bool did_work = false;
+ bool do_sched_dispatch = true;
LIST_HEAD(rq_list);
/* RCU or SRCU read lock is needed before checking quiesced flag */
@@ -125,18 +125,18 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx)
*/
if (!list_empty(&rq_list)) {
blk_mq_sched_mark_restart_hctx(hctx);
- did_work = blk_mq_dispatch_rq_list(q, &rq_list);
+ do_sched_dispatch = blk_mq_dispatch_rq_list(q, &rq_list);
} else if (!has_sched_dispatch) {
blk_mq_flush_busy_ctxs(hctx, &rq_list);
blk_mq_dispatch_rq_list(q, &rq_list);
}
/*
- * We want to dispatch from the scheduler if we had no work left
- * on the dispatch list, OR if we did have work but weren't able
- * to make progress.
+ * We want to dispatch from the scheduler if there was nothing
+ * on the dispatch list or we were able to dispatch from the
+ * dispatch list.
*/
- if (!did_work && has_sched_dispatch) {
+ if (do_sched_dispatch && has_sched_dispatch) {
do {
struct request *rq;
--
2.9.5
[toc] | [prev] | [next] | [standalone]
| From | Ming Lei <ming.lei@redhat.com> |
|---|---|
| Date | 2017-09-30 12:40 +0200 |
| Subject | Re: [PATCH V5 00/14] blk-mq-sched: improve sequential I/O performance(part 1) |
| Message-ID | <uvnlE-2UP-9@gated-at.bofh.it> |
| In reply to | #1742589 |
On Sat, Sep 30, 2017 at 06:27:13PM +0800, Ming Lei wrote: > Hi Jens, > > In Red Hat internal storage test wrt. blk-mq scheduler, we > found that I/O performance is much bad with mq-deadline, especially > about sequential I/O on some multi-queue SCSI devcies(lpfc, qla2xxx, > SRP...) > > Turns out one big issue causes the performance regression: requests > are still dequeued from sw queue/scheduler queue even when ldd's > queue is busy, so I/O merge becomes quite difficult to make, then > sequential IO degrades a lot. > > This issue becomes one of mains reasons for reverting default SCSI_MQ > in V4.13. > > The 1st patch takes direct issue in blk_mq_request_bypass_insert(), > then we can improve dm-mpath's performance in part 2, which will > be posted out soon. > > The 2nd six patches improve this situation, and brings back > some performance loss. > > With this change, SCSI-MQ sequential I/O performance is > improved much, Paolo reported that mq-deadline performance > improved much[2] in his dbench test wrt V2. Also performanc > improvement on lpfc/qla2xx was observed with V1.[1] > > Please consider it for V4.15. > > [1] http://marc.info/?l=linux-block&m=150151989915776&w=2 > [2] https://marc.info/?l=linux-block&m=150217980602843&w=2 > > V5: > - address some comments from Omar > - add Tested-by & Reveiewed-by tag > - use direct issue for blk_mq_request_bypass_insert(), and > start to consider to improve sequential I/O for dm-mpath > - only include part 1(the original patch 1 ~ 6), as suggested > by Omar > > V4: > - add Reviewed-by tag > - some trival change: typo fix in commit log or comment, > variable name, no actual functional change > > V3: > - totally round robin for picking req from ctx, as suggested > by Bart > - remove one local variable in __sbitmap_for_each_set() > - drop patches of single dispatch list, which can improve > performance on mq-deadline, but cause a bit degrade on > none because all hctxs need to be checked after ->dispatch > is flushed. Will post it again once it is mature. > - rebase on v4.13-rc6 with block for-next > > V2: > - dequeue request from sw queues in round roubin's style > as suggested by Bart, and introduces one helper in sbitmap > for this purpose > - improve bio merge via hash table from sw queue > - add comments about using DISPATCH_BUSY state in lockless way, > simplifying handling on busy state, > - hold ctx->lock when clearing ctx busy bit as suggested > by Bart > > > Ming Lei (7): > blk-mq: issue rq directly in blk_mq_request_bypass_insert() > blk-mq-sched: fix scheduler bad performance > sbitmap: introduce __sbitmap_for_each_set() > blk-mq: introduce blk_mq_dequeue_from_ctx() > blk-mq-sched: move actual dispatching into one helper > blk-mq-sched: improve dispatching from sw queue > blk-mq-sched: don't dequeue request until all in ->dispatch are > flushed > > block/blk-core.c | 3 +- > block/blk-mq-debugfs.c | 1 + > block/blk-mq-sched.c | 104 ++++++++++++++++++++++++++++++++++++------- > block/blk-mq.c | 114 +++++++++++++++++++++++++++++++++++++++--------- > block/blk-mq.h | 4 +- > drivers/md/dm-rq.c | 2 +- > include/linux/blk-mq.h | 3 ++ > include/linux/sbitmap.h | 64 +++++++++++++++++++-------- > 8 files changed, 238 insertions(+), 57 deletions(-) Oops, the title should have been: [PATCH V5 0/7] blk-mq-sched: improve sequential I/O performance(part 1) Sorry for that. -- Ming
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web