Commit e2a8be56 authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: resolve lockdep warnings

There were a number of erroneous comments and incorrect older lockdep
checks that were causing a number of warnings.

Resolve the following:

 - Inconsistent lock state warnings in lpfc_nvme_info_show().

 - Fixed comments and code on sequences where ring lock is now held instead
   of hbalock.

 - Reworked calling sequences around lpfc_sli_iocbq_lookup(). Rather than
   locking prior to the routine and have routine guess on what lock, take
   the lock within the routine. The lockdep check becomes unnecessary.

 - Fixed comments and removed erroneous hbalock checks.
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
CC: Bart Van Assche <bvanassche@acm.org>
Tested-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent d0adee5d
...@@ -176,6 +176,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, ...@@ -176,6 +176,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
int i; int i;
int len = 0; int len = 0;
char tmp[LPFC_MAX_NVME_INFO_TMP_LEN] = {0}; char tmp[LPFC_MAX_NVME_INFO_TMP_LEN] = {0};
unsigned long iflags = 0;
if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) { if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) {
len = scnprintf(buf, PAGE_SIZE, "NVME Disabled\n"); len = scnprintf(buf, PAGE_SIZE, "NVME Disabled\n");
...@@ -374,11 +375,11 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, ...@@ -374,11 +375,11 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
nrport = NULL; nrport = NULL;
spin_lock(&vport->phba->hbalock); spin_lock_irqsave(&vport->phba->hbalock, iflags);
rport = lpfc_ndlp_get_nrport(ndlp); rport = lpfc_ndlp_get_nrport(ndlp);
if (rport) if (rport)
nrport = rport->remoteport; nrport = rport->remoteport;
spin_unlock(&vport->phba->hbalock); spin_unlock_irqrestore(&vport->phba->hbalock, iflags);
if (!nrport) if (!nrport)
continue; continue;
......
...@@ -991,15 +991,14 @@ lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) ...@@ -991,15 +991,14 @@ lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
* @ndlp: Targets nodelist pointer for this exchange. * @ndlp: Targets nodelist pointer for this exchange.
* @xritag the xri in the bitmap to test. * @xritag the xri in the bitmap to test.
* *
* This function is called with hbalock held. This function * This function returns:
* returns 0 = rrq not active for this xri * 0 = rrq not active for this xri
* 1 = rrq is valid for this xri. * 1 = rrq is valid for this xri.
**/ **/
int int
lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
uint16_t xritag) uint16_t xritag)
{ {
lockdep_assert_held(&phba->hbalock);
if (!ndlp) if (!ndlp)
return 0; return 0;
if (!ndlp->active_rrqs_xri_bitmap) if (!ndlp->active_rrqs_xri_bitmap)
...@@ -1102,10 +1101,11 @@ lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, ...@@ -1102,10 +1101,11 @@ lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
* @phba: Pointer to HBA context object. * @phba: Pointer to HBA context object.
* @piocb: Pointer to the iocbq. * @piocb: Pointer to the iocbq.
* *
* This function is called with the ring lock held. This function * The driver calls this function with either the nvme ls ring lock
* gets a new driver sglq object from the sglq list. If the * or the fc els ring lock held depending on the iocb usage. This function
* list is not empty then it is successful, it returns pointer to the newly * gets a new driver sglq object from the sglq list. If the list is not empty
* allocated sglq object else it returns NULL. * then it is successful, it returns pointer to the newly allocated sglq
* object else it returns NULL.
**/ **/
static struct lpfc_sglq * static struct lpfc_sglq *
__lpfc_sli_get_els_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq) __lpfc_sli_get_els_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq)
...@@ -1115,9 +1115,15 @@ __lpfc_sli_get_els_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq) ...@@ -1115,9 +1115,15 @@ __lpfc_sli_get_els_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq)
struct lpfc_sglq *start_sglq = NULL; struct lpfc_sglq *start_sglq = NULL;
struct lpfc_io_buf *lpfc_cmd; struct lpfc_io_buf *lpfc_cmd;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
struct lpfc_sli_ring *pring = NULL;
int found = 0; int found = 0;
lockdep_assert_held(&phba->hbalock); if (piocbq->iocb_flag & LPFC_IO_NVME_LS)
pring = phba->sli4_hba.nvmels_wq->pring;
else
pring = lpfc_phba_elsring(phba);
lockdep_assert_held(&pring->ring_lock);
if (piocbq->iocb_flag & LPFC_IO_FCP) { if (piocbq->iocb_flag & LPFC_IO_FCP) {
lpfc_cmd = (struct lpfc_io_buf *) piocbq->context1; lpfc_cmd = (struct lpfc_io_buf *) piocbq->context1;
...@@ -1560,7 +1566,8 @@ lpfc_sli_ring_map(struct lpfc_hba *phba) ...@@ -1560,7 +1566,8 @@ lpfc_sli_ring_map(struct lpfc_hba *phba)
* @pring: Pointer to driver SLI ring object. * @pring: Pointer to driver SLI ring object.
* @piocb: Pointer to the driver iocb object. * @piocb: Pointer to the driver iocb object.
* *
* This function is called with hbalock held. The function adds the * The driver calls this function with the hbalock held for SLI3 ports or
* the ring lock held for SLI4 ports. The function adds the
* new iocb to txcmplq of the given ring. This function always returns * new iocb to txcmplq of the given ring. This function always returns
* 0. If this function is called for ELS ring, this function checks if * 0. If this function is called for ELS ring, this function checks if
* there is a vport associated with the ELS command. This function also * there is a vport associated with the ELS command. This function also
...@@ -1570,6 +1577,9 @@ static int ...@@ -1570,6 +1577,9 @@ static int
lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_iocbq *piocb) struct lpfc_iocbq *piocb)
{ {
if (phba->sli_rev == LPFC_SLI_REV4)
lockdep_assert_held(&pring->ring_lock);
else
lockdep_assert_held(&phba->hbalock); lockdep_assert_held(&phba->hbalock);
BUG_ON(!piocb); BUG_ON(!piocb);
...@@ -2967,8 +2977,8 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -2967,8 +2977,8 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
* *
* This function looks up the iocb_lookup table to get the command iocb * This function looks up the iocb_lookup table to get the command iocb
* corresponding to the given response iocb using the iotag of the * corresponding to the given response iocb using the iotag of the
* response iocb. This function is called with the hbalock held * response iocb. The driver calls this function with the hbalock held
* for sli3 devices or the ring_lock for sli4 devices. * for SLI3 ports or the ring lock held for SLI4 ports.
* This function returns the command iocb object if it finds the command * This function returns the command iocb object if it finds the command
* iocb else returns NULL. * iocb else returns NULL.
**/ **/
...@@ -2979,8 +2989,15 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba, ...@@ -2979,8 +2989,15 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba,
{ {
struct lpfc_iocbq *cmd_iocb = NULL; struct lpfc_iocbq *cmd_iocb = NULL;
uint16_t iotag; uint16_t iotag;
lockdep_assert_held(&phba->hbalock); spinlock_t *temp_lock = NULL;
unsigned long iflag = 0;
if (phba->sli_rev == LPFC_SLI_REV4)
temp_lock = &pring->ring_lock;
else
temp_lock = &phba->hbalock;
spin_lock_irqsave(temp_lock, iflag);
iotag = prspiocb->iocb.ulpIoTag; iotag = prspiocb->iocb.ulpIoTag;
if (iotag != 0 && iotag <= phba->sli.last_iotag) { if (iotag != 0 && iotag <= phba->sli.last_iotag) {
...@@ -2990,10 +3007,12 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba, ...@@ -2990,10 +3007,12 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba,
list_del_init(&cmd_iocb->list); list_del_init(&cmd_iocb->list);
cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ; cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
pring->txcmplq_cnt--; pring->txcmplq_cnt--;
spin_unlock_irqrestore(temp_lock, iflag);
return cmd_iocb; return cmd_iocb;
} }
} }
spin_unlock_irqrestore(temp_lock, iflag);
lpfc_printf_log(phba, KERN_ERR, LOG_SLI, lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"0317 iotag x%x is out of " "0317 iotag x%x is out of "
"range: max iotag x%x wd0 x%x\n", "range: max iotag x%x wd0 x%x\n",
...@@ -3009,8 +3028,8 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba, ...@@ -3009,8 +3028,8 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba,
* @iotag: IOCB tag. * @iotag: IOCB tag.
* *
* This function looks up the iocb_lookup table to get the command iocb * This function looks up the iocb_lookup table to get the command iocb
* corresponding to the given iotag. This function is called with the * corresponding to the given iotag. The driver calls this function with
* hbalock held. * the ring lock held because this function is an SLI4 port only helper.
* This function returns the command iocb object if it finds the command * This function returns the command iocb object if it finds the command
* iocb else returns NULL. * iocb else returns NULL.
**/ **/
...@@ -3019,8 +3038,15 @@ lpfc_sli_iocbq_lookup_by_tag(struct lpfc_hba *phba, ...@@ -3019,8 +3038,15 @@ lpfc_sli_iocbq_lookup_by_tag(struct lpfc_hba *phba,
struct lpfc_sli_ring *pring, uint16_t iotag) struct lpfc_sli_ring *pring, uint16_t iotag)
{ {
struct lpfc_iocbq *cmd_iocb = NULL; struct lpfc_iocbq *cmd_iocb = NULL;
spinlock_t *temp_lock = NULL;
unsigned long iflag = 0;
lockdep_assert_held(&phba->hbalock); if (phba->sli_rev == LPFC_SLI_REV4)
temp_lock = &pring->ring_lock;
else
temp_lock = &phba->hbalock;
spin_lock_irqsave(temp_lock, iflag);
if (iotag != 0 && iotag <= phba->sli.last_iotag) { if (iotag != 0 && iotag <= phba->sli.last_iotag) {
cmd_iocb = phba->sli.iocbq_lookup[iotag]; cmd_iocb = phba->sli.iocbq_lookup[iotag];
if (cmd_iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ) { if (cmd_iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ) {
...@@ -3028,10 +3054,12 @@ lpfc_sli_iocbq_lookup_by_tag(struct lpfc_hba *phba, ...@@ -3028,10 +3054,12 @@ lpfc_sli_iocbq_lookup_by_tag(struct lpfc_hba *phba,
list_del_init(&cmd_iocb->list); list_del_init(&cmd_iocb->list);
cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ; cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
pring->txcmplq_cnt--; pring->txcmplq_cnt--;
spin_unlock_irqrestore(temp_lock, iflag);
return cmd_iocb; return cmd_iocb;
} }
} }
spin_unlock_irqrestore(temp_lock, iflag);
lpfc_printf_log(phba, KERN_ERR, LOG_SLI, lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"0372 iotag x%x lookup error: max iotag (x%x) " "0372 iotag x%x lookup error: max iotag (x%x) "
"iocb_flag x%x\n", "iocb_flag x%x\n",
...@@ -3065,17 +3093,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -3065,17 +3093,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
int rc = 1; int rc = 1;
unsigned long iflag; unsigned long iflag;
/* Based on the iotag field, get the cmd IOCB from the txcmplq */
if (phba->sli_rev == LPFC_SLI_REV4)
spin_lock_irqsave(&pring->ring_lock, iflag);
else
spin_lock_irqsave(&phba->hbalock, iflag);
cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring, saveq); cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring, saveq);
if (phba->sli_rev == LPFC_SLI_REV4)
spin_unlock_irqrestore(&pring->ring_lock, iflag);
else
spin_unlock_irqrestore(&phba->hbalock, iflag);
if (cmdiocbp) { if (cmdiocbp) {
if (cmdiocbp->iocb_cmpl) { if (cmdiocbp->iocb_cmpl) {
/* /*
...@@ -3406,8 +3424,10 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, ...@@ -3406,8 +3424,10 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
break; break;
} }
spin_unlock_irqrestore(&phba->hbalock, iflag);
cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
&rspiocbq); &rspiocbq);
spin_lock_irqsave(&phba->hbalock, iflag);
if (unlikely(!cmdiocbq)) if (unlikely(!cmdiocbq))
break; break;
if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED)
...@@ -3601,9 +3621,12 @@ lpfc_sli_sp_handle_rspiocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -3601,9 +3621,12 @@ lpfc_sli_sp_handle_rspiocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
case LPFC_ABORT_IOCB: case LPFC_ABORT_IOCB:
cmdiocbp = NULL; cmdiocbp = NULL;
if (irsp->ulpCommand != CMD_XRI_ABORTED_CX) if (irsp->ulpCommand != CMD_XRI_ABORTED_CX) {
spin_unlock_irqrestore(&phba->hbalock, iflag);
cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring, cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring,
saveq); saveq);
spin_lock_irqsave(&phba->hbalock, iflag);
}
if (cmdiocbp) { if (cmdiocbp) {
/* Call the specified completion routine */ /* Call the specified completion routine */
if (cmdiocbp->iocb_cmpl) { if (cmdiocbp->iocb_cmpl) {
...@@ -12976,13 +12999,11 @@ lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *phba, ...@@ -12976,13 +12999,11 @@ lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *phba,
return NULL; return NULL;
wcqe = &irspiocbq->cq_event.cqe.wcqe_cmpl; wcqe = &irspiocbq->cq_event.cqe.wcqe_cmpl;
spin_lock_irqsave(&pring->ring_lock, iflags);
pring->stats.iocb_event++; pring->stats.iocb_event++;
/* Look up the ELS command IOCB and create pseudo response IOCB */ /* Look up the ELS command IOCB and create pseudo response IOCB */
cmdiocbq = lpfc_sli_iocbq_lookup_by_tag(phba, pring, cmdiocbq = lpfc_sli_iocbq_lookup_by_tag(phba, pring,
bf_get(lpfc_wcqe_c_request_tag, wcqe)); bf_get(lpfc_wcqe_c_request_tag, wcqe));
if (unlikely(!cmdiocbq)) { if (unlikely(!cmdiocbq)) {
spin_unlock_irqrestore(&pring->ring_lock, iflags);
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
"0386 ELS complete with no corresponding " "0386 ELS complete with no corresponding "
"cmdiocb: 0x%x 0x%x 0x%x 0x%x\n", "cmdiocb: 0x%x 0x%x 0x%x 0x%x\n",
...@@ -12992,6 +13013,7 @@ lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *phba, ...@@ -12992,6 +13013,7 @@ lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *phba,
return NULL; return NULL;
} }
spin_lock_irqsave(&pring->ring_lock, iflags);
/* Put the iocb back on the txcmplq */ /* Put the iocb back on the txcmplq */
lpfc_sli_ringtxcmpl_put(phba, pring, cmdiocbq); lpfc_sli_ringtxcmpl_put(phba, pring, cmdiocbq);
spin_unlock_irqrestore(&pring->ring_lock, iflags); spin_unlock_irqrestore(&pring->ring_lock, iflags);
...@@ -13762,9 +13784,9 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq, ...@@ -13762,9 +13784,9 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
/* Look up the FCP command IOCB and create pseudo response IOCB */ /* Look up the FCP command IOCB and create pseudo response IOCB */
spin_lock_irqsave(&pring->ring_lock, iflags); spin_lock_irqsave(&pring->ring_lock, iflags);
pring->stats.iocb_event++; pring->stats.iocb_event++;
spin_unlock_irqrestore(&pring->ring_lock, iflags);
cmdiocbq = lpfc_sli_iocbq_lookup_by_tag(phba, pring, cmdiocbq = lpfc_sli_iocbq_lookup_by_tag(phba, pring,
bf_get(lpfc_wcqe_c_request_tag, wcqe)); bf_get(lpfc_wcqe_c_request_tag, wcqe));
spin_unlock_irqrestore(&pring->ring_lock, iflags);
if (unlikely(!cmdiocbq)) { if (unlikely(!cmdiocbq)) {
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
"0374 FCP complete with no corresponding " "0374 FCP complete with no corresponding "
......
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