mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
Bluetooth: hci_sync: Set HCI_CMD_DRAIN_WORKQUEUE during device close
Since hci_dev_close_sync() can now be called during the reset path, we
should also set HCI_CMD_DRAIN_WORKQUEUE. This avoids queuing timeouts
while the hdev workqueue is being drained.
Fixes: 877afadad2 ("Bluetooth: When HCI work queue is drained, only queue chained work")
Signed-off-by: Heitor Alves de Siqueira <halves@igalia.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
40b8765720
commit
525daaea45
|
|
@ -5301,6 +5301,12 @@ int hci_dev_close_sync(struct hci_dev *hdev)
|
||||||
|
|
||||||
bt_dev_dbg(hdev, "");
|
bt_dev_dbg(hdev, "");
|
||||||
|
|
||||||
|
/* Set HCI_DRAIN_WORKQUEUE flag to prevent queuing work during
|
||||||
|
* reset/close. See hci_cmd_work() and handle_cmd_cnt_and_timer().
|
||||||
|
*/
|
||||||
|
hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
|
||||||
|
synchronize_rcu();
|
||||||
|
|
||||||
if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
|
if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
|
||||||
disable_delayed_work(&hdev->power_off);
|
disable_delayed_work(&hdev->power_off);
|
||||||
disable_delayed_work(&hdev->ncmd_timer);
|
disable_delayed_work(&hdev->ncmd_timer);
|
||||||
|
|
@ -5324,6 +5330,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
|
||||||
|
|
||||||
if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
|
if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
|
||||||
cancel_delayed_work_sync(&hdev->cmd_timer);
|
cancel_delayed_work_sync(&hdev->cmd_timer);
|
||||||
|
hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5423,6 +5430,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
|
||||||
/* Clear flags */
|
/* Clear flags */
|
||||||
hdev->flags &= BIT(HCI_RAW);
|
hdev->flags &= BIT(HCI_RAW);
|
||||||
hci_dev_clear_volatile_flags(hdev);
|
hci_dev_clear_volatile_flags(hdev);
|
||||||
|
hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
|
||||||
|
|
||||||
memset(hdev->eir, 0, sizeof(hdev->eir));
|
memset(hdev->eir, 0, sizeof(hdev->eir));
|
||||||
memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
|
memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user