Skip to content

Commit

Permalink
block: avoid blk_bio_segment_split for small I/O operations
Browse files Browse the repository at this point in the history
__blk_queue_split() adds significant overhead for small I/O operations.
Add a shortcut to avoid it for cases where we know we never need to
split.

Based on a patch from Ming Lei.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Christoph Hellwig authored and Jens Axboe committed Nov 5, 2019
1 parent d2c9be8 commit fa53228
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion block/blk-merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
void __blk_queue_split(struct request_queue *q, struct bio **bio,
unsigned int *nr_segs)
{
struct bio *split;
struct bio *split = NULL;

switch (bio_op(*bio)) {
case REQ_OP_DISCARD:
Expand All @@ -309,6 +309,20 @@ void __blk_queue_split(struct request_queue *q, struct bio **bio,
nr_segs);
break;
default:
/*
* All drivers must accept single-segments bios that are <=
* PAGE_SIZE. This is a quick and dirty check that relies on
* the fact that bi_io_vec[0] is always valid if a bio has data.
* The check might lead to occasional false negatives when bios
* are cloned, but compared to the performance impact of cloned
* bios themselves the loop below doesn't matter anyway.
*/
if (!q->limits.chunk_sectors &&
(*bio)->bi_vcnt == 1 &&
(*bio)->bi_io_vec[0].bv_len <= PAGE_SIZE) {
*nr_segs = 1;
break;
}
split = blk_bio_segment_split(q, *bio, &q->bio_split, nr_segs);
break;
}
Expand Down

0 comments on commit fa53228

Please sign in to comment.