diff mbox series

[4/4] block: don't use bio_split_rw on misc operations

Message ID 20240826173820.1690925-5-hch@lst.de (mailing list archive)
State New
Headers show
Series [1/4] block: rework bio splitting | expand

Commit Message

Christoph Hellwig Aug. 26, 2024, 5:37 p.m. UTC
bio_split_rw is designed to split read and write bios with a payload.
Currently it is called by __bio_split_to_limits for all operations not
explicitly list, which works because bio_may_need_split explicitly checks
for bi_vcnt == 1 and thus skips the bypass if there is no payload and
bio_for_each_bvec loop will never execute it's body if bi_size is 0.

But all this is hard to understand, fragile and wasted pointless cycles.
Switch __bio_split_to_limits to only call bio_split_rw for READ and
WRITE command and don't attempt any kind split for operation that do not
require splitting.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 block/blk.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

Damien Le Moal Aug. 26, 2024, 10:34 p.m. UTC | #1
On 8/27/24 02:37, Christoph Hellwig wrote:
> bio_split_rw is designed to split read and write bios with a payload.
> Currently it is called by __bio_split_to_limits for all operations not
> explicitly list, which works because bio_may_need_split explicitly checks
> for bi_vcnt == 1 and thus skips the bypass if there is no payload and
> bio_for_each_bvec loop will never execute it's body if bi_size is 0.
> 
> But all this is hard to understand, fragile and wasted pointless cycles.
> Switch __bio_split_to_limits to only call bio_split_rw for READ and
> WRITE command and don't attempt any kind split for operation that do not
> require splitting.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
diff mbox series

Patch

diff --git a/block/blk.h b/block/blk.h
index 61c2afa67daabb..32f4e9f630a3ac 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -372,7 +372,8 @@  static inline struct bio *__bio_split_to_limits(struct bio *bio,
 		const struct queue_limits *lim, unsigned int *nr_segs)
 {
 	switch (bio_op(bio)) {
-	default:
+	case REQ_OP_READ:
+	case REQ_OP_WRITE:
 		if (bio_may_need_split(bio, lim))
 			return bio_split_rw(bio, lim, nr_segs);
 		*nr_segs = 1;
@@ -384,6 +385,10 @@  static inline struct bio *__bio_split_to_limits(struct bio *bio,
 		return bio_split_discard(bio, lim, nr_segs);
 	case REQ_OP_WRITE_ZEROES:
 		return bio_split_write_zeroes(bio, lim, nr_segs);
+	default:
+		/* other operations can't be split */
+		*nr_segs = 0;
+		return bio;
 	}
 }