|
Hannes Reinecke |
16a9e5 |
From: James Smart <jsmart2021@gmail.com>
|
|
Hannes Reinecke |
16a9e5 |
Date: Tue, 31 Mar 2020 09:50:07 -0700
|
|
Hannes Reinecke |
16a9e5 |
Subject: [PATCH] lpfc: Refactor Send LS Abort support
|
|
Hannes Reinecke |
16a9e5 |
Git-commit: 2cd0363b234f8557d0ec3fa9a099854ce7940aa3
|
|
Hannes Reinecke |
16a9e5 |
Git-repo: git://git.infradead.org/nvme.git
|
|
Hannes Reinecke |
16a9e5 |
Patch-mainline: Queued in subsystem maintainer repository
|
|
Hannes Reinecke |
16a9e5 |
References: bsc#1169045
|
|
Hannes Reinecke |
16a9e5 |
|
|
Hannes Reinecke |
16a9e5 |
Send LS Abort support is needed when Send LS Request is supported.
|
|
Hannes Reinecke |
16a9e5 |
|
|
Hannes Reinecke |
16a9e5 |
Currently, the ability to abort an NVME LS request is limited to the nvme
|
|
Hannes Reinecke |
16a9e5 |
(host) side of the driver. In preparation of both the nvme and nvmet sides
|
|
Hannes Reinecke |
16a9e5 |
supporting Send LS Abort, rework the existing ls_req abort routines such
|
|
Hannes Reinecke |
16a9e5 |
that there is common code that can be used by both sides.
|
|
Hannes Reinecke |
16a9e5 |
|
|
Hannes Reinecke |
16a9e5 |
While refactoring it was seen the logic in the abort routine was incorrect.
|
|
Hannes Reinecke |
16a9e5 |
It attempted to abort all NVME LS's on the indicated port. As such, the
|
|
Hannes Reinecke |
16a9e5 |
routine was reworked to abort only the NVME LS request that was specified.
|
|
Hannes Reinecke |
16a9e5 |
|
|
Hannes Reinecke |
16a9e5 |
Signed-off-by: Paul Ely <paul.ely@broadcom.com>
|
|
Hannes Reinecke |
16a9e5 |
Signed-off-by: James Smart <jsmart2021@gmail.com>
|
|
Hannes Reinecke |
16a9e5 |
Reviewed-by: Hannes Reinecke <hare@suse.de>
|
|
Hannes Reinecke |
16a9e5 |
Signed-off-by: Christoph Hellwig <hch@lst.de>
|
|
Hannes Reinecke |
16a9e5 |
Acked-by: Hannes Reinecke <hare@suse.com>
|
|
Hannes Reinecke |
16a9e5 |
---
|
|
Hannes Reinecke |
16a9e5 |
drivers/scsi/lpfc/lpfc_nvme.c | 125 +++++++++++++++++++++++++-----------------
|
|
Hannes Reinecke |
16a9e5 |
drivers/scsi/lpfc/lpfc_nvme.h | 2 +
|
|
Hannes Reinecke |
16a9e5 |
2 files changed, 77 insertions(+), 50 deletions(-)
|
|
Hannes Reinecke |
16a9e5 |
|
|
Hannes Reinecke |
16a9e5 |
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
|
|
Hannes Reinecke |
16a9e5 |
index 2fa48d0049bd..776ee547740a 100644
|
|
Hannes Reinecke |
16a9e5 |
--- a/drivers/scsi/lpfc/lpfc_nvme.c
|
|
Hannes Reinecke |
16a9e5 |
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
|
|
Hannes Reinecke |
16a9e5 |
@@ -790,83 +790,108 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
|
|
Hannes Reinecke |
16a9e5 |
}
|
|
Hannes Reinecke |
16a9e5 |
|
|
Hannes Reinecke |
16a9e5 |
/**
|
|
Hannes Reinecke |
16a9e5 |
- * lpfc_nvme_ls_abort - Issue an Link Service request
|
|
Hannes Reinecke |
16a9e5 |
- * @lpfc_pnvme: Pointer to the driver's nvme instance data
|
|
Hannes Reinecke |
16a9e5 |
- * @lpfc_nvme_lport: Pointer to the driver's local port data
|
|
Hannes Reinecke |
16a9e5 |
- * @lpfc_nvme_rport: Pointer to the rport getting the @lpfc_nvme_ereq
|
|
Hannes Reinecke |
16a9e5 |
+ * __lpfc_nvme_ls_abort - Generic service routine to abort a prior
|
|
Hannes Reinecke |
16a9e5 |
+ * NVME LS request
|
|
Hannes Reinecke |
16a9e5 |
+ * @vport: The local port that issued the LS
|
|
Hannes Reinecke |
16a9e5 |
+ * @ndlp: The remote port the LS was sent to
|
|
Hannes Reinecke |
16a9e5 |
+ * @pnvme_lsreq: Pointer to LS request structure from the transport
|
|
Hannes Reinecke |
16a9e5 |
*
|
|
Hannes Reinecke |
16a9e5 |
- * Driver registers this routine to handle any link service request
|
|
Hannes Reinecke |
16a9e5 |
- * from the nvme_fc transport to a remote nvme-aware port.
|
|
Hannes Reinecke |
16a9e5 |
+ * The driver validates the ndlp, looks for the LS, and aborts the
|
|
Hannes Reinecke |
16a9e5 |
+ * LS if found.
|
|
Hannes Reinecke |
16a9e5 |
*
|
|
Hannes Reinecke |
16a9e5 |
- * Return value :
|
|
Hannes Reinecke |
16a9e5 |
- * 0 - Success
|
|
Hannes Reinecke |
16a9e5 |
- * TODO: What are the failure codes.
|
|
Hannes Reinecke |
16a9e5 |
+ * Returns:
|
|
Hannes Reinecke |
16a9e5 |
+ * 0 : if LS found and aborted
|
|
Hannes Reinecke |
16a9e5 |
+ * non-zero: various error conditions in form -Exxx
|
|
Hannes Reinecke |
16a9e5 |
**/
|
|
Hannes Reinecke |
16a9e5 |
-static void
|
|
Hannes Reinecke |
16a9e5 |
-lpfc_nvme_ls_abort(struct nvme_fc_local_port *pnvme_lport,
|
|
Hannes Reinecke |
16a9e5 |
- struct nvme_fc_remote_port *pnvme_rport,
|
|
Hannes Reinecke |
16a9e5 |
- struct nvmefc_ls_req *pnvme_lsreq)
|
|
Hannes Reinecke |
16a9e5 |
+int
|
|
Hannes Reinecke |
16a9e5 |
+__lpfc_nvme_ls_abort(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
Hannes Reinecke |
16a9e5 |
+ struct nvmefc_ls_req *pnvme_lsreq)
|
|
Hannes Reinecke |
16a9e5 |
{
|
|
Hannes Reinecke |
16a9e5 |
- struct lpfc_nvme_lport *lport;
|
|
Hannes Reinecke |
16a9e5 |
- struct lpfc_vport *vport;
|
|
Hannes Reinecke |
16a9e5 |
- struct lpfc_hba *phba;
|
|
Hannes Reinecke |
16a9e5 |
- struct lpfc_nodelist *ndlp;
|
|
Hannes Reinecke |
16a9e5 |
- LIST_HEAD(abort_list);
|
|
Hannes Reinecke |
16a9e5 |
+ struct lpfc_hba *phba = vport->phba;
|
|
Hannes Reinecke |
16a9e5 |
struct lpfc_sli_ring *pring;
|
|
Hannes Reinecke |
16a9e5 |
struct lpfc_iocbq *wqe, *next_wqe;
|
|
Hannes Reinecke |
16a9e5 |
+ bool foundit = false;
|
|
Hannes Reinecke |
16a9e5 |
|
|
Hannes Reinecke |
16a9e5 |
- lport = (struct lpfc_nvme_lport *)pnvme_lport->private;
|
|
Hannes Reinecke |
16a9e5 |
- if (unlikely(!lport))
|
|
Hannes Reinecke |
16a9e5 |
- return;
|
|
Hannes Reinecke |
16a9e5 |
- vport = lport->vport;
|
|
Hannes Reinecke |
16a9e5 |
- phba = vport->phba;
|
|
Hannes Reinecke |
16a9e5 |
-
|
|
Hannes Reinecke |
16a9e5 |
- if (vport->load_flag & FC_UNLOADING)
|
|
Hannes Reinecke |
16a9e5 |
- return;
|
|
Hannes Reinecke |
16a9e5 |
-
|
|
Hannes Reinecke |
16a9e5 |
- ndlp = lpfc_findnode_did(vport, pnvme_rport->port_id);
|
|
Hannes Reinecke |
16a9e5 |
if (!ndlp) {
|
|
Hannes Reinecke |
16a9e5 |
- lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_ABTS,
|
|
Hannes Reinecke |
16a9e5 |
- "6049 Could not find node for DID %x\n",
|
|
Hannes Reinecke |
16a9e5 |
- pnvme_rport->port_id);
|
|
Hannes Reinecke |
16a9e5 |
- return;
|
|
Hannes Reinecke |
16a9e5 |
+ lpfc_printf_log(phba, KERN_ERR,
|
|
Hannes Reinecke |
16a9e5 |
+ LOG_NVME_DISC | LOG_NODE |
|
|
Hannes Reinecke |
16a9e5 |
+ LOG_NVME_IOERR | LOG_NVME_ABTS,
|
|
Hannes Reinecke |
16a9e5 |
+ "6049 NVMEx LS REQ Abort: Bad NDLP x%px DID "
|
|
Hannes Reinecke |
16a9e5 |
+ "x%06x, Failing LS Req\n",
|
|
Hannes Reinecke |
16a9e5 |
+ ndlp, ndlp ? ndlp->nlp_DID : 0);
|
|
Hannes Reinecke |
16a9e5 |
+ return -EINVAL;
|
|
Hannes Reinecke |
16a9e5 |
}
|
|
Hannes Reinecke |
16a9e5 |
|
|
Hannes Reinecke |
16a9e5 |
- /* Expand print to include key fields. */
|
|
Hannes Reinecke |
16a9e5 |
- lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_ABTS,
|
|
Hannes Reinecke |
16a9e5 |
- "6040 ENTER. lport x%px, rport x%px lsreq x%px rqstlen:%d "
|
|
Hannes Reinecke |
16a9e5 |
- "rsplen:%d %pad %pad\n",
|
|
Hannes Reinecke |
16a9e5 |
- pnvme_lport, pnvme_rport,
|
|
Hannes Reinecke |
16a9e5 |
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC | LOG_NVME_ABTS,
|
|
Hannes Reinecke |
16a9e5 |
+ "6040 NVMEx LS REQ Abort: Issue LS_ABORT for lsreq "
|
|
Hannes Reinecke |
16a9e5 |
+ "x%p rqstlen:%d rsplen:%d %pad %pad\n",
|
|
Hannes Reinecke |
16a9e5 |
pnvme_lsreq, pnvme_lsreq->rqstlen,
|
|
Hannes Reinecke |
16a9e5 |
pnvme_lsreq->rsplen, &pnvme_lsreq->rqstdma,
|
|
Hannes Reinecke |
16a9e5 |
&pnvme_lsreq->rspdma);
|
|
Hannes Reinecke |
16a9e5 |
|
|
Hannes Reinecke |
16a9e5 |
/*
|
|
Hannes Reinecke |
16a9e5 |
- * Lock the ELS ring txcmplq and build a local list of all ELS IOs
|
|
Hannes Reinecke |
16a9e5 |
- * that need an ABTS. The IOs need to stay on the txcmplq so that
|
|
Hannes Reinecke |
16a9e5 |
- * the abort operation completes them successfully.
|
|
Hannes Reinecke |
16a9e5 |
+ * Lock the ELS ring txcmplq and look for the wqe that matches
|
|
Hannes Reinecke |
16a9e5 |
+ * this ELS. If found, issue an abort on the wqe.
|
|
Hannes Reinecke |
16a9e5 |
*/
|
|
Hannes Reinecke |
16a9e5 |
pring = phba->sli4_hba.nvmels_wq->pring;
|
|
Hannes Reinecke |
16a9e5 |
spin_lock_irq(&phba->hbalock);
|
|
Hannes Reinecke |
16a9e5 |
spin_lock(&pring->ring_lock);
|
|
Hannes Reinecke |
16a9e5 |
list_for_each_entry_safe(wqe, next_wqe, &pring->txcmplq, list) {
|
|
Hannes Reinecke |
16a9e5 |
- /* Add to abort_list on on NDLP match. */
|
|
Hannes Reinecke |
16a9e5 |
- if (lpfc_check_sli_ndlp(phba, pring, wqe, ndlp)) {
|
|
Hannes Reinecke |
16a9e5 |
+ if (wqe->context2 == pnvme_lsreq) {
|
|
Hannes Reinecke |
16a9e5 |
wqe->iocb_flag |= LPFC_DRIVER_ABORTED;
|
|
Hannes Reinecke |
16a9e5 |
- list_add_tail(&wqe->dlist, &abort_list);
|
|
Hannes Reinecke |
16a9e5 |
+ foundit = true;
|
|
Hannes Reinecke |
16a9e5 |
+ break;
|
|
Hannes Reinecke |
16a9e5 |
}
|
|
Hannes Reinecke |
16a9e5 |
}
|
|
Hannes Reinecke |
16a9e5 |
spin_unlock(&pring->ring_lock);
|
|
Hannes Reinecke |
16a9e5 |
+
|
|
Hannes Reinecke |
16a9e5 |
+ if (foundit)
|
|
Hannes Reinecke |
16a9e5 |
+ lpfc_sli_issue_abort_iotag(phba, pring, wqe);
|
|
Hannes Reinecke |
16a9e5 |
spin_unlock_irq(&phba->hbalock);
|
|
Hannes Reinecke |
16a9e5 |
|
|
Hannes Reinecke |
16a9e5 |
- /* Abort the targeted IOs and remove them from the abort list. */
|
|
Hannes Reinecke |
16a9e5 |
- list_for_each_entry_safe(wqe, next_wqe, &abort_list, dlist) {
|
|
Hannes Reinecke |
16a9e5 |
+ if (foundit)
|
|
Hannes Reinecke |
16a9e5 |
+ return 0;
|
|
Hannes Reinecke |
16a9e5 |
+
|
|
Hannes Reinecke |
16a9e5 |
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC | LOG_NVME_ABTS,
|
|
Hannes Reinecke |
16a9e5 |
+ "6213 NVMEx LS REQ Abort: Unable to locate req x%p\n",
|
|
Hannes Reinecke |
16a9e5 |
+ pnvme_lsreq);
|
|
Hannes Reinecke |
16a9e5 |
+ return 1;
|
|
Hannes Reinecke |
16a9e5 |
+}
|
|
Hannes Reinecke |
16a9e5 |
+
|
|
Hannes Reinecke |
16a9e5 |
+/**
|
|
Hannes Reinecke |
16a9e5 |
+ * lpfc_nvme_ls_abort - Abort a prior NVME LS request
|
|
Hannes Reinecke |
16a9e5 |
+ * @lpfc_nvme_lport: Transport localport that LS is to be issued from.
|
|
Hannes Reinecke |
16a9e5 |
+ * @lpfc_nvme_rport: Transport remoteport that LS is to be sent to.
|
|
Hannes Reinecke |
16a9e5 |
+ * @pnvme_lsreq - the transport nvme_ls_req structure for the LS
|
|
Hannes Reinecke |
16a9e5 |
+ *
|
|
Hannes Reinecke |
16a9e5 |
+ * Driver registers this routine to abort a NVME LS request that is
|
|
Hannes Reinecke |
16a9e5 |
+ * in progress (from the transports perspective).
|
|
Hannes Reinecke |
16a9e5 |
+ **/
|
|
Hannes Reinecke |
16a9e5 |
+static void
|
|
Hannes Reinecke |
16a9e5 |
+lpfc_nvme_ls_abort(struct nvme_fc_local_port *pnvme_lport,
|
|
Hannes Reinecke |
16a9e5 |
+ struct nvme_fc_remote_port *pnvme_rport,
|
|
Hannes Reinecke |
16a9e5 |
+ struct nvmefc_ls_req *pnvme_lsreq)
|
|
Hannes Reinecke |
16a9e5 |
+{
|
|
Hannes Reinecke |
16a9e5 |
+ struct lpfc_nvme_lport *lport;
|
|
Hannes Reinecke |
16a9e5 |
+ struct lpfc_vport *vport;
|
|
Hannes Reinecke |
16a9e5 |
+ struct lpfc_hba *phba;
|
|
Hannes Reinecke |
16a9e5 |
+ struct lpfc_nodelist *ndlp;
|
|
Hannes Reinecke |
16a9e5 |
+ int ret;
|
|
Hannes Reinecke |
16a9e5 |
+
|
|
Hannes Reinecke |
16a9e5 |
+ lport = (struct lpfc_nvme_lport *)pnvme_lport->private;
|
|
Hannes Reinecke |
16a9e5 |
+ if (unlikely(!lport))
|
|
Hannes Reinecke |
16a9e5 |
+ return;
|
|
Hannes Reinecke |
16a9e5 |
+ vport = lport->vport;
|
|
Hannes Reinecke |
16a9e5 |
+ phba = vport->phba;
|
|
Hannes Reinecke |
16a9e5 |
+
|
|
Hannes Reinecke |
16a9e5 |
+ if (vport->load_flag & FC_UNLOADING)
|
|
Hannes Reinecke |
16a9e5 |
+ return;
|
|
Hannes Reinecke |
16a9e5 |
+
|
|
Hannes Reinecke |
16a9e5 |
+ ndlp = lpfc_findnode_did(vport, pnvme_rport->port_id);
|
|
Hannes Reinecke |
16a9e5 |
+
|
|
Hannes Reinecke |
16a9e5 |
+ ret = __lpfc_nvme_ls_abort(vport, ndlp, pnvme_lsreq);
|
|
Hannes Reinecke |
16a9e5 |
+ if (!ret)
|
|
Hannes Reinecke |
16a9e5 |
atomic_inc(&lport->xmt_ls_abort);
|
|
Hannes Reinecke |
16a9e5 |
- spin_lock_irq(&phba->hbalock);
|
|
Hannes Reinecke |
16a9e5 |
- list_del_init(&wqe->dlist);
|
|
Hannes Reinecke |
16a9e5 |
- lpfc_sli_issue_abort_iotag(phba, pring, wqe);
|
|
Hannes Reinecke |
16a9e5 |
- spin_unlock_irq(&phba->hbalock);
|
|
Hannes Reinecke |
16a9e5 |
- }
|
|
Hannes Reinecke |
16a9e5 |
}
|
|
Hannes Reinecke |
16a9e5 |
|
|
Hannes Reinecke |
16a9e5 |
/* Fix up the existing sgls for NVME IO. */
|
|
Hannes Reinecke |
16a9e5 |
diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h
|
|
Hannes Reinecke |
16a9e5 |
index 6f8d44aa47b2..a9ad81d0c182 100644
|
|
Hannes Reinecke |
16a9e5 |
--- a/drivers/scsi/lpfc/lpfc_nvme.h
|
|
Hannes Reinecke |
16a9e5 |
+++ b/drivers/scsi/lpfc/lpfc_nvme.h
|
|
Hannes Reinecke |
16a9e5 |
@@ -237,6 +237,8 @@ int __lpfc_nvme_ls_req(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
Hannes Reinecke |
16a9e5 |
struct lpfc_wcqe_complete *wcqe));
|
|
Hannes Reinecke |
16a9e5 |
void __lpfc_nvme_ls_req_cmp(struct lpfc_hba *phba, struct lpfc_vport *vport,
|
|
Hannes Reinecke |
16a9e5 |
struct lpfc_iocbq *cmdwqe, struct lpfc_wcqe_complete *wcqe);
|
|
Hannes Reinecke |
16a9e5 |
+int __lpfc_nvme_ls_abort(struct lpfc_vport *vport,
|
|
Hannes Reinecke |
16a9e5 |
+ struct lpfc_nodelist *ndlp, struct nvmefc_ls_req *pnvme_lsreq);
|
|
Hannes Reinecke |
16a9e5 |
|
|
Hannes Reinecke |
16a9e5 |
/* routines found in lpfc_nvmet.c */
|
|
Hannes Reinecke |
16a9e5 |
int lpfc_nvme_unsol_ls_issue_abort(struct lpfc_hba *phba,
|
|
Hannes Reinecke |
16a9e5 |
--
|
|
Hannes Reinecke |
16a9e5 |
2.16.4
|
|
Hannes Reinecke |
16a9e5 |
|