Re: [PATCH v2 06/11] md: support to align bio to limits
Li Nan <[email protected]>
| Newsgroups | gmane.linux.raid |
|---|---|
| Message-ID | <[email protected]> |
在 2026/1/3 23:45, Yu Kuai 写道: > For personalities that report optimal IO size, it's indicate that users > can get the best IO bandwidth if they issue IO with this size. However > there is also an implicit condition that IO should also be aligned to the > optimal IO size. > > Currently, bio will only be split by limits, if bio offset is not aligned > to limits, then all split bio will not be aligned. This patch add a new > feature to align bio to limits first, and following patches will support > this for each personality if necessary. > > Signed-off-by: Yu Kuai <[email protected]> > --- > drivers/md/md.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ > drivers/md/md.h | 2 ++ > 2 files changed, 48 insertions(+) > > diff --git a/drivers/md/md.c b/drivers/md/md.c > index 21b0bc3088d2..7292aedef01b 100644 > --- a/drivers/md/md.c > +++ b/drivers/md/md.c > @@ -428,6 +428,48 @@ bool md_handle_request(struct mddev *mddev, struct bio *bio) > } > EXPORT_SYMBOL(md_handle_request); > > +static struct bio *__md_bio_align_to_limits(struct mddev *mddev, > + struct bio *bio) > +{ > + unsigned int max_sectors = mddev->gendisk->queue->limits.max_sectors; > + sector_t start = bio->bi_iter.bi_sector; > + sector_t align_start = roundup(start, max_sectors); > + sector_t end; > + sector_t align_end; > + > + /* already aligned */ > + if (align_start == start) > + return bio; > + > + end = start + bio_sectors(bio); > + align_end = rounddown(end, max_sectors); > + > + /* bio is too small to split */ > + if (align_end <= align_start) > + return bio; > + > + return bio_submit_split_bioset(bio, align_start - start, > + &mddev->gendisk->bio_split); > +} > + > +static struct bio *md_bio_align_to_limits(struct mddev *mddev, struct bio *bio) > +{ > + if (!test_bit(MD_BIO_ALIGN, &mddev->flags)) > + return bio; > + > + /* atomic write can't split */ > + if (bio->bi_opf & REQ_ATOMIC) > + return bio; > + > + switch (bio_op(bio)) { > + case REQ_OP_READ: > + case REQ_OP_WRITE: > + return __md_bio_align_to_limits(mddev, bio); > + default: > + return bio; > + } > +} > + > static void md_submit_bio(struct bio *bio) > { > const int rw = bio_data_dir(bio); > @@ -443,6 +485,10 @@ static void md_submit_bio(struct bio *bio) > return; > } > > + bio = md_bio_align_to_limits(mddev, bio); > + if (!bio) > + return; > + > bio = bio_split_to_limits(bio); > if (!bio) > return; > diff --git a/drivers/md/md.h b/drivers/md/md.h > index b8c5dec12b62..e7aba83b708b 100644 > --- a/drivers/md/md.h > +++ b/drivers/md/md.h > @@ -347,6 +347,7 @@ struct md_cluster_operations; > * @MD_HAS_SUPERBLOCK: There is persistence sb in member disks. > * @MD_FAILLAST_DEV: Allow last rdev to be removed. > * @MD_SERIALIZE_POLICY: Enforce write IO is not reordered, just used by raid1. > + * @MD_BIO_ALIGN: Bio issued to the array will align to io_opt before split. > * > * change UNSUPPORTED_MDDEV_FLAGS for each array type if new flag is added > */ > @@ -366,6 +367,7 @@ enum mddev_flags { > MD_HAS_SUPERBLOCK, > MD_FAILLAST_DEV, > MD_SERIALIZE_POLICY, > + MD_BIO_ALIGN, > }; > > enum mddev_sb_flags { LGTM Reviewed-by: Li Nan <[email protected]> -- Thanks, Nan