forked from Minki/linux
scsi: lpfc: Rework locations of ndlp reference taking
Now that the driver has gone to a normal ref interface (with no odd logic) the discovery logic needs to be updated to reworked so that it properly takes references when it should and give them up when it should. Rework the driver for the following get/put model: - Move gets to just before an I/O is issued. Add gets for places where an I/O was issued without one. - Ensure that failures from lpfc_nlp_get() are handled by the driver. - Check and fix the placement of lpfc_nlp_puts relative to io completions. Note: some of these paths may not release the reference on the exact io completion as the reference is held as the code takes another step in the discovery thread and which may cause another io to be issued. - Rearrange some code for error processing and calling lpfc_nlp_put. - Fix some places of incorrect reference freeing that was causing the premature releasing of the structure. - Nvmet plogi handling performs unreg_rpi's. The reference counts were unbalanced resulting in premature node removal. In some cases this caused loss of node discovery. Corrected the reftaking around nvmet plogis. Nodes that experience devloss now get released from the node list now that there is a proper reference taking. Link: https://lore.kernel.org/r/20201115192646.12977-3-james.smart@broadcom.com Co-developed-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
307e338097
commit
4430f7fd09
@ -329,7 +329,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
|
||||
spin_unlock_irqrestore(&phba->hbalock, flags);
|
||||
|
||||
iocb = &dd_data->context_un.iocb;
|
||||
ndlp = iocb->ndlp;
|
||||
ndlp = iocb->cmdiocbq->context_un.ndlp;
|
||||
rmp = iocb->rmp;
|
||||
cmp = cmdiocbq->context2;
|
||||
bmp = cmdiocbq->context3;
|
||||
@ -366,8 +366,8 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
|
||||
lpfc_free_bsg_buffers(phba, rmp);
|
||||
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
|
||||
kfree(bmp);
|
||||
lpfc_sli_release_iocbq(phba, cmdiocbq);
|
||||
lpfc_nlp_put(ndlp);
|
||||
lpfc_sli_release_iocbq(phba, cmdiocbq);
|
||||
kfree(dd_data);
|
||||
|
||||
/* Complete the job if the job is still active */
|
||||
@ -408,6 +408,9 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)
|
||||
/* in case no data is transferred */
|
||||
bsg_reply->reply_payload_rcv_len = 0;
|
||||
|
||||
if (ndlp->nlp_flag & NLP_ELS_SND_MASK)
|
||||
return -ENODEV;
|
||||
|
||||
/* allocate our bsg tracking structure */
|
||||
dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
|
||||
if (!dd_data) {
|
||||
@ -417,20 +420,10 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)
|
||||
goto no_dd_data;
|
||||
}
|
||||
|
||||
if (!lpfc_nlp_get(ndlp)) {
|
||||
rc = -ENODEV;
|
||||
goto no_ndlp;
|
||||
}
|
||||
|
||||
if (ndlp->nlp_flag & NLP_ELS_SND_MASK) {
|
||||
rc = -ENODEV;
|
||||
goto free_ndlp;
|
||||
}
|
||||
|
||||
cmdiocbq = lpfc_sli_get_iocbq(phba);
|
||||
if (!cmdiocbq) {
|
||||
rc = -ENOMEM;
|
||||
goto free_ndlp;
|
||||
goto free_dd;
|
||||
}
|
||||
|
||||
cmd = &cmdiocbq->iocb;
|
||||
@ -496,11 +489,10 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)
|
||||
cmdiocbq->context1 = dd_data;
|
||||
cmdiocbq->context2 = cmp;
|
||||
cmdiocbq->context3 = bmp;
|
||||
cmdiocbq->context_un.ndlp = ndlp;
|
||||
|
||||
dd_data->type = TYPE_IOCB;
|
||||
dd_data->set_job = job;
|
||||
dd_data->context_un.iocb.cmdiocbq = cmdiocbq;
|
||||
dd_data->context_un.iocb.ndlp = ndlp;
|
||||
dd_data->context_un.iocb.rmp = rmp;
|
||||
job->dd_data = dd_data;
|
||||
|
||||
@ -514,8 +506,13 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)
|
||||
readl(phba->HCregaddr); /* flush */
|
||||
}
|
||||
|
||||
iocb_stat = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0);
|
||||
cmdiocbq->context_un.ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!cmdiocbq->context_un.ndlp) {
|
||||
rc = -ENODEV;
|
||||
goto free_rmp;
|
||||
}
|
||||
|
||||
iocb_stat = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0);
|
||||
if (iocb_stat == IOCB_SUCCESS) {
|
||||
spin_lock_irqsave(&phba->hbalock, flags);
|
||||
/* make sure the I/O had not been completed yet */
|
||||
@ -532,7 +529,7 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)
|
||||
}
|
||||
|
||||
/* iocb failed so cleanup */
|
||||
job->dd_data = NULL;
|
||||
lpfc_nlp_put(ndlp);
|
||||
|
||||
free_rmp:
|
||||
lpfc_free_bsg_buffers(phba, rmp);
|
||||
@ -544,9 +541,7 @@ free_bmp:
|
||||
kfree(bmp);
|
||||
free_cmdiocbq:
|
||||
lpfc_sli_release_iocbq(phba, cmdiocbq);
|
||||
free_ndlp:
|
||||
lpfc_nlp_put(ndlp);
|
||||
no_ndlp:
|
||||
free_dd:
|
||||
kfree(dd_data);
|
||||
no_dd_data:
|
||||
/* make error code available to userspace */
|
||||
@ -640,8 +635,9 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
|
||||
}
|
||||
}
|
||||
|
||||
lpfc_nlp_put(ndlp);
|
||||
lpfc_els_free_iocb(phba, cmdiocbq);
|
||||
|
||||
lpfc_nlp_put(ndlp);
|
||||
kfree(dd_data);
|
||||
|
||||
/* Complete the job if the job is still active */
|
||||
@ -718,15 +714,14 @@ lpfc_bsg_rport_els(struct bsg_job *job)
|
||||
goto release_ndlp;
|
||||
}
|
||||
|
||||
rpi = ndlp->nlp_rpi;
|
||||
|
||||
/* Transfer the request payload to allocated command dma buffer */
|
||||
|
||||
sg_copy_to_buffer(job->request_payload.sg_list,
|
||||
job->request_payload.sg_cnt,
|
||||
((struct lpfc_dmabuf *)cmdiocbq->context2)->virt,
|
||||
cmdsize);
|
||||
|
||||
rpi = ndlp->nlp_rpi;
|
||||
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
cmdiocbq->iocb.ulpContext = phba->sli4_hba.rpi_ids[rpi];
|
||||
else
|
||||
@ -752,8 +747,13 @@ lpfc_bsg_rport_els(struct bsg_job *job)
|
||||
readl(phba->HCregaddr); /* flush */
|
||||
}
|
||||
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0);
|
||||
cmdiocbq->context1 = lpfc_nlp_get(ndlp);
|
||||
if (!cmdiocbq->context1) {
|
||||
rc = -EIO;
|
||||
goto linkdown_err;
|
||||
}
|
||||
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0);
|
||||
if (rc == IOCB_SUCCESS) {
|
||||
spin_lock_irqsave(&phba->hbalock, flags);
|
||||
/* make sure the I/O had not been completed/released */
|
||||
@ -769,11 +769,9 @@ lpfc_bsg_rport_els(struct bsg_job *job)
|
||||
rc = -EIO;
|
||||
}
|
||||
|
||||
/* iocb failed so cleanup */
|
||||
job->dd_data = NULL;
|
||||
/* I/O issue failed. Cleanup resources. */
|
||||
|
||||
linkdown_err:
|
||||
cmdiocbq->context1 = ndlp;
|
||||
lpfc_els_free_iocb(phba, cmdiocbq);
|
||||
|
||||
release_ndlp:
|
||||
@ -1469,6 +1467,15 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job, uint32_t tag,
|
||||
unsigned long flags;
|
||||
uint32_t creg_val;
|
||||
|
||||
ndlp = lpfc_findnode_did(phba->pport, phba->ct_ctx[tag].SID);
|
||||
if (!ndlp) {
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_ELS,
|
||||
"2721 ndlp null for oxid %x SID %x\n",
|
||||
phba->ct_ctx[tag].rxid,
|
||||
phba->ct_ctx[tag].SID);
|
||||
return IOCB_ERROR;
|
||||
}
|
||||
|
||||
/* allocate our bsg tracking structure */
|
||||
dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
|
||||
if (!dd_data) {
|
||||
@ -1559,7 +1566,11 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job, uint32_t tag,
|
||||
dd_data->type = TYPE_IOCB;
|
||||
dd_data->set_job = job;
|
||||
dd_data->context_un.iocb.cmdiocbq = ctiocb;
|
||||
dd_data->context_un.iocb.ndlp = ndlp;
|
||||
dd_data->context_un.iocb.ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!dd_data->context_un.iocb.ndlp) {
|
||||
rc = -IOCB_ERROR;
|
||||
goto issue_ct_rsp_exit;
|
||||
}
|
||||
dd_data->context_un.iocb.rmp = NULL;
|
||||
job->dd_data = dd_data;
|
||||
|
||||
@ -1574,7 +1585,6 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job, uint32_t tag,
|
||||
}
|
||||
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, ctiocb, 0);
|
||||
|
||||
if (rc == IOCB_SUCCESS) {
|
||||
spin_lock_irqsave(&phba->hbalock, flags);
|
||||
/* make sure the I/O had not been completed/released */
|
||||
@ -1588,6 +1598,7 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job, uint32_t tag,
|
||||
|
||||
/* iocb failed so cleanup */
|
||||
job->dd_data = NULL;
|
||||
lpfc_nlp_put(ndlp);
|
||||
|
||||
issue_ct_rsp_exit:
|
||||
lpfc_sli_release_iocbq(phba, ctiocb);
|
||||
|
@ -548,10 +548,8 @@ lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb)
|
||||
{
|
||||
struct lpfc_dmabuf *buf_ptr;
|
||||
|
||||
if (ctiocb->context_un.ndlp) {
|
||||
lpfc_nlp_put(ctiocb->context_un.ndlp);
|
||||
/* I/O job is complete so context is now invalid*/
|
||||
ctiocb->context_un.ndlp = NULL;
|
||||
}
|
||||
if (ctiocb->context1) {
|
||||
buf_ptr = (struct lpfc_dmabuf *) ctiocb->context1;
|
||||
lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
|
||||
@ -618,7 +616,6 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
|
||||
/* Save for completion so we can release these resources */
|
||||
geniocb->context1 = (uint8_t *) inp;
|
||||
geniocb->context2 = (uint8_t *) outp;
|
||||
geniocb->context_un.ndlp = lpfc_nlp_get(ndlp);
|
||||
|
||||
/* Fill in payload, bp points to frame payload */
|
||||
icmd->ulpCommand = CMD_GEN_REQUEST64_CR;
|
||||
@ -657,16 +654,21 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
|
||||
geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
|
||||
geniocb->vport = vport;
|
||||
geniocb->retry = retry;
|
||||
geniocb->context_un.ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!geniocb->context_un.ndlp)
|
||||
goto out;
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, geniocb, 0);
|
||||
|
||||
if (rc == IOCB_ERROR) {
|
||||
geniocb->context_un.ndlp = NULL;
|
||||
lpfc_nlp_put(ndlp);
|
||||
lpfc_sli_release_iocbq(phba, geniocb);
|
||||
return 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
lpfc_sli_release_iocbq(phba, geniocb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1134,8 +1136,8 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
lpfc_disc_start(vport);
|
||||
}
|
||||
out:
|
||||
cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
|
||||
lpfc_ct_free_iocb(phba, cmdiocb);
|
||||
lpfc_nlp_put(ndlp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1341,8 +1343,8 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
lpfc_disc_start(vport);
|
||||
}
|
||||
out:
|
||||
cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
|
||||
lpfc_ct_free_iocb(phba, cmdiocb);
|
||||
lpfc_nlp_put(ndlp);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1357,7 +1359,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
int did, rc, retry;
|
||||
uint8_t fbits;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
struct lpfc_nodelist *ndlp = NULL, *free_ndlp = NULL;
|
||||
|
||||
did = ((struct lpfc_sli_ct_request *) inp->virt)->un.gff.PortId;
|
||||
did = be32_to_cpu(did);
|
||||
@ -1423,7 +1425,9 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
cmdiocb->retry, did);
|
||||
if (rc == 0) {
|
||||
/* success */
|
||||
free_ndlp = cmdiocb->context_un.ndlp;
|
||||
lpfc_ct_free_iocb(phba, cmdiocb);
|
||||
lpfc_nlp_put(free_ndlp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1476,7 +1480,10 @@ out:
|
||||
}
|
||||
lpfc_disc_start(vport);
|
||||
}
|
||||
|
||||
free_ndlp = cmdiocb->context_un.ndlp;
|
||||
lpfc_ct_free_iocb(phba, cmdiocb);
|
||||
lpfc_nlp_put(free_ndlp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1490,7 +1497,8 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *)cmdiocb->context2;
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
int did;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
struct lpfc_nodelist *ndlp = NULL;
|
||||
struct lpfc_nodelist *ns_ndlp = NULL;
|
||||
uint32_t fc4_data_0, fc4_data_1;
|
||||
|
||||
did = ((struct lpfc_sli_ct_request *)inp->virt)->un.gft.PortId;
|
||||
@ -1500,6 +1508,9 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
"GFT_ID cmpl: status:x%x/x%x did:x%x",
|
||||
irsp->ulpStatus, irsp->un.ulpWord[4], did);
|
||||
|
||||
/* Preserve the nameserver node to release the reference. */
|
||||
ns_ndlp = cmdiocb->context_un.ndlp;
|
||||
|
||||
if (irsp->ulpStatus == IOSTAT_SUCCESS) {
|
||||
/* Good status, continue checking */
|
||||
CTrsp = (struct lpfc_sli_ct_request *)outp->virt;
|
||||
@ -1515,6 +1526,10 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
(fc4_data_1 & LPFC_FC4_TYPE_BITMASK) ?
|
||||
"NVME" : " ");
|
||||
|
||||
/* Lookup the NPort_ID queried in the GFT_ID and find the
|
||||
* driver's local node. It's an error if the driver
|
||||
* doesn't have one.
|
||||
*/
|
||||
ndlp = lpfc_findnode_did(vport, did);
|
||||
if (ndlp) {
|
||||
/* The bitmask value for FCP and NVME FCP types is
|
||||
@ -1560,6 +1575,7 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
"3065 GFT_ID failed x%08x\n", irsp->ulpStatus);
|
||||
|
||||
lpfc_ct_free_iocb(phba, cmdiocb);
|
||||
lpfc_nlp_put(ns_ndlp);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1629,8 +1645,8 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
}
|
||||
|
||||
out:
|
||||
cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
|
||||
lpfc_ct_free_iocb(phba, cmdiocb);
|
||||
lpfc_nlp_put(ndlp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2113,11 +2129,6 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
|
||||
}
|
||||
rc=6;
|
||||
|
||||
/* Decrement ndlp reference count to release ndlp reference held
|
||||
* for the failed command's callback function.
|
||||
*/
|
||||
lpfc_nlp_put(ndlp);
|
||||
|
||||
ns_cmd_free_bmpvirt:
|
||||
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
|
||||
ns_cmd_free_bmp:
|
||||
@ -2154,7 +2165,7 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;
|
||||
uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp;
|
||||
IOCB_t *irsp = &rspiocb->iocb;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
struct lpfc_nodelist *ndlp, *free_ndlp = NULL;
|
||||
uint32_t latt, cmd, err;
|
||||
|
||||
latt = lpfc_els_chk_latt(vport);
|
||||
@ -2200,7 +2211,10 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus,
|
||||
irsp->un.ulpWord[4]);
|
||||
}
|
||||
|
||||
free_ndlp = cmdiocb->context_un.ndlp;
|
||||
lpfc_ct_free_iocb(phba, cmdiocb);
|
||||
lpfc_nlp_put(free_ndlp);
|
||||
|
||||
ndlp = lpfc_findnode_did(vport, FDMI_DID);
|
||||
if (!ndlp)
|
||||
@ -3582,12 +3596,6 @@ port_out:
|
||||
if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, 0))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Decrement ndlp reference count to release ndlp reference held
|
||||
* for the failed command's callback function.
|
||||
*/
|
||||
lpfc_nlp_put(ndlp);
|
||||
|
||||
fdmi_cmd_free_bmpvirt:
|
||||
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
|
||||
fdmi_cmd_free_bmp:
|
||||
|
@ -166,8 +166,7 @@ struct lpfc_node_rrq {
|
||||
#define NLP_NVMET_RECOV 0x00001000 /* NVMET auditing node for recovery. */
|
||||
#define NLP_FCP_PRLI_RJT 0x00002000 /* Rport does not support FCP PRLI. */
|
||||
#define NLP_UNREG_INP 0x00008000 /* UNREG_RPI cmd is in progress */
|
||||
#define NLP_DEFER_RM 0x00010000 /* Remove this ndlp if no longer used */
|
||||
#define NLP_DROPPED 0x00000008 /* Init ref count has been dropped */
|
||||
#define NLP_DROPPED 0x00010000 /* Init ref count has been dropped */
|
||||
#define NLP_DELAY_TMO 0x00020000 /* delay timeout is running for node */
|
||||
#define NLP_NPR_2B_DISC 0x00040000 /* node is included in num_disc_nodes */
|
||||
#define NLP_RCV_PLOGI 0x00080000 /* Rcv'ed PLOGI from remote system */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4214,6 +4214,13 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
||||
rport->supported_classes = ndlp->nlp_class_sup;
|
||||
rdata = rport->dd_data;
|
||||
rdata->pnode = lpfc_nlp_get(ndlp);
|
||||
if (!rdata->pnode) {
|
||||
dev_warn(&phba->pcidev->dev,
|
||||
"Warning - node ref failed. Unreg rport\n");
|
||||
fc_remote_port_delete(rport);
|
||||
ndlp->rport = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ndlp->nlp_type & NLP_FCP_TARGET)
|
||||
rport_ids.roles |= FC_PORT_ROLE_FCP_TARGET;
|
||||
@ -5157,8 +5164,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
||||
int rc;
|
||||
|
||||
lpfc_cancel_retry_delay_tmo(vport, ndlp);
|
||||
if ((ndlp->nlp_flag & NLP_DEFER_RM) &&
|
||||
!(ndlp->nlp_flag & NLP_REG_LOGIN_SEND) &&
|
||||
if (!(ndlp->nlp_flag & NLP_REG_LOGIN_SEND) &&
|
||||
!(ndlp->nlp_flag & NLP_RPI_REGISTERED) &&
|
||||
phba->sli_rev != LPFC_SLI_REV4) {
|
||||
/* For this case we need to cleanup the default rpi
|
||||
|
@ -357,7 +357,6 @@ lpfc_defer_acc_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
* Complete the unreg rpi mbx request, and update flags.
|
||||
* This will also restart any deferred events.
|
||||
*/
|
||||
lpfc_nlp_get(ndlp);
|
||||
lpfc_sli4_unreg_rpi_cmpl_clr(phba, pmb);
|
||||
|
||||
if (!piocb) {
|
||||
@ -365,7 +364,7 @@ lpfc_defer_acc_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
"4578 PLOGI ACC fail\n");
|
||||
if (mbox)
|
||||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, piocb, ndlp, mbox);
|
||||
@ -376,8 +375,6 @@ lpfc_defer_acc_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
}
|
||||
kfree(piocb);
|
||||
out:
|
||||
lpfc_nlp_put(ndlp);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -588,7 +585,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
lpfc_unreg_login(phba, vport->vpi, rpi, link_mbox);
|
||||
link_mbox->vport = vport;
|
||||
link_mbox->ctx_ndlp = ndlp;
|
||||
link_mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!link_mbox->ctx_ndlp)
|
||||
goto out;
|
||||
|
||||
link_mbox->mbox_cmpl = lpfc_defer_acc_rsp;
|
||||
|
||||
if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&
|
||||
@ -1104,7 +1104,11 @@ lpfc_release_rpi(struct lpfc_hba *phba, struct lpfc_vport *vport,
|
||||
lpfc_unreg_login(phba, vport->vpi, rpi, pmb);
|
||||
pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
pmb->vport = vport;
|
||||
pmb->ctx_ndlp = ndlp;
|
||||
pmb->ctx_ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!pmb->ctx_ndlp) {
|
||||
mempool_free(pmb, phba->mbox_mem_pool);
|
||||
return;
|
||||
}
|
||||
|
||||
if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&
|
||||
(!(vport->fc_flag & FC_OFFLINE_MODE)))
|
||||
@ -1342,7 +1346,6 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
|
||||
uint32_t evt)
|
||||
{
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
struct lpfc_iocbq *cmdiocb, *rspiocb;
|
||||
struct lpfc_dmabuf *pcmd, *prsp, *mp;
|
||||
uint32_t *lp;
|
||||
@ -1488,7 +1491,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
|
||||
ndlp->nlp_flag |= NLP_REG_LOGIN_SEND;
|
||||
mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
|
||||
}
|
||||
|
||||
mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!mbox->ctx_ndlp)
|
||||
goto out;
|
||||
|
||||
mbox->vport = vport;
|
||||
if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
|
||||
!= MBX_NOT_FINISHED) {
|
||||
@ -1537,9 +1544,6 @@ out:
|
||||
|
||||
ndlp->nlp_prev_state = ndlp->nlp_state;
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
ndlp->nlp_flag |= NLP_DEFER_RM;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
return NLP_STE_FREED_NODE;
|
||||
}
|
||||
|
||||
@ -2797,16 +2801,12 @@ lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
{
|
||||
struct lpfc_iocbq *cmdiocb, *rspiocb;
|
||||
IOCB_t *irsp;
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
|
||||
cmdiocb = (struct lpfc_iocbq *) arg;
|
||||
rspiocb = cmdiocb->context_un.rsp_iocb;
|
||||
|
||||
irsp = &rspiocb->iocb;
|
||||
if (irsp->ulpStatus) {
|
||||
spin_lock_irq(shost->host_lock);
|
||||
ndlp->nlp_flag |= NLP_DEFER_RM;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
return NLP_STE_FREED_NODE;
|
||||
}
|
||||
return ndlp->nlp_state;
|
||||
|
@ -566,6 +566,13 @@ lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
|
||||
|
||||
/* Save for completion so we can release these resources */
|
||||
genwqe->context1 = lpfc_nlp_get(ndlp);
|
||||
if (!genwqe->context1) {
|
||||
dev_warn(&phba->pcidev->dev,
|
||||
"Warning: Failed node ref, not sending LS_REQ\n");
|
||||
lpfc_sli_release_iocbq(phba, genwqe);
|
||||
return 1;
|
||||
}
|
||||
|
||||
genwqe->context2 = (uint8_t *)pnvme_lsreq;
|
||||
/* Fill in payload, bp points to frame payload */
|
||||
|
||||
@ -2459,7 +2466,11 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
||||
spin_unlock_irq(&vport->phba->hbalock);
|
||||
} else {
|
||||
spin_unlock_irq(&vport->phba->hbalock);
|
||||
lpfc_nlp_get(ndlp);
|
||||
if (!lpfc_nlp_get(ndlp)) {
|
||||
dev_warn(&vport->phba->pcidev->dev,
|
||||
"Warning - No node ref - exit register\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ret = nvme_fc_register_remoteport(localport, &rpinfo, &remote_port);
|
||||
|
@ -2594,7 +2594,6 @@ lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
ndlp->nlp_flag,
|
||||
ndlp);
|
||||
ndlp->nlp_flag &= ~NLP_LOGO_ACC;
|
||||
lpfc_nlp_put(ndlp);
|
||||
|
||||
/* Check to see if there are any deferred
|
||||
* events to process
|
||||
@ -2617,6 +2616,8 @@ lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
} else {
|
||||
__lpfc_sli_rpi_release(vport, ndlp);
|
||||
}
|
||||
|
||||
lpfc_nlp_put(ndlp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11352,11 +11353,11 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
"x%x x%x x%x\n",
|
||||
irsp->ulpIoTag, irsp->ulpStatus,
|
||||
irsp->un.ulpWord[4], irsp->ulpTimeout);
|
||||
lpfc_nlp_put((struct lpfc_nodelist *)cmdiocb->context1);
|
||||
if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR)
|
||||
lpfc_ct_free_iocb(phba, cmdiocb);
|
||||
else
|
||||
lpfc_els_free_iocb(phba, cmdiocb);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -17924,6 +17925,10 @@ lpfc_sli4_seq_abort_rsp(struct lpfc_vport *vport,
|
||||
icmd->ulpClass = CLASS3;
|
||||
icmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
ctiocb->context1 = lpfc_nlp_get(ndlp);
|
||||
if (!ctiocb->context1) {
|
||||
lpfc_sli_release_iocbq(phba, ctiocb);
|
||||
return;
|
||||
}
|
||||
|
||||
ctiocb->vport = phba->pport;
|
||||
ctiocb->iocb_cmpl = lpfc_sli4_seq_abort_rsp_cmpl;
|
||||
|
Loading…
Reference in New Issue
Block a user