Re: [PATCH v2 2/5] md/md-llbitmap: raise barrier before state machine transition

From: Xiao Ni

Date: Mon Mar 09 2026 - 09:11:12 EST


On Mon, Feb 23, 2026 at 10:42 AM Yu Kuai <yukuai@xxxxxxxxx> wrote:
>
> Move the barrier raise operation before calling llbitmap_state_machine()
> in both llbitmap_start_write() and llbitmap_start_discard(). This
> ensures the barrier is in place before any state transitions occur,
> preventing potential race conditions where the state machine could
> complete before the barrier is properly raised.

Hi Kuai

In the above commit message, race conditions are mentioned. I want to
give an example here to check if I understand correctly.

raid1 with 2 disks is used in this case.
T0: Thread A calls llbitmap_state_machine() and state of bit is set to BitDirty
T1: Thread daemon calls llbitmap_daemon_work() and the state of the
bit is set to BitClean from BitDirty.
(Now the state is already wrong)
T2: Thread A calls llbitmap_raise_barrier to wait Thread daemon
finishes and go on working
T3: data is written to disk1 and disk2. A power failure occurs.
(The data on disk1 and disk2 maybe different, so a data curruption happens)

Does this case belong the race conditions you mentioned in the commit
message? Can you add one race condtion in your message?

Best Regards
Xiao

>
> Cc: stable@xxxxxxxxxxxxxxx
> Fixes: 5ab829f1971d ("md/md-llbitmap: introduce new lockless bitmap")
> Signed-off-by: Yu Kuai <yukuai@xxxxxxxxx>
> ---
> drivers/md/md-llbitmap.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
> index 30d7e36b22c4..5f9e7004e3e3 100644
> --- a/drivers/md/md-llbitmap.c
> +++ b/drivers/md/md-llbitmap.c
> @@ -1070,12 +1070,12 @@ static void llbitmap_start_write(struct mddev *mddev, sector_t offset,
> int page_start = (start + BITMAP_DATA_OFFSET) >> PAGE_SHIFT;
> int page_end = (end + BITMAP_DATA_OFFSET) >> PAGE_SHIFT;
>
> - llbitmap_state_machine(llbitmap, start, end, BitmapActionStartwrite);
> -
> while (page_start <= page_end) {
> llbitmap_raise_barrier(llbitmap, page_start);
> page_start++;
> }
> +
> + llbitmap_state_machine(llbitmap, start, end, BitmapActionStartwrite);
> }
>
> static void llbitmap_end_write(struct mddev *mddev, sector_t offset,
> @@ -1102,12 +1102,12 @@ static void llbitmap_start_discard(struct mddev *mddev, sector_t offset,
> int page_start = (start + BITMAP_DATA_OFFSET) >> PAGE_SHIFT;
> int page_end = (end + BITMAP_DATA_OFFSET) >> PAGE_SHIFT;
>
> - llbitmap_state_machine(llbitmap, start, end, BitmapActionDiscard);
> -
> while (page_start <= page_end) {
> llbitmap_raise_barrier(llbitmap, page_start);
> page_start++;
> }
> +
> + llbitmap_state_machine(llbitmap, start, end, BitmapActionDiscard);
> }
>
> static void llbitmap_end_discard(struct mddev *mddev, sector_t offset,
> --
> 2.51.0
>
>