FAILED: patch "[PATCH] Bluetooth: hci_conn: re-enable advertising only for" failed to apply to 5.10-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x ed5fb41d3b6b6e665e7f97fd54bd1f9531c7477f
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090318-staring-emphases-67af@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From ed5fb41d3b6b6e665e7f97fd54bd1f9531c7477f Mon Sep 17 00:00:00 2001
From: Valentin Kindschi <[email protected]>
Date: Tue, 18 Aug 2026 15:29:34 +0200
Subject: [PATCH] Bluetooth: hci_conn: re-enable advertising only for
peripheral role
hci_le_conn_failed() unconditionally calls hci_enable_advertising(), although its own comment states advertising should be re-enabled only when the failed attempt was made as a peripheral.
hci_le_conn_failed() is reached from hci_conn_failed() for every failed LE connection, including outgoing central connections. For a central attempt this enable is redundant: hci_le_create_conn_sync() already restores advertising via hci_resume_advertising_sync() in its done:
block. Because hci_enable_advertising() only queues the work on cmd_sync_work, it runs *after* that resume has already succeeded and set HCI_LE_ADV.
The resulting HCI sequence, captured on a BCM43455 (no LE Extended Advertising, so legacy advertising is used):
LE Create Connection Status Success
... 13.8 s, peer never answers ...
LE Set Advertising Parameters (0x2006) Success <- done: resume, LE Set Advertising Enable (0x200a) Success HCI_LE_ADV set LE Create Connection Cancel (0x200e) Success LE Connection Complete Unknown Conn Id LE Set Advertising Parameters (0x2006) Command Disallowed (0x0c)
The last command is the queued enable from hci_le_conn_failed() running as a second hci_enable_advertising_sync() pass. It clears HCI_LE_ADV (hci_sync.c, "Clear the HCI_LE_ADV bit temporarily"), then sends LE Set Advertising Parameters while the controller is still advertising, which the controller correctly rejects with Command Disallowed.
The disable-first call at the top of hci_enable_advertising_sync() cannot prevent this: hci_disable_advertising_sync() returns early without sending anything when HCI_LE_ADV is clear, so it is a no-op exactly when the flag is wrong.
hci_enable_advertising_sync() then returns without sending LE Set Advertising Enable, so HCI_LE_ADV is never set again. The legacy software rotation loop re-arms hci_schedule_adv_instance_sync() every HCI_DEFAULT_ADV_DURATION (2 s), and its "already advertising" shortcut tests HCI_LE_ADV, which can no longer become true. The command is therefore retried every 2 s indefinitely:
Bluetooth: hci0: Opcode 0x2006 failed: -16
Observed on a gateway as 5326 occurrences over 3 hours, ending only when bluetoothd was restarted. Connection attempts that succeed do not call hci_le_conn_failed() and never trigger this.
Add the role test the comment already describes. Both other hci_enable_advertising() call sites reached from a failed/closed LE connection (hci_cs_disconnect() and hci_disconn_complete_evt()) already guard on conn->role == HCI_ROLE_SLAVE; this one was missed.
Reproducing needs legacy advertising (ext_adv_capable() false, so the software rotation loop is used), simultaneous peripheral advertising and outgoing central connects, and a central connect that times out rather than failing fast.
The Fixes tag points at the commit that introduced the advertising restart into this path for the directed-advertising (peripheral) case; the role test that the later commit 0b1db38ca26b ("Bluetooth: Fix check for direct advertising") added to the sibling paths was never applied here.
net/bluetooth/hci_conn.c +2 -1
@@ -1391,7 +1391,8 @@ static void hci_le_conn_failed(struct hci_conn *conn, u8 status)/* Enable advertising in case this was a failed connection * attempt as a peripheral. */ -hci_enable_advertising (hdev); +if (conn->role ==HCI_ROLE_SLAVE ) +hci_enable_advertising (hdev); }/* This function requires the caller holds hdev->lock */
Sasha Levin
maintainerPATCH 1/2 Bluetooth: hci_sync: Convert MGMT_OP_START_DISCOVERY
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit abfeea476c68afea54c9c050a2d3b19d5d2ee873 ]
This make use of hci_cmd_sync_queue for MGMT_OP_START_DISCOVERY, MGMT_OP_START_SERVICE_DISCOVERY and MGMT_OP_STOP_DISCOVERY to use hci_cmd_sync_queue so they no longer depend on hdev->discov_update work to send any commands.
Tested with:
tools/mgmt-tester -s "Start Discovery"
Test Summary
------------
Start Discovery - Not powered 1 Passed Start Discovery - Invalid parameters 1 Passed Start Discovery - Not supported 1 Passed Start Discovery - Success 1 Passed Start Discovery - Success 2 Passed Start Discovery - Power Off 1 Passed Start Discovery BREDR LE - (Ext Scan Enable) Passed Start Discovery LE - (Ext Scan Enable) Passed Start Discovery LE - (Ext Scan Param) Passed Start Discovery - (2m, Scan Param) Passed Start Discovery - (coded, Scan Param) Passed Start Discovery - (1m, 2m, coded, Scan Param) Passed LL Privacy - Start Discovery 1 (Disable RL) Passed LL Privacy - Start Discovery 2 (Disable RL) Passed
Total: 14, Passed: 14 (100.0%), Failed: 0, Not Run: 0
tools/mgmt-tester -s "Start Service"
Test Summary
------------
Start Service Discovery - Not powered 1 Passed Start Service Discovery - Invalid parameters 1 Passed Start Service Discovery - Not supported 1 Passed Start Service Discovery - Success 1 Passed Start Service Discovery - Success 2 Passed
Total: 5, Passed: 5 (100.0%), Failed: 0, Not Run: 0
tools/mgmt-tester -s "Stop Discovery"
Test Summary
------------
Stop Discovery - Success 1 Passed Stop Discovery - BR/EDR (Inquiry) Success 1 Passed Stop Discovery - Rejected 1 Passed Stop Discovery - Invalid parameters 1 Passed Stop Discovery - (Ext Scan Disable) Passed
Total: 5, Passed: 5 (100.0%), Failed: 0, Not Run: 0
[ sashal: Reduced backport -- upstream abfeea476c68a touches 5 file(s), this
backport carries 2. Not backported here:
include/net/bluetooth/hci_sync.h
net/bluetooth/hci_event.c
net/bluetooth/hci_sync.c
net/bluetooth/mgmt.c
This note is generated from the file lists only; see the resolution record for the reasoning. ]
Stable-dep-of: ed5fb41d3b6b ("Bluetooth: hci_conn: re-enable advertising only for peripheral role")
--- net/bluetooth/hci_conn.c | 4 ++-- net/bluetooth/hci_request.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-)
net/bluetooth/hci_conn.c +2 -2
@@ -744,10 +744,10 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)*/ hci_update_background_scan (hdev); -/* Re-enable advertising in case this was a failed connection +/* Enable advertising in case this was a failed connection * attempt as a peripheral. */ -hci_req_reenable_advertising (hdev); +hci_enable_advertising (hdev); }static void create_le_conn_complete (struct hci_dev *hdev,u8 status,u16 opcode)
net/bluetooth/hci_request.h +1 -0
@@ -72,6 +72,7 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next);void hci_req_disable_address_resolution (struct hci_dev *hdev);void hci_req_reenable_advertising (struct hci_dev *hdev); +#define hci_enable_advertising hci_req_reenable_advertisingvoid __hci_req_enable_advertising (struct hci_request *req);void __hci_req_disable_advertising (struct hci_request *req);void __hci_req_update_adv_data (struct hci_request *req,u8 instance);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 Bluetooth: hci_conn: re-enable advertising only for peripheral role
From: Valentin Kindschi <[email protected]>
[ Upstream commit ed5fb41d3b6b6e665e7f97fd54bd1f9531c7477f ]
hci_le_conn_failed() unconditionally calls hci_enable_advertising(), although its own comment states advertising should be re-enabled only when the failed attempt was made as a peripheral.
hci_le_conn_failed() is reached from hci_conn_failed() for every failed LE connection, including outgoing central connections. For a central attempt this enable is redundant: hci_le_create_conn_sync() already restores advertising via hci_resume_advertising_sync() in its done:
block. Because hci_enable_advertising() only queues the work on cmd_sync_work, it runs *after* that resume has already succeeded and set HCI_LE_ADV.
The resulting HCI sequence, captured on a BCM43455 (no LE Extended Advertising, so legacy advertising is used):
LE Create Connection Status Success
... 13.8 s, peer never answers ...
LE Set Advertising Parameters (0x2006) Success <- done: resume, LE Set Advertising Enable (0x200a) Success HCI_LE_ADV set LE Create Connection Cancel (0x200e) Success LE Connection Complete Unknown Conn Id LE Set Advertising Parameters (0x2006) Command Disallowed (0x0c)
The last command is the queued enable from hci_le_conn_failed() running as a second hci_enable_advertising_sync() pass. It clears HCI_LE_ADV (hci_sync.c, "Clear the HCI_LE_ADV bit temporarily"), then sends LE Set Advertising Parameters while the controller is still advertising, which the controller correctly rejects with Command Disallowed.
The disable-first call at the top of hci_enable_advertising_sync() cannot prevent this: hci_disable_advertising_sync() returns early without sending anything when HCI_LE_ADV is clear, so it is a no-op exactly when the flag is wrong.
hci_enable_advertising_sync() then returns without sending LE Set Advertising Enable, so HCI_LE_ADV is never set again. The legacy software rotation loop re-arms hci_schedule_adv_instance_sync() every HCI_DEFAULT_ADV_DURATION (2 s), and its "already advertising" shortcut tests HCI_LE_ADV, which can no longer become true. The command is therefore retried every 2 s indefinitely:
Bluetooth: hci0: Opcode 0x2006 failed: -16
Observed on a gateway as 5326 occurrences over 3 hours, ending only when bluetoothd was restarted. Connection attempts that succeed do not call hci_le_conn_failed() and never trigger this.
Add the role test the comment already describes. Both other hci_enable_advertising() call sites reached from a failed/closed LE connection (hci_cs_disconnect() and hci_disconn_complete_evt()) already guard on conn->role == HCI_ROLE_SLAVE; this one was missed.
Reproducing needs legacy advertising (ext_adv_capable() false, so the software rotation loop is used), simultaneous peripheral advertising and outgoing central connects, and a central connect that times out rather than failing fast.
The Fixes tag points at the commit that introduced the advertising restart into this path for the directed-advertising (peripheral) case; the role test that the later commit 0b1db38ca26b ("Bluetooth: Fix check for direct advertising") added to the sibling paths was never applied here.
--- net/bluetooth/hci_conn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/bluetooth/hci_conn.c +2 -1
@@ -747,7 +747,8 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)/* Enable advertising in case this was a failed connection * attempt as a peripheral. */ -hci_enable_advertising (hdev); +if (conn->role ==HCI_ROLE_SLAVE ) +hci_enable_advertising (hdev); }static void create_le_conn_complete (struct hci_dev *hdev,u8 status,u16 opcode)
Signature · 1 line
2.53.0