aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2014-09-03 12:57:30 -0400
committerChristoph Hellwig <hch@lst.de>2014-09-16 12:10:11 -0400
commit9bd2bff5e7140beab948ad3934f4039246748a24 (patch)
treee949fa522286924bf3b580f3745bc992d4fac5fc /drivers/scsi/lpfc
parent12838e74f5164054fd7d5f5201a846ebb9755471 (diff)
lpfc: fix locking issues with abort data paths
Fix locking issues with abort data paths Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: Dick Kennedy <dick.kennedy@emulex.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c12
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c118
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h1
3 files changed, 83 insertions, 48 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 6094545883a3..0f6be8560508 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -3466,7 +3466,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
3466 */ 3466 */
3467 if ((phba->cfg_fof) && ((struct lpfc_device_data *) 3467 if ((phba->cfg_fof) && ((struct lpfc_device_data *)
3468 scsi_cmnd->device->hostdata)->oas_enabled) 3468 scsi_cmnd->device->hostdata)->oas_enabled)
3469 lpfc_cmd->cur_iocbq.iocb_flag |= LPFC_IO_OAS; 3469 lpfc_cmd->cur_iocbq.iocb_flag |= (LPFC_IO_OAS | LPFC_IO_FOF);
3470 return 0; 3470 return 0;
3471} 3471}
3472 3472
@@ -3606,6 +3606,14 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba,
3606 */ 3606 */
3607 iocb_cmd->un.fcpi.fcpi_parm = fcpdl; 3607 iocb_cmd->un.fcpi.fcpi_parm = fcpdl;
3608 3608
3609 /*
3610 * If the OAS driver feature is enabled and the lun is enabled for
3611 * OAS, set the oas iocb related flags.
3612 */
3613 if ((phba->cfg_fof) && ((struct lpfc_device_data *)
3614 scsi_cmnd->device->hostdata)->oas_enabled)
3615 lpfc_cmd->cur_iocbq.iocb_flag |= (LPFC_IO_OAS | LPFC_IO_FOF);
3616
3609 return 0; 3617 return 0;
3610err: 3618err:
3611 if (lpfc_cmd->seg_cnt) 3619 if (lpfc_cmd->seg_cnt)
@@ -4876,6 +4884,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
4876 /* ABTS WQE must go to the same WQ as the WQE to be aborted */ 4884 /* ABTS WQE must go to the same WQ as the WQE to be aborted */
4877 abtsiocb->fcp_wqidx = iocb->fcp_wqidx; 4885 abtsiocb->fcp_wqidx = iocb->fcp_wqidx;
4878 abtsiocb->iocb_flag |= LPFC_USE_FCPWQIDX; 4886 abtsiocb->iocb_flag |= LPFC_USE_FCPWQIDX;
4887 if (iocb->iocb_flag & LPFC_IO_FOF)
4888 abtsiocb->iocb_flag |= LPFC_IO_FOF;
4879 4889
4880 if (lpfc_is_link_up(phba)) 4890 if (lpfc_is_link_up(phba))
4881 icmd->ulpCommand = CMD_ABORT_XRI_CN; 4891 icmd->ulpCommand = CMD_ABORT_XRI_CN;
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index deb7f126a2f1..7185aac24324 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -8753,6 +8753,37 @@ lpfc_sli_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
8753 return 0; 8753 return 0;
8754} 8754}
8755 8755
8756int
8757lpfc_sli_calc_ring(struct lpfc_hba *phba, uint32_t ring_number,
8758 struct lpfc_iocbq *piocb)
8759{
8760 uint32_t idx;
8761
8762 if (phba->sli_rev == LPFC_SLI_REV4) {
8763 if (piocb->iocb_flag & (LPFC_IO_FCP | LPFC_USE_FCPWQIDX)) {
8764 /*
8765 * fcp_wqidx should already be setup based on what
8766 * completion queue we want to use.
8767 */
8768 if (!(phba->cfg_fof) ||
8769 (!(piocb->iocb_flag & LPFC_IO_FOF))) {
8770 if (unlikely(!phba->sli4_hba.fcp_wq))
8771 return LPFC_HBA_ERROR;
8772 idx = lpfc_sli4_scmd_to_wqidx_distr(phba);
8773 piocb->fcp_wqidx = idx;
8774 ring_number = MAX_SLI3_CONFIGURED_RINGS + idx;
8775 } else {
8776 if (unlikely(!phba->sli4_hba.oas_wq))
8777 return LPFC_HBA_ERROR;
8778 idx = 0;
8779 piocb->fcp_wqidx = idx;
8780 ring_number = LPFC_FCP_OAS_RING;
8781 }
8782 }
8783 }
8784 return ring_number;
8785}
8786
8756/** 8787/**
8757 * lpfc_sli_issue_iocb - Wrapper function for __lpfc_sli_issue_iocb 8788 * lpfc_sli_issue_iocb - Wrapper function for __lpfc_sli_issue_iocb
8758 * @phba: Pointer to HBA context object. 8789 * @phba: Pointer to HBA context object.
@@ -8778,61 +8809,42 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number,
8778 int rc, idx; 8809 int rc, idx;
8779 8810
8780 if (phba->sli_rev == LPFC_SLI_REV4) { 8811 if (phba->sli_rev == LPFC_SLI_REV4) {
8781 if (piocb->iocb_flag & LPFC_IO_FCP) { 8812 ring_number = lpfc_sli_calc_ring(phba, ring_number, piocb);
8782 if (!phba->cfg_fof || (!(piocb->iocb_flag & 8813 if (unlikely(ring_number == LPFC_HBA_ERROR))
8783 LPFC_IO_OAS))) { 8814 return IOCB_ERROR;
8784 if (unlikely(!phba->sli4_hba.fcp_wq)) 8815 idx = piocb->fcp_wqidx;
8785 return IOCB_ERROR;
8786 idx = lpfc_sli4_scmd_to_wqidx_distr(phba);
8787 piocb->fcp_wqidx = idx;
8788 ring_number = MAX_SLI3_CONFIGURED_RINGS + idx;
8789 } else {
8790 if (unlikely(!phba->sli4_hba.oas_wq))
8791 return IOCB_ERROR;
8792 idx = 0;
8793 piocb->fcp_wqidx = 0;
8794 ring_number = LPFC_FCP_OAS_RING;
8795 }
8796 pring = &phba->sli.ring[ring_number];
8797 spin_lock_irqsave(&pring->ring_lock, iflags);
8798 rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb,
8799 flag);
8800 spin_unlock_irqrestore(&pring->ring_lock, iflags);
8801 8816
8802 if (lpfc_fcp_look_ahead) { 8817 pring = &phba->sli.ring[ring_number];
8803 fcp_eq_hdl = &phba->sli4_hba.fcp_eq_hdl[idx]; 8818 spin_lock_irqsave(&pring->ring_lock, iflags);
8819 rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb, flag);
8820 spin_unlock_irqrestore(&pring->ring_lock, iflags);
8804 8821
8805 if (atomic_dec_and_test(&fcp_eq_hdl-> 8822 if (lpfc_fcp_look_ahead && (piocb->iocb_flag & LPFC_IO_FCP)) {
8806 fcp_eq_in_use)) { 8823 fcp_eq_hdl = &phba->sli4_hba.fcp_eq_hdl[idx];
8807 8824
8808 /* Get associated EQ with this index */ 8825 if (atomic_dec_and_test(&fcp_eq_hdl->
8809 fpeq = phba->sli4_hba.hba_eq[idx]; 8826 fcp_eq_in_use)) {
8810 8827
8811 /* Turn off interrupts from this EQ */ 8828 /* Get associated EQ with this index */
8812 lpfc_sli4_eq_clr_intr(fpeq); 8829 fpeq = phba->sli4_hba.hba_eq[idx];
8813 8830
8814 /* 8831 /* Turn off interrupts from this EQ */
8815 * Process all the events on FCP EQ 8832 lpfc_sli4_eq_clr_intr(fpeq);
8816 */
8817 while ((eqe = lpfc_sli4_eq_get(fpeq))) {
8818 lpfc_sli4_hba_handle_eqe(phba,
8819 eqe, idx);
8820 fpeq->EQ_processed++;
8821 }
8822 8833
8823 /* Always clear and re-arm the EQ */ 8834 /*
8824 lpfc_sli4_eq_release(fpeq, 8835 * Process all the events on FCP EQ
8825 LPFC_QUEUE_REARM); 8836 */
8837 while ((eqe = lpfc_sli4_eq_get(fpeq))) {
8838 lpfc_sli4_hba_handle_eqe(phba,
8839 eqe, idx);
8840 fpeq->EQ_processed++;
8826 } 8841 }
8827 atomic_inc(&fcp_eq_hdl->fcp_eq_in_use);
8828 }
8829 } else {
8830 pring = &phba->sli.ring[ring_number];
8831 spin_lock_irqsave(&pring->ring_lock, iflags);
8832 rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb,
8833 flag);
8834 spin_unlock_irqrestore(&pring->ring_lock, iflags);
8835 8842
8843 /* Always clear and re-arm the EQ */
8844 lpfc_sli4_eq_release(fpeq,
8845 LPFC_QUEUE_REARM);
8846 }
8847 atomic_inc(&fcp_eq_hdl->fcp_eq_in_use);
8836 } 8848 }
8837 } else { 8849 } else {
8838 /* For now, SLI2/3 will still use hbalock */ 8850 /* For now, SLI2/3 will still use hbalock */
@@ -9715,6 +9727,7 @@ lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
9715 struct lpfc_iocbq *abtsiocbp; 9727 struct lpfc_iocbq *abtsiocbp;
9716 IOCB_t *icmd = NULL; 9728 IOCB_t *icmd = NULL;
9717 IOCB_t *iabt = NULL; 9729 IOCB_t *iabt = NULL;
9730 int ring_number;
9718 int retval; 9731 int retval;
9719 unsigned long iflags; 9732 unsigned long iflags;
9720 9733
@@ -9755,6 +9768,8 @@ lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
9755 abtsiocbp->fcp_wqidx = cmdiocb->fcp_wqidx; 9768 abtsiocbp->fcp_wqidx = cmdiocb->fcp_wqidx;
9756 if (cmdiocb->iocb_flag & LPFC_IO_FCP) 9769 if (cmdiocb->iocb_flag & LPFC_IO_FCP)
9757 abtsiocbp->iocb_flag |= LPFC_USE_FCPWQIDX; 9770 abtsiocbp->iocb_flag |= LPFC_USE_FCPWQIDX;
9771 if (cmdiocb->iocb_flag & LPFC_IO_FOF)
9772 abtsiocbp->iocb_flag |= LPFC_IO_FOF;
9758 9773
9759 if (phba->link_state >= LPFC_LINK_UP) 9774 if (phba->link_state >= LPFC_LINK_UP)
9760 iabt->ulpCommand = CMD_ABORT_XRI_CN; 9775 iabt->ulpCommand = CMD_ABORT_XRI_CN;
@@ -9771,6 +9786,11 @@ lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
9771 abtsiocbp->iotag); 9786 abtsiocbp->iotag);
9772 9787
9773 if (phba->sli_rev == LPFC_SLI_REV4) { 9788 if (phba->sli_rev == LPFC_SLI_REV4) {
9789 ring_number =
9790 lpfc_sli_calc_ring(phba, pring->ringno, abtsiocbp);
9791 if (unlikely(ring_number == LPFC_HBA_ERROR))
9792 return 0;
9793 pring = &phba->sli.ring[ring_number];
9774 /* Note: both hbalock and ring_lock need to be set here */ 9794 /* Note: both hbalock and ring_lock need to be set here */
9775 spin_lock_irqsave(&pring->ring_lock, iflags); 9795 spin_lock_irqsave(&pring->ring_lock, iflags);
9776 retval = __lpfc_sli_issue_iocb(phba, pring->ringno, 9796 retval = __lpfc_sli_issue_iocb(phba, pring->ringno,
@@ -10068,6 +10088,8 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
10068 abtsiocb->fcp_wqidx = iocbq->fcp_wqidx; 10088 abtsiocb->fcp_wqidx = iocbq->fcp_wqidx;
10069 if (iocbq->iocb_flag & LPFC_IO_FCP) 10089 if (iocbq->iocb_flag & LPFC_IO_FCP)
10070 abtsiocb->iocb_flag |= LPFC_USE_FCPWQIDX; 10090 abtsiocb->iocb_flag |= LPFC_USE_FCPWQIDX;
10091 if (iocbq->iocb_flag & LPFC_IO_FOF)
10092 abtsiocb->iocb_flag |= LPFC_IO_FOF;
10071 10093
10072 if (lpfc_is_link_up(phba)) 10094 if (lpfc_is_link_up(phba))
10073 abtsiocb->iocb.ulpCommand = CMD_ABORT_XRI_CN; 10095 abtsiocb->iocb.ulpCommand = CMD_ABORT_XRI_CN;
@@ -10167,6 +10189,8 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
10167 abtsiocbq->fcp_wqidx = iocbq->fcp_wqidx; 10189 abtsiocbq->fcp_wqidx = iocbq->fcp_wqidx;
10168 if (iocbq->iocb_flag & LPFC_IO_FCP) 10190 if (iocbq->iocb_flag & LPFC_IO_FCP)
10169 abtsiocbq->iocb_flag |= LPFC_USE_FCPWQIDX; 10191 abtsiocbq->iocb_flag |= LPFC_USE_FCPWQIDX;
10192 if (iocbq->iocb_flag & LPFC_IO_FOF)
10193 abtsiocbq->iocb_flag |= LPFC_IO_FOF;
10170 10194
10171 if (lpfc_is_link_up(phba)) 10195 if (lpfc_is_link_up(phba))
10172 abtsiocbq->iocb.ulpCommand = CMD_ABORT_XRI_CN; 10196 abtsiocbq->iocb.ulpCommand = CMD_ABORT_XRI_CN;
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index edb48832c39b..4a01452415cf 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -79,6 +79,7 @@ struct lpfc_iocbq {
79#define LPFC_FIP_ELS_ID_SHIFT 14 79#define LPFC_FIP_ELS_ID_SHIFT 14
80 80
81#define LPFC_IO_OAS 0x10000 /* OAS FCP IO */ 81#define LPFC_IO_OAS 0x10000 /* OAS FCP IO */
82#define LPFC_IO_FOF 0x20000 /* FOF FCP IO */
82 83
83 uint32_t drvrTimeout; /* driver timeout in seconds */ 84 uint32_t drvrTimeout; /* driver timeout in seconds */
84 uint32_t fcp_wqidx; /* index to FCP work queue */ 85 uint32_t fcp_wqidx; /* index to FCP work queue */