Skip to content

Commit 86c6737

Browse files
jsmart-ghChristoph Hellwig
authored and
Christoph Hellwig
committed
Update ABORT processing for NVMET.
The driver with nvme had this routine stubbed. Right now XRI_ABORTED_CQE is not handled and the FC NVMET Transport has a new API for the driver. Missing code path, new NVME abort API Update ABORT processing for NVMET There are 3 new FC NVMET Transport API/ template routines for NVMET: lpfc_nvmet_xmt_fcp_release This NVMET template callback routine called to release context associated with an IO This routine is ALWAYS called last, even if the IO was aborted or completed in error. lpfc_nvmet_xmt_fcp_abort This NVMET template callback routine called to abort an exchange that has an IO in progress nvmet_fc_rcv_fcp_req When the lpfc driver receives an ABTS, this NVME FC transport layer callback routine is called. For this case there are 2 paths thru the driver: the driver either has an outstanding exchange / context for the XRI to be aborted or not. If not, a BA_RJT is issued otherwise a BA_ACC NVMET Driver abort paths: There are 2 paths for aborting an IO. The first one is we receive an IO and decide not to process it because of lack of resources. An unsolicated ABTS is immediately sent back to the initiator as a response. lpfc_nvmet_unsol_fcp_buffer lpfc_nvmet_unsol_issue_abort (XMIT_SEQUENCE_WQE) The second one is we sent the IO up to the NVMET transport layer to process, and for some reason the NVME Transport layer decided to abort the IO before it completes all its phases. For this case there are 2 paths thru the driver: the driver either has an outstanding TSEND/TRECEIVE/TRSP WQE or no outstanding WQEs are present for the exchange / context. lpfc_nvmet_xmt_fcp_abort if (LPFC_NVMET_IO_INP) lpfc_nvmet_sol_fcp_issue_abort (ABORT_WQE) lpfc_nvmet_sol_fcp_abort_cmp else lpfc_nvmet_unsol_fcp_issue_abort lpfc_nvmet_unsol_issue_abort (XMIT_SEQUENCE_WQE) lpfc_nvmet_unsol_fcp_abort_cmp Context flags: LPFC_NVMET_IOP - his flag signifies an IO is in progress on the exchange. LPFC_NVMET_XBUSY - this flag indicates the IO completed but the firmware is still busy with the corresponding exchange. The exchange should not be reused until after a XRI_ABORTED_CQE is received for that exchange. LPFC_NVMET_ABORT_OP - this flag signifies an ABORT_WQE was issued on the exchange. LPFC_NVMET_CTX_RLS - this flag signifies a context free was requested, but we are deferring it due to an XBUSY or ABORT in progress. A ctxlock is added to the context structure that is used whenever these flags are set/read within the context of an IO. The LPFC_NVMET_CTX_RLS flag is only set in the defer_relase routine when the transport has resolved all IO associated with the buffer. The flag is cleared when the CTX is associated with a new IO. An exchange can has both an LPFC_NVMET_XBUSY and a LPFC_NVMET_ABORT_OP condition active simultaneously. Both conditions must complete before the exchange is freed. When the abort callback (lpfc_nvmet_xmt_fcp_abort) is envoked: If there is an outstanding IO, the driver will issue an ABORT_WQE. This should result in 3 completions for the exchange: 1) IO cmpl with XB bit set 2) Abort WQE cmpl 3) XRI_ABORTED_CQE cmpl For this scenerio, after completion #1, the NVMET Transport IO rsp callback is called. After completion #2, no action is taken with respect to the exchange / context. After completion #3, the exchange context is free for re-use on another IO. If there is no outstanding activity on the exchange, the driver will send a ABTS to the Initiator. Upon completion of this WQE, the exchange / context is freed for re-use on another IO. Signed-off-by: Dick Kennedy <[email protected]> Signed-off-by: James Smart <[email protected]> Reviewed-by: Johannes Thumshirn <[email protected]>
1 parent 1c5b12f commit 86c6737

File tree

10 files changed

+409
-125
lines changed

10 files changed

+409
-125
lines changed

drivers/scsi/lpfc/lpfc_crtn.h

+7
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ typedef int (*node_filter)(struct lpfc_nodelist *, void *);
2424

2525
struct fc_rport;
2626
struct fc_frame_header;
27+
struct lpfc_nvmet_rcv_ctx;
2728
void lpfc_down_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
2829
void lpfc_sli_read_link_ste(struct lpfc_hba *);
2930
void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t, uint16_t);
@@ -245,6 +246,10 @@ struct hbq_dmabuf *lpfc_sli4_rb_alloc(struct lpfc_hba *);
245246
void lpfc_sli4_rb_free(struct lpfc_hba *, struct hbq_dmabuf *);
246247
struct rqb_dmabuf *lpfc_sli4_nvmet_alloc(struct lpfc_hba *phba);
247248
void lpfc_sli4_nvmet_free(struct lpfc_hba *phba, struct rqb_dmabuf *dmab);
249+
void lpfc_nvmet_rq_post(struct lpfc_hba *phba, struct lpfc_nvmet_rcv_ctx *ctxp,
250+
struct lpfc_dmabuf *mp);
251+
int lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport,
252+
struct fc_frame_header *fc_hdr);
248253
void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *,
249254
uint16_t);
250255
int lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq,
@@ -302,6 +307,8 @@ int lpfc_sli_check_eratt(struct lpfc_hba *);
302307
void lpfc_sli_handle_slow_ring_event(struct lpfc_hba *,
303308
struct lpfc_sli_ring *, uint32_t);
304309
void lpfc_sli4_handle_received_buffer(struct lpfc_hba *, struct hbq_dmabuf *);
310+
void lpfc_sli4_seq_abort_rsp(struct lpfc_vport *vport,
311+
struct fc_frame_header *fc_hdr, bool aborted);
305312
void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
306313
void lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *, LPFC_MBOXQ_t *);
307314
int lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t,

drivers/scsi/lpfc/lpfc_debugfs.c

+41-12
Original file line numberDiff line numberDiff line change
@@ -745,73 +745,102 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size)
745745
{
746746
struct lpfc_hba *phba = vport->phba;
747747
struct lpfc_nvmet_tgtport *tgtp;
748+
struct lpfc_nvmet_rcv_ctx *ctxp, *next_ctxp;
748749
int len = 0;
750+
int cnt;
749751

750752
if (phba->nvmet_support) {
751753
if (!phba->targetport)
752754
return len;
753755
tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
754-
len += snprintf(buf+len, size-len,
756+
len += snprintf(buf + len, size - len,
755757
"\nNVME Targetport Statistics\n");
756758

757-
len += snprintf(buf+len, size-len,
759+
len += snprintf(buf + len, size - len,
758760
"LS: Rcv %08x Drop %08x Abort %08x\n",
759761
atomic_read(&tgtp->rcv_ls_req_in),
760762
atomic_read(&tgtp->rcv_ls_req_drop),
761763
atomic_read(&tgtp->xmt_ls_abort));
762764
if (atomic_read(&tgtp->rcv_ls_req_in) !=
763765
atomic_read(&tgtp->rcv_ls_req_out)) {
764-
len += snprintf(buf+len, size-len,
766+
len += snprintf(buf + len, size - len,
765767
"Rcv LS: in %08x != out %08x\n",
766768
atomic_read(&tgtp->rcv_ls_req_in),
767769
atomic_read(&tgtp->rcv_ls_req_out));
768770
}
769771

770-
len += snprintf(buf+len, size-len,
772+
len += snprintf(buf + len, size - len,
771773
"LS: Xmt %08x Drop %08x Cmpl %08x Err %08x\n",
772774
atomic_read(&tgtp->xmt_ls_rsp),
773775
atomic_read(&tgtp->xmt_ls_drop),
774776
atomic_read(&tgtp->xmt_ls_rsp_cmpl),
775777
atomic_read(&tgtp->xmt_ls_rsp_error));
776778

777-
len += snprintf(buf+len, size-len,
779+
len += snprintf(buf + len, size - len,
778780
"FCP: Rcv %08x Drop %08x\n",
779781
atomic_read(&tgtp->rcv_fcp_cmd_in),
780782
atomic_read(&tgtp->rcv_fcp_cmd_drop));
781783

782784
if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
783785
atomic_read(&tgtp->rcv_fcp_cmd_out)) {
784-
len += snprintf(buf+len, size-len,
786+
len += snprintf(buf + len, size - len,
785787
"Rcv FCP: in %08x != out %08x\n",
786788
atomic_read(&tgtp->rcv_fcp_cmd_in),
787789
atomic_read(&tgtp->rcv_fcp_cmd_out));
788790
}
789791

790-
len += snprintf(buf+len, size-len,
791-
"FCP Rsp: read %08x readrsp %08x write %08x rsp %08x\n",
792+
len += snprintf(buf + len, size - len,
793+
"FCP Rsp: read %08x readrsp %08x "
794+
"write %08x rsp %08x\n",
792795
atomic_read(&tgtp->xmt_fcp_read),
793796
atomic_read(&tgtp->xmt_fcp_read_rsp),
794797
atomic_read(&tgtp->xmt_fcp_write),
795798
atomic_read(&tgtp->xmt_fcp_rsp));
796799

797-
len += snprintf(buf+len, size-len,
800+
len += snprintf(buf + len, size - len,
798801
"FCP Rsp: abort %08x drop %08x\n",
799802
atomic_read(&tgtp->xmt_fcp_abort),
800803
atomic_read(&tgtp->xmt_fcp_drop));
801804

802-
len += snprintf(buf+len, size-len,
805+
len += snprintf(buf + len, size - len,
803806
"FCP Rsp Cmpl: %08x err %08x drop %08x\n",
804807
atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
805808
atomic_read(&tgtp->xmt_fcp_rsp_error),
806809
atomic_read(&tgtp->xmt_fcp_rsp_drop));
807810

808-
len += snprintf(buf+len, size-len,
811+
len += snprintf(buf + len, size - len,
809812
"ABORT: Xmt %08x Err %08x Cmpl %08x",
810813
atomic_read(&tgtp->xmt_abort_rsp),
811814
atomic_read(&tgtp->xmt_abort_rsp_error),
812815
atomic_read(&tgtp->xmt_abort_cmpl));
813816

814-
len += snprintf(buf+len, size-len, "\n");
817+
len += snprintf(buf + len, size - len, "\n");
818+
819+
cnt = 0;
820+
spin_lock(&phba->sli4_hba.abts_nvme_buf_list_lock);
821+
list_for_each_entry_safe(ctxp, next_ctxp,
822+
&phba->sli4_hba.lpfc_abts_nvmet_ctx_list,
823+
list) {
824+
cnt++;
825+
}
826+
spin_unlock(&phba->sli4_hba.abts_nvme_buf_list_lock);
827+
if (cnt) {
828+
len += snprintf(buf + len, size - len,
829+
"ABORT: %d ctx entries\n", cnt);
830+
spin_lock(&phba->sli4_hba.abts_nvme_buf_list_lock);
831+
list_for_each_entry_safe(ctxp, next_ctxp,
832+
&phba->sli4_hba.lpfc_abts_nvmet_ctx_list,
833+
list) {
834+
if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ))
835+
break;
836+
len += snprintf(buf + len, size - len,
837+
"Entry: oxid %x state %x "
838+
"flag %x\n",
839+
ctxp->oxid, ctxp->state,
840+
ctxp->flag);
841+
}
842+
spin_unlock(&phba->sli4_hba.abts_nvme_buf_list_lock);
843+
}
815844
} else {
816845
if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME))
817846
return len;

drivers/scsi/lpfc/lpfc_hw4.h

+3
Original file line numberDiff line numberDiff line change
@@ -2720,6 +2720,9 @@ struct lpfc_mbx_request_features {
27202720
#define lpfc_mbx_rq_ftr_rq_ifip_SHIFT 7
27212721
#define lpfc_mbx_rq_ftr_rq_ifip_MASK 0x00000001
27222722
#define lpfc_mbx_rq_ftr_rq_ifip_WORD word2
2723+
#define lpfc_mbx_rq_ftr_rq_iaar_SHIFT 9
2724+
#define lpfc_mbx_rq_ftr_rq_iaar_MASK 0x00000001
2725+
#define lpfc_mbx_rq_ftr_rq_iaar_WORD word2
27232726
#define lpfc_mbx_rq_ftr_rq_perfh_SHIFT 11
27242727
#define lpfc_mbx_rq_ftr_rq_perfh_MASK 0x00000001
27252728
#define lpfc_mbx_rq_ftr_rq_perfh_WORD word2

drivers/scsi/lpfc/lpfc_init.c

+33-19
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@
4242
#include <scsi/scsi_device.h>
4343
#include <scsi/scsi_host.h>
4444
#include <scsi/scsi_transport_fc.h>
45+
#include <scsi/scsi_tcq.h>
46+
#include <scsi/fc/fc_fs.h>
47+
48+
#include <linux/nvme-fc-driver.h>
4549

4650
#include "lpfc_hw4.h"
4751
#include "lpfc_hw.h"
@@ -52,6 +56,7 @@
5256
#include "lpfc.h"
5357
#include "lpfc_scsi.h"
5458
#include "lpfc_nvme.h"
59+
#include "lpfc_nvmet.h"
5560
#include "lpfc_logmsg.h"
5661
#include "lpfc_crtn.h"
5762
#include "lpfc_vport.h"
@@ -1022,8 +1027,10 @@ static int
10221027
lpfc_hba_down_post_s4(struct lpfc_hba *phba)
10231028
{
10241029
struct lpfc_scsi_buf *psb, *psb_next;
1030+
struct lpfc_nvmet_rcv_ctx *ctxp, *ctxp_next;
10251031
LIST_HEAD(aborts);
10261032
LIST_HEAD(nvme_aborts);
1033+
LIST_HEAD(nvmet_aborts);
10271034
unsigned long iflag = 0;
10281035
struct lpfc_sglq *sglq_entry = NULL;
10291036

@@ -1046,16 +1053,10 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba)
10461053
list_for_each_entry(sglq_entry,
10471054
&phba->sli4_hba.lpfc_abts_els_sgl_list, list)
10481055
sglq_entry->state = SGL_FREED;
1049-
list_for_each_entry(sglq_entry,
1050-
&phba->sli4_hba.lpfc_abts_nvmet_sgl_list, list)
1051-
sglq_entry->state = SGL_FREED;
10521056

10531057
list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list,
10541058
&phba->sli4_hba.lpfc_els_sgl_list);
10551059

1056-
if (phba->sli4_hba.nvme_wq)
1057-
list_splice_init(&phba->sli4_hba.lpfc_abts_nvmet_sgl_list,
1058-
&phba->sli4_hba.lpfc_nvmet_sgl_list);
10591060

10601061
spin_unlock(&phba->sli4_hba.sgl_list_lock);
10611062
/* abts_scsi_buf_list_lock required because worker thread uses this
@@ -1072,6 +1073,8 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba)
10721073
spin_lock(&phba->sli4_hba.abts_nvme_buf_list_lock);
10731074
list_splice_init(&phba->sli4_hba.lpfc_abts_nvme_buf_list,
10741075
&nvme_aborts);
1076+
list_splice_init(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list,
1077+
&nvmet_aborts);
10751078
spin_unlock(&phba->sli4_hba.abts_nvme_buf_list_lock);
10761079
}
10771080

@@ -1085,13 +1088,20 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba)
10851088
list_splice(&aborts, &phba->lpfc_scsi_buf_list_put);
10861089
spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, iflag);
10871090

1088-
list_for_each_entry_safe(psb, psb_next, &nvme_aborts, list) {
1089-
psb->pCmd = NULL;
1090-
psb->status = IOSTAT_SUCCESS;
1091+
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
1092+
list_for_each_entry_safe(psb, psb_next, &nvme_aborts, list) {
1093+
psb->pCmd = NULL;
1094+
psb->status = IOSTAT_SUCCESS;
1095+
}
1096+
spin_lock_irqsave(&phba->nvme_buf_list_put_lock, iflag);
1097+
list_splice(&nvme_aborts, &phba->lpfc_nvme_buf_list_put);
1098+
spin_unlock_irqrestore(&phba->nvme_buf_list_put_lock, iflag);
1099+
1100+
list_for_each_entry_safe(ctxp, ctxp_next, &nvmet_aborts, list) {
1101+
ctxp->flag &= ~(LPFC_NVMET_XBUSY | LPFC_NVMET_ABORT_OP);
1102+
lpfc_nvmet_rq_post(phba, ctxp, &ctxp->rqb_buffer->hbuf);
1103+
}
10911104
}
1092-
spin_lock_irqsave(&phba->nvme_buf_list_put_lock, iflag);
1093-
list_splice(&nvme_aborts, &phba->lpfc_nvme_buf_list_put);
1094-
spin_unlock_irqrestore(&phba->nvme_buf_list_put_lock, iflag);
10951105

10961106
lpfc_sli4_free_sp_events(phba);
10971107
return 0;
@@ -5812,6 +5822,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
58125822
/* Initialize the Abort nvme buffer list used by driver */
58135823
spin_lock_init(&phba->sli4_hba.abts_nvme_buf_list_lock);
58145824
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_nvme_buf_list);
5825+
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list);
58155826
/* Fast-path XRI aborted CQ Event work queue list */
58165827
INIT_LIST_HEAD(&phba->sli4_hba.sp_nvme_xri_aborted_work_queue);
58175828
}
@@ -6439,7 +6450,7 @@ lpfc_init_sgl_list(struct lpfc_hba *phba)
64396450
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_els_sgl_list);
64406451
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_els_sgl_list);
64416452
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_nvmet_sgl_list);
6442-
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_nvmet_sgl_list);
6453+
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list);
64436454

64446455
/* els xri-sgl book keeping */
64456456
phba->sli4_hba.els_xri_cnt = 0;
@@ -9966,17 +9977,19 @@ lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba)
99669977
{
99679978
int wait_time = 0;
99689979
int nvme_xri_cmpl = 1;
9980+
int nvmet_xri_cmpl = 1;
99699981
int fcp_xri_cmpl = 1;
99709982
int els_xri_cmpl = list_empty(&phba->sli4_hba.lpfc_abts_els_sgl_list);
9971-
int nvmet_xri_cmpl =
9972-
list_empty(&phba->sli4_hba.lpfc_abts_nvmet_sgl_list);
99739983

99749984
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP)
99759985
fcp_xri_cmpl =
99769986
list_empty(&phba->sli4_hba.lpfc_abts_scsi_buf_list);
9977-
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)
9987+
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
99789988
nvme_xri_cmpl =
99799989
list_empty(&phba->sli4_hba.lpfc_abts_nvme_buf_list);
9990+
nvmet_xri_cmpl =
9991+
list_empty(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list);
9992+
}
99809993

99819994
while (!fcp_xri_cmpl || !els_xri_cmpl || !nvme_xri_cmpl ||
99829995
!nvmet_xri_cmpl) {
@@ -10002,9 +10015,12 @@ lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba)
1000210015
msleep(LPFC_XRI_EXCH_BUSY_WAIT_T1);
1000310016
wait_time += LPFC_XRI_EXCH_BUSY_WAIT_T1;
1000410017
}
10005-
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)
10018+
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
1000610019
nvme_xri_cmpl = list_empty(
1000710020
&phba->sli4_hba.lpfc_abts_nvme_buf_list);
10021+
nvmet_xri_cmpl = list_empty(
10022+
&phba->sli4_hba.lpfc_abts_nvmet_ctx_list);
10023+
}
1000810024

1000910025
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP)
1001010026
fcp_xri_cmpl = list_empty(
@@ -10013,8 +10029,6 @@ lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba)
1001310029
els_xri_cmpl =
1001410030
list_empty(&phba->sli4_hba.lpfc_abts_els_sgl_list);
1001510031

10016-
nvmet_xri_cmpl =
10017-
list_empty(&phba->sli4_hba.lpfc_abts_nvmet_sgl_list);
1001810032
}
1001910033
}
1002010034

drivers/scsi/lpfc/lpfc_mbox.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -2083,9 +2083,12 @@ lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq)
20832083
if (phba->max_vpi && phba->cfg_enable_npiv)
20842084
bf_set(lpfc_mbx_rq_ftr_rq_npiv, &mboxq->u.mqe.un.req_ftrs, 1);
20852085

2086-
if (phba->nvmet_support)
2086+
if (phba->nvmet_support) {
20872087
bf_set(lpfc_mbx_rq_ftr_rq_mrqp, &mboxq->u.mqe.un.req_ftrs, 1);
2088-
2088+
/* iaab/iaar NOT set for now */
2089+
bf_set(lpfc_mbx_rq_ftr_rq_iaab, &mboxq->u.mqe.un.req_ftrs, 0);
2090+
bf_set(lpfc_mbx_rq_ftr_rq_iaar, &mboxq->u.mqe.un.req_ftrs, 0);
2091+
}
20892092
return;
20902093
}
20912094

0 commit comments

Comments
 (0)