linux/drivers/bluetooth/hci_uart.h

218 lines
5.1 KiB

Bluetooth: hci_ldisc: Allow sleeping while proto locks are held. Commit dec2c92880cc5435381d50e3045ef018a762a917 ("Bluetooth: hci_ldisc: Use rwlocking to avoid closing proto races") introduced locks in hci_ldisc that are held while calling the proto functions. These locks are rwlock's, and hence do not allow sleeping while they are held. However, the proto functions that hci_bcm registers use mutexes and hence need to be able to sleep. In more detail: hci_uart_tty_receive() and hci_uart_dequeue() both acquire the rwlock, after which they call proto->recv() and proto->dequeue(), respectively. In the case of hci_bcm these point to bcm_recv() and bcm_dequeue(). The latter both acquire the bcm_device_lock, which is a mutex, so doing so results in a call to might_sleep(). But since we're holding a rwlock in hci_ldisc, that results in the following BUG (this for the dequeue case - a similar one for the receive case is omitted for brevity): BUG: sleeping function called from invalid context at kernel/locking/mutex.c in_atomic(): 1, irqs_disabled(): 0, pid: 7303, name: kworker/7:3 INFO: lockdep is turned off. CPU: 7 PID: 7303 Comm: kworker/7:3 Tainted: G W OE 4.13.2+ #17 Hardware name: Apple Inc. MacBookPro13,3/Mac-A5C67F76ED83108C, BIOS MBP133.8 Workqueue: events hci_uart_write_work [hci_uart] Call Trace: dump_stack+0x8e/0xd6 ___might_sleep+0x164/0x250 __might_sleep+0x4a/0x80 __mutex_lock+0x59/0xa00 ? lock_acquire+0xa3/0x1f0 ? lock_acquire+0xa3/0x1f0 ? hci_uart_write_work+0xd3/0x160 [hci_uart] mutex_lock_nested+0x1b/0x20 ? mutex_lock_nested+0x1b/0x20 bcm_dequeue+0x21/0xc0 [hci_uart] hci_uart_write_work+0xe6/0x160 [hci_uart] process_one_work+0x253/0x6a0 worker_thread+0x4d/0x3b0 kthread+0x133/0x150 We can't replace the mutex in hci_bcm, because there are other calls there that might sleep. Therefore this replaces the rwlock's in hci_ldisc with rw_semaphore's (which allow sleeping). This is a safer approach anyway as it reduces the restrictions on the proto callbacks. Also, because acquiring write-lock is very rare compared to acquiring the read-lock, the percpu variant of rw_semaphore is used. Lastly, because hci_uart_tx_wakeup() may be called from an IRQ context, we can't block (sleep) while trying acquire the read lock there, so we use the trylock variant. Signed-off-by: Ronald Tschalär <ronald@innovation.ch> Reviewed-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
2017-10-25 22:14:53 -07:00
Bluetooth: hci_h5: Disable the hci_suspend_notifier for btrtl devices The hci_suspend_notifier which was introduced last year, is causing problems for uart attached btrtl devices. These devices may loose their firmware and their baudrate setting over a suspend/resume. Since we don't even know the baudrate after a suspend/resume recovering from this is tricky. The driver solves this by treating these devices the same as USB BT HCIs which drop of the bus during suspend. Specifically the driver: 1. Simply unconditionally turns the device fully off during system-suspend to save maximum power. 2. Calls device_reprobe() from a workqueue to fully re-init the device from scratch on system-resume (unregistering the old HCI and registering a new HCI). This means that these devices do not benefit from the suspend / resume handling work done by the hci_suspend_notifier. At best this unnecessarily adds some time to the suspend/resume time. But in practice this is actually causing problems: 1. These btrtl devices seem to not like the HCI_OP_WRITE_SCAN_ENABLE( SCAN_DISABLED) request being send to them when entering the BT_SUSPEND_CONFIGURE_WAKE state. The same request send on BT_SUSPEND_DISCONNECT works fine, but the second one send (unnecessarily?) from the BT_SUSPEND_CONFIGURE_WAKE transition causes the device to hang: [ 573.497754] PM: suspend entry (s2idle) [ 573.554615] Filesystems sync: 0.056 seconds [ 575.837753] Bluetooth: hci0: Timed out waiting for suspend events [ 575.837801] Bluetooth: hci0: Suspend timeout bit: 4 [ 575.837925] Bluetooth: hci0: Suspend notifier action (3) failed: -110 2. The PM_POST_SUSPEND / BT_RUNNING transition races with the driver-unbinding done by the device_reprobe() work. If the hci_suspend_notifier wins the race it is talking to a dead device leading to the following errors being logged: [ 598.686060] Bluetooth: hci0: Timed out waiting for suspend events [ 598.686124] Bluetooth: hci0: Suspend timeout bit: 5 [ 598.686237] Bluetooth: hci0: Suspend notifier action (4) failed: -110 In both cases things still work, but the suspend-notifier is causing these ugly errors getting logged and ut increase both the suspend- and the resume-time by 2 seconds. This commit avoids these problems by disabling the hci_suspend_notifier. Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Cc: Vasily Khoruzhick <anarsoul@gmail.com> Cc: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
2021-06-29 21:59:07 +02:00
Bluetooth: hci_uart: Fix another race during initialization Do not set 'HCI_UART_PROTO_READY' before call 'hci_uart_register_dev()'. Possible race is when someone calls 'hci_tty_uart_close()' after this bit is set, but 'hci_uart_register_dev()' wasn't done. This leads to access to uninitialized fields. To fix it let's set this bit after device was registered (as before patch c411c62cc133) and to fix previous problem let's add one more bit in addition to 'HCI_UART_PROTO_READY' which allows to perform power up without original bit set (pls see commit c411c62cc133). Crash backtrace from syzbot report: RIP: 0010:skb_queue_empty_lockless include/linux/skbuff.h:1887 [inline] RIP: 0010:skb_queue_purge_reason+0x6d/0x140 net/core/skbuff.c:3936 Call Trace: <TASK> skb_queue_purge include/linux/skbuff.h:3364 [inline] mrvl_close+0x2f/0x90 drivers/bluetooth/hci_mrvl.c:100 hci_uart_tty_close+0xb6/0x120 drivers/bluetooth/hci_ldisc.c:557 tty_ldisc_close drivers/tty/tty_ldisc.c:455 [inline] tty_ldisc_kill+0x66/0xc0 drivers/tty/tty_ldisc.c:613 tty_ldisc_release+0xc9/0x120 drivers/tty/tty_ldisc.c:781 tty_release_struct+0x10/0x80 drivers/tty/tty_io.c:1690 tty_release+0x4ef/0x640 drivers/tty/tty_io.c:1861 __fput+0x86/0x2a0 fs/file_table.c:450 task_work_run+0x82/0xb0 kernel/task_work.c:239 resume_user_mode_work include/linux/resume_user_mode.h:50 [inline] exit_to_user_mode_loop kernel/entry/common.c:114 [inline] exit_to_user_mode_prepare include/linux/entry-common.h:329 [inline] __syscall_exit_to_user_mode_work kernel/entry/common.c:207 [inline] syscall_exit_to_user_mode+0xa3/0x1b0 kernel/entry/common.c:218 do_syscall_64+0x9a/0x190 arch/x86/entry/common.c:89 entry_SYSCALL_64_after_hwframe+0x77/0x7f Signed-off-by: Arseniy Krasnov <avkrasnov@salutedevices.com> Reported-by: syzbot+683f8cb11b94b1824c77@syzkaller.appspotmail.com Tested-by: syzbot+683f8cb11b94b1824c77@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-bluetooth/d159c57f-8490-4c26-79da-6ad3612c4a14@salutedevices.com/ Fixes: 366ceff495f9 ("Bluetooth: hci_uart: fix race during initialization") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2025-02-12 18:59:46 +03:00