syzbot
WARNING in raid_resume
Status:
upstream: reported on 2026/11/05 11:23
Subsystems:
dm
Labels:
prio:low
[Documentation on labels]
Reported-by: syzbot+8b22a0459202f76b4096@syzkaller.appspotmail.com
First crash: 4h16m, last: 4h16m
✨ AI-generated root cause summary:
In dm-raid, the target expects the underlying MD sync thread recovery state to remain frozen (MD_RECOVERY_FROZEN) from creation (raid_ctr()) or postsuspend (raid_postsuspend()) until resume (raid_resume()). When reshaping a RAID10 array with a dirty region bitmap, raid_preresume() executes rs_start_reshape(), which calls raid10_start_reshape(). If an error occurs (such as bitmap resize failure), raid10_start_reshape() branches to its abort label, which unconditionally executes mddev->recovery = 0;, wiping out MD_RECOVERY_FROZEN. Because raid_preresume() swallows the reshape failure to continue without change, the subsequent call to raid_resume() encounters RT_FLAG_RS_SUSPENDED with MD_RECOVERY_FROZEN missing, triggering the assertion WARN_ON_ONCE(!test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)).
▶
▼
✨ Full AI root cause analysis
Technical Root Cause Analysis
Involved Functions, Structs, and Files
Mechanism and Invariant Violation
-
dm-raid Frozen State Invariant:
In dm-raid, the MD array lifecycle requires that the MD sync thread remain frozen whenever the RAID set is suspended.
- When a target is constructed in
raid_ctr(), RT_FLAG_RS_SUSPENDED is set on rs->runtime_flags, and md_frozen_sync_thread(&rs->md) is invoked, setting MD_RECOVERY_FROZEN on rs->md.recovery.
- Likewise, during
raid_postsuspend(), md_stop_writes() sets MD_RECOVERY_FROZEN while RT_FLAG_RS_SUSPENDED is marked.
- When the device-mapper target is subsequently resumed via
dm_table_resume_targets(), it executes raid_preresume() followed by raid_resume(). In raid_resume(), the kernel asserts this invariant:
if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) {
...
mddev_lock_nointr(mddev);
WARN_ON_ONCE(!test_bit(MD_RECOVERY_FROZEN, &mddev->recovery));
...
md_unfrozen_sync_thread(mddev);
mddev_unlock_and_resume(mddev);
}
-
Triggering Reshape Failure in raid_preresume():
During raid_preresume(), dirty region bitmap loading (__load_dirty_region_bitmap()) is performed. If a reshape was requested (RT_FLAG_RESHAPE_RS set), raid_preresume() proceeds to initiate reshape:
if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) {
rs_set_rdev_sectors(rs);
mddev_lock_nointr(mddev);
r = rs_start_reshape(rs);
mddev_unlock(mddev);
if (r)
DMWARN("Failed to check/start reshape, continuing without change");
r = 0;
}
rs_start_reshape() calls the personality's pers->start_reshape(mddev), which is raid10_start_reshape() for RAID10.
-
Indiscriminate Zeroing of mddev->recovery:
Inside raid10_start_reshape() (drivers/md/raid10.c), if an error is encountered while preparing the reshape (such as when resizing the dirty region bitmap via mddev->bitmap_ops->resize() when mddev->delta_disks && mddev->bitmap), the function jumps to the abort: error recovery label:
abort:
mddev->recovery = 0;
spin_lock_irq(&conf->device_lock);
...
spin_unlock_irq(&conf->device_lock);
mempool_destroy(new_pool);
return ret;
Resetting mddev->recovery = 0; indiscriminately wipes all recovery flags, including MD_RECOVERY_FROZEN (as well as MD_RECOVERY_WAIT set by rs_start_reshape()).
-
Manifestation of Warning in raid_resume():
When raid10_start_reshape() returns the error code ret, rs_start_reshape() propagates it back to raid_preresume(). In raid_preresume(), dm-raid catches the error and deliberately resets r = 0 to allow the device resume sequence to continue without reshape ("continuing without change").
However, because raid10_start_reshape() cleared mddev->recovery = 0, MD_RECOVERY_FROZEN is now missing while RT_FLAG_RS_SUSPENDED remains set. dm_table_resume_targets() immediately invokes raid_resume(), where the assertion check:
WARN_ON_ONCE(!test_bit(MD_RECOVERY_FROZEN, &mddev->recovery));
evaluates to true and trips the warning.
Sample crash report:
device-mapper: table: 248:14: thin-pool: Error opening metadata block device (-ENOENT)
device-mapper: ioctl: error adding target to table
mdX: bitmap file is out of date, doing full recovery
------------[ cut here ]------------
!test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)
WARNING: drivers/md/dm-raid.c:4139 at raid_resume+0x11fe/0x1290 drivers/md/dm-raid.c:4139, CPU#0: syz.5.1272/11312
Modules linked in:
CPU: 0 UID: 0 PID: 11312 Comm: syz.5.1272 Tainted: G L syzkaller #0 PREEMPT(full)
Tainted: [L]=SOFTLOCKUP
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/15/2026
RIP: 0010:raid_resume+0x11fe/0x1290 drivers/md/dm-raid.c:4139
Code: c6 05 0f 85 fc 08 01 48 c7 c7 40 78 3d 8d be 2d 10 00 00 48 c7 c2 e0 b8 3d 8d e8 2d ec d6 f8 e9 b5 fe ff ff e8 13 95 fb f8 90 <0f> 0b 90 e9 63 fe ff ff e8 05 95 fb f8 90 0f 0b 90 e9 c5 fe ff ff
RSP: 0018:ffffc900039e78c0 EFLAGS: 00010283
RAX: ffffffff88cdbd5d RBX: 0000000000000000 RCX: 0000000000080000
RDX: ffffc90010680000 RSI: 0000000000001342 RDI: 0000000000001343
RBP: ffffc900039e7a40 R08: ffff888078c6c2bf R09: 1ffff1100f18d857
R10: dffffc0000000000 R11: ffffed100f18d858 R12: 1ffff9200073cf28
R13: ffff888078c6c058 R14: dffffc0000000000 R15: ffff888078c6c000
FS: 00007fbfa88c06c0(0000) GS:ffff888123161000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00005561081d2138 CR3: 000000007ce32000 CR4: 00000000003526f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000001800
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
dm_table_resume_targets+0x299/0x3f0 drivers/md/dm-table.c:2204
__dm_resume+0x22/0x1d0 drivers/md/dm.c:3117
dm_resume+0x21a/0x2e0 drivers/md/dm.c:3163
do_resume drivers/md/dm-ioctl.c:1332 [inline]
dev_suspend+0x6ff/0xaa0 drivers/md/dm-ioctl.c:1368
ctl_ioctl drivers/md/dm-ioctl.c:2221 [inline]
dm_ctl_ioctl+0x9ec/0xe10 drivers/md/dm-ioctl.c:2243
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x16a/0x530 arch/x86/entry/syscall_64.c:89
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x00007fbfa799fb19
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fbfa88c0028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007fbfa7c25fa0 RCX: 00007fbfa799fb19
RDX: 0000200000000480 RSI: 00000000c138fd06 RDI: 0000000000000003
RBP: 00007fbfa7a37b70 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fbfa7c26038 R14: 00007fbfa7c25fa0 R15: 00007fffea1356a8
</TASK>
* Struck through repros no longer work on HEAD.