Add one req flag REQ_TAG which will be used in the following patch for
supporting bio based IO polling.

Exactly this flag can help us to do:

1) request flag is cloned in bio_fast_clone(), so if we mark one FS bio
as REQ_TAG, all bios cloned from this FS bio will be marked as REQ_TAG.

2)create per-task io polling context if the bio based queue supports polling
and the submitted bio is HIPRI. This per-task io polling context will be
created during submit_bio() before marking this HIPRI bio as REQ_TAG. Then
we can avoid to create such io polling context if one cloned bio with REQ_TAG
is submitted from another kernel context.

3) for supporting bio based io polling, we need to poll IOs from all
underlying queues of bio device/driver, this way help us to recognize which
IOs need to polled in bio based style, which will be implemented in next
patch.

Signed-off-by: Ming Lei <[email protected]>
---
 block/blk-core.c          | 29 +++++++++++++++++++++++++++--
 include/linux/blk_types.h |  4 ++++
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 0b00c21cbefb..efc7a61a84b4 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -840,11 +840,30 @@ static inline bool blk_queue_support_bio_poll(struct 
request_queue *q)
 static inline void blk_bio_poll_preprocess(struct request_queue *q,
                struct bio *bio)
 {
+       bool mq;
+
        if (!(bio->bi_opf & REQ_HIPRI))
                return;
 
-       if (!blk_queue_poll(q) || (!queue_is_mq(q) && !blk_get_bio_poll_ctx()))
+       /*
+        * Can't support bio based IO poll without per-task poll queue
+        *
+        * Now we have created per-task io poll context, and mark this
+        * bio as REQ_TAG, so: 1) if any cloned bio from this bio is
+        * submitted from another kernel context, we won't create bio
+        * poll context for it, so that bio will be completed by IRQ;
+        * 2) If such bio is submitted from current context, we will
+        * complete it via blk_poll(); 3) If driver knows that one
+        * underlying bio allocated from driver is for FS bio, meantime
+        * it is submitted in current context, driver can mark such bio
+        * as REQ_TAG manually, so the bio can be completed via blk_poll
+        * too.
+        */
+       mq = queue_is_mq(q);
+       if (!blk_queue_poll(q) || (!mq && !blk_get_bio_poll_ctx()))
                bio->bi_opf &= ~REQ_HIPRI;
+       else if (!mq)
+               bio->bi_opf |= REQ_TAG;
 }
 
 static noinline_for_stack bool submit_bio_checks(struct bio *bio)
@@ -893,9 +912,15 @@ static noinline_for_stack bool submit_bio_checks(struct 
bio *bio)
 
        /*
         * Created per-task io poll queue if we supports bio polling
-        * and it is one HIPRI bio.
+        * and it is one HIPRI bio, and this HIPRI bio has to be from
+        * FS. If REQ_TAG isn't set for HIPRI bio, we think it originated
+        * from FS.
+        *
+        * Driver may allocated bio by itself and REQ_TAG is set, but they
+        * won't be marked as HIPRI.
         */
        blk_create_io_context(q, blk_queue_support_bio_poll(q) &&
+                       !(bio->bi_opf & REQ_TAG) &&
                        (bio->bi_opf & REQ_HIPRI));
 
        blk_bio_poll_preprocess(q, bio);
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index db026b6ec15a..a1bcade4bcc3 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -394,6 +394,9 @@ enum req_flag_bits {
 
        __REQ_HIPRI,
 
+       /* for marking IOs originated from same FS bio in same context */
+       __REQ_TAG,
+
        /* for driver use */
        __REQ_DRV,
        __REQ_SWAP,             /* swapping request. */
@@ -418,6 +421,7 @@ enum req_flag_bits {
 
 #define REQ_NOUNMAP            (1ULL << __REQ_NOUNMAP)
 #define REQ_HIPRI              (1ULL << __REQ_HIPRI)
+#define REQ_TAG                        (1ULL << __REQ_TAG)
 
 #define REQ_DRV                        (1ULL << __REQ_DRV)
 #define REQ_SWAP               (1ULL << __REQ_SWAP)
-- 
2.29.2

--
dm-devel mailing list
[email protected]
https://listman.redhat.com/mailman/listinfo/dm-devel

Reply via email to