On Thu, Oct 22, 2020 at 8:31 PM Christopher Unkel <cunkel@xxxxxxxxxxxxxx> wrote: > > Writes of the md superblock are aligned to the logical blocks of the > containing device, but no attempt is made to align them to physical > block boundaries. This means that on a "512e" device (4k physical, 512 > logical) every superblock update hits the 512-byte emulation and the > possible associated performance penalty. > > Respect the physical block alignment when possible. > > Signed-off-by: Christopher Unkel <cunkel@xxxxxxxxxxxxxx> > --- > drivers/md/md.c | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > > diff --git a/drivers/md/md.c b/drivers/md/md.c > index 98bac4f304ae..2b42850acfb3 100644 > --- a/drivers/md/md.c > +++ b/drivers/md/md.c > @@ -1732,6 +1732,21 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ > && rdev->new_data_offset < sb_start + (rdev->sb_size/512)) > return -EINVAL; > > + /* Respect physical block size if feasible. */ > + bmask = queue_physical_block_size(rdev->bdev->bd_disk->queue)-1; > + if (!((rdev->sb_start * 512) & bmask) && (rdev->sb_size & bmask)) { > + int candidate_size = (rdev->sb_size | bmask) + 1; > + > + if (minor_version) { > + int sectors = candidate_size / 512; > + > + if (rdev->data_offset >= sb_start + sectors > + && rdev->new_data_offset >= sb_start + sectors) > + rdev->sb_size = candidate_size; > + } else if (bmask <= 4095) > + rdev->sb_size = candidate_size; > + } In super_1_load() and super_1_sync(), we have bmask = queue_logical_block_size(rdev->bdev->bd_disk->queue)-1; I think we should replace it with queue_physical_block_size() so the logic is cleaner. Would this work? Thanks, Song