summaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorRonald Tschalär <ronald@innovation.ch>2017-10-26 07:15:19 +0200
committerMarcel Holtmann <marcel@holtmann.org>2017-10-30 15:48:32 +0100
commit0338b1b393ec7910898e8f7b25b3bf31a7282e16 (patch)
treea72e920fd7572388e6a16aec289de034f9c001bb /drivers/bluetooth
parentBluetooth: btusb: Fix isochronous interface assignments (diff)
downloadlinux-0338b1b393ec7910898e8f7b25b3bf31a7282e16.tar.xz
linux-0338b1b393ec7910898e8f7b25b3bf31a7282e16.zip
Bluetooth: hci_ldisc: Fix another race when closing the tty.
The following race condition still existed: P1 P2 cancel_work_sync() hci_uart_tx_wakeup() hci_uart_write_work() hci_uart_dequeue() clear_bit(HCI_UART_PROTO_READY) hci_unregister_dev(hdev) hci_free_dev(hdev) hu->proto->close(hu) kfree(hu) access to hdev and hu Cancelling the work after clearing the HCI_UART_PROTO_READY bit avoids this as any hci_uart_tx_wakeup() issued after the flag is cleared will detect that and not schedule further work. Signed-off-by: Ronald Tschalär <ronald@innovation.ch> Reviewed-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/hci_ldisc.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 31def781a562..c823914b3a80 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -523,13 +523,13 @@ static void hci_uart_tty_close(struct tty_struct *tty)
if (hdev)
hci_uart_close(hdev);
- cancel_work_sync(&hu->write_work);
-
if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) {
percpu_down_write(&hu->proto_lock);
clear_bit(HCI_UART_PROTO_READY, &hu->flags);
percpu_up_write(&hu->proto_lock);
+ cancel_work_sync(&hu->write_work);
+
if (hdev) {
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
hci_unregister_dev(hdev);