KCSAN: data-race in kcompactd / try_to_compact_pages

Status: moderation: reported on 2026/11/03 23:25
Subsystems: mm
Labels: prio:low race:benign
[Documentation on labels]
Reported-by: syzbot+212c2d1f47994035cf7f@syzkaller.appspotmail.com
First crash: 8h33m, last: 8h33m
✨ AI-generated root cause summary:

In mm/compaction.c, compaction_deferred() checks and increments the per-zone heuristic counter zone->compact_considered using an unsynchronized read-modify-write operation (++zone->compact_considered) without any locking or atomic primitives. When direct compaction threads executing try_to_compact_pages() run concurrently with background compaction in kcompactd_do_work() on the same memory zone, both contexts read and write zone->compact_considered concurrently without synchronization. KCSAN flags this concurrent access as a data race.

▶ ▼ ✨ Full AI root cause analysis
Based on kernel commit 05441d697f7f:

Technical Breakdown of the Root Cause

1. Involved Entities

  • Source file: mm/compaction.c (struct definition in include/linux/mmzone.h)
  • Functions: compaction_deferred(), try_to_compact_pages(), and kcompactd_do_work()
  • Struct and field: struct zone::compact_considered (at byte offset 0x430 / 1072 bytes within struct zone)

2. Compaction Deferral Mechanism

In the Linux page compaction subsystem, when compaction in a memory zone fails to yield an allocation of the requested order, future compaction attempts for that zone are deferred to avoid wasting CPU cycles.

  • When compaction fails, defer_compaction() resets zone->compact_considered = 0 and increments zone->compact_defer_shift up to COMPACT_MAX_DEFER_SHIFT (6).
  • The limit on how many compaction attempts should be skipped is calculated as:
    unsigned long defer_limit = 1UL << zone->compact_defer_shift;
    
  • Before attempting compaction in a zone, callers invoke compaction_deferred(zone, order). The function determines whether compaction should be deferred or attempted:
    static bool compaction_deferred(struct zone *zone, int order)
    {
        unsigned long defer_limit = 1UL << zone->compact_defer_shift;
    
        if (order < zone->compact_order_failed)
            return false;
    
        /* Avoid possible overflow */
        if (++zone->compact_considered >= defer_limit) {
            zone->compact_considered = defer_limit;
            return false;
        }
    
        trace_mm_compaction_deferred(zone, order);
    
        return true;
    }
    

3. Root Cause and Trigger Condition

  • compaction_deferred() performs an unsynchronized read-modify-write (++zone->compact_considered) followed by a potential cap assignment (zone->compact_considered = defer_limit) on plain unsigned int field zone->compact_considered.
  • No locks (such as zone->lock or pgdat locks) are acquired around compaction_deferred().
  • Multiple tasks can execute compaction paths simultaneously on the same zone:
    1. User/kernel tasks in the direct compaction path (__alloc_pages_direct_compact() -> try_to_compact_pages()).
    2. The background compaction kernel thread (kcompactd() -> kcompactd_do_work()).
  • When task 7236 (in try_to_compact_pages()) and task 34 (kcompactd0 in kcompactd_do_work()) evaluate compaction_deferred(zone, order) concurrently on CPU 1 and CPU 0 for the same zone, both execute ++zone->compact_considered concurrently at line 150 of mm/compaction.c.
  • Because these are non-atomic, unprotected accesses, KCSAN detects and reports a data race on zone->compact_considered.
▶ ▼ ✨ AI Jobs (2)
ID Workflow Result Correct Bug Created Started Finished Revision
a89fa2d5 assessment-security DenialOfService: ❌ Exploitable: ❌ FilesystemTrigger: ❌ FuzzingArtifact: ❌ MemoryCorruption: ❌ NetworkNeedsSetup: ❌ NetworkTrigger: ❌ PeripheralTrigger: ❌ RemoteTrigger: ❌ Unprivileged: ✅ UserNamespace: ✅ VMGuestTrigger: ❌ VMHostTrigger: ❌ ❓ KCSAN: data-race in kcompactd / try_to_compact_pages 2026/11/03 22:51 2026/11/03 22:51 2026/11/03 23:14 d02c3949
be6bf958 assessment-kcsan Benign: ✅ ❓ KCSAN: data-race in kcompactd / try_to_compact_pages 2026/11/03 22:51 2026/11/03 22:51 2026/11/04 00:16 d02c3949

Sample crash report:
==================================================================
BUG: KCSAN: data-race in kcompactd / try_to_compact_pages

read-write to 0xffff88823fffac30 of 4 bytes by task 7236 on cpu 1:
 compaction_deferred mm/compaction.c:150 [inline]
 try_to_compact_pages+0x1c4/0x930 mm/compaction.c:2858
 __alloc_pages_direct_compact+0x8e/0x3f0 mm/page_alloc.c:4168
 __alloc_pages_slowpath+0x334/0x690 mm/page_alloc.c:4946
 __alloc_frozen_pages_noprof+0x2ff/0x3d0 mm/page_alloc.c:5457
 alloc_pages_mpol+0xaf/0x1d0 mm/mempolicy.c:2511
 alloc_frozen_pages_noprof mm/mempolicy.c:2582 [inline]
 alloc_pages_noprof+0x94/0x140 mm/mempolicy.c:2602
 io_mem_alloc_compound io_uring/memmap.c:42 [inline]
 io_region_allocate_pages+0x12f/0x420 io_uring/memmap.c:189
 io_create_region+0x291/0x300 io_uring/memmap.c:251
 io_allocate_scq_urings+0x266/0x3a0 io_uring/io_uring.c:3014
 io_uring_create+0x2ec/0x4f0 io_uring/io_uring.c:3306
 io_uring_setup io_uring/io_uring.c:3376 [inline]
 __do_sys_io_uring_setup io_uring/io_uring.c:3410 [inline]
 __se_sys_io_uring_setup+0x1cb/0x1e0 io_uring/io_uring.c:3401
 __x64_sys_io_uring_setup+0x31/0x40 io_uring/io_uring.c:3401
 x64_sys_call+0x1fbf/0x2550 arch/x86/include/generated/asm/syscalls_64.h:426
 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x112/0x360 arch/x86/entry/syscall_64.c:84
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

read-write to 0xffff88823fffac30 of 4 bytes by task 34 on cpu 0:
 compaction_deferred mm/compaction.c:150 [inline]
 kcompactd_do_work mm/compaction.c:3114 [inline]
 kcompactd+0x513/0xd40 mm/compaction.c:3220
 kthread+0x223/0x270 kernel/kthread.c:436
 ret_from_fork+0x146/0x330 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

value changed: 0x00000007 -> 0x00000008

Reported by Kernel Concurrency Sanitizer on:
CPU: 0 UID: 0 PID: 34 Comm: kcompactd0 Tainted: G        W           syzkaller #0 PREEMPT(lazy) 
Tainted: [W]=WARN
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/07/2026
==================================================================

Crashes (1):
Time Kernel Commit Syzkaller Config Log Report Syz repro C repro VM info Assets (help?) Manager Title
2026/11/03 22:50 upstream 05441d697f7f e2d35131 .config console log report info [disk image] [vmlinux] [kernel image] ci2-upstream-kcsan-gce KCSAN: data-race in kcompactd / try_to_compact_pages
* Struck through repros no longer work on HEAD.