On Mon, Jun 30, 2025 at 11:46 AM Yu Kuai <yukuai1@xxxxxxxxxxxxxxx> wrote: > > Hi, > > 在 2025/06/30 11:25, Xiao Ni 写道: > > On Mon, Jun 30, 2025 at 10:34 AM Yu Kuai <yukuai1@xxxxxxxxxxxxxxx> wrote: > >> > >> Hi, > >> > >> 在 2025/06/30 9:59, Xiao Ni 写道: > >>> > >>> After reading other patches, I want to check if I understand right. > >>> > >>> The first write sets the bitmap bit. The second write which hits the > >>> same block (one sector, 512 bits) will call llbitmap_infect_dirty_bits > >>> to set all other bits. Then the third write doesn't need to set bitmap > >>> bits. If I'm right, the comments above should say only the first two > >>> writes have additional overhead? > >> > >> Yes, for the same bit, it's twice; For different bit in the same block, > >> it's third, by infect all bits in the block in the second. > > > > For different bits in the same block, test_and_set_bit(bit, > > pctl->dirty) should be true too, right? So it infects other bits when > > second write hits the same block too. > > The dirty will be cleared after bitmap_unplug. I understand you now. The for loop in llbitmap_set_page_dirty is used for new writes after unplug. > > > > [946761.035079] llbitmap_set_page_dirty:390 page[0] offset 2024, block 3 > > [946761.035430] llbitmap_state_machine:646 delay raid456 initial recovery > > [946761.035802] llbitmap_state_machine:652 bit 1001 state from 0 to 3 > > [946761.036498] llbitmap_set_page_dirty:390 page[0] offset 2025, block 3 > > [946761.036856] llbitmap_set_page_dirty:403 call llbitmap_infect_dirty_bits > > > > As the debug logs show, different bits in the same block, the second > > write (offset 2025) infects other bits. > > > >> > >> For Reload action, if the bitmap bit is > >>> NeedSync, the changed status will be x. It can't trigger resync/recovery. > >> > >> This is not expected, see llbitmap_state_machine(), if old or new state > >> is need_sync, it will trigger a resync. > >> > >> c = llbitmap_read(llbitmap, start); > >> if (c == BitNeedSync) > >> need_resync = true; > >> -> for RELOAD case, need_resync is still set. > >> > >> state = state_machine[c][action]; > >> if (state == BitNone) > >> continue > > > > If bitmap bit is BitNeedSync, > > state_machine[BitNeedSync][BitmapActionReload] returns BitNone, so if > > (state == BitNone) is true, it can't set MD_RECOVERY_NEEDED and it > > can't start sync after assembling the array. > > You missed what I said above that llbitmap_read() will trigger resync as > well. > > > >> if (state == BitNeedSync) > >> need_resync = true; > >> > >>> > >>> For example: > >>> > >>> cat /sys/block/md127/md/llbitmap/bits > >>> unwritten 3480 > >>> clean 2 > >>> dirty 0 > >>> need sync 510 > >>> > >>> It doesn't do resync after aseembling the array. Does it need to modify > >>> the changed status from x to NeedSync? > >> > >> Can you explain in detail how to reporduce this? Aseembling in my VM is > >> fine. > > > > I added many debug logs, so the sync request runs slowly. The test I do: > > mdadm -CR /dev/md0 -l5 -n3 /dev/loop[0-2] --bitmap=lockless -x 1 /dev/loop3 > > dd if=/dev/zero of=/dev/md0 bs=1M count=1 seek=500 oflag=direct > > mdadm --stop /dev/md0 (the sync thread finishes the region that two > > bitmap bits represent, so you can see llbitmap/bits has 510 bits (need > > sync)) > > mdadm -As > > I don't quite understand, in my case, mdadm -As works fine. Sorry for this, I forgot I removed the codes in function llbitmap_state_machine //if (c == BitNeedSync) // need_resync = true; The reason I do this: I find if the status table changes like this, it doesn't need to check the original status anymore - [BitmapActionReload] = BitNone, + [BitmapActionReload] = BitNeedSync,//? Regards Xiao Xiao > > > > Regards > > Xiao > >> > >> Thanks, > >> Kuai > >> > >> > > > > > > . > > >