]> www.infradead.org Git - users/griffoul/linux.git/commitdiff
Bluetooth: hci_event: Mark connection as closed during suspend disconnect
authorLudovico de Nittis <ludovico.denittis@collabora.com>
Tue, 12 Aug 2025 15:55:27 +0000 (17:55 +0200)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 22 Aug 2025 17:55:29 +0000 (13:55 -0400)
When suspending, the disconnect command for an active Bluetooth
connection could be issued, but the corresponding
`HCI_EV_DISCONN_COMPLETE` event might not be received before the system
completes the suspend process. This can lead to an inconsistent state.

On resume, the controller may auto-accept reconnections from the same
device (due to suspend event filters), but these new connections are
rejected by the kernel which still has connection objects from before
suspend. Resulting in errors like:
```
kernel: Bluetooth: hci0: ACL packet for unknown connection handle 1
kernel: Bluetooth: hci0: Ignoring HCI_Connection_Complete for existing
connection
```

This is a btmon snippet that shows the issue:
```
< HCI Command: Disconnect (0x01|0x0006) plen 3
        Handle: 1 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
        Reason: Remote User Terminated Connection (0x13)
> HCI Event: Command Status (0x0f) plen 4
      Disconnect (0x01|0x0006) ncmd 2
        Status: Success (0x00)
[...]
// Host suspends with the event filter set for the device
// On resume, the device tries to reconnect with a new handle

> HCI Event: Connect Complete (0x03) plen 11
        Status: Success (0x00)
        Handle: 2
        Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)

// Kernel ignores this event because there is an existing connection
with
// handle 1
```

By explicitly setting the connection state to BT_CLOSED we can ensure a
consistent state, even if we don't receive the disconnect complete event
in time.

Link: https://github.com/bluez/bluez/issues/1226
Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
net/bluetooth/hci_event.c

index 6c67dfa139e26e5a01d9dcedf1e4fd81bf1284f3..ce0ff06f2f731af7e865796bcac20a6dd4faf166 100644 (file)
@@ -2718,6 +2718,12 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
                goto done;
        }
 
+       /* During suspend, mark connection as closed immediately
+        * since we might not receive HCI_EV_DISCONN_COMPLETE
+        */
+       if (hdev->suspended)
+               conn->state = BT_CLOSED;
+
        mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
 
        if (conn->type == ACL_LINK) {