diff mbox series

[PATCHv3,5/6] block/bounce: count bytes instead of sectors

Message ID 20220523210119.2500150-6-kbusch@fb.com (mailing list archive)
State New, archived
Headers show
Series direct io dma alignment | expand

Commit Message

Keith Busch May 23, 2022, 9:01 p.m. UTC
From: Keith Busch <kbusch@kernel.org>

Individual bv_len's may not be a sector size.

Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 block/bounce.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Comments

Christoph Hellwig May 24, 2022, 6:09 a.m. UTC | #1
On Mon, May 23, 2022 at 02:01:18PM -0700, Keith Busch wrote:
> From: Keith Busch <kbusch@kernel.org>
> 
> Individual bv_len's may not be a sector size.
> 
> Signed-off-by: Keith Busch <kbusch@kernel.org>
> ---
>  block/bounce.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/block/bounce.c b/block/bounce.c
> index 8f7b6fe3b4db..20a43c4dbdda 100644
> --- a/block/bounce.c
> +++ b/block/bounce.c
> @@ -207,17 +207,18 @@ void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig)
>  	struct bvec_iter iter;
>  	unsigned i = 0;
>  	bool bounce = false;
> -	int sectors = 0;
> +	int sectors = 0, bytes = 0;
>  
>  	bio_for_each_segment(from, *bio_orig, iter) {
>  		if (i++ < BIO_MAX_VECS)
> -			sectors += from.bv_len >> 9;
> +			bytes += from.bv_len;
>  		if (PageHighMem(from.bv_page))
>  			bounce = true;
>  	}
>  	if (!bounce)
>  		return;
>  
> +	sectors = ALIGN_DOWN(bytes, queue_logical_block_size(q)) >> 9;

Same comment about SECTOR_SHIFT and a comment here.  That being said,
why do we even align here?  Shouldn't bytes always be setor aligned here
and this should be a WARN_ON or other sanity check?  Probably the same
for the previous patch.
Pankaj Raghav May 24, 2022, 2:32 p.m. UTC | #2
On Mon, May 23, 2022 at 02:01:18PM -0700, Keith Busch wrote:
> From: Keith Busch <kbusch@kernel.org>
> 
> Individual bv_len's may not be a sector size.
> 
> Signed-off-by: Keith Busch <kbusch@kernel.org>
> ---
>  block/bounce.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/block/bounce.c b/block/bounce.c
> index 8f7b6fe3b4db..20a43c4dbdda 100644
> --- a/block/bounce.c
> +++ b/block/bounce.c
> @@ -207,17 +207,18 @@ void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig)
>  	struct bvec_iter iter;
>  	unsigned i = 0;
>  	bool bounce = false;
> -	int sectors = 0;
> +	int sectors = 0, bytes = 0;
>  
>  	bio_for_each_segment(from, *bio_orig, iter) {
>  		if (i++ < BIO_MAX_VECS)
> -			sectors += from.bv_len >> 9;
> +			bytes += from.bv_len;
bv.len is unsigned int. bytes variable should also unsigned int to be on
the safe side.

>  		if (PageHighMem(from.bv_page))
>  			bounce = true;
>  	}
>  	if (!bounce)
>  		return;
>  
> +	sectors = ALIGN_DOWN(bytes, queue_logical_block_size(q)) >> 9;
>  	if (sectors < bio_sectors(*bio_orig)) {
>  		bio = bio_split(*bio_orig, sectors, GFP_NOIO, &bounce_bio_split);
>  		bio_chain(bio, *bio_orig);
> -- 
> 2.30.2
>
Keith Busch May 25, 2022, 2:08 p.m. UTC | #3
On Tue, May 24, 2022 at 08:09:21AM +0200, Christoph Hellwig wrote:
> On Mon, May 23, 2022 at 02:01:18PM -0700, Keith Busch wrote:
> > From: Keith Busch <kbusch@kernel.org>
> > 
> > Individual bv_len's may not be a sector size.
> > 
> > Signed-off-by: Keith Busch <kbusch@kernel.org>
> > ---
> >  block/bounce.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/block/bounce.c b/block/bounce.c
> > index 8f7b6fe3b4db..20a43c4dbdda 100644
> > --- a/block/bounce.c
> > +++ b/block/bounce.c
> > @@ -207,17 +207,18 @@ void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig)
> >  	struct bvec_iter iter;
> >  	unsigned i = 0;
> >  	bool bounce = false;
> > -	int sectors = 0;
> > +	int sectors = 0, bytes = 0;
> >  
> >  	bio_for_each_segment(from, *bio_orig, iter) {
> >  		if (i++ < BIO_MAX_VECS)
> > -			sectors += from.bv_len >> 9;
> > +			bytes += from.bv_len;
> >  		if (PageHighMem(from.bv_page))
> >  			bounce = true;
> >  	}
> >  	if (!bounce)
> >  		return;
> >  
> > +	sectors = ALIGN_DOWN(bytes, queue_logical_block_size(q)) >> 9;
> 
> Same comment about SECTOR_SHIFT and a comment here.  That being said,
> why do we even align here?  Shouldn't bytes always be setor aligned here
> and this should be a WARN_ON or other sanity check?  Probably the same
> for the previous patch.

Yes, the total bytes should be sector aligned.

I'm not exactly sure why we're counting it this way, though. We could just skip
the iterative addition and get the total from bio->bi_iter.bi_size. Unless
bio_orig has more segments that BIO_MAX_VECS, which doesn't seem possible.
Keith Busch May 25, 2022, 2:17 p.m. UTC | #4
On Wed, May 25, 2022 at 08:08:07AM -0600, Keith Busch wrote:
> On Tue, May 24, 2022 at 08:09:21AM +0200, Christoph Hellwig wrote:
> > >  	bio_for_each_segment(from, *bio_orig, iter) {
> > >  		if (i++ < BIO_MAX_VECS)
> > > -			sectors += from.bv_len >> 9;
> > > +			bytes += from.bv_len;
> > >  		if (PageHighMem(from.bv_page))
> > >  			bounce = true;
> > >  	}
> > >  	if (!bounce)
> > >  		return;
> > >  
> > > +	sectors = ALIGN_DOWN(bytes, queue_logical_block_size(q)) >> 9;
> > 
> > Same comment about SECTOR_SHIFT and a comment here.  That being said,
> > why do we even align here?  Shouldn't bytes always be setor aligned here
> > and this should be a WARN_ON or other sanity check?  Probably the same
> > for the previous patch.
> 
> Yes, the total bytes should be sector aligned.
> 
> I'm not exactly sure why we're counting it this way, though. We could just skip
> the iterative addition and get the total from bio->bi_iter.bi_size. Unless
> bio_orig has more segments that BIO_MAX_VECS, which doesn't seem possible.

Oh, there's a comment explaining the original can have more than BIO_MAX_VECS,
so the ALIGN_DOWN is necessary to ensure a logical block sized split.
diff mbox series

Patch

diff --git a/block/bounce.c b/block/bounce.c
index 8f7b6fe3b4db..20a43c4dbdda 100644
--- a/block/bounce.c
+++ b/block/bounce.c
@@ -207,17 +207,18 @@  void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig)
 	struct bvec_iter iter;
 	unsigned i = 0;
 	bool bounce = false;
-	int sectors = 0;
+	int sectors = 0, bytes = 0;
 
 	bio_for_each_segment(from, *bio_orig, iter) {
 		if (i++ < BIO_MAX_VECS)
-			sectors += from.bv_len >> 9;
+			bytes += from.bv_len;
 		if (PageHighMem(from.bv_page))
 			bounce = true;
 	}
 	if (!bounce)
 		return;
 
+	sectors = ALIGN_DOWN(bytes, queue_logical_block_size(q)) >> 9;
 	if (sectors < bio_sectors(*bio_orig)) {
 		bio = bio_split(*bio_orig, sectors, GFP_NOIO, &bounce_bio_split);
 		bio_chain(bio, *bio_orig);