From: Quinn Tran <[email protected]>

Move ATIO queue processing out of hardware_lock to prevent
deadlock.

Fixes: 3bb67df5b5f8 ("qla2xxx: Check for online flag instead of active reset 
when transmitting responses")
Signed-off-by: Quinn Tran <[email protected]>
Signed-off-by: Himanshu Madhani <[email protected]>
---
 drivers/scsi/qla2xxx/qla_init.c | 17 ++++-----------
 drivers/scsi/qla2xxx/qla_isr.c  | 48 +++++++++++++++++++----------------------
 2 files changed, 26 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f8f55184f542..c3c7ab6fe6e1 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -4859,19 +4859,10 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
                         */
                        if (qla_tgt_mode_enabled(vha) ||
                            qla_dual_mode_enabled(vha)) {
-                               if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) {
-                                       spin_lock_irqsave(&ha->tgt.atio_lock,
-                                           flags);
-                                       qlt_24xx_process_atio_queue(vha, 0);
-                                       spin_unlock_irqrestore(
-                                           &ha->tgt.atio_lock, flags);
-                               } else {
-                                       spin_lock_irqsave(&ha->hardware_lock,
-                                           flags);
-                                       qlt_24xx_process_atio_queue(vha, 1);
-                                       spin_unlock_irqrestore(
-                                           &ha->hardware_lock, flags);
-                               }
+                               spin_lock_irqsave(&ha->tgt.atio_lock, flags);
+                               qlt_24xx_process_atio_queue(vha, 0);
+                               spin_unlock_irqrestore(&ha->tgt.atio_lock,
+                                   flags);
                        }
                }
        }
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 36cbb29c84f6..bc97e3a1bef7 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -3121,6 +3121,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
        uint16_t        mb[8];
        struct rsp_que *rsp;
        unsigned long   flags;
+       bool process_atio = false;
 
        rsp = (struct rsp_que *) dev_id;
        if (!rsp) {
@@ -3181,22 +3182,13 @@ qla24xx_intr_handler(int irq, void *dev_id)
                        qla24xx_process_response_queue(vha, rsp);
                        break;
                case INTR_ATIO_QUE_UPDATE_27XX:
-               case INTR_ATIO_QUE_UPDATE:{
-                       unsigned long flags2;
-                       spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
-                       qlt_24xx_process_atio_queue(vha, 1);
-                       spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
+               case INTR_ATIO_QUE_UPDATE:
+                       process_atio = true;
                        break;
-               }
-               case INTR_ATIO_RSP_QUE_UPDATE: {
-                       unsigned long flags2;
-                       spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
-                       qlt_24xx_process_atio_queue(vha, 1);
-                       spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
-
+               case INTR_ATIO_RSP_QUE_UPDATE:
+                       process_atio = true;
                        qla24xx_process_response_queue(vha, rsp);
                        break;
-               }
                default:
                        ql_dbg(ql_dbg_async, vha, 0x504f,
                            "Unrecognized interrupt type (%d).\n", stat * 0xff);
@@ -3210,6 +3202,12 @@ qla24xx_intr_handler(int irq, void *dev_id)
        qla2x00_handle_mbx_completion(ha, status);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
+       if (process_atio) {
+               spin_lock_irqsave(&ha->tgt.atio_lock, flags);
+               qlt_24xx_process_atio_queue(vha, 0);
+               spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
+       }
+
        return IRQ_HANDLED;
 }
 
@@ -3256,6 +3254,7 @@ qla24xx_msix_default(int irq, void *dev_id)
        uint32_t        hccr;
        uint16_t        mb[8];
        unsigned long flags;
+       bool process_atio = false;
 
        rsp = (struct rsp_que *) dev_id;
        if (!rsp) {
@@ -3312,22 +3311,13 @@ qla24xx_msix_default(int irq, void *dev_id)
                        qla24xx_process_response_queue(vha, rsp);
                        break;
                case INTR_ATIO_QUE_UPDATE_27XX:
-               case INTR_ATIO_QUE_UPDATE:{
-                       unsigned long flags2;
-                       spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
-                       qlt_24xx_process_atio_queue(vha, 1);
-                       spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
+               case INTR_ATIO_QUE_UPDATE:
+                       process_atio = true;
                        break;
-               }
-               case INTR_ATIO_RSP_QUE_UPDATE: {
-                       unsigned long flags2;
-                       spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
-                       qlt_24xx_process_atio_queue(vha, 1);
-                       spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
-
+               case INTR_ATIO_RSP_QUE_UPDATE:
+                       process_atio = true;
                        qla24xx_process_response_queue(vha, rsp);
                        break;
-               }
                default:
                        ql_dbg(ql_dbg_async, vha, 0x5051,
                            "Unrecognized interrupt type (%d).\n", stat & 0xff);
@@ -3338,6 +3328,12 @@ qla24xx_msix_default(int irq, void *dev_id)
        qla2x00_handle_mbx_completion(ha, status);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
+       if (process_atio) {
+               spin_lock_irqsave(&ha->tgt.atio_lock, flags);
+               qlt_24xx_process_atio_queue(vha, 0);
+               spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
+       }
+
        return IRQ_HANDLED;
 }
 
-- 
2.12.0

Reply via email to