block: don't use bio_split_rw on misc operations
authorChristoph Hellwig <hch@lst.de>
Mon, 26 Aug 2024 17:37:57 +0000 (19:37 +0200)
committerJens Axboe <axboe@kernel.dk>
Thu, 29 Aug 2024 10:32:32 +0000 (04:32 -0600)
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>
Tested-by: Hans Holmberg <hans.holmberg@wdc.com>
Reviewed-by: Hans Holmberg <hans.holmberg@wdc.com>
Link: https://lore.kernel.org/r/20240826173820.1690925-5-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk.h

index 61c2afa67daabb7d0e99fdb9f90fa9be246c4397..32f4e9f630a3accae53b8622d6d2d71292406c80 100644 (file)
@@ -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;
        }
 }