From nobody Thu Apr 9 04:04:20 2026 Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.4]) (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 F3689359A9B; Wed, 11 Mar 2026 08:09:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=117.135.210.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773216557; cv=none; b=eh8QjTxv/LmSTzt8Bhu/jmOniD79eH3YjTk8Rlp/UFY7/r0f+yBiT5e8FNn2+PzoFbMvDB3r3d5k/J0kM1Q0v32SXMvthbKL3ZMUK0iJPX41JS1P4qmmIRRSjtcMmgyJ5X66BSQE9ASItTPz8UN15eiR9Wzn8sKSumoKcaUXzWA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773216557; c=relaxed/simple; bh=dgAkfbzUcICD9uzNT1R5Gar9UD7pnQu0oBlF5TjQKKo=; h=Date:From:To:Subject:Content-Type:MIME-Version:Message-ID; b=M+2f3KRo7vV1xsO1eJaHPu/4gjqn1/QEtMPR5Ty/XGCCarkgHMl/gXMSIpYlV5ci8Z17F9R0KA7GFiyxazSy+Jb99/3TxAU8R2obFasKJu5OkkYUrh5Wcv7PNQfJH9dnM16Sm4+xbMY5572u/DOt8jRmmv0WHNRY9M431zbLOqI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=LBIWg8cE; arc=none smtp.client-ip=117.135.210.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="LBIWg8cE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=Date:From:To:Subject:Content-Type:MIME-Version: Message-ID; bh=dgAkfbzUcICD9uzNT1R5Gar9UD7pnQu0oBlF5TjQKKo=; b=L BIWg8cE2w8oH6WIMgCfRWAYEvk+3UEo3YAzFwynAKwI1XfHtEPIU2axtXMsG2aBc /jEY24053XpWDBL2J1F/XdAzMszE51Spdl/hOQhDPilXJ/CKZAVz2I3Ys4YOZnNB 6wjqz7NPgGK38fk8w9rZ+cTwgv7Nm7HwvLYy/zz5VM= Received: from luckd0g$163.com ( [183.205.138.18] ) by ajax-webmail-wmsvr-40-127 (Coremail) ; Wed, 11 Mar 2026 16:09:04 +0800 (CST) Date: Wed, 11 Mar 2026 16:09:04 +0800 (CST) From: "Jianzhou Zhao" To: axboe@kernel.dk, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org Subject: KCSAN: data-race in __bio_queue_enter / __blk_mq_unfreeze_queue X-Priority: 3 X-Mailer: Coremail Webmail Server Version 2023.4-cmXT build 20251222(83accb85) Copyright (c) 2002-2026 www.mailtech.cn 163com X-NTES-SC: AL_Qu2cAf6auU0v4iScZekfmU4Rhug7UMO3uf8n24JfPJ9wjA/p2yseUUF9NmPf88CwFTuXvxiGfTNO1/ZAU5Bifrwxmoy3i+4fRfALfWwEJmRTxw== Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <251892a2.6e7e.19cdbf136c0.Coremail.luckd0g@163.com> X-Coremail-Locale: zh_CN X-CM-TRANSID: fygvCgDH954gI7Fp2MV2AA--.25774W X-CM-SenderInfo: poxfyvkqj6il2tof0z/xtbC9gCXImmxIyAUEgAA3e X-Coremail-Antispam: 1U5529EdanIXcx71UUUUU7vcSsGvfC2KfnxnUU== Content-Type: text/plain; charset="utf-8" Subject: [BUG] blk-core: KCSAN: data-race in __bio_queue_enter / __blk_mq_u= nfreeze_queue Dear Maintainers, We are writing to report a KCSAN-detected data race vulnerability within th= e block layer's freeze/unfreeze locking mechanisms. This bug was found by o= ur custom fuzzing tool, RacePilot. The race occurs when `__blk_mq_unfreeze_= queue()` decrements the `q->mq_freeze_depth` counter protected by the `mq_f= reeze_lock` mutex, while `__bio_queue_enter()` simultaneously executes a lo= ckless read check against `q->mq_freeze_depth` within the `wait_event` cond= ition evaluation. We observed this bug on the Linux kernel version 6.18.0-0= 8691-g2061f18ad76e-dirty. Call Trace & Context =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D BUG: KCSAN: data-race in __bio_queue_enter / __blk_mq_unfreeze_queue write to 0xffff88800b03e534 of 4 bytes by task 13701 on cpu 1: __blk_mq_unfreeze_queue+0x6f/0x140 block/blk-mq.c:226 blk_mq_unfreeze_queue_nomemrestore+0x17/0x20 block/blk-mq.c:242 blk_mq_unfreeze_queue include/linux/blk-mq.h:960 [inline] loop_set_status+0x371/0x580 drivers/block/loop.c:1268 ... __x64_sys_ioctl+0x121/0x170 fs/ioctl.c:591 read to 0xffff88800b03e534 of 4 bytes by task 4781 on cpu 0: __bio_queue_enter+0x32a/0x620 block/blk-core.c:353 bio_queue_enter block/blk.h:93 [inline] blk_mq_submit_bio+0xb57/0x1360 block/blk-mq.c:3172 __submit_bio+0x16f/0x580 block/blk-core.c:637 ... submit_bio+0x1b0/0x260 block/blk-core.c:921 ... __x64_sys_read+0x41/0x50 fs/read_write.c:737 value changed: 0x00000001 -> 0x00000000 Reported by Kernel Concurrency Sanitizer on: CPU: 0 UID: 0 PID: 4781 Comm: systemd-udevd Not tainted 6.18.0-08691-g2061f= 18ad76e-dirty #50 PREEMPT(voluntary)=20 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/= 2014 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Execution Flow & Code Context When adjusting device configurations (e.g., `loop_set_status()`), the subsy= stem invokes `blk_mq_unfreeze_queue()`, terminating the freezing sequence b= y acquiring `q->mq_freeze_lock` and decrementing `q->mq_freeze_depth`: ```c // block/blk-mq.c bool __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic) { ... mutex_lock(&q->mq_freeze_lock); ... q->mq_freeze_depth--; // <-- Concurrent 4-byte write (mutating to 0 via lo= ck) WARN_ON_ONCE(q->mq_freeze_depth < 0); if (!q->mq_freeze_depth) { percpu_ref_resurrect(&q->q_usage_counter); wake_up_all(&q->mq_freeze_wq); } ... } ``` Simultaneously, incoming normal bio submissions block dynamically via `__bi= o_queue_enter()` if the queue enforces a freeze. This path calls `wait_even= t` against `q->mq_freeze_wq` mapping a condition checking if `!q->mq_freeze= _depth`: ```c // block/blk-core.c int __bio_queue_enter(struct request_queue *q, struct bio *bio) { while (!blk_try_enter_queue(q, false)) { ... smp_rmb(); wait_event(q->mq_freeze_wq, (!q->mq_freeze_depth && // <-- Concurrent lockless 4-byte read blk_pm_resume_queue(false, q)) || test_bit(GD_DEAD, &disk->state)); ... } ``` Root Cause Analysis A KCSAN data race materializes because `__bio_queue_enter` issues uncontrol= led lockless reads of `q->mq_freeze_depth` through the `wait_event` conditi= on evaluation loop while `__blk_mq_unfreeze_queue` executes a standard dedu= ction operation protected exclusively by `mq_freeze_lock`. The unannotated = decrement and lockless read trigger consecutive memory tearing complaints b= y compiler sanitizers recognizing memory incoherencies under optimization s= tructures or multi-core delayed visibilities, even though the internal logi= c of the queue state typically compensates alongside barrier constructs lik= e `smp_rmb()`. Unfortunately, we were unable to generate a reproducer for this bug. Potential Impact Although the block layer implements resilient logic that withstands explici= t synchronization races utilizing retries or internal barrier pairings (mea= ning practical system consequences are highly unlikely), omitting compiler = atomic operations triggers ubiquitous KCSAN diagnostic pollution on a highl= y frequent kernel datapath.=20 Proposed Fix To establish explicit boundaries and quench KCSAN runtime tearing errors, `= WRITE_ONCE` and `READ_ONCE` can be introduced to formally denote the volati= le nature of `mq_freeze_depth` when queried locklessly and manipulated unde= r independent contexts. A concrete mitigation strategy is modifying the cou= nter decrement implementation alongside the predicate polling logic: ```diff --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -223,6 +223,7 @@ bool __blk_mq_unfreeze_queue(struct request_queue *q, b= ool force_atomic) q->q_usage_counter.data->force_atomic =3D true; } - q->mq_freeze_depth--; + WRITE_ONCE(q->mq_freeze_depth, q->mq_freeze_depth - 1); WARN_ON_ONCE(q->mq_freeze_depth < 0); =20 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -350,7 +350,7 @@ int __bio_queue_enter(struct request_queue *q, struct b= io *bio) smp_rmb(); wait_event(q->mq_freeze_wq, - (!q->mq_freeze_depth && + (!READ_ONCE(q->mq_freeze_depth) && blk_pm_resume_queue(false, q)) || test_bit(GD_DEAD, &disk->state)); ``` We would be highly honored if this could be of any help. Best regards, RacePilot Team