From nobody Thu Apr 2 23:55:50 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B67B63009E1; Sat, 14 Feb 2026 06:10:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771049427; cv=none; b=Cp4+/hj+8UP43ItX/1obG9gxIMzw+SS+wGWOWaYYmyClCOLcrq0nL+EGdT0YBtxeEcCXUXcZ45BzXnTxvMFFhcJ4one88V9//f3HWWw8ICsa9uzk9IE/T7qJ5TxHtQDICEs0pkH+nEeQSMlt/joQgdD8JVo7H/P6TFgr/UqEe3c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771049427; c=relaxed/simple; bh=jVBk1b/wivXQrHrNwPugL4S2SWbQ6unlwk6a0c7bpYs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=k1V/5P6MwfPGiad6yOhBqODcfkiMdHewI1KBs82gEMRLwfI0nhPXoxwpS3GIgq2vgVcuU0obDALhn1BbGD3y7La1b2Q5WGn3uc7iTKqrxpvoX6eWab/4OYSBOUxhALCVpL7Tp2AxECdNFX4ruzRrAoyQ0OjyrCA3VliLWgpSjsk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id DA9C9C19421; Sat, 14 Feb 2026 06:10:25 +0000 (UTC) From: Yu Kuai To: song@kernel.org Cc: linan122@huawei.com, xni@redhat.com, colyli@fnnas.com, linux-raid@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 5/5] md/md-llbitmap: optimize initial sync with write_zeroes_unmap support Date: Sat, 14 Feb 2026 14:10:13 +0800 Message-ID: <20260214061013.2335604-6-yukuai@fnnas.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260214061013.2335604-1-yukuai@fnnas.com> References: <20260214061013.2335604-1-yukuai@fnnas.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 ... =3D 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 --- 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 *llbi= tmap) return 0; } =20 +/* + * Check if all underlying disks support write_zeroes with unmap. + */ +static bool llbitmap_all_disks_support_wzeroes_unmap(struct llbitmap *llbi= tmap) +{ + struct mddev *mddev =3D 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) =3D=3D 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 =3D 0). + * Returns true if all disks were successfully zeroed. + */ +static bool llbitmap_zero_all_disks(struct llbitmap *llbitmap) +{ + struct mddev *mddev =3D llbitmap->mddev; + struct md_rdev *rdev; + sector_t dev_sectors =3D mddev->dev_sectors; + int ret; + + rdev_for_each(rdev, mddev) { + if (rdev->raid_disk < 0 || test_bit(Faulty, &rdev->flags)) + continue; + + ret =3D 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 =3D llbitmap->mddev; enum llbitmap_state state =3D BitUnwritten; unsigned long i; =20 - if (test_and_clear_bit(BITMAP_CLEAN, &llbitmap->flags)) + if (test_and_clear_bit(BITMAP_CLEAN, &llbitmap->flags)) { state =3D 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 =3D BitCleanUnwritten; + } =20 for (i =3D 0; i < llbitmap->chunks; i++) llbitmap_write(llbitmap, state, i); --=20 2.51.0