diff options
| author | ZhaoJinming <zhaojinming@uniontech.com> | 2026-08-10 18:22:38 +0800 |
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2026-08-11 15:40:18 -0400 |
| commit | fca8fe6149048c71ea8863f22674a8fc3cd84f2e (patch) | |
| tree | 9d8c6e415c82d8e83bc7728f1b113e819896addf /scripts/objdiff | |
| parent | 444612a87229d836193685eeda77067c79aed990 (diff) | |
| download | linux-next-fca8fe6149048c71ea8863f22674a8fc3cd84f2e.tar.gz linux-next-fca8fe6149048c71ea8863f22674a8fc3cd84f2e.zip | |
Bluetooth: btmtksdio: fix deadlock in close and reset paths
btmtksdio_close() and btmtksdio_reset() call cancel_work_sync() on
bdev->txrx_work while holding the sdio host lock, which is also acquired
by btmtksdio_txrx_work(). If txrx_work is queued when close/reset runs,
a worker thread may start it after the host lock is taken and block in
sdio_claim_host(), while cancel_work_sync() waits for the work to
finish. The host lock is only released after cancel_work_sync()
returns, so both sides wait forever, deadlocking close/reset.
Fix this by releasing the sdio host lock before calling
cancel_work_sync(), then re-acquiring it afterwards.
In btmtksdio_close() the interrupt is already disabled by
sdio_release_irq(), which also unregisters the IRQ handler, so no new
work can be scheduled and cancel_work_sync() fully quiesces txrx_work.
btmtksdio_reset() must additionally unregister the IRQ handler before
dropping the host lock: btmtksdio_txrx_work() unconditionally re-enables
the device interrupt (C_INT_EN_SET) when the handler is still registered,
so an in-flight worker would re-enable interrupts and be rescheduled
while the device is being reset, defeating the cancellation. The IRQ is
re-claimed by btmtksdio_open() when the HCI device is re-opened after
the reset.
This mirrors the pattern already used by btmtksdio_flush(), which
cancels the work without holding the host lock.
Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'scripts/objdiff')
0 files changed, 0 insertions, 0 deletions
