Skip to content

Commit e36f620

Browse files
Keith Buschaxboe
authored andcommitted
block: split bios to max possible length
This splits bio in the middle of a vector to form the largest possible bio at the h/w's desired alignment, and guarantees the bio being split will have some data. The criteria for splitting is changed from the max sectors to the h/w's optimal sector alignment if it is provided. For h/w that advertise their block storage's underlying chunk size, it's a big performance win to not submit commands that cross them. If sector alignment is not provided, this patch uses the max sectors as before. This addresses the performance issue commit d380561 attempted to fix, but was reverted due to splitting logic error. Signed-off-by: Keith Busch <keith.busch@intel.com> Cc: Jens Axboe <axboe@fb.com> Cc: Ming Lei <tom.leiming@gmail.com> Cc: Kent Overstreet <kent.overstreet@gmail.com> Cc: <stable@vger.kernel.org> # 4.4.x- Signed-off-by: Jens Axboe <axboe@fb.com>
1 parent cda2264 commit e36f620

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

block/blk-merge.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,29 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
8383
struct bio *new = NULL;
8484

8585
bio_for_each_segment(bv, bio, iter) {
86-
if (sectors + (bv.bv_len >> 9) > queue_max_sectors(q))
87-
goto split;
88-
8986
/*
9087
* If the queue doesn't support SG gaps and adding this
9188
* offset would create a gap, disallow it.
9289
*/
9390
if (bvprvp && bvec_gap_to_prev(q, bvprvp, bv.bv_offset))
9491
goto split;
9592

93+
if (sectors + (bv.bv_len >> 9) >
94+
blk_max_size_offset(q, bio->bi_iter.bi_sector)) {
95+
/*
96+
* Consider this a new segment if we're splitting in
97+
* the middle of this vector.
98+
*/
99+
if (nsegs < queue_max_segments(q) &&
100+
sectors < blk_max_size_offset(q,
101+
bio->bi_iter.bi_sector)) {
102+
nsegs++;
103+
sectors = blk_max_size_offset(q,
104+
bio->bi_iter.bi_sector);
105+
}
106+
goto split;
107+
}
108+
96109
if (bvprvp && blk_queue_cluster(q)) {
97110
if (seg_size + bv.bv_len > queue_max_segment_size(q))
98111
goto new_segment;

0 commit comments

Comments
 (0)