@@ -343,12 +343,19 @@ void __blk_queue_split(struct request_queue *q, struct bio **bio,
if (split) {
/* there isn't chance to merge the splitted bio */
- split->bi_opf |= REQ_NOMERGE;
+ split->bi_opf |= (REQ_NOMERGE | REQ_SPLIT);
+ if ((*bio)->bi_opf & REQ_SPLIT)
+ split->bi_opf |= REQ_PREEMPT;
+ else
+ (*bio)->bi_opf |= REQ_SPLIT;
bio_chain(split, *bio);
trace_block_split(split, (*bio)->bi_iter.bi_sector);
submit_bio_noacct(*bio);
*bio = split;
+ } else {
+ if ((*bio)->bi_opf & REQ_SPLIT)
+ (*bio)->bi_opf |= REQ_PREEMPT;
}
}
@@ -2737,6 +2737,7 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q,
.q = q,
.nr_tags = 1,
.cmd_flags = bio->bi_opf,
+ .preemption = (bio->bi_opf & REQ_PREEMPT),
};
struct request *rq;
@@ -418,6 +418,8 @@ enum req_flag_bits {
/* for driver use */
__REQ_DRV,
__REQ_SWAP, /* swapping request. */
+ __REQ_SPLIT,
+ __REQ_PREEMPT,
__REQ_NR_BITS, /* stops here */
};
@@ -443,6 +445,8 @@ enum req_flag_bits {
#define REQ_DRV (1ULL << __REQ_DRV)
#define REQ_SWAP (1ULL << __REQ_SWAP)
+#define REQ_SPLIT (1ULL << __REQ_SPLIT)
+#define REQ_PREEMPT (1ULL << __REQ_PREEMPT)
#define REQ_FAILFAST_MASK \
(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
For HDD, sequential io is much faster than random io, thus it's better to issue split io continuously. However, this is broken when tag preemption is disabled, because wakers can only get one tag each time. Thus tag preemption should be disabled for split bios, specifically the first bio won't preempt tag, and following split bios will preempt tag. Signed-off-by: Yu Kuai <yukuai3@huawei.com> --- block/blk-merge.c | 9 ++++++++- block/blk-mq.c | 1 + include/linux/blk_types.h | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-)