Commit 525daaea authored by Heitor Alves de Siqueira's avatar Heitor Alves de Siqueira Committed by Luiz Augusto von Dentz
Browse files

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: 877afada ("Bluetooth: When HCI work queue is drained, only queue chained work")
Signed-off-by: default avatarHeitor Alves de Siqueira <halves@igalia.com>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 40b87657
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -5301,6 +5301,12 @@ int hci_dev_close_sync(struct hci_dev *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)) {
		disable_delayed_work(&hdev->power_off);
		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)) {
		cancel_delayed_work_sync(&hdev->cmd_timer);
		hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
		return err;
	}

@@ -5423,6 +5430,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
	/* Clear flags */
	hdev->flags &= BIT(HCI_RAW);
	hci_dev_clear_volatile_flags(hdev);
	hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);

	memset(hdev->eir, 0, sizeof(hdev->eir));
	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));