All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: Jens Axboe <axboe@kernel.dk>
Cc: Jeffle Xu <jefflexu@linux.alibaba.com>,
	Ming Lei <ming.lei@redhat.com>,
	Damien Le Moal <Damien.LeMoal@wdc.com>,
	linux-block@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: [PATCH 06/12] blk-mq: refactor hybrid polling
Date: Mon, 26 Apr 2021 15:48:15 +0200	[thread overview]
Message-ID: <20210426134821.2191160-7-hch@lst.de> (raw)
In-Reply-To: <20210426134821.2191160-1-hch@lst.de>

Refactor the hybrid polling logic by moving the request lookup into a
helper, and the check if hybrid polling is enabled into blk_poll, and
then merging blk_mq_poll_hybrid and blk_mq_poll_hybrid_sleep into a
single function.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 block/blk-mq.c | 65 +++++++++++++++++++-------------------------------
 1 file changed, 25 insertions(+), 40 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 3dde5e7b2251..15a8bfd27aa2 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -69,6 +69,14 @@ static inline struct blk_mq_hw_ctx *blk_qc_to_hctx(struct request_queue *q,
 	return q->queue_hw_ctx[(qc & ~BLK_QC_T_INTERNAL) >> BLK_QC_T_SHIFT];
 }
 
+static inline struct request *blk_qc_to_rq(struct blk_mq_hw_ctx *hctx,
+		blk_qc_t qc)
+{
+	if (blk_qc_t_is_internal(qc))
+		return blk_mq_tag_to_rq(hctx->sched_tags, blk_qc_t_to_tag(qc));
+	return blk_mq_tag_to_rq(hctx->tags, blk_qc_t_to_tag(qc));
+}
+
 /*
  * Check if any of the ctx, dispatch list or elevator
  * have pending work in this hardware queue.
@@ -3781,15 +3789,20 @@ static unsigned long blk_mq_poll_nsecs(struct request_queue *q,
 	return ret;
 }
 
-static bool blk_mq_poll_hybrid_sleep(struct request_queue *q,
-				     struct request *rq)
+static bool blk_mq_poll_hybrid(struct request_queue *q, blk_qc_t qc)
 {
+	struct blk_mq_hw_ctx *hctx = blk_qc_to_hctx(q, qc);
+	struct request *rq = blk_qc_to_rq(hctx, qc);
 	struct hrtimer_sleeper hs;
 	enum hrtimer_mode mode;
 	unsigned int nsecs;
 	ktime_t kt;
 
-	if (rq->rq_flags & RQF_MQ_POLL_SLEPT)
+	/*
+	 * If a request has completed on queue that uses an I/O scheduler, we
+	 * won't get back a request from blk_qc_to_rq.
+	 */
+	if (!rq || (rq->rq_flags & RQF_MQ_POLL_SLEPT))
 		return false;
 
 	/*
@@ -3834,31 +3847,6 @@ static bool blk_mq_poll_hybrid_sleep(struct request_queue *q,
 	return true;
 }
 
-static bool blk_mq_poll_hybrid(struct request_queue *q,
-			       struct blk_mq_hw_ctx *hctx, blk_qc_t cookie)
-{
-	struct request *rq;
-
-	if (q->poll_nsec == BLK_MQ_POLL_CLASSIC)
-		return false;
-
-	if (!blk_qc_t_is_internal(cookie))
-		rq = blk_mq_tag_to_rq(hctx->tags, blk_qc_t_to_tag(cookie));
-	else {
-		rq = blk_mq_tag_to_rq(hctx->sched_tags, blk_qc_t_to_tag(cookie));
-		/*
-		 * With scheduling, if the request has completed, we'll
-		 * get a NULL return here, as we clear the sched tag when
-		 * that happens. The request still remains valid, like always,
-		 * so we should be safe with just the NULL check.
-		 */
-		if (!rq)
-			return false;
-	}
-
-	return blk_mq_poll_hybrid_sleep(q, rq);
-}
-
 static int blk_mq_poll_classic(struct request_queue *q, blk_qc_t qc, bool spin)
 {
 	struct blk_mq_hw_ctx *hctx = blk_qc_to_hctx(q, qc);
@@ -3906,8 +3894,6 @@ static int blk_mq_poll_classic(struct request_queue *q, blk_qc_t qc, bool spin)
  */
 int blk_poll(struct request_queue *q, blk_qc_t cookie, bool spin)
 {
-	struct blk_mq_hw_ctx *hctx;
-
 	if (!blk_qc_t_valid(cookie) ||
 	    !test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
 		return 0;
@@ -3915,18 +3901,17 @@ int blk_poll(struct request_queue *q, blk_qc_t cookie, bool spin)
 	if (current->plug)
 		blk_flush_plug_list(current->plug, false);
 
-	hctx = blk_qc_to_hctx(q, cookie);
-
 	/*
-	 * If we sleep, have the caller restart the poll loop to reset
-	 * the state. Like for the other success return cases, the
-	 * caller is responsible for checking if the IO completed. If
-	 * the IO isn't complete, we'll get called again and will go
-	 * straight to the busy poll loop. If specified not to spin,
-	 * we also should not sleep.
+	 * If we sleep, have the caller restart the poll loop to reset the
+	 * state.  Like for the other success return cases, the caller is
+	 * responsible for checking if the IO completed.  If the IO isn't
+	 * complete, we'll get called again and will go straight to the busy
+	 * poll loop. If specified not to spin, we also should not sleep.
 	 */
-	if (spin && blk_mq_poll_hybrid(q, hctx, cookie))
-		return 1;
+	if (spin && q->poll_nsec != BLK_MQ_POLL_CLASSIC) {
+		if (blk_mq_poll_hybrid(q, cookie))
+			return 1;
+	}
 	return blk_mq_poll_classic(q, cookie, spin);
 }
 EXPORT_SYMBOL_GPL(blk_poll);
-- 
2.30.1


  parent reply	other threads:[~2021-04-26 13:55 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-26 13:48 switch block layer polling to a bio based model Christoph Hellwig
2021-04-26 13:48 ` [PATCH 01/12] direct-io: remove blk_poll support Christoph Hellwig
2021-04-26 13:48 ` [PATCH 02/12] block: don't try to poll multi-bio I/Os in __blkdev_direct_IO Christoph Hellwig
2021-04-26 13:48 ` [PATCH 03/12] iomap: don't try to poll multi-bio I/Os in __iomap_dio_rw Christoph Hellwig
2021-04-26 13:48 ` [PATCH 04/12] blk-mq: factor out a "classic" poll helper Christoph Hellwig
2021-04-26 13:48 ` [PATCH 05/12] blk-mq: factor out a blk_qc_to_hctx helper Christoph Hellwig
2021-04-26 13:48 ` Christoph Hellwig [this message]
2021-04-26 13:48 ` [PATCH 07/12] blk-mq: remove blk_qc_t_to_tag and blk_qc_t_is_internal Christoph Hellwig
2021-04-26 13:48 ` [PATCH 08/12] blk-mq: remove blk_qc_t_valid Christoph Hellwig
2021-04-26 13:48 ` [PATCH 09/12] block: rename REQ_HIPRI to REQ_POLLED Christoph Hellwig
2021-04-26 13:48 ` [PATCH 10/12] block: RCU free polled bios Christoph Hellwig
2021-04-26 13:48 ` [PATCH 11/12] block: define 'struct bvec_iter' as packed Christoph Hellwig
2021-04-26 13:48 ` [PATCH 12/12] block: switch polling to be bio based Christoph Hellwig
2021-04-26 15:27   ` Ming Lei
2021-04-26 14:57 ` switch block layer polling to a bio based model Jens Axboe
2021-04-26 15:06   ` Christoph Hellwig
2021-04-26 15:12     ` Jens Axboe
2021-04-26 16:15       ` Christoph Hellwig
2021-04-26 16:48         ` Jens Axboe
2021-04-26 17:05   ` Christoph Hellwig
2021-04-26 17:18     ` Jens Axboe

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=20210426134821.2191160-7-hch@lst.de \
    --to=hch@lst.de \
    --cc=Damien.LeMoal@wdc.com \
    --cc=axboe@kernel.dk \
    --cc=jefflexu@linux.alibaba.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=ming.lei@redhat.com \
    /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.