Skip to content

Commit 5a8d75a

Browse files
Ming Leiaxboe
authored andcommitted
block: fix bio_will_gap() for first bvec with offset
Commit 729204e("block: relax check on sg gap") allows us to merge bios, if both are physically contiguous. This change can merge a huge number of small bios, through mkfs for example, mkfs.ntfs running time can be decreased to ~1/10. But if one rq starts with a non-aligned buffer (the 1st bvec's bv_offset is non-zero) and if we allow the merge, it is quite difficult to respect sg gap limit, especially the max segment size, or we risk having an unaligned virtual boundary. This patch tries to avoid the issue by disallowing a merge, if the req starts with an unaligned buffer. Also add comments to explain why the merged segment can't end in unaligned virt boundary. Fixes: 729204e ("block: relax check on sg gap") Tested-by: Johannes Thumshirn <jthumshirn@suse.de> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Ming Lei <ming.lei@redhat.com> Rewrote parts of the commit message and comments. Signed-off-by: Jens Axboe <axboe@fb.com>
1 parent c6c64a9 commit 5a8d75a

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

include/linux/blkdev.h

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,12 +1672,36 @@ static inline bool bios_segs_mergeable(struct request_queue *q,
16721672
return true;
16731673
}
16741674

1675-
static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
1676-
struct bio *next)
1675+
static inline bool bio_will_gap(struct request_queue *q,
1676+
struct request *prev_rq,
1677+
struct bio *prev,
1678+
struct bio *next)
16771679
{
16781680
if (bio_has_data(prev) && queue_virt_boundary(q)) {
16791681
struct bio_vec pb, nb;
16801682

1683+
/*
1684+
* don't merge if the 1st bio starts with non-zero
1685+
* offset, otherwise it is quite difficult to respect
1686+
* sg gap limit. We work hard to merge a huge number of small
1687+
* single bios in case of mkfs.
1688+
*/
1689+
if (prev_rq)
1690+
bio_get_first_bvec(prev_rq->bio, &pb);
1691+
else
1692+
bio_get_first_bvec(prev, &pb);
1693+
if (pb.bv_offset)
1694+
return true;
1695+
1696+
/*
1697+
* We don't need to worry about the situation that the
1698+
* merged segment ends in unaligned virt boundary:
1699+
*
1700+
* - if 'pb' ends aligned, the merged segment ends aligned
1701+
* - if 'pb' ends unaligned, the next bio must include
1702+
* one single bvec of 'nb', otherwise the 'nb' can't
1703+
* merge with 'pb'
1704+
*/
16811705
bio_get_last_bvec(prev, &pb);
16821706
bio_get_first_bvec(next, &nb);
16831707

@@ -1690,12 +1714,12 @@ static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
16901714

16911715
static inline bool req_gap_back_merge(struct request *req, struct bio *bio)
16921716
{
1693-
return bio_will_gap(req->q, req->biotail, bio);
1717+
return bio_will_gap(req->q, req, req->biotail, bio);
16941718
}
16951719

16961720
static inline bool req_gap_front_merge(struct request *req, struct bio *bio)
16971721
{
1698-
return bio_will_gap(req->q, bio, req->bio);
1722+
return bio_will_gap(req->q, NULL, bio, req->bio);
16991723
}
17001724

17011725
int kblockd_schedule_work(struct work_struct *work);

0 commit comments

Comments
 (0)