mirror of
https://github.com/torvalds/linux.git
synced 2025-11-02 09:40:27 +02:00
`cancel_work_sync(&hdev->power_on)` was moved to hci_dev_close_sync in commit [1] to ensure that power_on work is canceled after HCI interface down. But, in certain cases power_on work function may call hci_dev_close_sync itself: hci_power_on -> hci_dev_do_close -> hci_dev_close_sync -> cancel_work_sync(&hdev->power_on), causing deadlock. In particular, this happens when device is rfkilled on boot. To avoid deadlock, move power_on work canceling out of hci_dev_do_close/hci_dev_close_sync. Deadlock introduced by commit [1] was reported in [2,3] as broken suspend. Suspend did not work because `hdev->req_lock` held as result of `power_on` work deadlock. In fact, other BT features were not working. It was not observed when testing [1] since it was verified without rfkill in place. NOTE: It is not needed to cancel power_on work from other places where hci_dev_do_close/hci_dev_close_sync is called in case: * Requests were serialized due to `hdev->req_workqueue`. The power_on work is first in that workqueue. * hci_rfkill_set_block which won't close device anyway until HCI_SETUP is on. * hci_sock_release which runs after hci_sock_bind which ensures HCI_SETUP was cleared. As result, behaviour is the same as in pre-dd06ed7 commit, except power_on work cancel added to hci_dev_close. [1]: commit |
||
|---|---|---|
| .. | ||
| bnep | ||
| cmtp | ||
| hidp | ||
| rfcomm | ||
| 6lowpan.c | ||
| a2mp.c | ||
| a2mp.h | ||
| af_bluetooth.c | ||
| amp.c | ||
| amp.h | ||
| aosp.c | ||
| aosp.h | ||
| ecdh_helper.c | ||
| ecdh_helper.h | ||
| eir.c | ||
| eir.h | ||
| hci_codec.c | ||
| hci_codec.h | ||
| hci_conn.c | ||
| hci_core.c | ||
| hci_debugfs.c | ||
| hci_debugfs.h | ||
| hci_event.c | ||
| hci_request.c | ||
| hci_request.h | ||
| hci_sock.c | ||
| hci_sync.c | ||
| hci_sysfs.c | ||
| Kconfig | ||
| l2cap_core.c | ||
| l2cap_sock.c | ||
| leds.c | ||
| leds.h | ||
| lib.c | ||
| Makefile | ||
| mgmt.c | ||
| mgmt_config.c | ||
| mgmt_config.h | ||
| mgmt_util.c | ||
| mgmt_util.h | ||
| msft.c | ||
| msft.h | ||
| sco.c | ||
| selftest.c | ||
| selftest.h | ||
| smp.c | ||
| smp.h | ||