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]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.