History

block: relax check on sg gap

If the last bvec of the 1st bio and the 1st bvec of the next bio are physically contigious, and the latter can be merged to last segment of the 1st bio, we should think they don't violate sg gap(or virt boundary) limit. Both Vitaly and Dexuan reported lots of unmergeable small bios are observed when running mkfs on Hyper-V virtual storage, and performance becomes quite low. This patch fixes that performance issue. The same issue should exist on NVMe, since it sets virt boundary too.

Ming Lei committed 9 years ago

Commit 729204e1 parent 1661f2e1 file · +21 −1Browse files

Showing the changes to include/linux/blkdev.h (1 of 1 file). Show all

Unified · Split

include/linux/blkdev.h+21−1
@@ -1607,6 +1607,25 @@ static inline bool bvec_gap_to_prev(struct request_queue *q, · 1606 unmodified lines
1607 return __bvec_gap_to_prev(q, bprv, offset);1607 return __bvec_gap_to_prev(q, bprv, offset);
1608}1608}
1609 1609
1610/*
1611 * Check if the two bvecs from two bios can be merged to one segment.
1612 * If yes, no need to check gap between the two bios since the 1st bio
1613 * and the 1st bvec in the 2nd bio can be handled in one segment.
1614 */
1615static inline bool bios_segs_mergeable(struct request_queue *q,
1616 struct bio *prev, struct bio_vec *prev_last_bv,
1617 struct bio_vec *next_first_bv)
1618{
1619 if (!BIOVEC_PHYS_MERGEABLE(prev_last_bv, next_first_bv))
1620 return false;
1621 if (!BIOVEC_SEG_BOUNDARY(q, prev_last_bv, next_first_bv))
1622 return false;
1623 if (prev->bi_seg_back_size + next_first_bv->bv_len >
1624 queue_max_segment_size(q))
1625 return false;
1626 return true;
1627}
1628
1610static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,1629static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
1611 struct bio *next)1630 struct bio *next)
1612{1631{
@@ -1616,7 +1635,8 @@ static inline bool bio_will_gap(struct request_queue *q, struct bio *prev, · 3 unmodified lines
1616 bio_get_last_bvec(prev, &pb);1635 bio_get_last_bvec(prev, &pb);
1617 bio_get_first_bvec(next, &nb);1636 bio_get_first_bvec(next, &nb);
1618 1637
1619 return __bvec_gap_to_prev(q, &pb, nb.bv_offset);1638 if (!bios_segs_mergeable(q, prev, &pb, &nb))
1639 return __bvec_gap_to_prev(q, &pb, nb.bv_offset);
1620 }1640 }
1621 1641
1622 return false;1642 return false;