[SRU][Xenial][Yakkety][PATCH 1/1] block: relax check on sg gap
Colin Ian King
colin.king at canonical.com
Thu Apr 13 11:45:46 UTC 2017
On 13/04/17 11:45, Joseph Salisbury wrote:
> From: Ming Lei <ming.lei at canonical.com>
>
> BugLink: http://bugs.launchpad.net/bugs/1682215
>
> 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.
>
> Reported-by: Vitaly Kuznetsov <vkuznets at redhat.com>
> Reported-by: Dexuan Cui <decui at microsoft.com>
> Tested-by: Dexuan Cui <decui at microsoft.com>
> Cc: Keith Busch <keith.busch at intel.com>
> Signed-off-by: Ming Lei <ming.lei at canonical.com>
> Signed-off-by: Jens Axboe <axboe at fb.com>
> (cherry picked from commit 729204ef49ec00b788ce23deb9eb922a5769f55d)
> Signed-off-by: Joseph Salisbury <joseph.salisbury at canonical.com>
> ---
> include/linux/blkdev.h | 22 +++++++++++++++++++++-
> 1 file changed, 21 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index f28a95a..a0b6aae 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -1387,6 +1387,25 @@ static inline bool bvec_gap_to_prev(struct request_queue *q,
> return __bvec_gap_to_prev(q, bprv, offset);
> }
>
> +/*
> + * Check if the two bvecs from two bios can be merged to one segment.
> + * If yes, no need to check gap between the two bios since the 1st bio
> + * and the 1st bvec in the 2nd bio can be handled in one segment.
> + */
> +static inline bool bios_segs_mergeable(struct request_queue *q,
> + struct bio *prev, struct bio_vec *prev_last_bv,
> + struct bio_vec *next_first_bv)
> +{
> + if (!BIOVEC_PHYS_MERGEABLE(prev_last_bv, next_first_bv))
> + return false;
> + if (!BIOVEC_SEG_BOUNDARY(q, prev_last_bv, next_first_bv))
> + return false;
> + if (prev->bi_seg_back_size + next_first_bv->bv_len >
> + queue_max_segment_size(q))
> + return false;
> + return true;
> +}
> +
> static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
> struct bio *next)
> {
> @@ -1396,7 +1415,8 @@ static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
> bio_get_last_bvec(prev, &pb);
> bio_get_first_bvec(next, &nb);
>
> - return __bvec_gap_to_prev(q, &pb, nb.bv_offset);
> + if (!bios_segs_mergeable(q, prev, &pb, &nb))
> + return __bvec_gap_to_prev(q, &pb, nb.bv_offset);
> }
>
> return false;
>
Good test results, it's a clean cherry pick from upstream that has been
around for a few months and hence given some testing upstream.
Acked-by: Colin Ian King <colin.king at canonical.com>
More information about the kernel-team
mailing list