lpfc updates for 11.4.0.4
Subsystems (3)
v2 cover lpfc updates for 11.4.0.4
This patch set provides a number of bug fixes and additions to the driver.
The patches were cut against the Martin's 4.14/scsi-queue tree. There are no outside dependencies.
v2:
Split patch 1 into separate patches
Added stable cc's where requested
"Fix oops of nvme host during driver unload" revised to only
block submit routines due to bug. abort routines must function to cleanup.
Add "correct nvme sg segment count check" patch
Dick Kennedy (18):
lpfc: fix pci hot plug crash in timer management routines
lpfc: fix pci hot plug crash in list_add call
lpfc: Fix crash receiving ELS while detaching driver
lpfc: Fix lpfc nvme host rejecting IO with Not Ready message
lpfc: Fix warning messages when NVME_TARGET_FC not defined
lpfc: PLOGI failures during NPIV testing
lpfc: Make ktime sampling more accurate
lpfc: Move CQ processing to a soft IRQ
lpfc: Fix FCP hba_wqidx assignment
lpfc: Revise NVME module parameter descriptions for better clarity
lpfc: Fix oops if nvmet_fc_register_targetport fails
lpfc: Disable NPIV support if NVME is enabled
lpfc: Fix crash in lpfc_nvme_fcp_io_submit during LIP
lpfc: Fix secure firmware updates
lpfc: Ensure io aborts interlocked with the target.
lpfc: Extend RDP support
lpfc: Fix oops of nvme host during driver unload.
lpfc: change version to 11.4.0.4
James Smart (3):
lpfc: Reduce log spew on controller reconnects
lpfc: Set missing abort context
lpfc: correct nvme sg segment count check
drivers/scsi/lpfc/lpfc.h | 3 + drivers/scsi/lpfc/lpfc_attr.c | 10 +- drivers/scsi/lpfc/lpfc_bsg.c | 4 +- drivers/scsi/lpfc/lpfc_els.c | 19 ++-- drivers/scsi/lpfc/lpfc_hbadisc.c | 8 +- drivers/scsi/lpfc/lpfc_hw4.h | 2 +- drivers/scsi/lpfc/lpfc_init.c | 30 ++++-- drivers/scsi/lpfc/lpfc_nportdisc.c | 2 +- drivers/scsi/lpfc/lpfc_nvme.c | 167 ++++++++++++++++++---------- drivers/scsi/lpfc/lpfc_nvmet.c | 148 +++++++++++++++++-------- drivers/scsi/lpfc/lpfc_sli.c | 216 +++++++++++++++++++++++-------------- drivers/scsi/lpfc/lpfc_sli4.h | 4 +- drivers/scsi/lpfc/lpfc_version.h | 2 +- drivers/scsi/lpfc/lpfc_vport.c | 9 ++ 14 files changed, 405 insertions(+), 219 deletions(-)
Signature · 1 line
2.13.1
PATCH v2 1/21 lpfc: fix pci hot plug crash in timer management routines
From: Dick Kennedy <[email protected]>
During pci hot plug, the kernel crashes in timer management code.
The sli4 remove_one handler is not stoping the timers as it starts to remove the port so that it can be swapped.
Fix: Stop the timers early in the handler routine.
Note: Fix in SLI-4 only. SLI-3 already stopped the timers properly.
---
v2: original v1 hot plug patch split into 2 patches
drivers/scsi/lpfc/lpfc_init.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/lpfc/lpfc_init.c +1 -0
@@ -11419,6 +11419,7 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)lpfc_debugfs_terminate (vport);lpfc_sli4_hba_unset (phba); +lpfc_stop_hba_timers (phba);spin_lock_irq (&phba->hbalock);list_del_init (&vport->listentry);spin_unlock_irq (&phba->hbalock);
Signature · 1 line
2.13.1
Re: [PATCH v2 01/21] lpfc: fix pci hot plug crash in timer management routines
Looks good,
Signature · 6 lines
Johannes Thumshirn Storage [email protected] +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
PATCH v2 2/21 lpfc: fix pci hot plug crash in list_add call
In reply to James SmartFrom: Dick Kennedy <[email protected]>
During pci hot plug, the kernel crashes in a list_add_call
The lookup by tag function will return null if the IOCB is out of range or does not have the on txcmplq flag set.
Fix: Check for null return from lookup by tag.
---
v2: original v1 hot plug patch split into 2 patches
drivers/scsi/lpfc/lpfc_sli.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/scsi/lpfc/lpfc_sli.c +10 -7
@@ -12507,19 +12507,21 @@ lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *phba,/* Look up the ELS command IOCB and create pseudo response IOCB */ cmdiocbq =lpfc_sli_iocbq_lookup_by_tag (phba, pring,bf_get (lpfc_wcqe_c_request_tag, wcqe)); -/* Put the iocb back on the txcmplq */ -lpfc_sli_ringtxcmpl_put (phba, pring, cmdiocbq); -spin_unlock_irqrestore (&pring->ring_lock, iflags); -if (unlikely (!cmdiocbq)) { +spin_unlock_irqrestore (&pring->ring_lock, iflags);lpfc_printf_log (phba,KERN_WARNING ,LOG_SLI ,"0386 ELS complete with no corresponding " -"cmdiocb: iotag (%d)\n" , -bf_get (lpfc_wcqe_c_request_tag, wcqe)); +"cmdiocb: 0x%x 0x%x 0x%x 0x%x\n" , + wcqe->word0, wcqe->total_data_placed, + wcqe->parameter, wcqe->word3);lpfc_sli_release_iocbq (phba, irspiocbq);return NULL ; } +/* Put the iocb back on the txcmplq */ +lpfc_sli_ringtxcmpl_put (phba, pring, cmdiocbq); +spin_unlock_irqrestore (&pring->ring_lock, iflags); +/* Fake the irspiocbq and copy necessary response information */ lpfc_sli4_iocb_param_transfer (phba, irspiocbq, cmdiocbq, wcqe);
@@ -17137,7 +17139,8 @@ lpfc_sli4_handle_mds_loopback(struct lpfc_vport *vport,if (pcmd && pcmd->virt)dma_pool_free (phba->lpfc_drb_pool, pcmd->virt, pcmd->phys);kfree (pcmd); -lpfc_sli_release_iocbq (phba, iocbq); +if (iocbq) +lpfc_sli_release_iocbq (phba, iocbq);lpfc_in_buf_free (phba, &dmabuf->dbuf); }
Signature · 1 line
2.13.1
Re: [PATCH v2 02/21] lpfc: fix pci hot plug crash in list_add call
Looks good,
Signature · 6 lines
Johannes Thumshirn Storage [email protected] +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
PATCH v2 3/21 lpfc: Fix crash receiving ELS while detaching driver
In reply to James SmartFrom: Dick Kennedy <[email protected]>
The driver crashes when attempting to use a freed ndpl pointer.
The pci_remove_one handler runs on a separate kernel thread. The order of the removal is starting by freeing all of the ndlps and then disabling interrupts. In between these two events the driver can still receive an ELS and process it. When it tries to use the ndlp pointer will be NULL
Change the order of the pci_remove_one vs disable interrupts so that interrupts are disabled before the ndlp's are freed.
--- drivers/scsi/lpfc/lpfc_attr.c | 6 ++++-- drivers/scsi/lpfc/lpfc_bsg.c | 4 +++- drivers/scsi/lpfc/lpfc_els.c | 7 ++++++- drivers/scsi/lpfc/lpfc_hbadisc.c | 5 ++++- drivers/scsi/lpfc/lpfc_init.c | 14 +++++++------- drivers/scsi/lpfc/lpfc_nportdisc.c | 2 +- drivers/scsi/lpfc/lpfc_sli.c | 12 ++++++++++++ 7 files changed, 37 insertions(+), 13 deletions(-)
drivers/scsi/lpfc/lpfc_attr.c +4 -2
@@ -3132,7 +3132,8 @@ lpfc_txq_hw_show(struct device *dev, struct device_attribute *attr, char *buf)struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;struct lpfc_sli_ring *pring =lpfc_phba_elsring (phba); -return snprintf (buf,PAGE_SIZE ,"%d\n" , pring->txq_max); +return snprintf (buf,PAGE_SIZE ,"%d\n" , + pring ? pring->txq_max :0 ); } static DEVICE_ATTR(txq_hw, S_IRUGO,
@@ -3145,7 +3146,8 @@ lpfc_txcmplq_hw_show(struct device *dev, struct device_attribute *attr,struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;struct lpfc_sli_ring *pring =lpfc_phba_elsring (phba); -return snprintf (buf,PAGE_SIZE ,"%d\n" , pring->txcmplq_max); +return snprintf (buf,PAGE_SIZE ,"%d\n" , + pring ? pring->txcmplq_max :0 ); } static DEVICE_ATTR(txcmplq_hw, S_IRUGO,
drivers/scsi/lpfc/lpfc_bsg.c +3 -1
@@ -2911,7 +2911,7 @@ static int lpfcdiag_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri, } } -if (!cmdiocbq || !rxbmp || !rxbpl || !rxbuffer) { +if (!cmdiocbq || !rxbmp || !rxbpl || !rxbuffer || !pring) { ret_val = -ENOMEM ; goto err_post_rxbufs_exit; }
@@ -5421,6 +5421,8 @@ lpfc_bsg_timeout(struct bsg_job *job)struct lpfc_iocbq *check_iocb, *next_iocb; pring =lpfc_phba_elsring (phba); +if (unlikely (!pring)) +return -EIO ;/* if job's driver data is NULL, the command completed or is in the * the process of completing. In this case, return status to request
drivers/scsi/lpfc/lpfc_els.c +6 -1
@@ -7430,6 +7430,8 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) timeout = (uint32_t )(phba->fc_ratov <<1 ); pring =lpfc_phba_elsring (phba); +if (unlikely (!pring)) +return ;if ((phba->pport->load_flag &FC_UNLOADING ))return ;
@@ -9310,6 +9312,9 @@ void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp) pring =lpfc_phba_elsring (phba); +if (unlikely (!pring)) +return ; +spin_lock_irq (&phba->hbalock);list_for_each_entry_safe (piocb, tmp_iocb, &phba->fabric_iocb_list, list) {
@@ -9416,7 +9421,7 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, rxid, 1);/* Check if TXQ queue needs to be serviced */ -if (!(list_empty (&pring->txq))) +if (pring && !list_empty (&pring->txq))lpfc_worker_wake_up (phba);return ; }
drivers/scsi/lpfc/lpfc_hbadisc.c +4 -1
@@ -3324,7 +3324,8 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)/* Unblock ELS traffic */ pring =lpfc_phba_elsring (phba); - pring->flag &= ~LPFC_STOP_IOCB_EVENT ; +if (pring) + pring->flag &= ~LPFC_STOP_IOCB_EVENT ;/* Check for error */ if (mb->mbxStatus) {
@@ -5430,6 +5431,8 @@ lpfc_free_tx(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) psli = &phba->sli; pring =lpfc_phba_elsring (phba); +if (unlikely (!pring)) +return ;/* Error matching iocb on txq or txcmplq * First check the txq.
drivers/scsi/lpfc/lpfc_init.c +7 -7
@@ -11403,6 +11403,13 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)/* Remove FC host and then SCSI host with the physical port */ fc_remove_host (shost);scsi_remove_host (shost); +/* +* Bring down the SLI Layer. This step disables all interrupts, +* clears the rings, discards all mailbox commands, and resets +* the HBA FCoE function. +*/ +lpfc_debugfs_terminate (vport); +lpfc_sli4_hba_unset (phba);/* Perform ndlp cleanup on the physical port. The nvme and nvmet * localports are destroyed after to cleanup all transport memory.
@@ -11411,13 +11418,6 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)lpfc_nvmet_destroy_targetport (phba);lpfc_nvme_destroy_localport (vport); -/* -* Bring down the SLI Layer. This step disables all interrupts, -* clears the rings, discards all mailbox commands, and resets -* the HBA FCoE function. -*/ -lpfc_debugfs_terminate (vport); -lpfc_sli4_hba_unset (phba);lpfc_stop_hba_timers (phba);spin_lock_irq (&phba->hbalock);
drivers/scsi/lpfc/lpfc_nportdisc.c +1 -1
@@ -216,7 +216,7 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) pring =lpfc_phba_elsring (phba);/* In case of error recovery path, we might have a NULL pring here */ -if (!pring) +if (unlikely (!pring))return ;/* Abort outstanding I/O on NPort <nlp_DID> */
drivers/scsi/lpfc/lpfc_sli.c +12 -0
@@ -10632,6 +10632,14 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, (cmdiocb->iocb_flag & LPFC_DRIVER_ABORTED) != 0)return 0 ; +if (!pring) { +if (cmdiocb->iocb_flag &LPFC_IO_FABRIC ) + cmdiocb->fabric_iocb_cmpl = lpfc_ignore_els_cmpl; +else + cmdiocb->iocb_cmpl = lpfc_ignore_els_cmpl; + goto abort_iotag_exit; + } +/* * If we're unloading, don't abort iocb on the ELS ring, but change * the callback so that nothing happens when it finishes.
@@ -12500,6 +12508,8 @@ lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *phba,unsigned long iflags; pring =lpfc_phba_elsring (phba); +if (unlikely (!pring)) +return NULL ; wcqe = &irspiocbq->cq_event.cqe.wcqe_cmpl;spin_lock_irqsave (&pring->ring_lock, iflags);
@@ -18694,6 +18704,8 @@ lpfc_drain_txq(struct lpfc_hba *phba)uint32_t txq_cnt =0 ; pring =lpfc_phba_elsring (phba); +if (unlikely (!pring)) +return 0 ;spin_lock_irqsave (&pring->ring_lock, iflags);list_for_each_entry (piocbq, &pring->txq, list) {
Signature · 1 line
2.13.1
PATCH v2 4/21 lpfc: Fix lpfc nvme host rejecting IO with Not Ready message
In reply to James SmartFrom: Dick Kennedy <[email protected]>
In a link bounce scenario, a condition can occur where the discovery engine swaps an ndlp structure (address changbe for an nport). While the swap was successfully executed by the discovery engine, the driver did not properly detect a change in the ndlp bound to the nvme rport. This error resulted in the nvme host transport issuing an IO to the correct nvme rport, but the lpfc driver addressed a ndlp with an NLP_UNUSED status and failed the io. This resulting it it looking like there were missing namespaces and applications failed due to io errors.
To fix, in lpfc_nvme_register_rport, rework the "rebind" case to break the nvme rport<->ndlp association when the ndlp already has an nrport. Then rebind the rport to the correct ndlp data and backpointers.
--- drivers/scsi/lpfc/lpfc_nvme.c | 46 ++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 18 deletions(-)
drivers/scsi/lpfc/lpfc_nvme.c +28 -18
@@ -2296,6 +2296,7 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)struct lpfc_nvme_rport *rport;struct nvme_fc_remote_port *remote_port;struct nvme_fc_port_info rpinfo; +struct lpfc_nodelist *prev_ndlp; lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NVME_DISC, "6006 Register NVME PORT. DID x%06x nlptype x%x\n",
@@ -2332,7 +2333,7 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)* new rport. */ rport = remote_port->private; -if (ndlp->nrport == rport) { +if (ndlp->nrport) {lpfc_printf_vlog (ndlp->vport,KERN_INFO ,LOG_NVME_DISC , "6014 Rebinding lport to "
@@ -2343,24 +2344,33 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) remote_port->port_role, ndlp->nlp_type, ndlp->nlp_DID); - }else { -/* New rport. */ - rport->remoteport = remote_port; - rport->lport = lport; - rport->ndlp =lpfc_nlp_get (ndlp); -if (!rport->ndlp) -return -1 ; - ndlp->nrport = rport; -lpfc_printf_vlog (vport,KERN_INFO , -LOG_NVME_DISC |LOG_NODE , -"6022 Binding new rport to " -"lport %p Rport WWNN 0x%llx, " -"Rport WWPN 0x%llx DID " -"x%06x Role x%x\n" , - lport, - rpinfo.node_name, rpinfo.port_name, - rpinfo.port_id, rpinfo.port_role); + prev_ndlp = rport->ndlp; + +/* Sever the ndlp<->rport connection before dropping +* the ndlp ref from register. +*/ + ndlp->nrport =NULL ; + rport->ndlp =NULL ; +if (prev_ndlp) +lpfc_nlp_put (ndlp); } + +/* Clean bind the rport to the ndlp. */ + rport->remoteport = remote_port; + rport->lport = lport; + rport->ndlp =lpfc_nlp_get (ndlp); +if (!rport->ndlp) +return -1 ; + ndlp->nrport = rport; +lpfc_printf_vlog (vport,KERN_INFO , +LOG_NVME_DISC |LOG_NODE , +"6022 Binding new rport to " +"lport %p Rport WWNN 0x%llx, " +"Rport WWPN 0x%llx DID " +"x%06x Role x%x\n" , + lport, + rpinfo.node_name, rpinfo.port_name, + rpinfo.port_id, rpinfo.port_role); }else { lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC | LOG_NODE,
Signature · 1 line
2.13.1
PATCH v2 5/21 lpfc: Fix warning messages when NVME_TARGET_FC not defined
In reply to James SmartFrom: Dick Kennedy <[email protected]>
Warning messages when NVME_TARGET_FC not defined on ppc builds
The lpfc_nvmet_replenish_context() function is only meaningful when NVME target mode enabled. Surround the function body with ifdefs for target mode enablement.
--- drivers/scsi/lpfc/lpfc_nvmet.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/scsi/lpfc/lpfc_nvmet.c +2 -0
@@ -1438,6 +1438,7 @@ static struct lpfc_nvmet_ctxbuf * lpfc_nvmet_replenish_context(struct lpfc_hba *phba, struct lpfc_nvmet_ctx_info *current_infop) { +#if (IS_ENABLED(CONFIG_NVME_TARGET_FC)) struct lpfc_nvmet_ctxbuf *ctx_buf = NULL;struct lpfc_nvmet_ctx_info *get_infop;int i;
@@ -1485,6 +1486,7 @@ lpfc_nvmet_replenish_context(struct lpfc_hba *phba, get_infop = get_infop->nvmet_ctx_next_cpu; } +#endif /* Nothing found, all contexts for the MRQ are in-flight */ return NULL ; }
Signature · 1 line
2.13.1
PATCH v2 6/21 lpfc: PLOGI failures during NPIV testing
In reply to James SmartFrom: Dick Kennedy <[email protected]>
Local Reject/Invalid RPI errors seen during discovery.
Temporary RPI cleanup was occurring regardless of SLI rev. It's only necessary on SLI-4.
Adjust the test for whether cleanup is necessary.
--- drivers/scsi/lpfc/lpfc_hbadisc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/lpfc/lpfc_hbadisc.c +2 -1
@@ -4983,7 +4983,8 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)lpfc_cancel_retry_delay_tmo (vport, ndlp);if ((ndlp->nlp_flag &NLP_DEFER_RM ) && !(ndlp->nlp_flag &NLP_REG_LOGIN_SEND ) && - !(ndlp->nlp_flag &NLP_RPI_REGISTERED )) { + !(ndlp->nlp_flag &NLP_RPI_REGISTERED ) && + phba->sli_rev !=LPFC_SLI_REV4 ) {/* For this case we need to cleanup the default rpi * allocated by the firmware. */
Signature · 1 line
2.13.1
PATCH v2 7/21 lpfc: Make ktime sampling more accurate
In reply to James SmartFrom: Dick Kennedy <[email protected]>
Need to make ktime samples more accurate
If ktime is turned on in the middle of an IO, the max calculation could be misleading. Base sampling on the start time of the IO as opposed to ktime_on.
Make ISR ktime timestamps be from when CQE is read instead of EQE. Added additional sanity checks when deciding whether to accept an IO sample or not.
--- drivers/scsi/lpfc/lpfc_nvme.c | 34 ++++++++++----- drivers/scsi/lpfc/lpfc_nvmet.c | 99 ++++++++++++++++++++++++++++-------------- drivers/scsi/lpfc/lpfc_sli.c | 34 +++++++++------ 3 files changed, 109 insertions(+), 58 deletions(-)
drivers/scsi/lpfc/lpfc_nvme.c +23 -11
@@ -667,15 +667,17 @@ lpfc_nvme_ktime(struct lpfc_hba *phba, struct lpfc_nvme_buf *lpfc_ncmd) {uint64_t seg1, seg2, seg3, seg4; +uint64_t segsum; -if (!phba->ktime_on) -return ;if (!lpfc_ncmd->ts_last_cmd || !lpfc_ncmd->ts_cmd_start || !lpfc_ncmd->ts_cmd_wqput || !lpfc_ncmd->ts_isr_cmpl || !lpfc_ncmd->ts_data_nvme)return ; + +if (lpfc_ncmd->ts_data_nvme < lpfc_ncmd->ts_cmd_start) +return ;if (lpfc_ncmd->ts_cmd_start < lpfc_ncmd->ts_last_cmd)return ;if (lpfc_ncmd->ts_cmd_wqput < lpfc_ncmd->ts_cmd_start)
@@ -695,15 +697,23 @@ lpfc_nvme_ktime(struct lpfc_hba *phba,* cmpl is handled off to the NVME Layer. */ seg1 = lpfc_ncmd->ts_cmd_start - lpfc_ncmd->ts_last_cmd; -if (seg1 >5000000 )/* 5 ms - for sequential IOs */ -return ; +if (seg1 >5000000 )/* 5 ms - for sequential IOs only */ + seg1 =0 ;/* Calculate times relative to start of IO */ seg2 = (lpfc_ncmd->ts_cmd_wqput - lpfc_ncmd->ts_cmd_start); - seg3 = (lpfc_ncmd->ts_isr_cmpl - - lpfc_ncmd->ts_cmd_start) - seg2; - seg4 = (lpfc_ncmd->ts_data_nvme - - lpfc_ncmd->ts_cmd_start) - seg2 - seg3; + segsum = seg2; + seg3 = lpfc_ncmd->ts_isr_cmpl - lpfc_ncmd->ts_cmd_start; +if (segsum > seg3) +return ; + seg3 -= segsum; + segsum += seg3; + + seg4 = lpfc_ncmd->ts_data_nvme - lpfc_ncmd->ts_cmd_start; +if (segsum > seg4) +return ; + seg4 -= segsum; + phba->ktime_data_samples++; phba->ktime_seg1_total += seg1;if (seg1 < phba->ktime_seg1_min)
@@ -902,7 +912,7 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,* owns the dma address. */ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS -if (phba->ktime_on) { +if (lpfc_ncmd->ts_cmd_start) { lpfc_ncmd->ts_isr_cmpl = pwqeIn->isr_timestamp; lpfc_ncmd->ts_data_nvme =ktime_get_ns (); phba->ktime_last_cmd = lpfc_ncmd->ts_data_nvme;
@@ -1283,9 +1293,11 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, goto out_fail; }#ifdef CONFIG_SCSI_LPFC_DEBUG_FS -if (phba->ktime_on) { +if (start) { lpfc_ncmd->ts_cmd_start = start; lpfc_ncmd->ts_last_cmd = phba->ktime_last_cmd; + }else { + lpfc_ncmd->ts_cmd_start =0 ; }#endif
@@ -1336,7 +1348,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, }#ifdef CONFIG_SCSI_LPFC_DEBUG_FS -if (phba->ktime_on) +if (lpfc_ncmd->ts_cmd_start) lpfc_ncmd->ts_cmd_wqput =ktime_get_ns ();if (phba->cpucheck_on &LPFC_CHECK_NVME_IO ) {
drivers/scsi/lpfc/lpfc_nvmet.c +66 -33
172 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_sli.c +20 -14
@@ -13064,13 +13064,20 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,break ;case LPFC_WCQ :while ((cqe =lpfc_sli4_cq_get (cq))) { -if ((cq->subtype ==LPFC_FCP ) || - (cq->subtype ==LPFC_NVME )) +if (cq->subtype ==LPFC_FCP || + cq->subtype ==LPFC_NVME ) { +#ifdef CONFIG_SCSI_LPFC_DEBUG_FS +if (phba->ktime_on) + cq->isr_timestamp =ktime_get_ns (); +else + cq->isr_timestamp =0 ; +#endif workposted |=lpfc_sli4_fp_handle_cqe (phba, cq, cqe); -else + }else { workposted |=lpfc_sli4_sp_handle_cqe (phba, cq, cqe); + }if (!(++ecount % cq->entry_repost))break ; }
@@ -13155,11 +13162,9 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq, bf_get(lpfc_wcqe_c_request_tag, wcqe));return ; } - -if (cq->assoc_qp) - cmdiocbq->isr_timestamp = - cq->assoc_qp->isr_timestamp; - +#ifdef CONFIG_SCSI_LPFC_DEBUG_FS + cmdiocbq->isr_timestamp = cq->isr_timestamp; +#endif if (cmdiocbq->iocb_cmpl ==NULL ) {if (cmdiocbq->wqe_cmpl) {if (cmdiocbq->iocb_flag &LPFC_DRIVER_ABORTED ) {
@@ -13304,7 +13309,7 @@ lpfc_sli4_nvmet_handle_rcqe(struct lpfc_hba *phba, struct lpfc_queue *cq, dma_buf->bytes_recv =bf_get (lpfc_rcqe_length, rcqe);lpfc_nvmet_unsol_fcp_event ( phba, idx, dma_buf, - cq->assoc_qp->isr_timestamp); + cq->isr_timestamp);return false; } drop:
@@ -13479,6 +13484,12 @@ lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,/* Process all the entries to the CQ */ while ((cqe =lpfc_sli4_cq_get (cq))) { +#ifdef CONFIG_SCSI_LPFC_DEBUG_FS +if (phba->ktime_on) + cq->isr_timestamp =ktime_get_ns (); +else + cq->isr_timestamp =0 ; +#endif workposted |=lpfc_sli4_fp_handle_cqe (phba, cq, cqe);if (!(++ecount % cq->entry_repost))break ;
@@ -13741,11 +13752,6 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id)if (unlikely (!fpeq))return IRQ_NONE ; -#ifdef CONFIG_SCSI_LPFC_DEBUG_FS -if (phba->ktime_on) - fpeq->isr_timestamp =ktime_get_ns (); -#endif -if (lpfc_fcp_look_ahead) {if (atomic_dec_and_test (&hba_eq_hdl->hba_eq_in_use))lpfc_sli4_eq_clr_intr (fpeq);
Signature · 1 line
2.13.1
Re: [PATCH v2 07/21] lpfc: Make ktime sampling more accurate
Looks good,
Signature · 6 lines
Johannes Thumshirn Storage [email protected] +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
PATCH v2 8/21 lpfc: Move CQ processing to a soft IRQ
In reply to James SmartFrom: Dick Kennedy <[email protected]>
Under heavy target nvme load duration, the lpfc irq handler is encountering cpu lockup warnings.
Convert the driver to a shortened ISR handler which identifies the interrupting condition then schedules a workq thread to process the completion queue the interrupt was for. This moves all the real work into the workq element.
As nvmet_fc upcalls are no longer in ISR context, don't set the feature flags
--- drivers/scsi/lpfc/lpfc.h | 3 + drivers/scsi/lpfc/lpfc_init.c | 15 +++++ drivers/scsi/lpfc/lpfc_nvmet.c | 4 +- drivers/scsi/lpfc/lpfc_sli.c | 148 ++++++++++++++++++++++++----------------- drivers/scsi/lpfc/lpfc_sli4.h | 4 +- 5 files changed, 109 insertions(+), 65 deletions(-)
drivers/scsi/lpfc/lpfc.h +3 -0
@@ -23,6 +23,7 @@#include <scsi/scsi_host.h> #include <linux/ktime.h> +#include <linux/workqueue.h> #if defined(CONFIG_DEBUG_FS ) && !defined(CONFIG_SCSI_LPFC_DEBUG_FS )#define CONFIG_SCSI_LPFC_DEBUG_FS
@@ -653,6 +654,8 @@ struct lpfc_hba {/* SLI4 specific HBA data structure */ struct lpfc_sli4_hba sli4_hba; +struct workqueue_struct *wq; +struct lpfc_sli sli;uint8_t pci_dev_grp;/* lpfc PCI dev group: 0x0, 0x1, 0x2,... */ uint32_t sli_rev;/* SLI2, SLI3, or SLI4 */
drivers/scsi/lpfc/lpfc_init.c +15 -0
@@ -3216,6 +3216,9 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action)lpfc_destroy_vport_work_array (phba, vports);lpfc_sli_mbox_sys_shutdown (phba, mbx_action); + +if (phba->wq) +flush_workqueue (phba->wq); }/**
@@ -4176,6 +4179,9 @@ void lpfc_stop_port(struct lpfc_hba *phba) { phba->lpfc_stop_port (phba); + +if (phba->wq) +flush_workqueue (phba->wq); }/**
@@ -6369,6 +6375,9 @@ lpfc_setup_driver_resource_phase2(struct lpfc_hba *phba)return error; } +/* workqueue for deferred irq use */ + phba->wq =alloc_workqueue ("lpfc_wq" ,WQ_MEM_RECLAIM ,0 ); +return 0 ; }
@@ -6383,6 +6392,12 @@ lpfc_setup_driver_resource_phase2(struct lpfc_hba *phba)static void lpfc_unset_driver_resource_phase2 (struct lpfc_hba *phba) { +if (phba->wq) { +flush_workqueue (phba->wq); +destroy_workqueue (phba->wq); + phba->wq =NULL ; + } +/* Stop kernel worker thread */ kthread_stop (phba->worker_thread); }
drivers/scsi/lpfc/lpfc_nvmet.c +1 -3
@@ -1137,9 +1137,7 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba) } lpfc_tgttemplate.max_sgl_segments = phba->cfg_nvme_seg_cnt +1 ; lpfc_tgttemplate.max_hw_queues = phba->cfg_nvme_io_channel; - lpfc_tgttemplate.target_features =NVMET_FCTGTFEAT_READDATA_RSP | -NVMET_FCTGTFEAT_CMD_IN_ISR | -NVMET_FCTGTFEAT_OPDONE_IN_ISR ; + lpfc_tgttemplate.target_features =NVMET_FCTGTFEAT_READDATA_RSP ;#if (IS_ENABLED (CONFIG_NVME_TARGET_FC )) error = nvmet_fc_register_targetport(&pinfo, &lpfc_tgttemplate,
drivers/scsi/lpfc/lpfc_sli.c +87 -61
288 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_sli4.h +3 -1
@@ -158,7 +158,6 @@ struct lpfc_queue {#define LPFC_MQ_REPOST 8#define LPFC_CQ_REPOST 64#define LPFC_RQ_REPOST 64 -#define LPFC_MAX_ISR_CQE 64#define LPFC_RELEASE_NOTIFICATION_INTERVAL 32/* For WQs */ uint32_t queue_id;/* Queue ID assigned by the hardware */ uint32_t assoc_qid;/* Queue ID associated with, for CQ/WQ/MQ */
@@ -202,6 +201,9 @@ struct lpfc_queue {#define RQ_buf_posted q_cnt_3#define RQ_rcv_buf q_cnt_4 +struct work_struct irqwork; +struct work_struct spwork; +uint64_t isr_timestamp;struct lpfc_queue *assoc_qp;union sli4_qe qe[1 ];/* array to index entries (must be last) */
Signature · 1 line
2.13.1
PATCH v2 9/21 lpfc: Fix FCP hba_wqidx assignment
In reply to James SmartFrom: Dick Kennedy <[email protected]>
The driver is encountering oops in lpfc_sli_calc_ring.
The driver is setting hba_wqidx for FCP based on the policy in use for NVME. The two may not be the same. Change to set the wqidx based on the FCP policy.
--- drivers/scsi/lpfc/lpfc_sli.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/scsi/lpfc/lpfc_sli.c +4 -1
@@ -9396,10 +9396,13 @@ lpfc_sli4_calc_ring(struct lpfc_hba *phba, struct lpfc_iocbq *piocb)* for abort iocb hba_wqidx should already * be setup based on what work queue we used. */ -if (!(piocb->iocb_flag &LPFC_USE_FCPWQIDX )) +if (!(piocb->iocb_flag &LPFC_USE_FCPWQIDX )) { piocb->hba_wqidx =lpfc_sli4_scmd_to_wqidx_distr (phba, piocb->context1); + piocb->hba_wqidx = piocb->hba_wqidx % + phba->cfg_fcp_io_channel; + }return phba->sli4_hba.fcp_wq[piocb->hba_wqidx]->pring; }else {if (unlikely (!phba->sli4_hba.oas_wq))
Signature · 1 line
2.13.1
Re: [PATCH v2 09/21] lpfc: Fix FCP hba_wqidx assignment
Looks good,
Signature · 6 lines
Johannes Thumshirn Storage [email protected] +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
PATCH v2 10/21 lpfc: Reduce log spew on controller reconnects
In reply to James SmartThere are several log messages that report abnormal terminations that by default are marked warn. These are typically the result of failures due to invalid controller state or abort completions. They are all natural when a controller resets.
Unfortunately, as they are logged by default, it makes the admin very concerned.
Convert the messages to Info.
--- drivers/scsi/lpfc/lpfc_nvme.c | 6 +++--- drivers/scsi/lpfc/lpfc_nvmet.c | 16 ++++++++++------ 2 files changed, 13 insertions(+), 9 deletions(-)
drivers/scsi/lpfc/lpfc_nvme.c +3 -3
@@ -886,7 +886,7 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,break ;default : out_err: - lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_IOERR, + lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR, "6072 NVME Completion Error: xri %x " "status x%x result x%x placed x%x\n", lpfc_ncmd->cur_iocbq.sli4_xritag,
@@ -1339,7 +1339,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, ret =lpfc_sli4_issue_wqe (phba,LPFC_FCP_RING , &lpfc_ncmd->cur_iocbq);if (ret) {atomic_dec (&ndlp->cmd_pending); - lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_IOERR, + lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR, "6113 FCP could not issue WQE err %x " "sid: x%x did: x%x oxid: x%x\n", ret, vport->fc_myDID, ndlp->nlp_DID,
@@ -1399,7 +1399,7 @@ void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_wcqe_complete *abts_cmpl) { - lpfc_printf_log(phba, KERN_ERR, LOG_NVME, + lpfc_printf_log(phba, KERN_INFO, LOG_NVME,"6145 ABORT_XRI_CN completing on rpi x%x " "original iotag x%x, abort cmd iotag x%x " "req_tag x%x, status x%x, hwstatus x%x\n",
drivers/scsi/lpfc/lpfc_nvmet.c +10 -6
@@ -76,7 +76,7 @@ lpfc_nvmet_defer_release(struct lpfc_hba *phba, struct lpfc_nvmet_rcv_ctx *ctxp) {unsigned long iflag; -lpfc_printf_log (phba,KERN_ERR ,LOG_NVME_ABTS , +lpfc_printf_log (phba,KERN_INFO ,LOG_NVME_ABTS ,"6313 NVMET Defer ctx release xri x%x flg x%x\n" , ctxp->oxid, ctxp->flag);
@@ -494,7 +494,7 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,struct lpfc_nvmet_tgtport *tgtp;struct nvmefc_tgt_fcp_req *rsp;struct lpfc_nvmet_rcv_ctx *ctxp; -uint32_t status, result, op, start_clean; +uint32_t status, result, op, start_clean, logerr;#ifdef CONFIG_SCSI_LPFC_DEBUG_FS uint32_t id;#endif
@@ -522,17 +522,21 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,if (tgtp)atomic_inc (&tgtp->xmt_fcp_rsp_error); + logerr =LOG_NVME_IOERR ; +/* pick up SLI4 exhange busy condition */ if (bf_get (lpfc_wcqe_c_xb, wcqe)) { ctxp->flag |=LPFC_NVMET_XBUSY ; + logerr |=LOG_NVME_ABTS ; -lpfc_printf_log (phba,KERN_INFO ,LOG_NVME_ABTS , -"6315 IO Cmpl XBUSY: xri x%x: %x/%x\n" , - ctxp->oxid, status, result); }else { ctxp->flag &= ~LPFC_NVMET_XBUSY ; } +lpfc_printf_log (phba,KERN_INFO , logerr, +"6315 IO Error Cmpl xri x%x: %x/%x XBUSY:x%x\n" , + ctxp->oxid, status, result, ctxp->flag); + }else { rsp->fcp_error =NVME_SC_SUCCESS ;if (op ==NVMET_FCOP_RSP )
@@ -2323,7 +2327,7 @@ lpfc_nvmet_sol_fcp_abort_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,spin_unlock_irqrestore (&ctxp->ctxlock, flags);atomic_inc (&tgtp->xmt_abort_rsp); - lpfc_printf_log(phba, KERN_ERR, LOG_NVME_ABTS, + lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, "6165 ABORT cmpl: xri x%x flg x%x (%d) " "WCQE: %08x %08x %08x %08x\n", ctxp->oxid, ctxp->flag, released,
Signature · 1 line
2.13.1
PATCH v2 11/21 lpfc: Set missing abort context
In reply to James SmartAlways set ctxp->state to LPFC_NVMET_STE_ABORT if ABORT op gets called
--- drivers/scsi/lpfc/lpfc_nvmet.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/lpfc/lpfc_nvmet.c +1 -0
@@ -822,6 +822,7 @@ lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port *tgtport,atomic_inc (&lpfc_nvmep->xmt_fcp_abort);spin_lock_irqsave (&ctxp->ctxlock, flags); + ctxp->state =LPFC_NVMET_STE_ABORT ;/* Since iaab/iaar are NOT set, we need to check * if the firmware is in process of aborting IO
Signature · 1 line
2.13.1
PATCH v2 12/21 lpfc: Revise NVME module parameter descriptions for better clarity
In reply to James SmartFrom: Dick Kennedy <[email protected]>
The descriptions for lpfc_xri_split and lpfc_enable_fc4_type were poor. Revise for better understanding:
lpfc_xri_split - Percentage of FCP XRI resources versus NVME lpfc_enable_fc4_type - Enable FC4 Protocol support - FCP / NVME
--- drivers/scsi/lpfc/lpfc_attr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/lpfc/lpfc_attr.c +2 -2
@@ -3375,7 +3375,7 @@ LPFC_ATTR_R(nvmet_mrq,*/ LPFC_ATTR_R (enable_fc4_type,LPFC_ENABLE_FCP ,LPFC_ENABLE_FCP ,LPFC_ENABLE_BOTH , -"Define fc4 type to register with fabric." ); +"Enable FC4 Protocol support - FCP / NVME" );/* * lpfc_xri_split: Defines the division of XRI resources between SCSI and NVME
@@ -3391,7 +3391,7 @@ LPFC_ATTR_R(enable_fc4_type, LPFC_ENABLE_FCP,* percentage will go to NVME. */ LPFC_ATTR_R (xri_split,50 ,10 ,90 , -"Division of XRI resources between SCSI and NVME" ); +"Percentage of FCP XRI resources versus NVME" );/* # lpfc_log_verbose: Only turn this flag on if you are willing to risk being
Signature · 1 line
2.13.1
PATCH v2 13/21 lpfc: Fix oops if nvmet_fc_register_targetport fails
In reply to James SmartFrom: Dick Kennedy <[email protected]>
if nvmet targetport registration fails, the driver encounters a NULL pointer oops in lpfc_hb_timeout_handler.
To fix: if registration fails, ensure nvmet_support is cleared on the port structure.
Also enhanced the log message on failure.
--- drivers/scsi/lpfc/lpfc_nvmet.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/scsi/lpfc/lpfc_nvmet.c +11 -4
@@ -1153,9 +1153,14 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba)#endif if (error) {lpfc_printf_log (phba,KERN_ERR ,LOG_NVME_DISC , -"6025 Cannot register NVME targetport " -"x%x\n" , error); +"6025 Cannot register NVME targetport x%x: " +"portnm %llx nodenm %llx segs %d qs %d\n" , + error, + pinfo.port_name, pinfo.node_name, + lpfc_tgttemplate.max_sgl_segments, + lpfc_tgttemplate.max_hw_queues); phba->targetport =NULL ; + phba->nvmet_support =0 ;lpfc_nvmet_cleanup_io_context (phba);
@@ -1167,9 +1172,11 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba)lpfc_printf_log (phba,KERN_INFO ,LOG_NVME_DISC ,"6026 Registered NVME " "targetport: %p, private %p " -"portnm %llx nodenm %llx\n" , +"portnm %llx nodenm %llx segs %d qs %d\n" , phba->targetport, tgtp, - pinfo.port_name, pinfo.node_name); + pinfo.port_name, pinfo.node_name, + lpfc_tgttemplate.max_sgl_segments, + lpfc_tgttemplate.max_hw_queues);atomic_set (&tgtp->rcv_ls_req_in,0 );atomic_set (&tgtp->rcv_ls_req_out,0 );
Signature · 1 line
2.13.1
PATCH v2 14/21 lpfc: Disable NPIV support if NVME is enabled
In reply to James SmartFrom: Dick Kennedy <[email protected]>
The initial implementation of NVME didn't merge with NPIV support. As such, there are several issues if NPIV is used with NVME. For now, ensure that if NVME is enabled then NPIV is not enabled.
Support for NPIV with NVME will be added in the near future.
--- drivers/scsi/lpfc/lpfc_vport.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/scsi/lpfc/lpfc_vport.c +9 -0
@@ -313,6 +313,15 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) goto error_out; } +/* NPIV is not supported if HBA has NVME enabled */ +if (phba->cfg_enable_fc4_type &LPFC_ENABLE_NVME ) { +lpfc_printf_log (phba,KERN_ERR ,LOG_VPORT , +"3189 Create VPORT failed: " +"NPIV is not supported on NVME\n" ); + rc =VPORT_INVAL ; + goto error_out; + } + vpi =lpfc_alloc_vpi (phba);if (vpi ==0 ) { lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
Signature · 1 line
2.13.1
PATCH v2 15/21 lpfc: Fix crash in lpfc_nvme_fcp_io_submit during LIP
In reply to James SmartFrom: Dick Kennedy <[email protected]>
The driver is seeing a NULL pointer in lpfc_nvme_fcp_io_submit. This was ultimately due to a transport AER being sent on a terminated controller, thus some of the values were not set. In case we're in a system without a corrected transport and in case a race condition occurs where we enter the routine as the teardown is happening in a separate thread, validate the parameters before starting the io.
--- drivers/scsi/lpfc/lpfc_nvme.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/scsi/lpfc/lpfc_nvme.c +10 -0
@@ -1235,6 +1235,16 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, vport = lport->vport; phba = vport->phba; +/* Validate pointers. */ +if (!pnvme_lport || !pnvme_rport || !freqpriv) { +lpfc_printf_vlog (vport,KERN_INFO ,LOG_NVME_IOERR |LOG_NODE , +"6117 No Send:IO submit ptrs NULL, lport %p, " +"rport %p fcreq_priv %p\n" , + pnvme_lport, pnvme_rport, freqpriv); + ret = -ENODEV ; + goto out_fail; + } +#ifdef CONFIG_SCSI_LPFC_DEBUG_FS if (phba->ktime_on) start =ktime_get_ns ();
Signature · 1 line
2.13.1
PATCH v2 16/21 lpfc: Fix secure firmware updates
In reply to James SmartFrom: Dick Kennedy <[email protected]>
Firmware update fails with: status x17 add_status x56 on the final write
If multiple DMA buffers are used for the download, some firmware revs have difficulty with signatures and crcs split across the dma buffer boundaries. Resolve by making all writes be a single 4k page in length.
--- drivers/scsi/lpfc/lpfc_hw4.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/lpfc/lpfc_hw4.h +1 -1
@@ -3636,7 +3636,7 @@ struct lpfc_mbx_get_port_name {#define MB_CEQ_STATUS_QUEUE_FLUSHING 0x4#define MB_CQE_STATUS_DMA_FAILED 0x5 -#define LPFC_MBX_WR_CONFIG_MAX_BDE 8 +#define LPFC_MBX_WR_CONFIG_MAX_BDE 1struct lpfc_mbx_wr_object {struct mbox_header header;union {
Signature · 1 line
2.13.1
PATCH v2 17/21 lpfc: Ensure io aborts interlocked with the target.
In reply to James SmartFrom: Dick Kennedy <[email protected]>
Before releasing nvme io back to the io stack for possible retry on other paths, ensure the io termination is interlocked with the target device by ensuring the entire ABTS-LS protocol is complete.
Additionally, FC-NVME ABTS-LS protocol does not use RRQ. Remove RRQ behavior from ABTS-LS.
--- drivers/scsi/lpfc/lpfc_nvme.c | 59 +++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 25 deletions(-)
drivers/scsi/lpfc/lpfc_nvme.c +34 -25
@@ -850,7 +850,7 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, }else { lpfc_ncmd->status = (bf_get (lpfc_wcqe_c_status, wcqe) &LPFC_IOCB_STATUS_MASK ); - lpfc_ncmd->result = wcqe->parameter; + lpfc_ncmd->result = (wcqe->parameter &IOERR_PARAM_MASK );/* For NVME, the only failure path that results in an * IO error is when the adapter rejects it. All other
@@ -884,6 +884,17 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, lpfc_ncmd->status, lpfc_ncmd->result, wcqe->total_data_placed);break ; +case IOSTAT_LOCAL_REJECT : +/* Let fall through to set command final state. */ +if (lpfc_ncmd->result ==IOERR_ABORT_REQUESTED ) +lpfc_printf_vlog (vport,KERN_INFO , +LOG_NVME_IOERR , +"6032 Delay Aborted cmd %p " +"nvme cmd %p, xri x%x, " +"xb %d\n" , + lpfc_ncmd, nCmd, + lpfc_ncmd->cur_iocbq.sli4_xritag, +bf_get (lpfc_wcqe_c_xb, wcqe));default : out_err: lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR,
@@ -930,12 +941,18 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,#endif freqpriv = nCmd->private; freqpriv->nvme_buf =NULL ; - nCmd->done (nCmd); + +/* NVME targets need completion held off until the abort exchange +* completes. +*/ +if (!lpfc_ncmd->flags &LPFC_SBUF_XBUSY ) + nCmd->done (nCmd);spin_lock_irqsave (&phba->hbalock, flags); lpfc_ncmd->nrport =NULL ;spin_unlock_irqrestore (&phba->hbalock, flags); +/* Call release with XB=1 to queue the IO into the abort list. */ lpfc_release_nvme_buf (phba, lpfc_ncmd); }
@@ -2064,9 +2081,6 @@ lpfc_get_nvme_buf(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)spin_lock_irqsave (&phba->nvme_buf_list_get_lock, iflag);list_for_each_entry_safe (lpfc_ncmd, lpfc_ncmd_next, &phba->lpfc_nvme_buf_list_get, list) { -if (lpfc_test_rrq_active (phba, ndlp, - lpfc_ncmd->cur_iocbq.sli4_lxritag)) -continue ;list_del_init (&lpfc_ncmd->list); found =1 ;break ;
@@ -2079,9 +2093,6 @@ lpfc_get_nvme_buf(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)spin_unlock (&phba->nvme_buf_list_put_lock);list_for_each_entry_safe (lpfc_ncmd, lpfc_ncmd_next, &phba->lpfc_nvme_buf_list_get, list) { -if (lpfc_test_rrq_active ( - phba, ndlp, lpfc_ncmd->cur_iocbq.sli4_lxritag)) -continue ;list_del_init (&lpfc_ncmd->list); found =1 ;break ;
@@ -2118,7 +2129,6 @@ lpfc_release_nvme_buf(struct lpfc_hba *phba, struct lpfc_nvme_buf *lpfc_ncmd)spin_lock_irqsave (&phba->sli4_hba.abts_nvme_buf_list_lock, iflag); - lpfc_ncmd->nvmeCmd =NULL ;list_add_tail (&lpfc_ncmd->list, &phba->sli4_hba.lpfc_abts_nvme_buf_list); spin_unlock_irqrestore(&phba->sli4_hba.abts_nvme_buf_list_lock,
@@ -2486,18 +2496,18 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)* @axri: pointer to the fcp xri abort wcqe structure. * * This routine is invoked by the worker thread to process a SLI4 fast-path -* FCP aborted xri. +* NVME aborted xri. Aborted NVME IO commands are completed to the transport +* here. **/ void lpfc_sli4_nvme_xri_aborted (struct lpfc_hba *phba,struct sli4_wcqe_xri_aborted *axri) {uint16_t xri =bf_get (lpfc_wcqe_xa_xri, axri); -uint16_t rxid =bf_get (lpfc_wcqe_xa_remote_xid, axri);struct lpfc_nvme_buf *lpfc_ncmd, *next_lpfc_ncmd; +struct nvmefc_fcp_req *nvme_cmd =NULL ;struct lpfc_nodelist *ndlp;unsigned long iflag =0 ; -int rrq_empty =0 ;if (!(phba->cfg_enable_fc4_type &LPFC_ENABLE_NVME ))return ;
@@ -2513,25 +2523,24 @@ lpfc_sli4_nvme_xri_aborted(struct lpfc_hba *phba,spin_unlock ( &phba->sli4_hba.abts_nvme_buf_list_lock); - rrq_empty =list_empty (&phba->active_rrq_list);spin_unlock_irqrestore (&phba->hbalock, iflag); ndlp = lpfc_ncmd->ndlp; -if (ndlp) { -lpfc_set_rrq_active ( - phba, ndlp, - lpfc_ncmd->cur_iocbq.sli4_lxritag, - rxid,1 ); +if (ndlp)lpfc_sli4_abts_err_handler (phba, ndlp, axri); - }lpfc_printf_log (phba,KERN_INFO ,LOG_NVME_ABTS , -"6311 XRI Aborted xri x%x tag x%x " -"released\n" , - xri, lpfc_ncmd->cur_iocbq.iotag); - +"6311 nvme_cmd %p xri x%x tag x%x " +"abort complete and xri released\n" , + lpfc_ncmd->nvmeCmd, xri, + lpfc_ncmd->cur_iocbq.iotag); + +/* Aborted NVME commands are required to not complete +* before the abort exchange command fully completes. +* Once completed, it is available via the put list. +*/ + nvme_cmd = lpfc_ncmd->nvmeCmd; + nvme_cmd->done (nvme_cmd);lpfc_release_nvme_buf (phba, lpfc_ncmd); -if (rrq_empty) -lpfc_worker_wake_up (phba);return ; } }
Signature · 1 line
2.13.1
PATCH v2 18/21 lpfc: Extend RDP support
In reply to James SmartFrom: Dick Kennedy <[email protected]>
Support RDP and Multiple Frames
If the remote Nport is not logged in, the driver would not populate all the descriptors in the RDP response payload. Doing so would create a payload length that requires multiple frames due to exceeding the default rx buffer size without an explicit login. Currently FC-LS explicitly states the RDP response must be a single frame sequence. Thus we did not violate the standard.
Recently, a modification to FC-LS was accepted which allows multi-frame sequences and all vendors have indicated they are interoperable with the change. As such, extend RDP support with the additional fields and send a multi-frame sequence.
--- drivers/scsi/lpfc/lpfc_els.c | 12 ------------ 1 file changed, 12 deletions(-)
drivers/scsi/lpfc/lpfc_els.c +0 -12
@@ -5394,10 +5394,6 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, (len + pcmd), vport, ndlp); len +=lpfc_rdp_res_fec_desc ((struct fc_fec_rdp_desc *)(len + pcmd), &rdp_context->link_stat); -/* Check if nport is logged, BZ190632 */ -if (!(ndlp->nlp_flag &NLP_RPI_REGISTERED )) - goto lpfc_skip_descriptor; - len +=lpfc_rdp_res_bbc_desc ((struct fc_rdp_bbc_desc *)(len + pcmd), &rdp_context->link_stat, vport); len += lpfc_rdp_res_oed_temp_desc(phba,
@@ -5418,7 +5414,6 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, len +=lpfc_rdp_res_opd_desc ((struct fc_rdp_opd_sfp_desc *)(len + pcmd), rdp_context->page_a0, vport); -lpfc_skip_descriptor: rdp_res->length =cpu_to_be32 (len -8 ); elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
@@ -5540,7 +5535,6 @@ lpfc_els_rcv_rdp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; rdp_req = (struct fc_rdp_req_frame *) pcmd->virt; - lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "2422 ELS RDP Request " "dec len %d tag x%x port_id %d len %d\n",
@@ -5549,12 +5543,6 @@ lpfc_els_rcv_rdp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,be32_to_cpu (rdp_req->nport_id_desc.nport_id), be32_to_cpu(rdp_req->nport_id_desc.length)); -if (!(ndlp->nlp_flag &NLP_RPI_REGISTERED ) && - !phba->cfg_enable_SmartSAN) { - rjt_err =LSRJT_UNABLE_TPC ; - rjt_expl =LSEXP_PORT_LOGIN_REQ ; - goto error; - }if (sizeof (struct fc_rdp_nport_desc ) !=be32_to_cpu (rdp_req->rdp_des_length)) goto rjt_logerr;
Signature · 1 line
2.13.1
PATCH v2 19/21 lpfc: Fix oops of nvme host during driver unload.
In reply to James SmartFrom: Dick Kennedy <[email protected]>
When running NVME io as a NVME host, if the driver is unloaded there would be oops in lpfc_sli4_issue_wqe.
When unloading, controllers are torn down and the transport initiates set_property commands to reset the controller and issues aborts to terminate existing io. The drivers nvme abort and fcp io submit routines needed to recognize the driver is unloading and fail the new requests. It didn't, resulting in the oops.
Revise the ls and fcp io submit routines to detect the unloading state and properly handle their cleanup.
---
v2: reduce scope to only submit routines. aborts necessary for cleanup.
this was a bug found after submit.
drivers/scsi/lpfc/lpfc_nvme.c | 8 ++++++++ drivers/scsi/lpfc/lpfc_nvmet.c | 11 +++++++++++ 2 files changed, 19 insertions(+)
drivers/scsi/lpfc/lpfc_nvme.c +8 -0
@@ -416,6 +416,9 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport, lport = (struct lpfc_nvme_lport *)pnvme_lport->private; vport = lport->vport; +if (vport->load_flag &FC_UNLOADING ) +return -ENODEV ; + ndlp =lpfc_findnode_did (vport, pnvme_rport->port_id);if (!ndlp || !NLP_CHK_NODE_ACT (ndlp)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR,
@@ -1252,6 +1255,11 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, vport = lport->vport; phba = vport->phba; +if (vport->load_flag &FC_UNLOADING ) { + ret = -ENODEV ; + goto out_fail; + } +/* Validate pointers. */ if (!pnvme_lport || !pnvme_rport || !freqpriv) { lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR | LOG_NODE,
drivers/scsi/lpfc/lpfc_nvmet.c +11 -0
@@ -632,6 +632,9 @@ lpfc_nvmet_xmt_ls_rsp(struct nvmet_fc_target_port *tgtport,struct ulp_bde64 bpl;int rc; +if (phba->pport->load_flag &FC_UNLOADING ) +return -ENODEV ; +lpfc_printf_log (phba,KERN_INFO ,LOG_NVME_DISC ,"6023 NVMET LS rsp oxid x%x\n" , ctxp->oxid);
@@ -713,6 +716,11 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,struct lpfc_iocbq *nvmewqeq;int rc; +if (phba->pport->load_flag &FC_UNLOADING ) { + rc = -ENODEV ; + goto aerr; + } +#ifdef CONFIG_SCSI_LPFC_DEBUG_FS if (ctxp->ts_cmd_nvme) {if (rsp->op ==NVMET_FCOP_RSP )
@@ -812,6 +820,9 @@ lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port *tgtport,struct lpfc_hba *phba = ctxp->phba;unsigned long flags; +if (phba->pport->load_flag &FC_UNLOADING ) +return ; +lpfc_printf_log (phba,KERN_INFO ,LOG_NVME_ABTS ,"6103 NVMET Abort op: oxri x%x flg x%x ste %d\n" , ctxp->oxid, ctxp->flag, ctxp->state);
Signature · 1 line
2.13.1
Re: [PATCH v2 19/21] lpfc: Fix oops of nvme host during driver unload.
Looks good,
Signature · 6 lines
Johannes Thumshirn Storage [email protected] +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
PATCH v2 20/21 lpfc: correct nvme sg segment count check
In reply to James SmartThe internal cfg flag is actually smaller, by 1 (for a partial page sge), than the sg list maintained by the driver. Thus the check on sg segments errored out when it shouldn't have
Ensure the check is +1
Note: having a value that is less than what it really is is bogus.
Correcting it now would be a significant rework. Add this item to the list to be refactored in the merge with efct.
--- drivers/scsi/lpfc/lpfc_nvme.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/lpfc/lpfc_nvme.c +2 -2
@@ -1149,12 +1149,12 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport, first_data_sgl = sgl; lpfc_ncmd->seg_cnt = nCmd->sg_cnt; -if (lpfc_ncmd->seg_cnt > phba->cfg_nvme_seg_cnt) { +if (lpfc_ncmd->seg_cnt > phba->cfg_nvme_seg_cnt +1 ) {lpfc_printf_log (phba,KERN_ERR ,LOG_NVME_IOERR ,"6058 Too many sg segments from " "NVME Transport. Max %d, " "nvmeIO sg_cnt %d\n" , - phba->cfg_nvme_seg_cnt, + phba->cfg_nvme_seg_cnt +1 , lpfc_ncmd->seg_cnt); lpfc_ncmd->seg_cnt =0 ;return 1 ;
Signature · 1 line
2.13.1
Re: [PATCH v2 20/21] lpfc: correct nvme sg segment count check
Looks good,
Signature · 6 lines
Johannes Thumshirn Storage [email protected] +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
PATCH v2 21/21 lpfc: change version to 11.4.0.4
In reply to James SmartFrom: Dick Kennedy <[email protected]>
Change version to 11.4.0.4
--- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/lpfc/lpfc_version.h +1 -1
@@ -20,7 +20,7 @@* included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "11.4.0.3" +#define LPFC_DRIVER_VERSION "11.4.0.4"#define LPFC_DRIVER_NAME "lpfc"/* Used for SLI 2/3 */
Signature · 1 line
2.13.1
Martin K. Petersen
AppliedJames,
Quoted 5 lines
This patch set provides a number of bug fixes and additions to the driver.
The patches were cut against the Martin's 4.14/scsi-queue tree. There are no outside dependencies.
Applied to 4.15/scsi-queue.
I got a conflict in patch 8 in the "Process all the event on FCP fast-path EQ" hunk. Please verify.
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
Martin,
Contents of 4.15/scsi-queue look good.
-- james
Quoted 12 lines · Martin K. Petersen
James,
Quoted 5 lines
This patch set provides a number of bug fixes and additions to the driver.
The patches were cut against the Martin's 4.14/scsi-queue tree. There are no outside dependencies.
Applied to 4.15/scsi-queue.
I got a conflict in patch 8 in the "Process all the event on FCP fast-path EQ" hunk. Please verify.