[PATCH 5.4 146/408] scsi: mpt3sas: Fix sync irqs

Greg Kroah-Hartman
2020-10-27T17:36:04Z

From: Tomas Henzl <thenzl@redhat.com>

[ Upstream commit 45181eab8ba79ed7a41b549f00500c0093828521 ]

_base_process_reply_queue() called from _base_interrupt() may schedule a
new irq poll. Fix this by calling synchronize_irq() first.

Also ensure that enable_irq() is called only when necessary to avoid
"Unbalanced enable for IRQ..." errors.

Link: https://lore.kernel.org/r/20200910142126.8147-1-thenzl@redhat.com
Fixes: 320e77acb327 ("scsi: mpt3sas: Irq poll to avoid CPU hard lockups")
Acked-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/mpt3sas/mpt3sas_base.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index b7e44634d0dc2..3d58d24de6b61 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1708,18 +1708,22 @@ mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc)
/* TMs are on msix_index == 0 */
if (reply_q->msix_index == 0)
continue;
+ synchronize_irq(pci_irq_vector(ioc->pdev, reply_q->msix_index));
if (reply_q->irq_poll_scheduled) {
/* Calling irq_poll_disable will wait for any pending
* callbacks to have completed.
*/
irq_poll_disable(&reply_q->irqpoll);
irq_poll_enable(&reply_q->irqpoll);
- reply_q->irq_poll_scheduled = false;
- reply_q->irq_line_enable = true;
- enable_irq(reply_q->os_irq);
- continue;
+ /* check how the scheduled poll has ended,
+ * clean up only if necessary
+ */
+ if (reply_q->irq_poll_scheduled) {
+ reply_q->irq_poll_scheduled = false;
+ reply_q->irq_line_enable = true;
+ enable_irq(reply_q->os_irq);
+ }
}
- synchronize_irq(pci_irq_vector(ioc->pdev, reply_q->msix_index));
}
}

--
2.25.1