[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