Bluetooth: hci_core: Disable works on hci_unregister_dev
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 22 Oct 2024 15:09:13 +0000 (11:09 -0400)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 23 Oct 2024 14:19:44 +0000 (10:19 -0400)
This make use of disable_work_* on hci_unregister_dev since the hci_dev is
about to be freed new submissions are not disarable.

Fixes: 0d151a103775 ("Bluetooth: hci_core: cancel all works upon hci_unregister_dev()")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
net/bluetooth/hci_core.c
net/bluetooth/hci_sync.c

index 629c302f740795e6d296ecbc498534a72c4462ce..96d097b21d13f2f52cee5f998fe2174ae8b97a06 100644 (file)
@@ -1644,12 +1644,12 @@ void hci_adv_instances_clear(struct hci_dev *hdev)
        struct adv_info *adv_instance, *n;
 
        if (hdev->adv_instance_timeout) {
-               cancel_delayed_work(&hdev->adv_instance_expire);
+               disable_delayed_work(&hdev->adv_instance_expire);
                hdev->adv_instance_timeout = 0;
        }
 
        list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
-               cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
+               disable_delayed_work_sync(&adv_instance->rpa_expired_cb);
                list_del(&adv_instance->list);
                kfree(adv_instance);
        }
@@ -2685,11 +2685,11 @@ void hci_unregister_dev(struct hci_dev *hdev)
        list_del(&hdev->list);
        write_unlock(&hci_dev_list_lock);
 
-       cancel_work_sync(&hdev->rx_work);
-       cancel_work_sync(&hdev->cmd_work);
-       cancel_work_sync(&hdev->tx_work);
-       cancel_work_sync(&hdev->power_on);
-       cancel_work_sync(&hdev->error_reset);
+       disable_work_sync(&hdev->rx_work);
+       disable_work_sync(&hdev->cmd_work);
+       disable_work_sync(&hdev->tx_work);
+       disable_work_sync(&hdev->power_on);
+       disable_work_sync(&hdev->error_reset);
 
        hci_cmd_sync_clear(hdev);
 
@@ -2796,8 +2796,14 @@ static void hci_cancel_cmd_sync(struct hci_dev *hdev, int err)
 {
        bt_dev_dbg(hdev, "err 0x%2.2x", err);
 
-       cancel_delayed_work_sync(&hdev->cmd_timer);
-       cancel_delayed_work_sync(&hdev->ncmd_timer);
+       if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
+               disable_delayed_work_sync(&hdev->cmd_timer);
+               disable_delayed_work_sync(&hdev->ncmd_timer);
+       } else  {
+               cancel_delayed_work_sync(&hdev->cmd_timer);
+               cancel_delayed_work_sync(&hdev->ncmd_timer);
+       }
+
        atomic_set(&hdev->cmd_cnt, 1);
 
        hci_cmd_sync_cancel_sync(hdev, err);
index 40ccdef168d7da0f939a6832bf472b66bf206de7..ae7a5817883aade3a83611d2e9e6e8db33c8daf6 100644 (file)
@@ -5131,9 +5131,15 @@ int hci_dev_close_sync(struct hci_dev *hdev)
 
        bt_dev_dbg(hdev, "");
 
-       cancel_delayed_work(&hdev->power_off);
-       cancel_delayed_work(&hdev->ncmd_timer);
-       cancel_delayed_work(&hdev->le_scan_disable);
+       if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
+               disable_delayed_work(&hdev->power_off);
+               disable_delayed_work(&hdev->ncmd_timer);
+               disable_delayed_work(&hdev->le_scan_disable);
+       } else {
+               cancel_delayed_work(&hdev->power_off);
+               cancel_delayed_work(&hdev->ncmd_timer);
+               cancel_delayed_work(&hdev->le_scan_disable);
+       }
 
        hci_cmd_sync_cancel_sync(hdev, ENODEV);