aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorChad Dupuis <chad.dupuis@qlogic.com>2013-02-08 01:57:50 -0500
committerJames Bottomley <JBottomley@Parallels.com>2013-02-22 07:35:40 -0500
commitb00ee7d770abbe1e63df74eada0376c75ceb2daf (patch)
tree65a6889fe5d365b777d8cb5b88790c84aa1280b5 /drivers/scsi/qla2xxx
parent619d5a0ded06f6d46092205a68a92f7c3a01dd44 (diff)
[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: Chad Dupuis <chad.dupuis@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c10
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_inline.h7
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c4
4 files changed, 15 insertions, 10 deletions
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 525c339436ab..79babab8353f 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -27,7 +27,7 @@ void
27qla2x00_bsg_sp_free(void *data, void *ptr) 27qla2x00_bsg_sp_free(void *data, void *ptr)
28{ 28{
29 srb_t *sp = (srb_t *)ptr; 29 srb_t *sp = (srb_t *)ptr;
30 struct scsi_qla_host *vha = (scsi_qla_host_t *)data; 30 struct scsi_qla_host *vha = sp->fcport->vha;
31 struct fc_bsg_job *bsg_job = sp->u.bsg_job; 31 struct fc_bsg_job *bsg_job = sp->u.bsg_job;
32 struct qla_hw_data *ha = vha->hw; 32 struct qla_hw_data *ha = vha->hw;
33 33
@@ -40,7 +40,7 @@ qla2x00_bsg_sp_free(void *data, void *ptr)
40 if (sp->type == SRB_CT_CMD || 40 if (sp->type == SRB_CT_CMD ||
41 sp->type == SRB_ELS_CMD_HST) 41 sp->type == SRB_ELS_CMD_HST)
42 kfree(sp->fcport); 42 kfree(sp->fcport);
43 mempool_free(sp, vha->hw->srb_mempool); 43 qla2x00_rel_sp(vha, sp);
44} 44}
45 45
46int 46int
@@ -368,7 +368,7 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
368 if (rval != QLA_SUCCESS) { 368 if (rval != QLA_SUCCESS) {
369 ql_log(ql_log_warn, vha, 0x700e, 369 ql_log(ql_log_warn, vha, 0x700e,
370 "qla2x00_start_sp failed = %d\n", rval); 370 "qla2x00_start_sp failed = %d\n", rval);
371 mempool_free(sp, ha->srb_mempool); 371 qla2x00_rel_sp(vha, sp);
372 rval = -EIO; 372 rval = -EIO;
373 goto done_unmap_sg; 373 goto done_unmap_sg;
374 } 374 }
@@ -515,7 +515,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
515 if (rval != QLA_SUCCESS) { 515 if (rval != QLA_SUCCESS) {
516 ql_log(ql_log_warn, vha, 0x7017, 516 ql_log(ql_log_warn, vha, 0x7017,
517 "qla2x00_start_sp failed=%d.\n", rval); 517 "qla2x00_start_sp failed=%d.\n", rval);
518 mempool_free(sp, ha->srb_mempool); 518 qla2x00_rel_sp(vha, sp);
519 rval = -EIO; 519 rval = -EIO;
520 goto done_free_fcport; 520 goto done_free_fcport;
521 } 521 }
@@ -1995,6 +1995,6 @@ done:
1995 spin_unlock_irqrestore(&ha->hardware_lock, flags); 1995 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1996 if (bsg_job->request->msgcode == FC_BSG_HST_CT) 1996 if (bsg_job->request->msgcode == FC_BSG_HST_CT)
1997 kfree(sp->fcport); 1997 kfree(sp->fcport);
1998 mempool_free(sp, ha->srb_mempool); 1998 qla2x00_rel_sp(vha, sp);
1999 return 0; 1999 return 0;
2000} 2000}
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 97f268433b9f..7568324d86a6 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -70,9 +70,7 @@ qla2x00_sp_free(void *data, void *ptr)
70 struct scsi_qla_host *vha = (scsi_qla_host_t *)data; 70 struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
71 71
72 del_timer(&iocb->timer); 72 del_timer(&iocb->timer);
73 mempool_free(sp, vha->hw->srb_mempool); 73 qla2x00_rel_sp(vha, sp);
74
75 QLA_VHA_MARK_NOT_BUSY(vha);
76} 74}
77 75
78/* Asynchronous Login/Logout Routines -------------------------------------- */ 76/* Asynchronous Login/Logout Routines -------------------------------------- */
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index deb8618d1b81..130f6f3c2a97 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -198,6 +198,13 @@ done:
198} 198}
199 199
200static inline void 200static inline void
201qla2x00_rel_sp(scsi_qla_host_t *vha, srb_t *sp)
202{
203 mempool_free(sp, vha->hw->srb_mempool);
204 QLA_VHA_MARK_NOT_BUSY(vha);
205}
206
207static inline void
201qla2x00_init_timer(srb_t *sp, unsigned long tmo) 208qla2x00_init_timer(srb_t *sp, unsigned long tmo)
202{ 209{
203 init_timer(&sp->u.iocb_cmd.timer); 210 init_timer(&sp->u.iocb_cmd.timer);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 9e3ae1d8de51..33fb2178eb4d 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -630,7 +630,7 @@ qla2x00_sp_free_dma(void *vha, void *ptr)
630 } 630 }
631 631
632 CMD_SP(cmd) = NULL; 632 CMD_SP(cmd) = NULL;
633 mempool_free(sp, ha->srb_mempool); 633 qla2x00_rel_sp(sp->fcport->vha, sp);
634} 634}
635 635
636static void 636static void
@@ -718,7 +718,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
718 goto qc24_target_busy; 718 goto qc24_target_busy;
719 } 719 }
720 720
721 sp = qla2x00_get_sp(base_vha, fcport, GFP_ATOMIC); 721 sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
722 if (!sp) { 722 if (!sp) {
723 set_bit(HOST_RAMP_DOWN_QUEUE_DEPTH, &vha->dpc_flags); 723 set_bit(HOST_RAMP_DOWN_QUEUE_DEPTH, &vha->dpc_flags);
724 goto qc24_host_busy; 724 goto qc24_host_busy;