All of lore.kernel.org
 help / color / mirror / Atom feed
From: chengming.zhou@linux.dev
To: axboe@kernel.dk, hch@lst.de, ming.lei@redhat.com
Cc: linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
	zhouchengming@bytedance.com
Subject: [PATCH 2/2] blk-flush: don't need to end rq twice for non post-flush requests
Date: Mon, 10 Jul 2023 14:47:05 +0800	[thread overview]
Message-ID: <20230710064705.1847287-2-chengming.zhou@linux.dev> (raw)
In-Reply-To: <20230710064705.1847287-1-chengming.zhou@linux.dev>

From: Chengming Zhou <zhouchengming@bytedance.com>

Now we unconditionally blk_rq_init_flush() to replace rq->end_io to
make rq return twice back to the flush state machine for post-flush.

Obviously, non post-flush requests don't need it, they don't need to
end request twice, so they don't need to replace rq->end_io callback.
And the same for requests with the FUA bit on hardware with FUA support.

So we move blk_rq_init_flush() to REQ_FSEQ_DATA stage and only replace
rq->end_io if it needs post-flush. Otherwise, it can end like normal
request and doesn't need to return back to the flush state machine.

There are also some other good points:
1. all requests on hardware with FUA support won't have post-flush, so
   all of them don't need to end twice.

2. non post-flush requests won't have RQF_FLUSH_SEQ rq_flags set, so
   they can merge like normal requests.

3. we don't account non post-flush requests in flush_data_in_flight,
   since there is no point to defer pending flush for these requests.

Signed-off-by: Chengming Zhou <zhouchengming@bytedance.com>
---
 block/blk-flush.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/block/blk-flush.c b/block/blk-flush.c
index 094a6adb2718..1b92654e8757 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -93,6 +93,7 @@ enum {
 
 static void blk_kick_flush(struct request_queue *q,
 			   struct blk_flush_queue *fq, blk_opf_t flags);
+static void blk_rq_init_flush(struct request *rq);
 
 static inline struct blk_flush_queue *
 blk_get_flush_queue(struct request_queue *q, struct blk_mq_ctx *ctx)
@@ -187,7 +188,15 @@ static void blk_flush_complete_seq(struct request *rq,
 		break;
 
 	case REQ_FSEQ_DATA:
-		fq->flush_data_in_flight++;
+		/*
+		 * Only for requests that need post-flush,
+		 * we need to do rq->end_io replacement trick
+		 * to return back to the flush state machine.
+		 */
+		if (!(rq->flush.seq & REQ_FSEQ_POSTFLUSH)) {
+			blk_rq_init_flush(rq);
+			fq->flush_data_in_flight++;
+		}
 		spin_lock(&q->requeue_lock);
 		list_move_tail(&rq->queuelist, &q->flush_list);
 		spin_unlock(&q->requeue_lock);
@@ -202,7 +211,13 @@ static void blk_flush_complete_seq(struct request *rq,
 		 * normal completion and end it.
 		 */
 		list_del_init(&rq->queuelist);
-		blk_flush_restore_request(rq);
+		/*
+		 * Only for requests that had rq->end_io replaced,
+		 * we need to restore rq->end_io and make it a normal
+		 * request before the second end.
+		 */
+		if (rq->rq_flags & RQF_FLUSH_SEQ)
+			blk_flush_restore_request(rq);
 		blk_mq_end_request(rq, error);
 		break;
 
@@ -389,7 +404,6 @@ static enum rq_end_io_ret mq_flush_data_end_io(struct request *rq,
 
 static void blk_rq_init_flush(struct request *rq)
 {
-	rq->flush.seq = 0;
 	rq->rq_flags |= RQF_FLUSH_SEQ;
 	rq->flush.saved_end_io = rq->end_io; /* Usually NULL */
 	rq->end_io = mq_flush_data_end_io;
@@ -424,6 +438,7 @@ bool blk_insert_flush(struct request *rq)
 	 * the request accounting.
 	 */
 	rq->cmd_flags |= REQ_SYNC;
+	rq->flush.seq = 0;
 
 	switch (policy) {
 	case 0:
@@ -458,7 +473,6 @@ bool blk_insert_flush(struct request *rq)
 		 * Mark the request as part of a flush sequence and submit it
 		 * for further processing to the flush state machine.
 		 */
-		blk_rq_init_flush(rq);
 		spin_lock_irq(&fq->mq_flush_lock);
 		blk_flush_complete_seq(rq, fq, REQ_FSEQ_ACTIONS & ~policy, 0);
 		spin_unlock_irq(&fq->mq_flush_lock);
-- 
2.41.0


  reply	other threads:[~2023-07-10  6:47 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-10  6:47 [PATCH 1/2] blk-flush: fix rq->flush.seq for post-flush requests chengming.zhou
2023-07-10  6:47 ` chengming.zhou [this message]
2023-07-10 13:33   ` [PATCH 2/2] blk-flush: don't need to end rq twice for non " Christoph Hellwig
2023-07-25 13:15     ` Chengming Zhou
2023-07-10 13:30 ` [PATCH 1/2] blk-flush: fix rq->flush.seq for " Christoph Hellwig
2023-07-11 11:06   ` Chengming Zhou
2023-07-11 11:15     ` [External] " Chengming Zhou
2023-07-11 11:31     ` Christoph Hellwig
2023-07-11 11:52       ` Chengming Zhou
2023-07-11 12:09         ` Christoph Hellwig

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=20230710064705.1847287-2-chengming.zhou@linux.dev \
    --to=chengming.zhou@linux.dev \
    --cc=axboe@kernel.dk \
    --cc=hch@lst.de \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ming.lei@redhat.com \
    --cc=zhouchengming@bytedance.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.