Commit b00ee7d7 authored by Chad Dupuis's avatar Chad Dupuis Committed by James Bottomley

[SCSI] qla2xxx: Unload hangs after issuing BSG commands to vport.

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: default avatarChad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: default avatarSaurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 619d5a0d
...@@ -27,7 +27,7 @@ void ...@@ -27,7 +27,7 @@ void
qla2x00_bsg_sp_free(void *data, void *ptr) qla2x00_bsg_sp_free(void *data, void *ptr)
{ {
srb_t *sp = (srb_t *)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 fc_bsg_job *bsg_job = sp->u.bsg_job;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
...@@ -40,7 +40,7 @@ qla2x00_bsg_sp_free(void *data, void *ptr) ...@@ -40,7 +40,7 @@ qla2x00_bsg_sp_free(void *data, void *ptr)
if (sp->type == SRB_CT_CMD || if (sp->type == SRB_CT_CMD ||
sp->type == SRB_ELS_CMD_HST) sp->type == SRB_ELS_CMD_HST)
kfree(sp->fcport); kfree(sp->fcport);
mempool_free(sp, vha->hw->srb_mempool); qla2x00_rel_sp(vha, sp);
} }
int int
...@@ -368,7 +368,7 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) ...@@ -368,7 +368,7 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0x700e, ql_log(ql_log_warn, vha, 0x700e,
"qla2x00_start_sp failed = %d\n", rval); "qla2x00_start_sp failed = %d\n", rval);
mempool_free(sp, ha->srb_mempool); qla2x00_rel_sp(vha, sp);
rval = -EIO; rval = -EIO;
goto done_unmap_sg; goto done_unmap_sg;
} }
...@@ -515,7 +515,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) ...@@ -515,7 +515,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0x7017, ql_log(ql_log_warn, vha, 0x7017,
"qla2x00_start_sp failed=%d.\n", rval); "qla2x00_start_sp failed=%d.\n", rval);
mempool_free(sp, ha->srb_mempool); qla2x00_rel_sp(vha, sp);
rval = -EIO; rval = -EIO;
goto done_free_fcport; goto done_free_fcport;
} }
...@@ -1995,6 +1995,6 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job) ...@@ -1995,6 +1995,6 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (bsg_job->request->msgcode == FC_BSG_HST_CT) if (bsg_job->request->msgcode == FC_BSG_HST_CT)
kfree(sp->fcport); kfree(sp->fcport);
mempool_free(sp, ha->srb_mempool); qla2x00_rel_sp(vha, sp);
return 0; return 0;
} }
...@@ -70,9 +70,7 @@ qla2x00_sp_free(void *data, void *ptr) ...@@ -70,9 +70,7 @@ qla2x00_sp_free(void *data, void *ptr)
struct scsi_qla_host *vha = (scsi_qla_host_t *)data; struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
del_timer(&iocb->timer); del_timer(&iocb->timer);
mempool_free(sp, vha->hw->srb_mempool); qla2x00_rel_sp(vha, sp);
QLA_VHA_MARK_NOT_BUSY(vha);
} }
/* Asynchronous Login/Logout Routines -------------------------------------- */ /* Asynchronous Login/Logout Routines -------------------------------------- */
......
...@@ -197,6 +197,13 @@ qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag) ...@@ -197,6 +197,13 @@ qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag)
return sp; 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 static inline void
qla2x00_init_timer(srb_t *sp, unsigned long tmo) qla2x00_init_timer(srb_t *sp, unsigned long tmo)
{ {
......
...@@ -630,7 +630,7 @@ qla2x00_sp_free_dma(void *vha, void *ptr) ...@@ -630,7 +630,7 @@ qla2x00_sp_free_dma(void *vha, void *ptr)
} }
CMD_SP(cmd) = NULL; CMD_SP(cmd) = NULL;
mempool_free(sp, ha->srb_mempool); qla2x00_rel_sp(sp->fcport->vha, sp);
} }
static void static void
...@@ -718,7 +718,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) ...@@ -718,7 +718,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
goto qc24_target_busy; goto qc24_target_busy;
} }
sp = qla2x00_get_sp(base_vha, fcport, GFP_ATOMIC); sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
if (!sp) { if (!sp) {
set_bit(HOST_RAMP_DOWN_QUEUE_DEPTH, &vha->dpc_flags); set_bit(HOST_RAMP_DOWN_QUEUE_DEPTH, &vha->dpc_flags);
goto qc24_host_busy; goto qc24_host_busy;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment