[SCSI] qla2xxx: Unload hangs after issuing BSG commands to vport.
authorChad Dupuis <chad.dupuis@qlogic.com>
Fri, 8 Feb 2013 06:57:50 +0000 (01:57 -0500)
committerJames Bottomley <JBottomley@Parallels.com>
Fri, 22 Feb 2013 12:35:40 +0000 (12:35 +0000)
BSG code path increments ref count in the send path, but does not
decrement in the return path leading to hang during unload of the
driver.

Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/qla2xxx/qla_bsg.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_inline.h
drivers/scsi/qla2xxx/qla_os.c

index 525c339436abf7c957e4b141133b224894e1b67d..79babab8353f44de619d6170f8896f2448002e09 100644 (file)
@@ -27,7 +27,7 @@ void
 qla2x00_bsg_sp_free(void *data, void *ptr)
 {
        srb_t *sp = (srb_t *)ptr;
-       struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
+       struct scsi_qla_host *vha = sp->fcport->vha;
        struct fc_bsg_job *bsg_job = sp->u.bsg_job;
        struct qla_hw_data *ha = vha->hw;
 
@@ -40,7 +40,7 @@ qla2x00_bsg_sp_free(void *data, void *ptr)
        if (sp->type == SRB_CT_CMD ||
            sp->type == SRB_ELS_CMD_HST)
                kfree(sp->fcport);
-       mempool_free(sp, vha->hw->srb_mempool);
+       qla2x00_rel_sp(vha, sp);
 }
 
 int
@@ -368,7 +368,7 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
        if (rval != QLA_SUCCESS) {
                ql_log(ql_log_warn, vha, 0x700e,
                    "qla2x00_start_sp failed = %d\n", rval);
-               mempool_free(sp, ha->srb_mempool);
+               qla2x00_rel_sp(vha, sp);
                rval = -EIO;
                goto done_unmap_sg;
        }
@@ -515,7 +515,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
        if (rval != QLA_SUCCESS) {
                ql_log(ql_log_warn, vha, 0x7017,
                    "qla2x00_start_sp failed=%d.\n", rval);
-               mempool_free(sp, ha->srb_mempool);
+               qla2x00_rel_sp(vha, sp);
                rval = -EIO;
                goto done_free_fcport;
        }
@@ -1995,6 +1995,6 @@ done:
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
        if (bsg_job->request->msgcode == FC_BSG_HST_CT)
                kfree(sp->fcport);
-       mempool_free(sp, ha->srb_mempool);
+       qla2x00_rel_sp(vha, sp);
        return 0;
 }
index 97f268433b9f8100fc543d3259cfb19a6acbf4cb..7568324d86a6b9e24b2c0d39020b22692322c8a6 100644 (file)
@@ -70,9 +70,7 @@ qla2x00_sp_free(void *data, void *ptr)
        struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
 
        del_timer(&iocb->timer);
-       mempool_free(sp, vha->hw->srb_mempool);
-
-       QLA_VHA_MARK_NOT_BUSY(vha);
+       qla2x00_rel_sp(vha, sp);
 }
 
 /* Asynchronous Login/Logout Routines -------------------------------------- */
index deb8618d1b8124b1e50900cb4f4dc6c303f6bcd0..130f6f3c2a9722a4a71e4291b943d2e32249dd09 100644 (file)
@@ -197,6 +197,13 @@ done:
        return sp;
 }
 
+static inline void
+qla2x00_rel_sp(scsi_qla_host_t *vha, srb_t *sp)
+{
+       mempool_free(sp, vha->hw->srb_mempool);
+       QLA_VHA_MARK_NOT_BUSY(vha);
+}
+
 static inline void
 qla2x00_init_timer(srb_t *sp, unsigned long tmo)
 {
index 9e3ae1d8de513a46a91289def9b547361718efc8..33fb2178eb4d4c32770962244281f2b286b2f22c 100644 (file)
@@ -630,7 +630,7 @@ qla2x00_sp_free_dma(void *vha, void *ptr)
        }
 
        CMD_SP(cmd) = NULL;
-       mempool_free(sp, ha->srb_mempool);
+       qla2x00_rel_sp(sp->fcport->vha, sp);
 }
 
 static void
@@ -718,7 +718,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
                goto qc24_target_busy;
        }
 
-       sp = qla2x00_get_sp(base_vha, fcport, GFP_ATOMIC);
+       sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
        if (!sp) {
                set_bit(HOST_RAMP_DOWN_QUEUE_DEPTH, &vha->dpc_flags);
                goto qc24_host_busy;
This page took 0.04749 seconds and 5 git commands to generate.