diff options
| author | Shuai Zhang <shuai.zhang@oss.qualcomm.com> | 2026-04-10 17:54:43 +0800 |
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2026-04-13 09:19:42 -0400 |
| commit | c347ca17d62a32c25564fee0ca3a2a7bc2d5fd6f (patch) | |
| tree | bc19e8e054e2b3560493c4971f1d4aa6cc655257 /drivers/bluetooth | |
| parent | 76388eae1da94f6c29886c7e49bce1d5abf88734 (diff) | |
| download | lwn-c347ca17d62a32c25564fee0ca3a2a7bc2d5fd6f.tar.gz lwn-c347ca17d62a32c25564fee0ca3a2a7bc2d5fd6f.zip | |
Bluetooth: hci_qca: Fix missing wakeup during SSR memdump handling
When a Bluetooth controller encounters a coredump, it triggers the
Subsystem Restart (SSR) mechanism. The controller first reports the
coredump data and, once the upload is complete, sends a hw_error
event. The host relies on this event to proceed with subsequent
recovery actions.
If the host has not finished processing the coredump data when the
hw_error event is received, it waits until either the processing is
complete or the 8-second timeout expires before handling the event.
The current implementation clears QCA_MEMDUMP_COLLECTION using
clear_bit(), which does not wake up waiters sleeping in
wait_on_bit_timeout(). As a result, the waiting thread may remain
blocked until the timeout expires even if the coredump collection
has already completed.
Fix this by clearing QCA_MEMDUMP_COLLECTION with
clear_and_wake_up_bit(), which also wakes up the waiting thread and
allows the hw_error handling to proceed immediately.
Test case:
- Trigger a controller coredump using:
hcitool cmd 0x3f 0c 26
- Tested on QCA6390.
- Capture HCI logs using btmon.
- Verify that the delay between receiving the hw_error event and
initiating the power-off sequence is reduced compared to the
timeout-based behavior.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Shuai Zhang <shuai.zhang@oss.qualcomm.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'drivers/bluetooth')
| -rw-r--r-- | drivers/bluetooth/hci_qca.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 4512ff7cd0c0..cd1834246b47 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1108,7 +1108,7 @@ static void qca_controller_memdump(struct work_struct *work) qca->qca_memdump = NULL; qca->memdump_state = QCA_MEMDUMP_COLLECTED; cancel_delayed_work(&qca->ctrl_memdump_timeout); - clear_bit(QCA_MEMDUMP_COLLECTION, &qca->flags); + clear_and_wake_up_bit(QCA_MEMDUMP_COLLECTION, &qca->flags); clear_bit(QCA_IBS_DISABLED, &qca->flags); mutex_unlock(&qca->hci_memdump_lock); return; @@ -1186,7 +1186,7 @@ static void qca_controller_memdump(struct work_struct *work) kfree(qca->qca_memdump); qca->qca_memdump = NULL; qca->memdump_state = QCA_MEMDUMP_COLLECTED; - clear_bit(QCA_MEMDUMP_COLLECTION, &qca->flags); + clear_and_wake_up_bit(QCA_MEMDUMP_COLLECTION, &qca->flags); } mutex_unlock(&qca->hci_memdump_lock); |
