Bluetooth: hci_qca: disable irqs when spinlock is acquired
Looks like Deadlock is observed in hci_qca while performing stress and stability tests. Since same lock is getting acquired from qca_wq_awake_rx and hci_ibs_tx_idle_timeout seeing spinlock recursion, irqs should be disable while acquiring the spinlock always. Signed-off-by: Harish Bandi <c-hbandi@codeaurora.org> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
parent
6d0762b19c
commit
31fb1bbdab
|
@ -309,13 +309,14 @@ static void qca_wq_awake_device(struct work_struct *work)
|
||||||
ws_awake_device);
|
ws_awake_device);
|
||||||
struct hci_uart *hu = qca->hu;
|
struct hci_uart *hu = qca->hu;
|
||||||
unsigned long retrans_delay;
|
unsigned long retrans_delay;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
BT_DBG("hu %p wq awake device", hu);
|
BT_DBG("hu %p wq awake device", hu);
|
||||||
|
|
||||||
/* Vote for serial clock */
|
/* Vote for serial clock */
|
||||||
serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu);
|
serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu);
|
||||||
|
|
||||||
spin_lock(&qca->hci_ibs_lock);
|
spin_lock_irqsave(&qca->hci_ibs_lock, flags);
|
||||||
|
|
||||||
/* Send wake indication to device */
|
/* Send wake indication to device */
|
||||||
if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0)
|
if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0)
|
||||||
|
@ -327,7 +328,7 @@ static void qca_wq_awake_device(struct work_struct *work)
|
||||||
retrans_delay = msecs_to_jiffies(qca->wake_retrans);
|
retrans_delay = msecs_to_jiffies(qca->wake_retrans);
|
||||||
mod_timer(&qca->wake_retrans_timer, jiffies + retrans_delay);
|
mod_timer(&qca->wake_retrans_timer, jiffies + retrans_delay);
|
||||||
|
|
||||||
spin_unlock(&qca->hci_ibs_lock);
|
spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
|
||||||
|
|
||||||
/* Actually send the packets */
|
/* Actually send the packets */
|
||||||
hci_uart_tx_wakeup(hu);
|
hci_uart_tx_wakeup(hu);
|
||||||
|
@ -338,12 +339,13 @@ static void qca_wq_awake_rx(struct work_struct *work)
|
||||||
struct qca_data *qca = container_of(work, struct qca_data,
|
struct qca_data *qca = container_of(work, struct qca_data,
|
||||||
ws_awake_rx);
|
ws_awake_rx);
|
||||||
struct hci_uart *hu = qca->hu;
|
struct hci_uart *hu = qca->hu;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
BT_DBG("hu %p wq awake rx", hu);
|
BT_DBG("hu %p wq awake rx", hu);
|
||||||
|
|
||||||
serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);
|
serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);
|
||||||
|
|
||||||
spin_lock(&qca->hci_ibs_lock);
|
spin_lock_irqsave(&qca->hci_ibs_lock, flags);
|
||||||
qca->rx_ibs_state = HCI_IBS_RX_AWAKE;
|
qca->rx_ibs_state = HCI_IBS_RX_AWAKE;
|
||||||
|
|
||||||
/* Always acknowledge device wake up,
|
/* Always acknowledge device wake up,
|
||||||
|
@ -354,7 +356,7 @@ static void qca_wq_awake_rx(struct work_struct *work)
|
||||||
|
|
||||||
qca->ibs_sent_wacks++;
|
qca->ibs_sent_wacks++;
|
||||||
|
|
||||||
spin_unlock(&qca->hci_ibs_lock);
|
spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
|
||||||
|
|
||||||
/* Actually send the packets */
|
/* Actually send the packets */
|
||||||
hci_uart_tx_wakeup(hu);
|
hci_uart_tx_wakeup(hu);
|
||||||
|
|
Loading…
Reference in New Issue