Re: [PATCH v2 5/5] md/md-llbitmap: optimize initial sync with write_zeroes_unmap support
Xiao Ni <[email protected]>
| Newsgroups | gmane.linux.kernel,gmane.linux.raid |
|---|---|
| Message-ID | <CALTww2_zudwj_h8pOw-DWsfECWW6tiD7fVYcXr9TDRfh8Kbvjw@mail.gmail.com> |
On Mon, Feb 23, 2026 at 10:41 AM Yu Kuai <[email protected]> wrote: > > For RAID-456 arrays with llbitmap, if all underlying disks support > write_zeroes with unmap, issue write_zeroes to zero all disk data > regions and initialize the bitmap to BitCleanUnwritten instead of > BitUnwritten. > > This optimization skips the initial XOR parity building because: > 1. write_zeroes with unmap guarantees zeroed reads after the operation > 2. For RAID-456, when all data is zero, parity is automatically > consistent (0 XOR 0 XOR ... = 0) > 3. BitCleanUnwritten indicates parity is valid but no user data > has been written > > The implementation adds two helper functions: > - llbitmap_all_disks_support_wzeroes_unmap(): Checks if all active > disks support write_zeroes with unmap > - llbitmap_zero_all_disks(): Issues blkdev_issue_zeroout() to each > rdev's data region to zero all disks > > The zeroing and bitmap state setting happens in llbitmap_init_state() > during bitmap initialization. If any disk fails to zero, we fall back > to BitUnwritten and normal lazy recovery. > > This significantly reduces array initialization time for RAID-456 > arrays built on modern NVMe SSDs or other devices that support > write_zeroes with unmap. > > Signed-off-by: Yu Kuai <[email protected]> > --- > drivers/md/md-llbitmap.c | 62 +++++++++++++++++++++++++++++++++++++++- > 1 file changed, 61 insertions(+), 1 deletion(-) > > diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c > index 461050b2771b..48bc6a639edd 100644 > --- a/drivers/md/md-llbitmap.c > +++ b/drivers/md/md-llbitmap.c > @@ -654,13 +654,73 @@ static int llbitmap_cache_pages(struct llbitmap *llbitmap) > return 0; > } > > +/* > + * Check if all underlying disks support write_zeroes with unmap. > + */ > +static bool llbitmap_all_disks_support_wzeroes_unmap(struct llbitmap *llbitmap) > +{ > + struct mddev *mddev = llbitmap->mddev; > + struct md_rdev *rdev; > + > + rdev_for_each(rdev, mddev) { > + if (rdev->raid_disk < 0 || test_bit(Faulty, &rdev->flags)) > + continue; > + > + if (bdev_write_zeroes_unmap_sectors(rdev->bdev) == 0) > + return false; > + } > + > + return true; > +} > + > +/* > + * Issue write_zeroes to all underlying disks to zero their data regions. > + * This ensures parity consistency for RAID-456 (0 XOR 0 = 0). > + * Returns true if all disks were successfully zeroed. > + */ > +static bool llbitmap_zero_all_disks(struct llbitmap *llbitmap) > +{ > + struct mddev *mddev = llbitmap->mddev; > + struct md_rdev *rdev; > + sector_t dev_sectors = mddev->dev_sectors; > + int ret; > + > + rdev_for_each(rdev, mddev) { > + if (rdev->raid_disk < 0 || test_bit(Faulty, &rdev->flags)) > + continue; > + > + ret = blkdev_issue_zeroout(rdev->bdev, > + rdev->data_offset, > + dev_sectors, > + GFP_KERNEL, 0); > + if (ret) { > + pr_warn("md/llbitmap: failed to zero disk %pg: %d\n", > + rdev->bdev, ret); > + return false; > + } > + } > + > + return true; > +} > + > static void llbitmap_init_state(struct llbitmap *llbitmap) > { > + struct mddev *mddev = llbitmap->mddev; > enum llbitmap_state state = BitUnwritten; > unsigned long i; > > - if (test_and_clear_bit(BITMAP_CLEAN, &llbitmap->flags)) > + if (test_and_clear_bit(BITMAP_CLEAN, &llbitmap->flags)) { > state = BitClean; > + } else if (raid_is_456(mddev) && > + llbitmap_all_disks_support_wzeroes_unmap(llbitmap)) { > + /* > + * All disks support write_zeroes with unmap. Zero all disks > + * to ensure parity consistency, then set BitCleanUnwritten > + * to skip initial sync. > + */ > + if (llbitmap_zero_all_disks(llbitmap)) > + state = BitCleanUnwritten; > + } > > for (i = 0; i < llbitmap->chunks; i++) > llbitmap_write(llbitmap, state, i); > -- > 2.51.0 > > Hi Kuai This patch looks good to me. Reviewed-by: Xiao Ni <[email protected]>