From: Ming Lei <ming.lei@redhat.com>
To: Jens Axboe <axboe@kernel.dk>
Cc: linux-block@vger.kernel.org, Ming Lei <ming.lei@redhat.com>,
Bart Van Assche <bvanassche@acm.org>,
Hannes Reinecke <hare@suse.com>, Christoph Hellwig <hch@lst.de>,
Thomas Gleixner <tglx@linutronix.de>,
John Garry <john.garry@huawei.com>
Subject: [PATCH V7 2/9] blk-mq: assign rq->tag in blk_mq_get_driver_tag
Date: Sat, 18 Apr 2020 11:09:18 +0800 [thread overview]
Message-ID: <20200418030925.31996-3-ming.lei@redhat.com> (raw)
In-Reply-To: <20200418030925.31996-1-ming.lei@redhat.com>
Especially for none elevator, rq->tag is assigned after the request is
allocated, so there isn't any way to figure out if one request is in
being dispatched. Also the code path wrt. driver tag becomes a bit
difference between none and io scheduler.
When one hctx becomes inactive, we have to prevent any request from
being dispatched to LLD. And get driver tag provides one perfect chance
to do that. Meantime we can drain any such requests by checking if
rq->tag is assigned.
So only assign rq->tag until blk_mq_get_driver_tag() is called.
This way also simplifies code of dealing with driver tag a lot.
Cc: Bart Van Assche <bvanassche@acm.org>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: John Garry <john.garry@huawei.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
block/blk-flush.c | 18 +++---------------
block/blk-mq.c | 45 +++++++++++++++++++++++----------------------
block/blk-mq.h | 21 ++++++++++-----------
block/blk.h | 5 -----
4 files changed, 36 insertions(+), 53 deletions(-)
diff --git a/block/blk-flush.c b/block/blk-flush.c
index c7f396e3d5e2..977edf95d711 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -236,13 +236,8 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error)
error = fq->rq_status;
hctx = flush_rq->mq_hctx;
- if (!q->elevator) {
- blk_mq_tag_set_rq(hctx, flush_rq->tag, fq->orig_rq);
- flush_rq->tag = -1;
- } else {
- blk_mq_put_driver_tag(flush_rq);
- flush_rq->internal_tag = -1;
- }
+ flush_rq->internal_tag = -1;
+ blk_mq_put_driver_tag(flush_rq);
running = &fq->flush_queue[fq->flush_running_idx];
BUG_ON(fq->flush_pending_idx == fq->flush_running_idx);
@@ -317,14 +312,7 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq,
flush_rq->mq_ctx = first_rq->mq_ctx;
flush_rq->mq_hctx = first_rq->mq_hctx;
- if (!q->elevator) {
- fq->orig_rq = first_rq;
- flush_rq->tag = first_rq->tag;
- blk_mq_tag_set_rq(flush_rq->mq_hctx, first_rq->tag, flush_rq);
- } else {
- flush_rq->internal_tag = first_rq->internal_tag;
- }
-
+ flush_rq->internal_tag = first_rq->internal_tag;
flush_rq->cmd_flags = REQ_OP_FLUSH | REQ_PREFLUSH;
flush_rq->cmd_flags |= (flags & REQ_DRV) | (flags & REQ_FAILFAST_MASK);
flush_rq->rq_flags |= RQF_FLUSH_SEQ;
diff --git a/block/blk-mq.c b/block/blk-mq.c
index ecc9c7f405b5..29ffa40db793 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -276,18 +276,8 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data,
struct request *rq = tags->static_rqs[tag];
req_flags_t rq_flags = 0;
- if (data->flags & BLK_MQ_REQ_INTERNAL) {
- rq->tag = -1;
- rq->internal_tag = tag;
- } else {
- if (data->hctx->flags & BLK_MQ_F_TAG_SHARED) {
- rq_flags = RQF_MQ_INFLIGHT;
- atomic_inc(&data->hctx->nr_active);
- }
- rq->tag = tag;
- rq->internal_tag = -1;
- data->hctx->tags->rqs[rq->tag] = rq;
- }
+ rq->internal_tag = tag;
+ rq->tag = -1;
/* csd/requeue_work/fifo_time is initialized before use */
rq->q = data->q;
@@ -472,14 +462,18 @@ static void __blk_mq_free_request(struct request *rq)
struct request_queue *q = rq->q;
struct blk_mq_ctx *ctx = rq->mq_ctx;
struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
- const int sched_tag = rq->internal_tag;
blk_pm_mark_last_busy(rq);
rq->mq_hctx = NULL;
- if (rq->tag != -1)
- blk_mq_put_tag(hctx->tags, ctx, rq->tag);
- if (sched_tag != -1)
- blk_mq_put_tag(hctx->sched_tags, ctx, sched_tag);
+
+ if (hctx->sched_tags) {
+ if (rq->tag >= 0)
+ blk_mq_put_tag(hctx->tags, ctx, rq->tag);
+ blk_mq_put_tag(hctx->sched_tags, ctx, rq->internal_tag);
+ } else {
+ blk_mq_put_tag(hctx->tags, ctx, rq->internal_tag);
+ }
+
blk_mq_sched_restart(hctx);
blk_queue_exit(q);
}
@@ -527,7 +521,7 @@ inline void __blk_mq_end_request(struct request *rq, blk_status_t error)
blk_stat_add(rq, now);
}
- if (rq->internal_tag != -1)
+ if (rq->q->elevator && rq->internal_tag != -1)
blk_mq_sched_completed_request(rq, now);
blk_account_io_done(rq, now);
@@ -1037,14 +1031,21 @@ static bool blk_mq_get_driver_tag(struct request *rq)
};
bool shared;
- if (rq->tag != -1)
- return true;
+ if (rq->tag >= 0)
+ goto allocated;
+
+ if (!data.hctx->sched_tags) {
+ rq->tag = rq->internal_tag;
+ goto set_rq;
+ }
if (blk_mq_tag_is_reserved(data.hctx->sched_tags, rq->internal_tag))
data.flags |= BLK_MQ_REQ_RESERVED;
- shared = blk_mq_tag_busy(data.hctx);
rq->tag = blk_mq_get_tag(&data);
+
+set_rq:
+ shared = blk_mq_tag_busy(data.hctx);
if (rq->tag >= 0) {
if (shared) {
rq->rq_flags |= RQF_MQ_INFLIGHT;
@@ -1052,7 +1053,7 @@ static bool blk_mq_get_driver_tag(struct request *rq)
}
data.hctx->tags->rqs[rq->tag] = rq;
}
-
+allocated:
return rq->tag != -1;
}
diff --git a/block/blk-mq.h b/block/blk-mq.h
index e7d1da4b1f73..d0c72d7d07c8 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -196,26 +196,25 @@ static inline bool blk_mq_get_dispatch_budget(struct blk_mq_hw_ctx *hctx)
return true;
}
-static inline void __blk_mq_put_driver_tag(struct blk_mq_hw_ctx *hctx,
- struct request *rq)
+static inline void blk_mq_put_driver_tag(struct request *rq)
{
- blk_mq_put_tag(hctx->tags, rq->mq_ctx, rq->tag);
+ struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
+ int tag = rq->tag;
+
+ if (tag < 0)
+ return;
+
rq->tag = -1;
+ if (hctx->sched_tags)
+ blk_mq_put_tag(hctx->tags, rq->mq_ctx, tag);
+
if (rq->rq_flags & RQF_MQ_INFLIGHT) {
rq->rq_flags &= ~RQF_MQ_INFLIGHT;
atomic_dec(&hctx->nr_active);
}
}
-static inline void blk_mq_put_driver_tag(struct request *rq)
-{
- if (rq->tag == -1 || rq->internal_tag == -1)
- return;
-
- __blk_mq_put_driver_tag(rq->mq_hctx, rq);
-}
-
static inline void blk_mq_clear_mq_map(struct blk_mq_queue_map *qmap)
{
int cpu;
diff --git a/block/blk.h b/block/blk.h
index 0a94ec68af32..88f0359faada 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -26,11 +26,6 @@ struct blk_flush_queue {
struct list_head flush_data_in_flight;
struct request *flush_rq;
- /*
- * flush_rq shares tag with this rq, both can't be active
- * at the same time
- */
- struct request *orig_rq;
struct lock_class_key key;
spinlock_t mq_flush_lock;
};
--
2.25.2
next prev parent reply other threads:[~2020-04-18 3:09 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-18 3:09 [PATCH V7 0/9] blk-mq: improvement CPU hotplug Ming Lei
2020-04-18 3:09 ` [PATCH V7 1/9] blk-mq: mark blk_mq_get_driver_tag as static Ming Lei
2020-04-23 7:14 ` Christoph Hellwig
2020-04-18 3:09 ` Ming Lei [this message]
2020-04-23 7:30 ` [PATCH V7 2/9] blk-mq: assign rq->tag in blk_mq_get_driver_tag Christoph Hellwig
2020-04-18 3:09 ` [PATCH V7 3/9] blk-mq: prepare for draining IO when hctx's all CPUs are offline Ming Lei
2020-04-23 7:31 ` Christoph Hellwig
2020-04-18 3:09 ` [PATCH V7 4/9] blk-mq: support rq filter callback when iterating rqs Ming Lei
2020-04-20 10:34 ` John Garry
2020-04-23 7:31 ` Christoph Hellwig
2020-04-23 7:32 ` Christoph Hellwig
2020-04-18 3:09 ` [PATCH V7 5/9] blk-mq: stop to handle IO and drain IO before hctx becomes inactive Ming Lei
2020-04-23 7:38 ` Christoph Hellwig
2020-04-18 3:09 ` [PATCH V7 6/9] block: add blk_end_flush_machinery Ming Lei
2020-04-23 7:40 ` Christoph Hellwig
2020-04-18 3:09 ` [PATCH V7 7/9] blk-mq: re-submit IO in case that hctx is inactive Ming Lei
2020-04-23 7:50 ` Christoph Hellwig
2020-04-23 8:46 ` Ming Lei
2020-04-18 3:09 ` [PATCH V7 8/9] blk-mq: handle requests dispatched from IO scheduler in case of inactive hctx Ming Lei
2020-04-23 7:51 ` Christoph Hellwig
2020-04-18 3:09 ` [PATCH V7 9/9] block: deactivate hctx when the hctx is actually inactive Ming Lei
2020-04-20 10:29 ` [PATCH V7 0/9] blk-mq: improvement CPU hotplug John Garry
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200418030925.31996-3-ming.lei@redhat.com \
--to=ming.lei@redhat.com \
--cc=axboe@kernel.dk \
--cc=bvanassche@acm.org \
--cc=hare@suse.com \
--cc=hch@lst.de \
--cc=john.garry@huawei.com \
--cc=linux-block@vger.kernel.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.