Ming Lei <ming....@canonical.com> writes:

> The number of bio->bi_phys_segments is always obtained
> during bio splitting, so it is natural to setup it
> just after bio splitting, then we can avoid to compute
> nr_segment again during merge.
>
> Signed-off-by: Ming Lei <ming....@canonical.com>

Reviewed-by: Jeff Moyer <jmo...@redhat.com>

> ---
>  block/blk-merge.c | 29 ++++++++++++++++++++++-------
>  1 file changed, 22 insertions(+), 7 deletions(-)
>
> diff --git a/block/blk-merge.c b/block/blk-merge.c
> index c4e9c37..22293fd 100644
> --- a/block/blk-merge.c
> +++ b/block/blk-merge.c
> @@ -11,13 +11,16 @@
>  
>  static struct bio *blk_bio_discard_split(struct request_queue *q,
>                                        struct bio *bio,
> -                                      struct bio_set *bs)
> +                                      struct bio_set *bs,
> +                                      unsigned *nsegs)
>  {
>       unsigned int max_discard_sectors, granularity;
>       int alignment;
>       sector_t tmp;
>       unsigned split_sectors;
>  
> +     *nsegs = 1;
> +
>       /* Zero-sector (unknown) and one-sector granularities are the same.  */
>       granularity = max(q->limits.discard_granularity >> 9, 1U);
>  
> @@ -51,8 +54,11 @@ static struct bio *blk_bio_discard_split(struct 
> request_queue *q,
>  
>  static struct bio *blk_bio_write_same_split(struct request_queue *q,
>                                           struct bio *bio,
> -                                         struct bio_set *bs)
> +                                         struct bio_set *bs,
> +                                         unsigned *nsegs)
>  {
> +     *nsegs = 1;
> +
>       if (!q->limits.max_write_same_sectors)
>               return NULL;
>  
> @@ -64,7 +70,8 @@ static struct bio *blk_bio_write_same_split(struct 
> request_queue *q,
>  
>  static struct bio *blk_bio_segment_split(struct request_queue *q,
>                                        struct bio *bio,
> -                                      struct bio_set *bs)
> +                                      struct bio_set *bs,
> +                                      unsigned *segs)
>  {
>       struct bio_vec bv, bvprv, *bvprvp = NULL;
>       struct bvec_iter iter;
> @@ -106,22 +113,30 @@ new_segment:
>               sectors += bv.bv_len >> 9;
>       }
>  
> +     *segs = nsegs;
>       return NULL;
>  split:
> +     *segs = nsegs;
>       return bio_split(bio, sectors, GFP_NOIO, bs);
>  }
>  
>  void blk_queue_split(struct request_queue *q, struct bio **bio,
>                    struct bio_set *bs)
>  {
> -     struct bio *split;
> +     struct bio *split, *res;
> +     unsigned nsegs;
>  
>       if ((*bio)->bi_rw & REQ_DISCARD)
> -             split = blk_bio_discard_split(q, *bio, bs);
> +             split = blk_bio_discard_split(q, *bio, bs, &nsegs);
>       else if ((*bio)->bi_rw & REQ_WRITE_SAME)
> -             split = blk_bio_write_same_split(q, *bio, bs);
> +             split = blk_bio_write_same_split(q, *bio, bs, &nsegs);
>       else
> -             split = blk_bio_segment_split(q, *bio, q->bio_split);
> +             split = blk_bio_segment_split(q, *bio, q->bio_split, &nsegs);
> +
> +     /* physical segments can be figured out during splitting */
> +     res = split ? split : *bio;
> +     res->bi_phys_segments = nsegs;
> +     bio_set_flag(res, BIO_SEG_VALID);
>  
>       if (split) {
>               bio_chain(split, *bio);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to