From nobody Tue Apr 7 06:24:38 2026 Received: from mail-pg1-f182.google.com (mail-pg1-f182.google.com [209.85.215.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1036934E741 for ; Sun, 15 Mar 2026 12:23:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773577428; cv=none; b=B79U62lqqugl8qPpS1+zLiV5k5pvq+Bm4SrePDjAUQ8wipAmmpb2MChFsAsZeyt/PMlJyolSHNTMhmyoSP4Yf4ouN6aQgM+jiYJP/wORCiY7B47SNySkj+WiEpYvZ6fQFVJi74qdAfgBj1AeyaowWXiDEX0TVUK2VUzVKIpzFaY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773577428; c=relaxed/simple; bh=mTsAFaXacqnW48UkKN6ehxn0iOX+CEp8wT75dIpaAmY=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=bjtIkhdBOj1HrisrtzWI1ef+IzZB3iYYaA3EzRPOnqgk9ObOVKLZAyBynIBbiN3Yrozap8ZBxCFHGHUzZ27Qkeohl3rgDuNiuJJGJowCAAoJRrW3u/uvGlzV4laOc8d9/a19Qq0RGbWpxaynPj8LRAz4TNSWciatFiAXoamhg9I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=PqOiWl3R; arc=none smtp.client-ip=209.85.215.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PqOiWl3R" Received: by mail-pg1-f182.google.com with SMTP id 41be03b00d2f7-c737d3a51bdso1487955a12.3 for ; Sun, 15 Mar 2026 05:23:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773577424; x=1774182224; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=Ev7olukrabSeI4uImqOW82xjRpOYvekb7Hyttgv7/9Q=; b=PqOiWl3RJkTIRK/FtDQ70zUr/hGR+DcqoR61LtGGrcdCgOHg1G9X7jhOXflZEt+aDs hFYfT82ZYD3SnGPXiQMqHcRIrLgUDCH9UnzpOzWba/NsvV2aJs9e3+yC7x5/8AMVTpX0 BWuJCgh+9SY/Jr0Ayh2qgiyp7+dZPvUa7XDtTyoW7sbXbu2/jVLtn67D966VYVNNmHRe ZeHSvqpNXFBC+P7gaYUwQ8DlhqMWj6mEhtdv7YNq98J37kgEmOkCA1WUMk9eYoPSWEBE Ml+qOWglfLDpu89BxIaZhtuwySBCDh6CXVsgJLQ7WXyTc1Vnot0lTFZtImUcqks3i9b3 io4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773577424; x=1774182224; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Ev7olukrabSeI4uImqOW82xjRpOYvekb7Hyttgv7/9Q=; b=mVhdlpQkTCin/ieVg9BBfyVY9KaIQgmJ7TmJaXE3/L4wqPcRozzHokYdRxuKKvNY9i K/62BiHXNzXVy9XNGIyl55XV3AI2X5YNK+jlpD8zxHiK7EgYr/cOIRQiL5QXHazDO4iI CArx0E/w9KPeqJAJKpo1wjHHQdvbs1DwGh4PRZuS0JI9WXDJIrjPjCn3hlj/SY3oECp9 wWg9tIrPL88ksEwn37WnAS8cHBkjhyWPQrvIDeGMkmSulyV+zZTJJNEZKtJdTzgDgQf9 58EFsVikZpnNucKZq1TFA8Hil8leIcWdy5Z94zUWhcxtEylwQUE7XDBSg45Fo03q8k13 3W2A== X-Gm-Message-State: AOJu0YyqQUoKdN2wTKE8fKmMvxLi3SxLoFxIssOuIBrvy/myOH/P2fUb QYvbpBRZXPdDG7LL+PDtob757vm11MoV4SMI+eJnp61ODvd/pAbgWcHt X-Gm-Gg: ATEYQzykFEhRuBxa0becJ7ZQGir2OBlOXOruf5hcGNSkyM0RCxWuBdcg0NX5/3kS108 VQ3u8UVZqS7gALkLNeH33qxl/R6OEHFTDxlRwG4j4G9TE+HM6ddoRVYA7mZCnsDWALR//N1z7it SgP0u/s0jXSEITxclrVwD5i2fJk+cn2PyRNVLskTWeO/hzXeJm/GIG0xyqwpod6MnAfFNEz2L4v OjryfWUFLUDVqG6pz90LXzXwvsyNU6+54WIBbOjUG8qR8EOSQD0IB39ify6nEMr5/yTUAEgaiy0 zawJ31P6dKIg8WEDAfJfB0u6lnMBj6PF488xkNkKRTi6DCjN+lbff7GArP2rfJaKk51ZqoyGI9Z myoJXm8fjGsY70xcjIK8Lyaha1m/WXGFUMchekB7Qq633IHyIzwkqqLpNFKQlK2InC2FzpXrxqi kpJ9HtpXU1eqbNlg572U6yfo0J/VVg X-Received: by 2002:a17:903:3850:b0:2ae:cb0e:fd5e with SMTP id d9443c01a7336-2aecb0f01cdmr103020325ad.23.1773577424164; Sun, 15 Mar 2026 05:23:44 -0700 (PDT) Received: from lavm-prs74opxn5.. ([111.228.63.84]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2aece7ee1d8sm81749935ad.55.2026.03.15.05.23.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Mar 2026 05:23:43 -0700 (PDT) From: Cen Zhang To: luiz.dentz@gmail.com, johan.hedberg@gmail.com, marcel@holtmann.org Cc: linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org, baijiaju1990@gmail.com, r33s3n6@gmail.com, gality369@gmail.com, zhenghaoran154@gmail.com, hanguidong02@gmail.com, ziyuzhang201@gmail.com, Cen Zhang Subject: [PATCH] Bluetooth: hci_sync: annotate data-races around hdev->req_status Date: Sun, 15 Mar 2026 20:07:26 +0800 Message-Id: <20260315120726.2772382-1-zzzccc427@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" __hci_cmd_sync_sk() sets hdev->req_status under hdev->req_lock: hdev->req_status =3D HCI_REQ_PEND; However, several other functions read or write hdev->req_status without holding any lock: - hci_send_cmd_sync() reads req_status in hci_cmd_work (workqueue) - hci_cmd_sync_complete() reads/writes from HCI event completion - hci_cmd_sync_cancel() / hci_cmd_sync_cancel_sync() read/write - hci_abort_conn() reads in connection abort path Since __hci_cmd_sync_sk() runs on hdev->req_workqueue while hci_send_cmd_sync() runs on hdev->workqueue, these are different workqueues that can execute concurrently on different CPUs. The plain C accesses constitute a data race. Add READ_ONCE()/WRITE_ONCE() annotations on all concurrent accesses to hdev->req_status to prevent potential compiler optimizations that could affect correctness (e.g., load fusing in the wait_event condition or store reordering). Signed-off-by: Cen Zhang --- net/bluetooth/hci_conn.c | 2 +- net/bluetooth/hci_core.c | 2 +- net/bluetooth/hci_sync.c | 20 ++++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 4719dac07190..81c4df0ade0f 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -3095,7 +3095,7 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason) * hci_connect_le serializes the connection attempts so only one * connection can be in BT_CONNECT at time. */ - if (conn->state =3D=3D BT_CONNECT && hdev->req_status =3D=3D HCI_REQ_PEND= ) { + if (conn->state =3D=3D BT_CONNECT && READ_ONCE(hdev->req_status) =3D=3D H= CI_REQ_PEND) { switch (hci_skb_event(hdev->sent_cmd)) { case HCI_EV_CONN_COMPLETE: case HCI_EV_LE_CONN_COMPLETE: diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 31308c1de4ec..01f8ceeb1c0c 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -4126,7 +4126,7 @@ static int hci_send_cmd_sync(struct hci_dev *hdev, st= ruct sk_buff *skb) kfree_skb(skb); } =20 - if (hdev->req_status =3D=3D HCI_REQ_PEND && + if (READ_ONCE(hdev->req_status) =3D=3D HCI_REQ_PEND && !hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) { kfree_skb(hdev->req_skb); hdev->req_skb =3D skb_clone(hdev->sent_cmd, GFP_KERNEL); diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index 121dbc8208ec..335ec52a8e99 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -25,11 +25,11 @@ static void hci_cmd_sync_complete(struct hci_dev *hdev,= u8 result, u16 opcode, { bt_dev_dbg(hdev, "result 0x%2.2x", result); =20 - if (hdev->req_status !=3D HCI_REQ_PEND) + if (READ_ONCE(hdev->req_status) !=3D HCI_REQ_PEND) return; =20 hdev->req_result =3D result; - hdev->req_status =3D HCI_REQ_DONE; + WRITE_ONCE(hdev->req_status, HCI_REQ_DONE); =20 /* Free the request command so it is not used as response */ kfree_skb(hdev->req_skb); @@ -167,20 +167,20 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hde= v, u16 opcode, u32 plen, =20 hci_cmd_sync_add(&req, opcode, plen, param, event, sk); =20 - hdev->req_status =3D HCI_REQ_PEND; + WRITE_ONCE(hdev->req_status, HCI_REQ_PEND); =20 err =3D hci_req_sync_run(&req); if (err < 0) return ERR_PTR(err); =20 err =3D wait_event_interruptible_timeout(hdev->req_wait_q, - hdev->req_status !=3D HCI_REQ_PEND, + READ_ONCE(hdev->req_status) !=3D HCI_REQ_PEND, timeout); =20 if (err =3D=3D -ERESTARTSYS) return ERR_PTR(-EINTR); =20 - switch (hdev->req_status) { + switch (READ_ONCE(hdev->req_status)) { case HCI_REQ_DONE: err =3D -bt_to_errno(hdev->req_result); break; @@ -194,7 +194,7 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev,= u16 opcode, u32 plen, break; } =20 - hdev->req_status =3D 0; + WRITE_ONCE(hdev->req_status, 0); hdev->req_result =3D 0; skb =3D hdev->req_rsp; hdev->req_rsp =3D NULL; @@ -665,9 +665,9 @@ void hci_cmd_sync_cancel(struct hci_dev *hdev, int err) { bt_dev_dbg(hdev, "err 0x%2.2x", err); =20 - if (hdev->req_status =3D=3D HCI_REQ_PEND) { + if (READ_ONCE(hdev->req_status) =3D=3D HCI_REQ_PEND) { hdev->req_result =3D err; - hdev->req_status =3D HCI_REQ_CANCELED; + WRITE_ONCE(hdev->req_status, HCI_REQ_CANCELED); =20 queue_work(hdev->workqueue, &hdev->cmd_sync_cancel_work); } @@ -683,12 +683,12 @@ void hci_cmd_sync_cancel_sync(struct hci_dev *hdev, i= nt err) { bt_dev_dbg(hdev, "err 0x%2.2x", err); =20 - if (hdev->req_status =3D=3D HCI_REQ_PEND) { + if (READ_ONCE(hdev->req_status) =3D=3D HCI_REQ_PEND) { /* req_result is __u32 so error must be positive to be properly * propagated. */ hdev->req_result =3D err < 0 ? -err : err; - hdev->req_status =3D HCI_REQ_CANCELED; + WRITE_ONCE(hdev->req_status, HCI_REQ_CANCELED); =20 wake_up_interruptible(&hdev->req_wait_q); } --=20 2.34.1