public inbox for [email protected]
 help / color / mirror / Atom feed
From: Jeffle Xu <[email protected]>
To: [email protected], [email protected]
Cc: [email protected], [email protected],
	[email protected], [email protected],
	[email protected], [email protected]
Subject: [PATCH v5 11/12] block: sub-fastpath for bio-based polling
Date: Wed,  3 Mar 2021 19:57:39 +0800	[thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>

Offer one sub-fastpath for bio-based polling when bio submitted to dm
device gets split and enqueued into multiple hw queues, while the IO
submission process has not been migrated to another CPU.

In this case, the IO submission routine will return the CPU number on
which the IO submission happened as the returned cookie, while the
polling routine will only iterate and poll on hw queues that this CPU
number maps, instead of iterating *all* hw queues.

This optimization can dramatically reduce cache ping-pong and thus
improve the polling performance, when multiple hw queues in polling mode
per device could be reserved when there are multiple polling processes.

It will fall back to iterating all hw queues in polling mode, once the
process has ever been migrated to another CPU during the IO submission
phase.

Signed-off-by: Jeffle Xu <[email protected]>
---
 block/blk-core.c          | 18 ++++++++++++++++--
 include/linux/blk_types.h | 38 ++++++++++++++++++++++++++++++++++----
 2 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index e5cd4ff08f5c..5479fd74d3be 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -948,7 +948,8 @@ static blk_qc_t __submit_bio_noacct(struct bio *bio)
 	struct bio_list bio_list_on_stack[2];
 	blk_qc_t ret = BLK_QC_T_NONE;
 	struct request_queue *top_q;
-	bool poll_on;
+	bool orig_poll_on, poll_on;
+	u64 old_nr_migrations;
 
 	BUG_ON(bio->bi_next);
 
@@ -958,6 +959,8 @@ static blk_qc_t __submit_bio_noacct(struct bio *bio)
 	top_q = bio->bi_bdev->bd_disk->queue;
 	poll_on = test_bit(QUEUE_FLAG_POLL, &top_q->queue_flags) &&
 		  (bio->bi_opf & REQ_HIPRI);
+	orig_poll_on = poll_on;
+	old_nr_migrations = READ_ONCE(current->se.nr_migrations);
 
 	do {
 		blk_qc_t cookie;
@@ -987,7 +990,7 @@ static blk_qc_t __submit_bio_noacct(struct bio *bio)
 				ret = cookie;
 			} else if (ret != cookie) {
 				/* bio gets split and enqueued to multi hctxs */
-				ret = BLK_QC_T_BIO_POLL_ALL;
+				ret = blk_qc_t_get_by_cpu();
 				poll_on = false;
 			}
 		}
@@ -1014,6 +1017,17 @@ static blk_qc_t __submit_bio_noacct(struct bio *bio)
 
 	current->bio_list = NULL;
 
+	/*
+	 * For cases when bio gets split and enqueued into multi hctxs, return
+	 * the corresponding CPU number when current process has not been
+	 * migrated to another CPU. Return BLK_QC_T_BIO_POLL_ALL otherwise,
+	 * falling back to iterating and polling on all hw queues, since split
+	 * bios are submitted to different CPUs in this case.
+	 */
+	if (orig_poll_on != poll_on &&
+	    old_nr_migrations != READ_ONCE(current->se.nr_migrations))
+		ret = BLK_QC_T_BIO_POLL_ALL;
+
 	return ret;
 }
 
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 8f970e026be9..32de4fb79eff 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -555,8 +555,21 @@ static inline bool blk_qc_t_is_internal(blk_qc_t cookie)
  *                         ^
  *                         reserved for compatibility with mq
  *
- * 2. When @bio gets split and enqueued into multi hw queues, the returned
- *    cookie is just BLK_QC_T_BIO_POLL_ALL flag.
+ * 2. When @bio gets split and enqueued into multi hw queues, and current
+ *    process has *not* been migrated to another CPU, the returned cookie
+ *    actually stores the corresponding CPU number on which the IO submission
+ *    happened. Also with BLK_QC_T_BIO_POLL_CPU flag set.
+ *
+ * 63                    31                         0 (bit)
+ * +----------------------+-----------------------+-+
+ * |          cpu         |                       |1|
+ * +----------------------+-----------------------+-+
+ *                                                 ^
+ *                                                 BLK_QC_T_BIO_POLL_CPU
+ *
+ * 3. When @bio gets split and enqueued into multi hw queues, and current
+ *    process has ever been migrated to another CPU, the returned cookie is just
+ *    BLK_QC_T_BIO_POLL_ALL flag.
  *
  * 63                                              0 (bit)
  * +----------------------------------------------+-+
@@ -565,7 +578,7 @@ static inline bool blk_qc_t_is_internal(blk_qc_t cookie)
  *                                                 ^
  *                                                 BLK_QC_T_BIO_POLL_ALL
  *
- * 3. Otherwise, return BLK_QC_T_NONE as the cookie.
+ * 4. Otherwise, return BLK_QC_T_NONE as the cookie.
  *
  * 63                                              0 (bit)
  * +-----------------------------------------------+
@@ -574,12 +587,18 @@ static inline bool blk_qc_t_is_internal(blk_qc_t cookie)
  */
 #define BLK_QC_T_HIGH_SHIFT	32
 #define BLK_QC_T_BIO_POLL_ALL	1U
+#define BLK_QC_T_BIO_POLL_CPU	2U
 
 static inline unsigned int blk_qc_t_to_devt(blk_qc_t cookie)
 {
 	return cookie >> BLK_QC_T_HIGH_SHIFT;
 }
 
+static inline unsigned int blk_qc_t_to_cpu(blk_qc_t cookie)
+{
+	return cookie >> BLK_QC_T_HIGH_SHIFT;
+}
+
 static inline blk_qc_t blk_qc_t_get_by_devt(unsigned int dev,
 					    unsigned int queue_num)
 {
@@ -587,9 +606,20 @@ static inline blk_qc_t blk_qc_t_get_by_devt(unsigned int dev,
 	       (queue_num << BLK_QC_T_SHIFT);
 }
 
+static inline blk_qc_t blk_qc_t_get_by_cpu(void)
+{
+	return ((blk_qc_t)raw_smp_processor_id() << BLK_QC_T_HIGH_SHIFT) |
+	       BLK_QC_T_BIO_POLL_CPU;
+}
+
 static inline bool blk_qc_t_is_poll_multi(blk_qc_t cookie)
 {
-	return cookie & BLK_QC_T_BIO_POLL_ALL;
+	return cookie & (BLK_QC_T_BIO_POLL_ALL | BLK_QC_T_BIO_POLL_CPU);
+}
+
+static inline bool blk_qc_t_is_poll_cpu(blk_qc_t cookie)
+{
+	return cookie & BLK_QC_T_BIO_POLL_CPU;
 }
 
 struct blk_rq_stat {
-- 
2.27.0


  parent reply	other threads:[~2021-03-04  0:26 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-03 11:57 [PATCH v5 00/12] dm: support polling Jeffle Xu
2021-03-03 11:57 ` [PATCH v5 01/12] block: move definition of blk_qc_t to types.h Jeffle Xu
2021-03-03 11:57 ` [PATCH v5 02/12] block: add queue_to_disk() to get gendisk from request_queue Jeffle Xu
2021-03-03 11:57 ` [PATCH v5 03/12] block: add poll method to support bio-based IO polling Jeffle Xu
2021-03-10 22:01   ` Mike Snitzer
2021-03-11  5:31     ` [dm-devel] " JeffleXu
2021-03-03 11:57 ` [PATCH v5 04/12] block: add poll_capable " Jeffle Xu
2021-03-10 22:21   ` Mike Snitzer
2021-03-11  5:43     ` [dm-devel] " JeffleXu
2021-03-03 11:57 ` [PATCH v5 05/12] blk-mq: extract one helper function polling hw queue Jeffle Xu
2021-03-03 11:57 ` [PATCH v5 06/12] blk-mq: add iterator for polling hw queues Jeffle Xu
2021-03-03 11:57 ` [PATCH v5 07/12] blk-mq: add one helper function getting hw queue Jeffle Xu
2021-03-03 11:57 ` [PATCH v5 08/12] dm: always return BLK_QC_T_NONE for bio-based device Jeffle Xu
2021-03-03 11:57 ` [PATCH v5 09/12] nvme/pci: don't wait for locked polling queue Jeffle Xu
2021-03-10 21:57   ` Mike Snitzer
2021-03-03 11:57 ` [PATCH v5 10/12] block: fastpath for bio-based polling Jeffle Xu
2021-03-10 23:18   ` Mike Snitzer
2021-03-11  6:36     ` [dm-devel] " JeffleXu
2021-03-12  2:26       ` JeffleXu
2021-03-11 13:56   ` Ming Lei
2021-03-12  1:56     ` [dm-devel] " JeffleXu
2021-03-03 11:57 ` Jeffle Xu [this message]
2021-03-03 11:57 ` [PATCH v5 12/12] dm: support IO polling for bio-based dm device Jeffle Xu

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=20210303115740.127001-12-jefflexu@linux.alibaba.com \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox