[dm-devel] [RFC PATCH V2 05/13] block: add req flag of REQ_TAG
Ming Lei
ming.lei at redhat.com
Thu Mar 18 16:48:19 UTC 2021
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 <ming.lei at redhat.com>
---
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
More information about the dm-devel
mailing list