[PATCH v2 14/20] lpfc: Fix relative offset error on large nvmet target ios
From: Dick Kennedyif the nvmet_fc transport breaks an io into multiple sequences, the driver will improperly set the relative offset on the 2nd through N sequences. Correct by properly formatting the hw cmd so the relative offset is picked up from the hw cmd. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_nvmet.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index cd6c93a17760..40fa5dd72bfa 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -559,7 +559,7 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, /* lpfc_nvmet_xmt_fcp_release() will recycle the context */ } else { ctxp->entry_cnt++; - start_clean = offsetof(struct lpfc_iocbq, wqe); + start_clean = offsetof(struct lpfc_iocbq, iocb_flag); memset(((char *)cmdwqe) + start_clean, 0, (sizeof(struct lpfc_iocbq) - start_clean)); #ifdef CONFIG_SCSI_LPFC_DEBUG_FS @@ -1024,7 +1024,6 @@ lpfc_nvmet_setup_io_context(struct lpfc_hba *phba) /* Word 7 */ bf_set(wqe_ct, >generic.wqe_com, SLI4_CT_RPI); bf_set(wqe_class, >generic.wqe_com, CLASS3); - bf_set(wqe_pu, >generic.wqe_com, 1); /* Word 10 */ bf_set(wqe_nvme, >fcp_tsend.wqe_com, 1); bf_set(wqe_ebde_cnt, >generic.wqe_com, 0); @@ -1974,6 +1973,7 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, nvmewqe->sli4_xritag); /* Word 7 */ + bf_set(wqe_pu, >fcp_tsend.wqe_com, 1); bf_set(wqe_cmnd, >fcp_tsend.wqe_com, CMD_FCP_TSEND64_WQE); /* Word 8 */ @@ -2082,6 +2082,7 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, nvmewqe->sli4_xritag); /* Word 7 */ + bf_set(wqe_pu, >fcp_treceive.wqe_com, 1); bf_set(wqe_ar, >fcp_treceive.wqe_com, 0); bf_set(wqe_cmnd, >fcp_treceive.wqe_com, CMD_FCP_TRECEIVE64_WQE); @@ -2165,6 +2166,7 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, nvmewqe->sli4_xritag); /* Word 7 */ + bf_set(wqe_pu, >fcp_trsp.wqe_com, 0); bf_set(wqe_ag, >fcp_trsp.wqe_com, 1); bf_set(wqe_cmnd, >fcp_trsp.wqe_com, CMD_FCP_TRSP64_WQE); -- 2.13.1
[PATCH v2 17/20] lpfc: remove console log clutter
Change hw queue binding messages to info - not error. Signed-off-by: Dick KennedySigned-off-by: James Smart --- drivers/scsi/lpfc/lpfc_nvme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 8e7cdbd5d7d3..d3c171a72ae0 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -110,7 +110,7 @@ lpfc_nvme_create_queue(struct nvme_fc_local_port *pnvme_lport, qhandle->index = qidx; } - lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME, + lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, "6073 Binding %s HdwQueue %d (cpu %d) to " "io_channel %d qhandle %p\n", str, qidx, qhandle->cpu_id, qhandle->index, qhandle); -- 2.13.1
[PATCH v2 12/20] lpfc: Limit amount of work processed in IRQ
From: Dick KennedyVarious oops being seen on being in the ISR too long and cpu lockups, when under heavy load. The amount of work being posted off of completion queues kept the ISR running almost all the time Correct the issue by limiting the amount of work per itteration. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_sli.c | 31 +++ drivers/scsi/lpfc/lpfc_sli4.h | 1 + 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index d68afec00f57..9ccd8fed0bed 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -80,8 +80,8 @@ static int lpfc_sli4_fp_handle_cqe(struct lpfc_hba *, struct lpfc_queue *, struct lpfc_cqe *); static int lpfc_sli4_post_sgl_list(struct lpfc_hba *, struct list_head *, int); -static void lpfc_sli4_hba_handle_eqe(struct lpfc_hba *, struct lpfc_eqe *, - uint32_t); +static int lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, + struct lpfc_eqe *eqe, uint32_t qidx); static bool lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba); static bool lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba); static int lpfc_sli4_abort_nvme_io(struct lpfc_hba *phba, @@ -13010,7 +13010,7 @@ lpfc_sli4_sp_handle_cqe(struct lpfc_hba *phba, struct lpfc_queue *cq, * completion queue, and then return. * **/ -static void +static int lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe, struct lpfc_queue *speq) { @@ -13034,7 +13034,7 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe, lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "0365 Slow-path CQ identifier " "(%d) does not exist\n", cqid); - return; + return 0; } /* Save EQ associated with this CQ */ @@ -13071,7 +13071,7 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe, lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "0370 Invalid completion queue type (%d)\n", cq->type); - return; + return 0; } /* Catch the no cq entry condition, log an error */ @@ -13086,6 +13086,8 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe, /* wake up worker thread if there are works to be done */ if (workposted) lpfc_worker_wake_up(phba); + + return ecount; } /** @@ -13393,7 +13395,7 @@ lpfc_sli4_fp_handle_cqe(struct lpfc_hba *phba, struct lpfc_queue *cq, * queue and process all the entries on the completion queue, rearm the * completion queue, and then return. **/ -static void +static int lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe, uint32_t qidx) { @@ -13409,7 +13411,7 @@ lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe, "event: majorcode=x%x, minorcode=x%x\n", bf_get_le32(lpfc_eqe_major_code, eqe), bf_get_le32(lpfc_eqe_minor_code, eqe)); - return; + return 0; } /* Get the reference to the corresponding CQ */ @@ -13446,8 +13448,9 @@ lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe, /* Otherwise this is a Slow path event */ if (cq == NULL) { - lpfc_sli4_sp_handle_eqe(phba, eqe, phba->sli4_hba.hba_eq[qidx]); - return; + ecount = lpfc_sli4_sp_handle_eqe(phba, eqe, +phba->sli4_hba.hba_eq[qidx]); + return ecount; } process_cq: @@ -13456,7 +13459,7 @@ lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe, "0368 Miss-matched fast-path completion " "queue identifier: eqcqid=%d, fcpcqid=%d\n", cqid, cq->queue_id); - return; + return 0; } /* Save EQ associated with this CQ */ @@ -13486,6 +13489,8 @@ lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe, /* wake up worker thread if there are works to be done */ if (workposted) lpfc_worker_wake_up(phba); + + return ecount; } static void @@ -13706,6 +13711,7 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) struct lpfc_eqe *eqe; unsigned long iflag; int ecount = 0; + int ccount = 0; int hba_eqidx; /* Get the driver's phba
[PATCH v2 16/20] lpfc: Fix bad sgl reposting after 2nd adapter reset
From: Dick KennedyFix bad sgl reposting after 2nd adapter reset port issue was fixed, the hbacmd reset would take more than 8 minutes to complete. There were conflicting NVME SGL posting/reposting responsibilities between lpfc_online()/lpfc_sli4_hba_setup() and lpfc_nvme_create_localport(). The lpfc_online() causes a REPOST on existing NVME SGLs which is not released during the fc port reset. However, lpfc_nvme_create_localport() wants to allocate new NVME buffers and post them. Both cancelled out each other which had a side effect of hosing the mailbox handling that was used to remove the sgl lists - causing multiple 60s mbx timeouts. Fix by preserving all SGL lists over the fc port reset. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_nvme.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 87e0743c4ace..8e7cdbd5d7d3 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -2181,8 +2181,15 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport) vport->localport = localport; lport->vport = vport; vport->nvmei_support = 1; - len = lpfc_new_nvme_buf(vport, phba->sli4_hba.nvme_xri_max); - vport->phba->total_nvme_bufs += len; + + /* Don't post more new bufs if repost already recovered +* the nvme sgls. +*/ + if (phba->sli4_hba.nvme_xri_cnt == 0) { + len = lpfc_new_nvme_buf(vport, +phba->sli4_hba.nvme_xri_max); + vport->phba->total_nvme_bufs += len; + } } return ret; -- 2.13.1
[PATCH v2 13/20] lpfc: Fix MRQ > 1 context list handling
From: Dick KennedyVarious oops including cpu LOCKUPs were seen. For asynchronously received ius where the driver must assign exchange resources, the resources were on a single get (free) list and put list (finished, waiting to be put on get list). As all cpus are sharing the lists, an interrupt for a receive frame may have to wait for all the other cpus to place their done work onto the put list before it can acquire the lock to pull from the list. Fix by breaking the resource lists into per-cpu lists or at least more than 1 list with cpu's sharing the lists). A cpu would allocate from the free list for its own cpu, and put its done work on the its own put list - avoiding the contention. As cpu load may vary, when empty, a cpu may grab from another cpu, thereby changing resource distribution. But searching for a resource only occurs on 1 or a few cpus until a single resource can be allocated. if the condition reoccurs, it starts looking at a different cpu. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_attr.c| 11 +- drivers/scsi/lpfc/lpfc_crtn.h| 5 +- drivers/scsi/lpfc/lpfc_debugfs.c | 11 +- drivers/scsi/lpfc/lpfc_init.c| 18 ++- drivers/scsi/lpfc/lpfc_nvmet.c | 265 ++- drivers/scsi/lpfc/lpfc_nvmet.h | 14 +++ drivers/scsi/lpfc/lpfc_sli.c | 2 +- drivers/scsi/lpfc/lpfc_sli4.h| 7 +- 8 files changed, 236 insertions(+), 97 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 4ed48ed38e79..d3d01ff44423 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -245,13 +245,10 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, atomic_read(>xmt_abort_rsp), atomic_read(>xmt_abort_rsp_error)); - spin_lock(>sli4_hba.nvmet_ctx_get_lock); - spin_lock(>sli4_hba.nvmet_ctx_put_lock); - tot = phba->sli4_hba.nvmet_xri_cnt - - (phba->sli4_hba.nvmet_ctx_get_cnt + - phba->sli4_hba.nvmet_ctx_put_cnt); - spin_unlock(>sli4_hba.nvmet_ctx_put_lock); - spin_unlock(>sli4_hba.nvmet_ctx_get_lock); + /* Calculate outstanding IOs */ + tot = atomic_read(>rcv_fcp_cmd_drop); + tot += atomic_read(>xmt_fcp_release); + tot = atomic_read(>rcv_fcp_cmd_in) - tot; len += snprintf(buf + len, PAGE_SIZE - len, "IO_CTX: %08x WAIT: cur %08x tot %08x\n" diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index da669dce12fe..7e300734b345 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -556,9 +556,8 @@ int lpfc_nvmet_update_targetport(struct lpfc_hba *phba); void lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba); void lpfc_nvmet_unsol_ls_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *piocb); -void lpfc_nvmet_unsol_fcp_event(struct lpfc_hba *phba, - struct lpfc_sli_ring *pring, - struct rqb_dmabuf *nvmebuf, uint64_t isr_ts); +void lpfc_nvmet_unsol_fcp_event(struct lpfc_hba *phba, uint32_t idx, + struct rqb_dmabuf *nvmebuf, uint64_t isr_ts); void lpfc_nvme_mod_param_dep(struct lpfc_hba *phba); void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 5cc8b0f7d885..c292264aa687 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -848,13 +848,10 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) spin_unlock(>sli4_hba.abts_nvme_buf_list_lock); } - spin_lock(>sli4_hba.nvmet_ctx_get_lock); - spin_lock(>sli4_hba.nvmet_ctx_put_lock); - tot = phba->sli4_hba.nvmet_xri_cnt - - (phba->sli4_hba.nvmet_ctx_get_cnt + - phba->sli4_hba.nvmet_ctx_put_cnt); - spin_unlock(>sli4_hba.nvmet_ctx_put_lock); - spin_unlock(>sli4_hba.nvmet_ctx_get_lock); + /* Calculate outstanding IOs */ + tot = atomic_read(>rcv_fcp_cmd_drop); + tot += atomic_read(>xmt_fcp_release); + tot = atomic_read(>rcv_fcp_cmd_in) - tot; len += snprintf(buf + len, size - len, "IO_CTX: %08x WAIT: cur %08x tot %08x\n" diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 5f32a7fe169d..897eb62ed4e6 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++
[PATCH v2 09/20] lpfc: Fix crash in lpfc nvmet when fc port is reset
From: Dick Kennedyin adapter reset tests, an oops was seen with a NULL pointer in lpfc_free_rq_buffer+0x20/0x60 The driver is failing to properly repost the nvmet sgl list when recovering from the reset. Thus the driver eventually trys to walk an errant buffer list. Corrected the sgl buffer recovery as well as strengthening the initialization of the bufferlist. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_init.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 491aa95eb0f6..5f32a7fe169d 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3226,6 +3226,13 @@ lpfc_offline(struct lpfc_hba *phba) /* stop port and all timers associated with this hba */ lpfc_stop_port(phba); + + /* Tear down the local and target port registrations. The +* nvme transports need to cleanup. +*/ + lpfc_nvmet_destroy_targetport(phba); + lpfc_nvme_destroy_localport(phba->pport); + vports = lpfc_create_vport_work_array(phba); if (vports != NULL) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) @@ -6516,6 +6523,12 @@ lpfc_free_nvmet_sgl_list(struct lpfc_hba *phba) lpfc_nvmet_buf_free(phba, sglq_entry->virt, sglq_entry->phys); kfree(sglq_entry); } + + /* Update the nvmet_xri_cnt to reflect no current sgls. +* The next initialization cycle sets the count and allocates +* the sgls over again. +*/ + phba->sli4_hba.nvmet_xri_cnt = 0; } /** @@ -8301,6 +8314,9 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) goto out_error; } + /* Put list in known state in case driver load fails. */ + INIT_LIST_HEAD(>rqbp->rqb_buffer_list); + /* Create NVMET Receive Queue for data */ qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.rq_esize, -- 2.13.1
[PATCH v2 10/20] lpfc: Fix NVME PRLI handling during RSCN
From: Dick KennedyA race condition was found whereby the initiator would receive the RSCN for a new NVME device before it had a chance to register its FC4 support with the fabric. Thus, when queried by the initiator, it would see that the target supported FC-NVME. Corrected by making the assumption that the target always supports FC-NVME thus a PRLI is sent. It's ok for the target to reject it. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_els.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index fe0dd42b75af..9a8808abe61f 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2177,6 +2177,16 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, uint16_t cmdsize; u32 local_nlp_type, elscmd; + /* +* If we are in RSCN mode, the FC4 types supported from a +* previous GFT_ID command may not be accurate. So, if we +* are a NVME Initiator, always look for the possibility of +* the remote NPort beng a NVME Target. +*/ + if (phba->sli_rev == LPFC_SLI_REV4 && + vport->fc_flag & FC_RSCN_MODE && + vport->nvmei_support) + ndlp->nlp_fc4_type |= NLP_FC4_NVME; local_nlp_type = ndlp->nlp_fc4_type; send_next_prli: -- 2.13.1
[PATCH v2 15/20] lpfc: Fix nvme target failure after 2nd adapter reset
From: Dick KennedyFix nvme target failure after 2nd adapter reset The nonrecovery occurred because the lpfc nvme initiator function did not reestablish its localport creation with the nvme host transport in lpfc_oneline. Because of that, an NVME rport binding could not take place. Corrected by recreating the localport in the adapter reset recovery routine. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_init.c | 18 +- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 897eb62ed4e6..659662777b65 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3048,7 +3048,7 @@ lpfc_online(struct lpfc_hba *phba) { struct lpfc_vport *vport; struct lpfc_vport **vports; - int i; + int i, error = 0; bool vpis_cleared = false; if (!phba) @@ -3072,6 +3072,22 @@ lpfc_online(struct lpfc_hba *phba) if (!phba->sli4_hba.max_cfg_param.vpi_used) vpis_cleared = true; spin_unlock_irq(>hbalock); + + /* Reestablish the local initiator port. +* The offline process destroyed the previous lport. +*/ + if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { + if (!phba->nvmet_support) { + error = lpfc_nvme_create_localport(phba->pport); + if (error) { + lpfc_printf_log(phba, KERN_ERR, + LOG_INIT, + "6132 NVME restore reg " + "failed on nvmei error " + "x%x\n", error); + } + } + } } else { lpfc_sli_queue_init(phba); if (lpfc_sli_hba_setup(phba)) { /* Initialize SLI2/SLI3 HBA */ -- 2.13.1
[PATCH v2 11/20] lpfc: Correct issues with FAWWN and FDISCs
From: Dick KennedyWhen using fabric-assigned WWNs, the switch doesn't like copy of the FLOGI payload, which includes valid VVL bits, to be used as the FDISC paylaod. Rather than wait for corrected switch firmware, ensure the VVL bits are marked invalid on FDISCs. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_els.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 9a8808abe61f..f97d578ea6bd 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -8868,6 +8868,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, pcmd += sizeof(uint32_t); /* Node Name */ pcmd += sizeof(uint32_t); /* Node Name */ memcpy(pcmd, >fc_nodename, 8); + sp->cmn.valid_vendor_ver_level = 0; memset(sp->un.vendorVersion, 0, sizeof(sp->un.vendorVersion)); lpfc_set_disctmo(vport); -- 2.13.1
[PATCH v2 18/20] lpfc: Add Buffer to Buffer credit recovery support
Add Buffer to buffer credit recovery support to the driver. This is a negotiated feature with the peer that allows for both sides to detect dropped RRDY's and FC Frames and recover credit. Signed-off-by: Dick KennedySigned-off-by: James Smart --- drivers/scsi/lpfc/lpfc.h | 3 ++- drivers/scsi/lpfc/lpfc_attr.c| 41 drivers/scsi/lpfc/lpfc_attr.h| 10 ++ drivers/scsi/lpfc/lpfc_els.c | 14 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 12 ++-- drivers/scsi/lpfc/lpfc_hw.h | 18 +++--- drivers/scsi/lpfc/lpfc_hw4.h | 23 ++ drivers/scsi/lpfc/lpfc_init.c| 5 + drivers/scsi/lpfc/lpfc_mbox.c| 35 +++--- drivers/scsi/lpfc/lpfc_sli4.h| 15 +++ 10 files changed, 162 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 562dc0139735..50aaae3d966e 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -733,7 +733,6 @@ struct lpfc_hba { uint32_t fc_rttov; /* R_T_TOV timer value */ uint32_t fc_altov; /* AL_TOV timer value */ uint32_t fc_crtov; /* C_R_TOV timer value */ - uint32_t fc_citov; /* C_I_TOV timer value */ struct serv_parm fc_fabparam; /* fabric service parameters buffer */ uint8_t alpa_map[128]; /* AL_PA map from READ_LA */ @@ -757,6 +756,7 @@ struct lpfc_hba { #define LPFC_NVMET_MAX_PORTS 32 uint8_t mds_diags_support; uint32_t initial_imax; + uint8_t bbcredit_support; /* HBA Config Parameters */ uint32_t cfg_ack0; @@ -836,6 +836,7 @@ struct lpfc_hba { uint32_t cfg_enable_SmartSAN; uint32_t cfg_enable_mds_diags; uint32_t cfg_enable_fc4_type; + uint32_t cfg_enable_bbcr; /*Enable BB Credit Recovery*/ uint32_t cfg_xri_split; #define LPFC_ENABLE_FCP 1 #define LPFC_ENABLE_NVME 2 diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index d3d01ff44423..0806323829e6 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1889,6 +1889,36 @@ static inline bool lpfc_rangecheck(uint val, uint min, uint max) } /** + * lpfc_enable_bbcr_set: Sets an attribute value. + * @phba: pointer the the adapter structure. + * @val: integer attribute value. + * + * Description: + * Validates the min and max values then sets the + * adapter config field if in the valid range. prints error message + * and does not set the parameter if invalid. + * + * Returns: + * zero on success + * -EINVAL if val is invalid + */ +static ssize_t +lpfc_enable_bbcr_set(struct lpfc_hba *phba, uint val) +{ + if (lpfc_rangecheck(val, 0, 1) && phba->sli_rev == LPFC_SLI_REV4) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "3068 %s_enable_bbcr changed from %d to %d\n", + LPFC_DRIVER_NAME, phba->cfg_enable_bbcr, val); + phba->cfg_enable_bbcr = val; + return 0; + } + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "0451 %s_enable_bbcr cannot set to %d, range is 0, 1\n", + LPFC_DRIVER_NAME, val); + return -EINVAL; +} + +/** * lpfc_param_show - Return a cfg attribute value in decimal * * Description: @@ -5111,6 +5141,14 @@ LPFC_ATTR_R(sg_seg_cnt, LPFC_DEFAULT_SG_SEG_CNT, LPFC_DEFAULT_SG_SEG_CNT, */ LPFC_ATTR_R(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics"); +/* + * lpfc_enable_bbcr: Enable BB Credit Recovery + * 0 = BB Credit Recovery disabled + * 1 = BB Credit Recovery enabled (default) + * Value range is [0,1]. Default value is 1. + */ +LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery"); + struct device_attribute *lpfc_hba_attrs[] = { _attr_nvme_info, _attr_bg_info, @@ -5218,6 +5256,7 @@ struct device_attribute *lpfc_hba_attrs[] = { _attr_protocol, _attr_lpfc_xlane_supported, _attr_lpfc_enable_mds_diags, + _attr_lpfc_enable_bbcr, NULL, }; @@ -6229,11 +6268,13 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_nvmet_fb_size_init(phba, lpfc_nvmet_fb_size); lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel); lpfc_nvme_io_channel_init(phba, lpfc_nvme_io_channel); + lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr); if (phba->sli_rev != LPFC_SLI_REV4) { /* NVME only supported on SLI4 */ phba->nvmet_support = 0; phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP; + phba->cfg_enable_bbcr = 0; } else { /* We MUST have FCP support */ if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP)) diff --git a/drivers/scsi/lpfc/lpfc_attr.h b/drivers/scsi/lpfc/lpfc_attr.h index
[PATCH v2 19/20] scsi: lpfc: fix "integer constant too large" error on 32bit archs
From: Maurizio Lombardicc1: warnings being treated as errors drivers/scsi/lpfc/lpfc_init.c: In function 'lpfc_get_wwpn': drivers/scsi/lpfc/lpfc_init.c:3253: error: integer constant is too large for 'long' type Signed-off-by: Maurizio Lombardi Signed-off-by: James Smart --- v2: use rol64() --- drivers/scsi/lpfc/lpfc_init.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 19af7e2c2ac0..8c512e494353 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -3733,9 +3734,7 @@ lpfc_get_wwpn(struct lpfc_hba *phba) if (phba->sli_rev == LPFC_SLI_REV4) return be64_to_cpu(wwn); else - return (((wwn & 0x) >> 32) | - ((wwn & 0x) << 32)); - + return rol64(wwn, 32); } /** -- 2.13.1
[PATCH v2 20/20] lpfc: lpfc version bump 11.4.0.3
From: Dick KennedyUpdate driver version to 11.4.0.3 Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index c6a24c3e2d5e..6aa192b3e4bf 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -20,7 +20,7 @@ * included with this package. * ***/ -#define LPFC_DRIVER_VERSION "11.4.0.1" +#define LPFC_DRIVER_VERSION "11.4.0.3" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ -- 2.13.1
[PATCH v2 07/20] lpfc: Fix handling of FCP and NVME FC4 types in Pt2Pt topology
From: Dick KennedyAfter link bounce in a NVME Pt2Pt config, the driver managed to map the same nport twice, resulting in multiple device nodes for the same namespace. In Pt2Pt, the driver must send PRLI's for both (scsi) FCP and NVME rather than using fabric aids. The driver was inconsistent on handling various PRLI completions, especially rejects, which had reject codes cross the different protocol PRLI completions. Fixed to perform the following: if nvmet mode (fc port can only be a nvme target) - rejects all unsolicitly FCP PRLI's. Never issues a FCP PRLI. The multiple protocol PRLI's are sent simultaneously. However, driver will now only state transition after both PRLI's are complete. New flags were added to aid tracking the responses from the different PRLI's. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_disc.h | 1 + drivers/scsi/lpfc/lpfc_els.c | 30 ++ drivers/scsi/lpfc/lpfc_nportdisc.c | 9 + 3 files changed, 40 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 094c97b9e5f7..f9a566eaef04 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h @@ -159,6 +159,7 @@ struct lpfc_node_rrq { #define NLP_RNID_SND 0x0400 /* sent RNID request for this entry */ #define NLP_ELS_SND_MASK 0x07e0 /* sent ELS request for this entry */ #define NLP_NVMET_RECOV0x1000 /* NVMET auditing node for recovery. */ +#define NLP_FCP_PRLI_RJT 0x2000 /* Rport does not support FCP PRLI. */ #define NLP_DEFER_RM 0x0001 /* Remove this ndlp if no longer used */ #define NLP_DELAY_TMO 0x0002 /* delay timeout is running for node */ #define NLP_NPR_2B_DISC0x0004 /* node is included in num_disc_nodes */ diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 9e9aa8bb7001..6962e22087c8 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1966,6 +1966,7 @@ int lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) { struct lpfc_hba *phba = vport->phba; + struct Scsi_Host *shost; struct serv_parm *sp; struct lpfc_nodelist *ndlp; struct lpfc_iocbq *elsiocb; @@ -1984,6 +1985,11 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) if (!elsiocb) return 1; + shost = lpfc_shost_from_vport(vport); + spin_lock_irq(shost->host_lock); + ndlp->nlp_flag &= ~NLP_FCP_PRLI_RJT; + spin_unlock_irq(shost->host_lock); + pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); /* For PLOGI request, remainder of payload is service parameters */ @@ -3442,6 +3448,23 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, goto out_retry; } break; + case LSRJT_CMD_UNSUPPORTED: + /* lpfc nvmet returns this type of LS_RJT when it +* receives an FCP PRLI because lpfc nvmet only +* support NVME. ELS request is terminated for FCP4 +* on this rport. +*/ + if (stat.un.b.lsRjtRsnCodeExp == + LSEXP_REQ_UNSUPPORTED) { + if (cmd == ELS_CMD_PRLI) { + spin_lock_irq(shost->host_lock); + ndlp->nlp_flag |= NLP_FCP_PRLI_RJT; + spin_unlock_irq(shost->host_lock); + retry = 0; + goto out_retry; + } + } + break; } break; @@ -8013,6 +8036,13 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, rjt_exp = LSEXP_NOTHING_MORE; break; } + + /* NVMET accepts NVME PRLI only. Reject FCP PRLI */ + if (cmd == ELS_CMD_PRLI && phba->nvmet_support) { + rjt_err = LSRJT_CMD_UNSUPPORTED; + rjt_exp = LSEXP_REQ_UNSUPPORTED; + break; + } lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI); break; case ELS_CMD_LIRR: diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index a4488d6339c1..f3ad7cac355d 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1895,6 +1895,15 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
[PATCH v2 05/20] lpfc: convert info messages to standard messages
From: Dick KennedyTransitioned some informational discovery messages to now always be displayed when log_verbose is set. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_ct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 9c0c1463057d..33417681f5d4 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -955,7 +955,7 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, CTrsp = (struct lpfc_sli_ct_request *)outp->virt; fc4_data_0 = be32_to_cpu(CTrsp->un.gft_acc.fc4_types[0]); fc4_data_1 = be32_to_cpu(CTrsp->un.gft_acc.fc4_types[1]); - lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "3062 DID x%06x GFT Wd0 x%08x Wd1 x%08x\n", did, fc4_data_0, fc4_data_1); @@ -969,7 +969,7 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ndlp->nlp_fc4_type |= NLP_FC4_FCP; if (fc4_data_1 & LPFC_FC4_TYPE_BITMASK) ndlp->nlp_fc4_type |= NLP_FC4_NVME; - lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "3064 Setting ndlp %p, DID x%06x with " "FC4 x%08x, Data: x%08x x%08x\n", ndlp, did, ndlp->nlp_fc4_type, -- 2.13.1
[PATCH v2 06/20] lpfc: Correct return error codes to align with nvme_fc transport
From: Dick KennedyModify driver return error codes to align with host nvme transport. Driver isn't returning Exxx error codes to properly reflect out of resource or connectivity conditions (-EBUSY), yet there were hard error conditions returning -EBUSY. Fix to return: temporary failures or temporary resource availability: -EBUSY Connectivity issues: -ENODEV all others are treated as hard errors and return an -Exxx value that indicates the type of error. Also, lpfc_sli4_issue_wqe() was modified to not translate error from -Exxx to WQE state. This allows lpfc_nvme_fcp_io_submit() routine to just return whatever -E value was returned from other routines. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_nvme.c | 9 - drivers/scsi/lpfc/lpfc_sli.c | 23 ++- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 2f50df6a3dca..87e0743c4ace 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -364,7 +364,7 @@ lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, genwqe->sli4_xritag, genwqe->iotag, ndlp->nlp_DID); rc = lpfc_sli4_issue_wqe(phba, LPFC_ELS_RING, genwqe); - if (rc == WQE_ERROR) { + if (rc) { lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "6045 Issue GEN REQ WQE to NPORT x%x " "Data: x%x x%x\n", @@ -1270,7 +1270,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, * not exceed the programmed depth. */ if (atomic_read(>cmd_pending) >= ndlp->cmd_qdepth) { - ret = -EAGAIN; + ret = -EBUSY; goto out_fail; } @@ -1279,7 +1279,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR, "6065 driver's buffer pool is empty, " "IO failed\n"); - ret = -ENOMEM; + ret = -EBUSY; goto out_fail; } #ifdef CONFIG_SCSI_LPFC_DEBUG_FS @@ -1332,7 +1332,6 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, "sid: x%x did: x%x oxid: x%x\n", ret, vport->fc_myDID, ndlp->nlp_DID, lpfc_ncmd->cur_iocbq.sli4_xritag); - ret = -EBUSY; goto out_free_nvme_buf; } @@ -1576,7 +1575,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, abts_buf->wqe_cmpl = lpfc_nvme_abort_fcreq_cmpl; ret_val = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, abts_buf); spin_unlock_irqrestore(>hbalock, flags); - if (ret_val == IOCB_ERROR) { + if (ret_val) { lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_ABTS, "6137 Failed abts issue_wqe with status x%x " "for nvme_fcreq %p.\n", diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index e948ea05fd33..d68afec00f57 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -106,7 +106,7 @@ lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq) * -ENOMEM. * The caller is expected to hold the hbalock when calling this routine. **/ -static uint32_t +static int lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe) { union lpfc_wqe *temp_wqe; @@ -123,7 +123,7 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe) idx = ((q->host_index + 1) % q->entry_count); if (idx == q->hba_index) { q->WQ_overflow++; - return -ENOMEM; + return -EBUSY; } q->WQ_posted++; /* set consumption flag every once in a while */ @@ -10741,7 +10741,7 @@ lpfc_sli4_abort_nvme_io(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, abtsiocbp->vport = vport; abtsiocbp->wqe_cmpl = lpfc_nvme_abort_fcreq_cmpl; retval = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, abtsiocbp); - if (retval == IOCB_ERROR) { + if (retval) { lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME, "6147 Failed abts issue_wqe with status x%x " "for oxid x%x\n", @@ -1,6 +1,7 @@ lpfc_sli4_issue_wqe(struct lpfc_hba *phba, uint32_t ring_number, struct lpfc_sglq *sglq; struct lpfc_sli_ring *pring; unsigned long iflags; + uint32_t ret = 0; /* NVME_LS and NVME_LS ABTS requests. */ if (pwqe->iocb_flag & LPFC_IO_NVME_LS) { @@ -18906,10 +18907,12 @@ lpfc_sli4_issue_wqe(struct lpfc_hba *phba, uint32_t ring_number, }
[PATCH v2 08/20] lpfc: Fix duplicate NVME rport entries and namespaces.
From: Dick KennedyAfter lip, the driver sometimes would have two rports for the same device, allowing the namespaces to be duplicated by nvme. In lpfc_plogi_confirm_nport() the driver was not swapping the nrport maintained by the ndlp's undergoing address swapping. This allowed the 2nd rport to sneak in as it was considered a separate device. This patch adds the fixes to Swap the nrport in each ndlp and take care of the reference counts on the ndlps similar to FCP rports. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_els.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 6962e22087c8..fe0dd42b75af 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1527,6 +1527,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, uint8_t name[sizeof(struct lpfc_name)]; uint32_t rc, keepDID = 0, keep_nlp_flag = 0; uint16_t keep_nlp_state; + struct lpfc_nvme_rport *keep_nrport = NULL; int put_node; int put_rport; unsigned long *active_rrqs_xri_bitmap = NULL; @@ -1624,6 +1625,10 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, keep_nlp_state = new_ndlp->nlp_state; lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state); + /* For nvme, swap the nrport. */ + keep_nrport = new_ndlp->nrport; + new_ndlp->nrport = ndlp->nrport; + /* Move this back to NPR state */ if (memcmp(>nlp_portname, name, sizeof(struct lpfc_name)) == 0) { /* The new_ndlp is replacing ndlp totally, so we need @@ -1646,6 +1651,13 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, } new_ndlp->nlp_type = ndlp->nlp_type; } + + /* Fix up the nvme rport */ + if (ndlp->nrport) { + ndlp->nrport = NULL; + lpfc_nlp_put(ndlp); + } + /* We shall actually free the ndlp with both nlp_DID and * nlp_portname fields equals 0 to avoid any ndlp on the * nodelist never to be used. @@ -1690,6 +1702,14 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, keep_nlp_state = NLP_STE_NPR_NODE; lpfc_nlp_set_state(vport, ndlp, keep_nlp_state); + /* Previous ndlp no longer active with nvme host transport. +* Remove reference from earlier registration unless the +* nvme host took care of it. +*/ + if (ndlp->nrport) + lpfc_nlp_put(ndlp); + ndlp->nrport = keep_nrport; + /* Fix up the rport accordingly */ rport = ndlp->rport; if (rport) { -- 2.13.1
[PATCH v2 02/20] lpfc: Fix loop mode target discovery
From: Dick KennedyThe driver does not discover targets when in loop mode. The NLP type is correctly getting set when a fabric connection is detected but, not for loop. The unknown NLP type means that the driver does not issue a PRLI when in loop topology. Thus target discovery fails. Fix by checking the topology during discovery. If it is loop, set the NLP FC4 type to FCP. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_nportdisc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index f74cb0142fd4..95b2b43ac37d 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1724,6 +1724,9 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, lpfc_nvme_update_localport(vport); } + } else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) { + ndlp->nlp_fc4_type |= NLP_FC4_FCP; + } else if (ndlp->nlp_fc4_type == 0) { rc = lpfc_ns_cmd(vport, SLI_CTNS_GFT_ID, 0, ndlp->nlp_DID); -- 2.13.1
[PATCH v2 03/20] lpfc: Fix rediscovery on switch blade pull
From: Dick KennedyWhen the switch blade is pulled out then plugged back in, the driver does not issue a PLOGI to the target When the switch blade is pulled out, it does not reset the link. The driver ends up issuing a LOGO to the target, and finally sees devloss. Since the driver believes that a LOGO is outstanding, it does not issue a PLOGI to the target upon link up Correct by placing the ndlp in UNUSED state When devloss happens in LOGO_ISSUE state. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_nportdisc.c | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 95b2b43ac37d..a4488d6339c1 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -2192,12 +2192,15 @@ lpfc_device_rm_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) { /* -* Take no action. If a LOGO is outstanding, then possibly DevLoss has -* timed out and is calling for Device Remove. In this case, the LOGO -* must be allowed to complete in state LOGO_ISSUE so that the rpi -* and other NLP flags are correctly cleaned up. +* DevLoss has timed out and is calling for Device Remove. +* In this case, abort the LOGO and cleanup the ndlp */ - return ndlp->nlp_state; + + lpfc_unreg_rpi(vport, ndlp); + /* software abort outstanding PLOGI */ + lpfc_els_abort(vport->phba, ndlp); + lpfc_drop_node(vport, ndlp); + return NLP_STE_FREED_NODE; } static uint32_t -- 2.13.1
[PATCH v2 01/20] lpfc: Fix plogi collision that causes illegal state transition
From: Dick KennedyMessage "0271 Illegal State Transition: node" seen in logs, all luns are unuseable for that target. A window exists in the rcv_plogi path where if the state is plogi issue but the driver has not issued a plogi, then two reglogins will be sent for the same RPI. The first one to complete will advance the state to prli issue the second one will be detected as an illegal state, and leave the node in an unusable state. Correct the completion routine for the PLOGI ACC that detects the state change when the driver starts discovery on the node again and drop the REGLOGIN mailbox command. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_els.c | 26 +- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 6d1d6f691df4..9e9aa8bb7001 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -3930,7 +3930,31 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (mbox) { if ((rspiocb->iocb.ulpStatus == 0) && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { - lpfc_unreg_rpi(vport, ndlp); + if (!lpfc_unreg_rpi(vport, ndlp)) { + if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE || + ndlp->nlp_state == +NLP_STE_REG_LOGIN_ISSUE) { + lpfc_printf_vlog(vport, KERN_INFO, +LOG_DISCOVERY, +"0314 PLOGI recov " +"DID x%x " +"Data: x%x x%x x%x\n", +ndlp->nlp_DID, +ndlp->nlp_state, +ndlp->nlp_rpi, +ndlp->nlp_flag); + mp = (struct lpfc_dmabuf *) + mbox->context1; + if (mp) { + lpfc_mbuf_free(phba, mp->virt, + mp->phys); + kfree(mp); + } + mempool_free(mbox, phba->mbox_mem_pool); + goto out; + } + } + /* Increment reference count to ndlp to hold the * reference to ndlp for the callback function. */ -- 2.13.1
[PATCH v2 04/20] lpfc: Fix oops when NVME Target is discovered in a nonNVME environment
From: Dick Kennedylpfc oops when it discovers a NVME target but is configured for SCSI only operation. Oops is in lpfc_nvme_register_port+0x33/0x300. The localport is not valid so it should not have been referenced. Added validity check for localport Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_nvme.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 0a0a1b92d01d..2f50df6a3dca 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -2296,6 +2296,9 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) ndlp->nlp_DID, ndlp->nlp_type); localport = vport->localport; + if (!localport) + return 0; + lport = (struct lpfc_nvme_lport *)localport->private; /* NVME rports are not preserved across devloss. -- 2.13.1
[PATCH v2 00/20] lpfc updates for 11.4.0.3
This patch set provides a number of bug fixes and one additions. The additions are BB credit support. The patches were cut against the Martin's 4.13/scsi-fixes tree. There are no outside dependencies. V2: removed redundant Expresslane patch removed if type 6 support. Will add later. Incorporated patch from Maurizio Lombardi int constant too large Dick Kennedy (17): lpfc: Fix plogi collision that causes illegal state transition lpfc: Fix loop mode target discovery lpfc: Fix rediscovery on switch blade pull lpfc: Fix oops when NVME Target is discovered in a nonNVME environment lpfc: convert info messages to standard messages lpfc: Correct return error codes to align with nvme_fc transport lpfc: Fix handling of FCP and NVME FC4 types in Pt2Pt topology lpfc: Fix duplicate NVME rport entries and namespaces. lpfc: Fix crash in lpfc nvmet when fc port is reset lpfc: Fix NVME PRLI handling during RSCN lpfc: Correct issues with FAWWN and FDISCs lpfc: Limit amount of work processed in IRQ lpfc: Fix MRQ > 1 context list handling lpfc: Fix relative offset error on large nvmet target ios lpfc: Fix nvme target failure after 2nd adapter reset lpfc: Fix bad sgl reposting after 2nd adapter reset lpfc: lpfc version bump 11.4.0.3 James Smart (2): lpfc: remove console log clutter lpfc: Add Buffer to Buffer credit recovery support Maurizio Lombardi (1): scsi: lpfc: fix "integer constant too large" error on 32bit archs drivers/scsi/lpfc/lpfc.h | 3 +- drivers/scsi/lpfc/lpfc_attr.c | 52 ++- drivers/scsi/lpfc/lpfc_attr.h | 10 ++ drivers/scsi/lpfc/lpfc_crtn.h | 5 +- drivers/scsi/lpfc/lpfc_ct.c| 4 +- drivers/scsi/lpfc/lpfc_debugfs.c | 11 +- drivers/scsi/lpfc/lpfc_disc.h | 1 + drivers/scsi/lpfc/lpfc_els.c | 101 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 12 +- drivers/scsi/lpfc/lpfc_hw.h| 18 ++- drivers/scsi/lpfc/lpfc_hw4.h | 23 +++- drivers/scsi/lpfc/lpfc_init.c | 62 +++-- drivers/scsi/lpfc/lpfc_mbox.c | 35 - drivers/scsi/lpfc/lpfc_nportdisc.c | 25 +++- drivers/scsi/lpfc/lpfc_nvme.c | 25 ++-- drivers/scsi/lpfc/lpfc_nvmet.c | 271 - drivers/scsi/lpfc/lpfc_nvmet.h | 14 ++ drivers/scsi/lpfc/lpfc_sli.c | 56 +--- drivers/scsi/lpfc/lpfc_sli4.h | 23 +++- drivers/scsi/lpfc/lpfc_version.h | 2 +- 20 files changed, 598 insertions(+), 155 deletions(-) -- 2.13.1
Re: [PATCH 01/21] lpfc: Fix opps when ExpressLane is enabled
On 8/3/2017 3:43 AM, Nikola Pajkovsky wrote: James Smartwrites: From: Dick Kennedy Null pointer dereference in lpfc_sli4_fof_intr_handler The driver does not set up cq->assoc_qp for sli4_hba->oas_cq Initialize cq->assoc_qp before accessing it Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_sli.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index e948ea05fd33..0615bf9def23 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -13557,6 +13557,9 @@ lpfc_sli4_fof_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe) /* Save EQ associated with this CQ */ cq->assoc_qp = phba->sli4_hba.fof_eq; + /* Save EQ associated with this CQ */ + cq->assoc_qp = phba->sli4_hba.fof_eq; + Copy & paste error? Above lines are similar. yeah - a pretty stupid error. I believe we merged the same patch twice at different time points. surprised git am allowed it. Thanks. patch will be removed. -- james
[PATCH v2 1/2] nvmet_fc: add defer_req callback for deferment of cmd buffer return
At queue creation, the transport allocates a local job struct (struct nvmet_fc_fcp_iod) for each possible element of the queue. When a new CMD is received from the wire, a jobs struct is allocated from the queue and then used for the duration of the command. The job struct contains buffer space for the wire command iu. Thus, upon allocation of the job struct, the cmd iu buffer is copied to the job struct and the LLDD may immediately free/reuse the CMD IU buffer passed in the call. However, in some circumstances, due to the packetized nature of FC and the api of the FC LLDD which may issue a hw command to send the wire response, but the LLDD may not get the hw completion for the command and upcall the nvmet_fc layer before a new command may be asynchronously received on the wire. In other words, its possible for the initiator to get the response from the wire, thus believe a command slot free, and send a new command iu. The new command iu may be received by the LLDD and passed to the transport before the LLDD had serviced the hw completion and made the teardown calls for the original job struct. As such, there is no available job struct available for the new io. E.g. it appears like the host sent more queue elements than the queue size. It didn't based on it's understanding. Rather than treat this as a hard connection failure queue the new request until the job struct does free up. As the buffer isn't copied as there's no job struct, a special return value must be returned to the LLDD to signify to hold off on recycling the cmd iu buffer. And later, when a job struct is allocated and the buffer copied, a new LLDD callback is introduced to notify the LLDD and allow it to recycle it's command iu buffer. Signed-off-by: James Smart--- V2: added lockdep check in nvmet_fc_alloc_fcp_iod() converted for(;;) to while drivers/nvme/target/fc.c | 210 +++-- include/linux/nvme-fc-driver.h | 7 ++ 2 files changed, 189 insertions(+), 28 deletions(-) diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c index 49948a412dcc..01f99b9fe6fc 100644 --- a/drivers/nvme/target/fc.c +++ b/drivers/nvme/target/fc.c @@ -114,6 +114,11 @@ struct nvmet_fc_tgtport { u32 max_sg_cnt; }; +struct nvmet_fc_defer_fcp_req { + struct list_headreq_list; + struct nvmefc_tgt_fcp_req *fcp_req; +}; + struct nvmet_fc_tgt_queue { boolninetypercent; u16 qid; @@ -132,6 +137,8 @@ struct nvmet_fc_tgt_queue { struct nvmet_fc_tgt_assoc *assoc; struct nvmet_fc_fcp_iod *fod; /* array of fcp_iods */ struct list_headfod_list; + struct list_headpending_cmd_list; + struct list_headavail_defer_list; struct workqueue_struct *work_q; struct kref ref; } __aligned(sizeof(unsigned long long)); @@ -223,6 +230,8 @@ static void nvmet_fc_tgt_q_put(struct nvmet_fc_tgt_queue *queue); static int nvmet_fc_tgt_q_get(struct nvmet_fc_tgt_queue *queue); static void nvmet_fc_tgtport_put(struct nvmet_fc_tgtport *tgtport); static int nvmet_fc_tgtport_get(struct nvmet_fc_tgtport *tgtport); +static void nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, + struct nvmet_fc_fcp_iod *fod); /* *** FC-NVME DMA Handling */ @@ -463,9 +472,9 @@ static struct nvmet_fc_fcp_iod * nvmet_fc_alloc_fcp_iod(struct nvmet_fc_tgt_queue *queue) { static struct nvmet_fc_fcp_iod *fod; - unsigned long flags; - spin_lock_irqsave(>qlock, flags); + lockdep_assert_held(>qlock); + fod = list_first_entry_or_null(>fod_list, struct nvmet_fc_fcp_iod, fcp_list); if (fod) { @@ -477,17 +486,37 @@ nvmet_fc_alloc_fcp_iod(struct nvmet_fc_tgt_queue *queue) * will "inherit" that reference. */ } - spin_unlock_irqrestore(>qlock, flags); return fod; } static void +nvmet_fc_queue_fcp_req(struct nvmet_fc_tgtport *tgtport, + struct nvmet_fc_tgt_queue *queue, + struct nvmefc_tgt_fcp_req *fcpreq) +{ + struct nvmet_fc_fcp_iod *fod = fcpreq->nvmet_fc_private; + + /* +* put all admin cmds on hw queue id 0. All io commands go to +* the respective hw queue based on a modulo basis +*/ + fcpreq->hwqid = queue->qid ? + ((queue->qid - 1) % tgtport->ops->max_hw_queues) : 0; + + if (tgtport->ops->target_features & NVMET_FCTGTFEAT_CMD_IN_ISR) + queue_work_on(queue->cpu, queue->work_q, >work); + else + nvmet_fc_handle_fcp_rqst(tgtport, fod); +} + +static void
[PATCH v2 2/2] lpfc: support nvmet_fc defer_rcv callback
Currently, calls to nvmet_fc_rcv_fcp_req() always copied the FC-NVME cmd iu to a temporary buffer before returning, allowing the driver to immediately repost the buffer to the hardware. To address timing conditions on queue element structures vs async command reception, the nvmet_fc transport occasionally may need to hold on to the command iu buffer for a short period. In these cases, the nvmet_fc_rcv_fcp_req() will return a special return code (-EOVERFLOW). In these cases, the LLDD must delay until the new defer_rcv lldd callback is called before recycling the buffer back to the hw. This patch adds support for the new nvmet_fc transport defer_rcv callback and recognition of the new error code when passing commands to the transport. Signed-off-by: Dick KennedySigned-off-by: James Smart --- This patch is intended to enter the kernel through the nvme block tree which pulls in the nvmet_fc api change at the same time. It is not to be merged via the scsi trees without the latest nvme support in it. v2: removed unnecessary casts drivers/scsi/lpfc/lpfc_attr.c| 4 +++- drivers/scsi/lpfc/lpfc_debugfs.c | 5 - drivers/scsi/lpfc/lpfc_nvmet.c | 30 ++ drivers/scsi/lpfc/lpfc_nvmet.h | 1 + 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 4ed48ed38e79..7ee1a94c0b33 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -205,8 +205,10 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, atomic_read(>xmt_ls_rsp_error)); len += snprintf(buf+len, PAGE_SIZE-len, - "FCP: Rcv %08x Release %08x Drop %08x\n", + "FCP: Rcv %08x Defer %08x Release %08x " + "Drop %08x\n", atomic_read(>rcv_fcp_cmd_in), + atomic_read(>rcv_fcp_cmd_defer), atomic_read(>xmt_fcp_release), atomic_read(>rcv_fcp_cmd_drop)); diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 5cc8b0f7d885..744f3f395b64 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -782,8 +782,11 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) atomic_read(>xmt_ls_rsp_error)); len += snprintf(buf + len, size - len, - "FCP: Rcv %08x Drop %08x\n", + "FCP: Rcv %08x Defer %08x Release %08x " + "Drop %08x\n", atomic_read(>rcv_fcp_cmd_in), + atomic_read(>rcv_fcp_cmd_defer), + atomic_read(>xmt_fcp_release), atomic_read(>rcv_fcp_cmd_drop)); if (atomic_read(>rcv_fcp_cmd_in) != diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index fbeec344c6cc..bbbd0f84160d 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -841,12 +841,31 @@ lpfc_nvmet_xmt_fcp_release(struct nvmet_fc_target_port *tgtport, lpfc_nvmet_ctxbuf_post(phba, ctxp->ctxbuf); } +static void +lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport, +struct nvmefc_tgt_fcp_req *rsp) +{ + struct lpfc_nvmet_tgtport *tgtp; + struct lpfc_nvmet_rcv_ctx *ctxp = + container_of(rsp, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req); + struct rqb_dmabuf *nvmebuf = ctxp->rqb_buffer; + struct lpfc_hba *phba = ctxp->phba; + + lpfc_nvmeio_data(phba, "NVMET DEFERRCV: xri x%x sz %d CPU %02x\n", +ctxp->oxid, ctxp->size, smp_processor_id()); + + tgtp = phba->targetport->private; + atomic_inc(>rcv_fcp_cmd_defer); + lpfc_rq_buf_free(phba, >hbuf); /* repost */ +} + static struct nvmet_fc_target_template lpfc_tgttemplate = { .targetport_delete = lpfc_nvmet_targetport_delete, .xmt_ls_rsp = lpfc_nvmet_xmt_ls_rsp, .fcp_op = lpfc_nvmet_xmt_fcp_op, .fcp_abort = lpfc_nvmet_xmt_fcp_abort, .fcp_req_release = lpfc_nvmet_xmt_fcp_release, + .defer_rcv = lpfc_nvmet_defer_rcv, .max_hw_queues = 1, .max_sgl_segments = LPFC_NVMET_DEFAULT_SEGS, @@ -1504,6 +1523,17 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba, return; } + /* Processing of FCP command is deferred */ + if (rc == -EOVERFLOW) { + lpfc_nvmeio_data(phba, +"NVMET RCV BUSY: xri x%x sz %d from %06x\n", +oxid, size, sid); + /* defer reposting rcv buffer till
[PATCH v2 0/2] nvmet_fc: work around overalloc of queue elements
At queue creation, the transport allocates a local job struct (struct nvmet_fc_fcp_iod) for each possible element of the queue. When a new CMD is received from the wire, a jobs struct is allocated from the queue and then used for the duration of the command. The job struct contains buffer space for the wire command iu. Thus, upon allocation of the job struct, the cmd iu buffer is copied to the job struct and the LLDD may immediately free/reuse the CMD IU buffer passed in the call. However, in some circumstances, due to the packetized nature of FC and the api of the FC LLDD which may issue a hw command to send the wire response, but the LLDD may not get the hw completion for the command and upcall the nvmet_fc layer before a new command may be asynchronously received on the wire. In other words, its possible for the initiator to get the response from the wire, thus believe a command slot free, and send a new command iu. The new command iu may be received by the LLDD and passed to the transport before the LLDD had serviced the hw completion and made the teardown calls for the original job struct. As such, there is no available job struct available for the new io. E.g. it appears like the host sent more queue elements than the queue size. It didn't based on it's understanding. Rather than treat this temporarily overflow of the queue resources as a hard connection failure, change the api slightly to temporarily queue the new command until the job resource is freed up. The impact to the LLDD is in the cases where release can't be immediate, the LLDD must wait until a new callback is called notifying the release of the cmd iu buffer. Support for this api change is indicated by a non-null callback function, and the new buffer-held semantic is indicated by an -EOVERFLOW status code return from nvmet_fc_rcv_fcp_req(). v2: respond to comments from Johannes. James Smart (2): nvmet_fc: add defer_req callback for deferment of cmd buffer return lpfc: support nvmet_fc defer_rcv callback drivers/nvme/target/fc.c | 210 +-- drivers/scsi/lpfc/lpfc_attr.c| 4 +- drivers/scsi/lpfc/lpfc_debugfs.c | 5 +- drivers/scsi/lpfc/lpfc_nvmet.c | 30 ++ drivers/scsi/lpfc/lpfc_nvmet.h | 1 + include/linux/nvme-fc-driver.h | 7 ++ 6 files changed, 227 insertions(+), 30 deletions(-) -- 2.13.1
Re: Undefined behaviour in drivers/scsi/sym53c8xx_2/sym_hipd.c:762:24
On 2017-08-04, at 6:12 PM, Helge Deller wrote: > On the parisc platform I noticed the UBSAN warning below. > Maybe nr_divisor isn't correctly initialized ? > Helge > > [ 18.555455] sym0: <896> rev 0x7 at pci :00:0f.0 irq 68 > [ 18.625415] > > [ 18.726489] UBSAN: Undefined behaviour in > ./drivers/scsi/sym53c8xx_2/sym_hipd.c:762:24 > [ 18.864911] index -1903078336 is out of range for type 'u32 [7]' What about np->clock_divn? Dave -- John David Anglin dave.ang...@bell.net
.Your Payment..
Top of the day to you and I once tried to notify you as my earlier letter was returned undelivered and I deemed it necessary and urgent to contact you again via your e-mail address and to notify you finally about your outstanding compensation payment. After the last annual calculation of your Banking/Financial activities, you are qualified and eligible to receive a compensation check payment of $850,080.00 USD from the 2017 United Nations Compensation Commission Payment Reconciliation program. In line with the payment instruction and modalities as outlined by the financial committee of the United Nations Compensation Commission, your Cashier’s Check ($850,080.00 USD) has been forwarded to the Highspeed Courier Oberschleißheim for shipment to you. Send your Name, Resident Address, Country and Telephone number to the Highspeed Courier Oberschleißheim (HSCO) in order to receive your compensation check payment. Highspeed Courier Oberschleißheim (HSCO) E-mail: 6755455...@gmail.com Sincerely. Information Officer
Undefined behaviour in drivers/scsi/sym53c8xx_2/sym_hipd.c:762:24
On the parisc platform I noticed the UBSAN warning below. Maybe nr_divisor isn't correctly initialized ? Helge [ 18.555455] sym0: <896> rev 0x7 at pci :00:0f.0 irq 68 [ 18.625415] [ 18.726489] UBSAN: Undefined behaviour in ./drivers/scsi/sym53c8xx_2/sym_hipd.c:762:24 [ 18.864911] index -1903078336 is out of range for type 'u32 [7]' [ 18.936779] CPU: 0 PID: 1 Comm: swapper Not tainted 4.13.0-rc3-32bit+ #427 [ 19.019138] Backtrace: [ 19.047353] [<10191eb4>] show_stack+0x3c/0x50 [ 19.100577] [<10ce82fc>] dump_stack+0x28/0x38 [ 19.153826] [<10771b3c>] ubsan_epilogue+0x1c/0x60 [ 19.211229] [<107722ec>] __ubsan_handle_out_of_bounds+0x68/0x80 [ 19.283194] [<10924074>] sym_hcb_attach+0xc2c/0x3204 [ 19.343724] [<107aaa38>] sba_dma_supported+0x4c/0x208 [ 19.405291] [<10911984>] sym2_probe+0xd64/0x122c [ 19.461661] [<10501c64>] kernfs_add_one+0x328/0x354 [ 19.521134] [ 19.538916] [ 19.640086] sym0: PA-RISC Firmware, ID 7, Fast-40, SE, parity checking [ 19.725169] sym0: SCSI BUS has been reset. [ 19.774192] sym0: SCSI BUS mode change from SE to SE. [ 19.837034] sym0: SCSI BUS has been reset. [ 19.886092] scsi host0: sym-2.2.3 [ 25.154088] sym1: <896> rev 0x7 at pci :00:0f.1 irq 68 [ 25.222639] sym1: PA-RISC Firmware, ID 7, Fast-40, LVD, parity checking [ 25.308775] sym1: SCSI BUS has been reset. [ 25.357840] scsi host1: sym-2.2.3
Increased memory usage with scsi-mq
https://bugzilla.redhat.com/show_bug.cgi?id=1478201 We have a libguestfs test which adds 256 virtio-scsi disks to a qemu virtual machine. The VM has 500 MB of RAM, 1 vCPU and no swap. This test has been failing for a little while. It runs out of memory during SCSI enumeration in early boot. Tonight I bisected the cause to: 5c279bd9e40624f4ab6e688671026d6005b066fa is the first bad commit commit 5c279bd9e40624f4ab6e688671026d6005b066fa Author: Christoph HellwigDate: Fri Jun 16 10:27:55 2017 +0200 scsi: default to scsi-mq Remove the SCSI_MQ_DEFAULT config option and default to the blk-mq I/O path now that we had plenty of testing, and have I/O schedulers for blk-mq. The module option to disable the blk-mq path is kept around for now. Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen :04 04 57ec7d5d2ba76592a695f533a69f747700c31966 c79f6ecb070acc4fadf6fc05ca9ba32bc9c0c665 Mdrivers I also wrote a small test to see the maximum number of virtio-scsi disks I could add to the above VM. The results were very surprising (to me anyhow): With scsi-mq enabled: 175 disks With scsi-mq disabled: 1755 disks I don't know why the ratio is almost exactly 10 times. I read your slides about scsi-mq and it seems like a significant benefit to large machines, but could the out of the box defaults be made more friendly for small memory machines? Thanks, Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org
Re: [PATCH] hpsa: disable volume status check for older controller
> You should be able to suppress the "can't get device id' messages with: Yes, these messages are gone and it still works. -- Meelis Roos (mr...@linux.ee)
Re: [PATCH 0/2] generate uevent for SCSI sense code
Hi all, Could you please share your feedback on this version of the change? Thanks in advance, Song >> On 7/21/17, 3:58 PM, "Song Liu"wrote: This change is to follow up our discussion on event log for media management during LSF/MM 2017. Changes from RFC v3: Incorporate feedback by Johannes Thumshirn Thanks, Song Song Liu (2): scsi: generate uevent for SCSI sense code scsi: add rate limit to scsi sense code uevent drivers/scsi/Kconfig | 14 +++ drivers/scsi/hosts.c | 4 drivers/scsi/scsi_error.c | 58 ++ drivers/scsi/scsi_lib.c| 58 +- drivers/scsi/scsi_sysfs.c | 51 include/scsi/scsi_common.h | 6 + include/scsi/scsi_device.h | 27 - include/scsi/scsi_host.h | 13 +++ 8 files changed, 229 insertions(+), 2 deletions(-) -- 2.9.3
Re: [PATCH] hpsa: disable volume status check for older controller
On 08/04/2017 06:36 PM, Hannes Reinecke wrote: > On 08/04/2017 06:26 PM, Meelis Roos wrote: >>> Older Controller might not support volume status, so disable >>> it if 'hpsa_allow_any' is present. >> >> It makes my DL380G4 boot with hpsa.hpsa_allow_any=1 and it seems to >> work. Howevere, there are multiole verbose dmesg entries about failing >> things: >> > Hehe. How cool is that? > >> 0.267224] HP HPSA Driver (v 3.4.18-0) >> [0.267351] hpsa :04:03.0: unsupported board ID: 0x40910e11 >> [0.267494] hpsa :04:03.0: unsupported board ID: 0x40910e11 >> [0.267695] hpsa :04:03.0: PCI IRQ 51 -> rerouted to legacy IRQ 19 >> [0.267889] hpsa :04:03.0: Physical aborts not supported >> [0.268036] hpsa :04:03.0: Logical aborts not supported >> [0.268163] hpsa :04:03.0: HP SSD Smart Path aborts not supported >> [0.448240] scsi host0: hpsa >> [0.452228] hpsa :04:03.0: report luns requested format 2, got 0 >> [0.453950] hpsa :04:03.0: hpsa0: hpsa_update_device_info: can't get >> device id for host 0:C0:T0:L0 Direct-Access MAN3735MC >> [0.454312] hpsa :04:03.0: SCSI status: LUN: >> CDB:260015000801 >> [0.454525] hpsa :04:03.0: SCSI Status = 02, Sense key = 0x05, ASC = >> 0x3a, ASCQ = 0x00 > Curious. CDB 26 is a vendor specific command, and the controller > responds with 'Medium not present'. > Will be checking what's happening here. > >> Among these, the following show up red in dmesg: >> >> report luns requested format 2, got 0 >> hpsa0: hpsa_update_device_info: can't get device id for host 0:C0:T0:L0 >> Direct-Access MAN3735MC >> hpsa0: hpsa_update_device_info: can't get device id for host 0:C0:T-1:L-1 >> Direct-Access MAP3735NC >> report luns requested format 2, got 0 >> > Hmm. Looking into it. > > But thanks for testing! > You should be able to suppress the "can't get device id' messages with: diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 2cf6cccf067f..56fd654c1ecd 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -3813,7 +3813,7 @@ static int hpsa_update_device_info(struct ctlr_info *h, memset(this_device->device_id, 0, sizeof(this_device->device_id)); if (hpsa_get_device_id(h, scsi3addr, this_device->device_id, 8, - sizeof(this_device->device_id))) + sizeof(this_device->device_id)) < 0) dev_err(>pdev->dev, "hpsa%d: %s: can't get device id for host %d:C0:T%d:L%d\t%s\t%.16s\n", h->ctlr, __func__, Cheers, Hannes -- Dr. Hannes ReineckeTeamlead Storage & Networking h...@suse.de +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg)
Re: [PATCH] scsi_devinfo: fixup string compare
On Fri, 2017-08-04 at 18:28 +0200, Hannes Reinecke wrote: > Well, maybe; however, the current logic fails to match the entry > > {"HITACHI", "OPEN-", "*", BLIST_REPORTLUN2}, > > against the 'real' name, which is "HITACHI" "OPEN-V". > And for some reason we have far more customer using Hitachi arrays than > using scanner of dubious provenance with no Vendor (which is the real > bug if you ask me...) Hello Hannes, So for some entries in the table a prefix match should be performed (e.g. the model string for the Hitachi entry) but for other entries (e.g. the scanner entry) an exact match should be performed on the vendor name? If so, how about one of the following two approaches: * Adding ".*" at the end of the entries in the table for which a prefix match is sufficient and to change scsi_dev_info_list_find() such that it performs a regex match instead of an exact match or a prefix match. * Performing an exact match on the vendor name and a prefix match on the model name. Thanks, Bart.
Re: [PATCH] hpsa: disable volume status check for older controller
On 08/04/2017 06:26 PM, Meelis Roos wrote: >> Older Controller might not support volume status, so disable >> it if 'hpsa_allow_any' is present. > > It makes my DL380G4 boot with hpsa.hpsa_allow_any=1 and it seems to > work. Howevere, there are multiole verbose dmesg entries about failing > things: > Hehe. How cool is that? > 0.267224] HP HPSA Driver (v 3.4.18-0) > [0.267351] hpsa :04:03.0: unsupported board ID: 0x40910e11 > [0.267494] hpsa :04:03.0: unsupported board ID: 0x40910e11 > [0.267695] hpsa :04:03.0: PCI IRQ 51 -> rerouted to legacy IRQ 19 > [0.267889] hpsa :04:03.0: Physical aborts not supported > [0.268036] hpsa :04:03.0: Logical aborts not supported > [0.268163] hpsa :04:03.0: HP SSD Smart Path aborts not supported > [0.448240] scsi host0: hpsa > [0.452228] hpsa :04:03.0: report luns requested format 2, got 0 > [0.453950] hpsa :04:03.0: hpsa0: hpsa_update_device_info: can't get > device id for host 0:C0:T0:L0 Direct-Access MAN3735MC > [0.454312] hpsa :04:03.0: SCSI status: LUN: > CDB:260015000801 > [0.454525] hpsa :04:03.0: SCSI Status = 02, Sense key = 0x05, ASC = > 0x3a, ASCQ = 0x00 Curious. CDB 26 is a vendor specific command, and the controller responds with 'Medium not present'. Will be checking what's happening here. > Among these, the following show up red in dmesg: > > report luns requested format 2, got 0 > hpsa0: hpsa_update_device_info: can't get device id for host 0:C0:T0:L0 > Direct-Access MAN3735MC > hpsa0: hpsa_update_device_info: can't get device id for host 0:C0:T-1:L-1 > Direct-Access MAP3735NC > report luns requested format 2, got 0 > Hmm. Looking into it. But thanks for testing! Cheers, Hannes -- Dr. Hannes ReineckeTeamlead Storage & Networking h...@suse.de +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg)
Re: [PATCH] scsi_devinfo: fixup string compare
On 08/04/2017 05:32 PM, Bart Van Assche wrote: > On Fri, 2017-08-04 at 11:40 +0200, Hannes Reinecke wrote: >> When checking the model and vendor string we need to use the >> minimum value of either string, otherwise we'll miss out on >> wildcard matches. >> Without this patch certain Hitachi arrays will not be presenting >> VPD pages correctly. >> >> Fixes: 5e7ff2c ("SCSI: fix new bug in scsi_dev_info_list string matching") >> Signed-off-by: Hannes Reinecke>> --- >> drivers/scsi/scsi_devinfo.c | 6 -- >> 1 file changed, 4 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c >> index 28fea83..f8a302f 100644 >> --- a/drivers/scsi/scsi_devinfo.c >> +++ b/drivers/scsi/scsi_devinfo.c >> @@ -456,11 +456,13 @@ static struct scsi_dev_info_list >> *scsi_dev_info_list_find(const char *vendor, >> /* >> * Behave like the older version of get_device_flags. >> */ >> -if (memcmp(devinfo->vendor, vskip, vmax) || >> +if (memcmp(devinfo->vendor, vskip, >> + min(vmax, strlen(devinfo->vendor))) || >> (vmax < sizeof(devinfo->vendor) && >> devinfo->vendor[vmax])) >> continue; >> -if (memcmp(devinfo->model, mskip, mmax) || >> +if (memcmp(devinfo->model, mskip, >> + min(mmax, strlen(devinfo->model))) || >> (mmax < sizeof(devinfo->model) && >> devinfo->model[mmax])) >> continue; > > Hello Hannes, > > Will this reintroduce the bug mentioned in commit b704f70ce200? The > description > of that commit is as follows: > > = > > SCSI: fix bug in scsi_dev_info_list matching > > The "compatible" matching algorithm used for looking up old-style > blacklist entries in a scsi_dev_info_list is buggy. The core of the > algorithm looks like this: > > if (memcmp(devinfo->vendor, vendor, > min(max, strlen(devinfo->vendor > /* not a match */ > > where max is the length of the device's vendor string after leading > spaces have been removed but trailing spaces have not. Because of the > min() computation, either entry could be a proper substring of the > other and the code would still think that they match. > > In the case originally reported, the device's vendor and product > strings were "Inateck " and "". These matched against > the following entry in the global device list: > > {"", "Scanner", "1.80", BLIST_NOLUN} > > because "" is a substring of "Inateck " and "" (the result of removing > leading spaces from the device's product string) is a substring of > "Scanner". The mistaken match prevented the system from scanning and > finding the device's second Logical Unit. > > This patch fixes the problem by making two changes. First, the code > for leading-space removal is hoisted out of the loop. (This means it > will sometimes run unnecessarily, but since a large percentage of all > lookups involve the "compatible" entries in global device list, this > should be an overall improvement.) Second and more importantly, the > patch removes trailing spaces and adds a check to verify that the two > resulting strings are exactly the same length. This prevents matches > where one entry is a proper substring of the other. > Well, maybe; however, the current logic fails to match the entry {"HITACHI", "OPEN-", "*", BLIST_REPORTLUN2}, against the 'real' name, which is "HITACHI" "OPEN-V". And for some reason we have far more customer using Hitachi arrays than using scanner of dubious provenance with no Vendor (which is the real bug if you ask me...) Cheers, Hannes -- Dr. Hannes ReineckeTeamlead Storage & Networking h...@suse.de +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg)
Re: [PATCH] hpsa: disable volume status check for older controller
> Older Controller might not support volume status, so disable > it if 'hpsa_allow_any' is present. It makes my DL380G4 boot with hpsa.hpsa_allow_any=1 and it seems to work. Howevere, there are multiole verbose dmesg entries about failing things: 0.267224] HP HPSA Driver (v 3.4.18-0) [0.267351] hpsa :04:03.0: unsupported board ID: 0x40910e11 [0.267494] hpsa :04:03.0: unsupported board ID: 0x40910e11 [0.267695] hpsa :04:03.0: PCI IRQ 51 -> rerouted to legacy IRQ 19 [0.267889] hpsa :04:03.0: Physical aborts not supported [0.268036] hpsa :04:03.0: Logical aborts not supported [0.268163] hpsa :04:03.0: HP SSD Smart Path aborts not supported [0.448240] scsi host0: hpsa [0.452228] hpsa :04:03.0: report luns requested format 2, got 0 [0.453950] hpsa :04:03.0: hpsa0: hpsa_update_device_info: can't get device id for host 0:C0:T0:L0 Direct-Access MAN3735MC [0.454312] hpsa :04:03.0: SCSI status: LUN: CDB:260015000801 [0.454525] hpsa :04:03.0: SCSI Status = 02, Sense key = 0x05, ASC = 0x3a, ASCQ = 0x00 [0.458100] hpsa :04:03.0: hpsa0: hpsa_update_device_info: can't get device id for host 0:C0:T-1:L-1 Direct-Access MAP3735NC [0.458453] hpsa :04:03.0: SCSI status: LUN: CDB:2600010015000801 [0.458668] hpsa :04:03.0: SCSI Status = 02, Sense key = 0x05, ASC = 0x3a, ASCQ = 0x00 [0.485980] hpsa :04:03.0: C0:T-1:L-1 Volume status not available, assuming online. [0.486807] hpsa :04:03.0: scsi 0:0:0:0: masked Direct-Access FUJITSU MAN3735MCPHYS DRV SSDSmartPathCap- En- Exp=0 [0.487020] hpsa :04:03.0: scsi 0:0:1:0: masked Direct-Access FUJITSU MAP3735NCPHYS DRV SSDSmartPathCap- En- Exp=0 [0.487229] hpsa :04:03.0: scsi 0:1:0:0: added Direct-Access HP LOGICAL VOLUME RAID-1(+0) SSDSmartPathCap- En- Exp=1 [0.487440] hpsa :04:03.0: scsi 0:3:0:0: added RAID HP SA6i controller SSDSmartPathCap- En- Exp=1 [0.487997] scsi 0:1:0:0: Direct-Access HP LOGICAL VOLUME 2.84 PQ: 0 ANSI: 4 [0.488989] scsi 0:3:0:0: RAID HP SA6i 2.84 PQ: 0 ANSI: 0 [0.489390] hpsa :0b:04.0: unsupported board ID: 0x409c0e11 [0.489532] hpsa :0b:04.0: unsupported board ID: 0x409c0e11 [0.489870] hpsa :0b:04.0: Physical aborts not supported [0.489995] hpsa :0b:04.0: Logical aborts not supported [0.490118] hpsa :0b:04.0: HP SSD Smart Path aborts not supported [0.628221] scsi host1: hpsa [0.632143] hpsa :0b:04.0: report luns requested format 2, got 0 [0.633498] hpsa :0b:04.0: scsi 1:3:0:0: added RAID HP SA6400 controller SSDSmartPathCap- En- Exp=1 [0.634246] scsi 1:0:0:0: RAID HP SA6400 2.84 PQ: 0 ANSI: 0 [0.634882] i8042: PNP: PS/2 Controller [PNP0303:KBD,PNP0f0e:PS2M] at 0x60,0x64 irq 1,12 [0.635581] sd 0:1:0:0: [sda] 430622325 512-byte logical blocks: (220 GB/205 GiB) [0.635974] sd 0:1:0:0: [sda] Write Protect is off [0.636118] sd 0:1:0:0: [sda] Mode Sense: 5b 00 00 08 [0.636337] sd 0:1:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA Among these, the following show up red in dmesg: report luns requested format 2, got 0 hpsa0: hpsa_update_device_info: can't get device id for host 0:C0:T0:L0 Direct-Access MAN3735MC hpsa0: hpsa_update_device_info: can't get device id for host 0:C0:T-1:L-1 Direct-Access MAP3735NC report luns requested format 2, got 0 -- Meelis Roos (mr...@linux.ee)
Re: [PATCH] scsi_dh_alua: suppress errors from unsupported devices
On Fri, 2017-08-04 at 08:37 +0200, Hannes Reinecke wrote: > ALUA is only relevant for disk-like devices, so we shouldn't > be printing out warning messages for other device types. Reviewed-by: Bart Van Assche
Re: [PATCH 1/2] block: Zoned block device single-threaded submission
On Fri, 2017-08-04 at 16:52 +0900, Damien Le Moal wrote: > From: Hannes Reinecke> > The scsi_request_fn() dispatch function internally unlocks the request > queue before submitting a request to the underlying LLD. This can > potentially lead to write request reordering if the context executing > scsi_request_fn() is preempted before the request is submitted to the > LLD and another context start the same function execution. > > This is not a problem for regular disks but leads to write I/O errors > on host managed zoned block devices and reduce the effectivness of > sequential write optimizations for host aware disks. > (Note: the zone write lock in place in the scsi command init code will > prevent multiple writes from being issued simultaneously to the same > zone to avoid HBA level reordering issues, but this locking mechanism > is ineffective to prevent reordering at the dispatch level) > > Prevent this from happening by limiting the number of context that can > simultaneously execute the queue request_fn() function to a single > thread. > > A similar patch was originally proposed by Hannes Reinecke in a first > set of patches implementing ZBC support but ultimately not included in > the final support implementation. See commit 92f5e2a295 > "block: add flag for single-threaded submission" in the tree > https://git.kernel.org/pub/scm/linux/kernel/git/hare/scsi-devel.git/log/?h=zac.v3 > > Authorship thus goes to Hannes. > > Signed-off-by: Hannes Reinecke > Signed-off-by: Damien Le Moal > --- > block/blk-core.c | 7 +++ > 1 file changed, 7 insertions(+) > > diff --git a/block/blk-core.c b/block/blk-core.c > index dbecbf4a64e0..cf590cbddcfd 100644 > --- a/block/blk-core.c > +++ b/block/blk-core.c > @@ -371,7 +371,14 @@ inline void __blk_run_queue_uncond(struct request_queue > *q) >* running such a request function concurrently. Keep track of the >* number of active request_fn invocations such that blk_drain_queue() >* can wait until all these request_fn calls have finished. > + * > + * For zoned block devices, do not allow multiple threads to > + * dequeue requests as this can lead to write request reordering > + * during the time the queue is unlocked. >*/ > + if (blk_queue_is_zoned(q) && q->request_fn_active) > + return; > + > q->request_fn_active++; > q->request_fn(q); > q->request_fn_active--; Hello Damien, Since serialization of request queue processing is only needed for ZBC and since all ZBC devices use the SCSI core, could this serialization have been achieved by modifying the SCSI core, e.g. by adding the following before the for-loop in scsi_request_fn(): if (blk_queue_is_zoned(q) && q->request_fn_active > 1) return; Thanks, Bart.
Re: [PATCH 2/2] sd_zbc: Write unlock zones from sd_uninit_cmnd()
On Fri, 2017-08-04 at 16:52 +0900, Damien Le Moal wrote: > Releasing the write lock of a zone when the write commnand that > acquired the lock completes can cause deadlocks with scsi-mq due to > potential queue reordering if the lock owning request is requeued and > not executed. > > Since sd_uninit_cmnd() is always called when a request is requeued, > call sd_zbc_write_unlock_zone() from that function for write requests > that acquired a zone lock. Acquisition of a zone lock by a write command > is indicated using the new command flag SCMD_ZONE_WRITE_LOCK. > > Signed-off-by: Damien Le MoalHello Damien, Should "Cc: " be added to this patch? > diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c > index 96855df9f49d..6423ae70477e 100644 > --- a/drivers/scsi/sd_zbc.c > +++ b/drivers/scsi/sd_zbc.c > @@ -294,6 +294,9 @@ int sd_zbc_write_lock_zone(struct scsi_cmnd *cmd) > test_and_set_bit(zno, sdkp->zones_wlock)) > return BLKPREP_DEFER; > > + WARN_ON(cmd->flags & SCMD_ZONE_WRITE_LOCK); > + cmd->flags |= SCMD_ZONE_WRITE_LOCK; > + > return BLKPREP_OK; > } Did you perhaps intend WARN_ON_ONCE() instead of WARN_ON()? Thanks, Bart.
Re: [PATCH] aacraid: Fix out of bounds in aac_get_name_resp
On Fri, 2017-08-04 at 03:51 -0700, Raghava Aditya Renukunta wrote: > diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c > index 707ee2f5954d..a875175d58d1 100644 > --- a/drivers/scsi/aacraid/aachba.c > +++ b/drivers/scsi/aacraid/aachba.c > @@ -549,7 +549,9 @@ static void get_container_name_callback(void *context, > struct fib * fibptr) > if ((le32_to_cpu(get_name_reply->status) == CT_OK) >&& (get_name_reply->data[0] != '\0')) { > char *sp = get_name_reply->data; > - sp[sizeof(((struct aac_get_name_resp *)NULL)->data)] = '\0'; > + int data_size = FIELD_SIZEOF(struct aac_get_name_resp, data); > + > + sp[data_size - 1] = '\0'; > while (*sp == ' ') > ++sp; > if (*sp) { > @@ -579,12 +581,15 @@ static void get_container_name_callback(void *context, > struct fib * fibptr) > static int aac_get_container_name(struct scsi_cmnd * scsicmd) > { > int status; > + int data_size; > struct aac_get_name *dinfo; > struct fib * cmd_fibcontext; > struct aac_dev * dev; > > dev = (struct aac_dev *)scsicmd->device->host->hostdata; > > + data_size = FIELD_SIZEOF(struct aac_get_name_resp, data); > + > cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); > > aac_fib_init(cmd_fibcontext); > @@ -593,7 +598,7 @@ static int aac_get_container_name(struct scsi_cmnd * > scsicmd) > dinfo->command = cpu_to_le32(VM_ContainerConfig); > dinfo->type = cpu_to_le32(CT_READ_NAME); > dinfo->cid = cpu_to_le32(scmd_id(scsicmd)); > - dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp > *)NULL)->data)); > + dinfo->count = cpu_to_le32(data_size - 1); > > status = aac_fib_send(ContainerCommand, > cmd_fibcontext, > diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h > index 69812994b81e..92fabf2b0c24 100644 > --- a/drivers/scsi/aacraid/aacraid.h > +++ b/drivers/scsi/aacraid/aacraid.h > @@ -2275,7 +2275,7 @@ struct aac_get_name_resp { > __le32 parm3; > __le32 parm4; > __le32 parm5; > - u8 data[16]; > + u8 data[17]; > }; > > #define CT_CID_TO_32BITS_UID 165 Hello Raghava, This patch would have been more brief if FIELD_SIZEOF(struct aac_get_name_resp, data) would have been used directly instead of introducing the new local variable 'data_size'. Anyway: Reviewed-by: Bart Van Assche
Re: [PATCH] scsi_devinfo: fixup string compare
On Fri, 2017-08-04 at 11:40 +0200, Hannes Reinecke wrote: > When checking the model and vendor string we need to use the > minimum value of either string, otherwise we'll miss out on > wildcard matches. > Without this patch certain Hitachi arrays will not be presenting > VPD pages correctly. > > Fixes: 5e7ff2c ("SCSI: fix new bug in scsi_dev_info_list string matching") > Signed-off-by: Hannes Reinecke> --- > drivers/scsi/scsi_devinfo.c | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c > index 28fea83..f8a302f 100644 > --- a/drivers/scsi/scsi_devinfo.c > +++ b/drivers/scsi/scsi_devinfo.c > @@ -456,11 +456,13 @@ static struct scsi_dev_info_list > *scsi_dev_info_list_find(const char *vendor, > /* >* Behave like the older version of get_device_flags. >*/ > - if (memcmp(devinfo->vendor, vskip, vmax) || > + if (memcmp(devinfo->vendor, vskip, > +min(vmax, strlen(devinfo->vendor))) || > (vmax < sizeof(devinfo->vendor) && > devinfo->vendor[vmax])) > continue; > - if (memcmp(devinfo->model, mskip, mmax) || > + if (memcmp(devinfo->model, mskip, > +min(mmax, strlen(devinfo->model))) || > (mmax < sizeof(devinfo->model) && > devinfo->model[mmax])) > continue; Hello Hannes, Will this reintroduce the bug mentioned in commit b704f70ce200? The description of that commit is as follows: = SCSI: fix bug in scsi_dev_info_list matching The "compatible" matching algorithm used for looking up old-style blacklist entries in a scsi_dev_info_list is buggy. The core of the algorithm looks like this: if (memcmp(devinfo->vendor, vendor, min(max, strlen(devinfo->vendor /* not a match */ where max is the length of the device's vendor string after leading spaces have been removed but trailing spaces have not. Because of the min() computation, either entry could be a proper substring of the other and the code would still think that they match. In the case originally reported, the device's vendor and product strings were "Inateck " and "". These matched against the following entry in the global device list: {"", "Scanner", "1.80", BLIST_NOLUN} because "" is a substring of "Inateck " and "" (the result of removing leading spaces from the device's product string) is a substring of "Scanner". The mistaken match prevented the system from scanning and finding the device's second Logical Unit. This patch fixes the problem by making two changes. First, the code for leading-space removal is hoisted out of the loop. (This means it will sometimes run unnecessarily, but since a large percentage of all lookups involve the "compatible" entries in global device list, this should be an overall improvement.) Second and more importantly, the patch removes trailing spaces and adds a check to verify that the two resulting strings are exactly the same length. This prevents matches where one entry is a proper substring of the other. = Thanks, Bart.
Re: Gift-
Good Day, My wife and I have awarded you with a donation of $ 1,000,000.00 Dollars from part of our Jackpot Lottery of 50 Million Dollars, respond with your details for claims. We await your earliest response and God Bless you. Friedrich And Annand Mayrhofer. --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
Re: [RFC 4/9] zfcp: decouple FSF request setup of TMF from scsi_cmnd
Just for the records: There's another bug below. On 07/25/2017 04:14 PM, Steffen Maier wrote: The scsi_device argument of zfcp_fc_fcp_tm() can now be NULL. In zfcp_fsf_fcp_task_mgmt() resolve the still old argument scsi_cmnd into scsi_device very early and only depend on scsi_device and derived objects in the function body. Scsi_device and derived zfcp_scsi_dev can later be NULL for the target reset case, so do not depend on them unconditionally. For the generic case, rather change to using zfcp_port directly. This prepares to later change the function signature replacing the scsi_cmnd argument with zfcp_port and an optional scsi_device which can be NULL. Signed-off-by: Steffen Maier--- drivers/s390/scsi/zfcp_fc.h | 6 -- drivers/s390/scsi/zfcp_fsf.c | 25 + 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index f221a34c26df..2dc7d2a6f6ea 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -2339,13 +2339,19 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd, { struct zfcp_fsf_req *req = NULL; struct fcp_cmnd *fcp_cmnd; - struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scmnd->device); - struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio; + struct scsi_device *sdev = scmnd->device; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); BUG: must not unconditionally dereference sdev which can be NULL later on in the patch set! Fix: + struct zfcp_scsi_dev *zfcp_sdev = sdev ? sdev_to_zfcp(sdev) : NULL; Fix is no longer necessary in my reworked v2 (always having a non-NULL sdev) to be sent when I successfully completed function test. + struct zfcp_port *port = zfcp_sdev->port; This line was removed in the subsequent patch 5/9, so here the unconditional deref is OK because here in this patch we still get a non-NULL sdev. (The line is just argument lifting preparing for the function argument replacement in 5/9.) Other accesses to sdev or zfcp_sdev were properly guarded with this patch. -- Mit freundlichen Grüßen / Kind regards Steffen Maier Linux on z Systems Development IBM Deutschland Research & Development GmbH Vorsitzende des Aufsichtsrats: Martina Koederitz Geschaeftsfuehrung: Dirk Wittkopp Sitz der Gesellschaft: Boeblingen Registergericht: Amtsgericht Stuttgart, HRB 243294
Koch
Ishmeal Camara, presently working under the central bank of Togo, i have financier offer for both of us 2.5 M USD deal.
[PATCH] scsi_devinfo: fixup string compare
When checking the model and vendor string we need to use the minimum value of either string, otherwise we'll miss out on wildcard matches. Without this patch certain Hitachi arrays will not be presenting VPD pages correctly. Fixes: 5e7ff2c ("SCSI: fix new bug in scsi_dev_info_list string matching") Signed-off-by: Hannes Reinecke--- drivers/scsi/scsi_devinfo.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 28fea83..f8a302f 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -456,11 +456,13 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor, /* * Behave like the older version of get_device_flags. */ - if (memcmp(devinfo->vendor, vskip, vmax) || + if (memcmp(devinfo->vendor, vskip, + min(vmax, strlen(devinfo->vendor))) || (vmax < sizeof(devinfo->vendor) && devinfo->vendor[vmax])) continue; - if (memcmp(devinfo->model, mskip, mmax) || + if (memcmp(devinfo->model, mskip, + min(mmax, strlen(devinfo->model))) || (mmax < sizeof(devinfo->model) && devinfo->model[mmax])) continue; -- 1.8.5.6
Re: [PATCH v2 4/5] aic7xxx: regenerate firmware files
On 08/04/2017 01:28 AM, Michał Mirosław wrote: > Regenerate firmware files to make cleaner base for following fix. > This removes some unused definitions and reorders some #defines, but > the code remains the same. > > Signed-off-by: Michał Mirosław> --- > drivers/scsi/aic7xxx/aic79xx_reg.h_shipped | 1267 > -- > drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped | 34 +- > drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped | 44 +- > 3 files changed, 235 insertions(+), 1110 deletions(-) > Reviewed-by: Hannes Reinecke Cheers, Hannes -- Dr. Hannes ReineckeTeamlead Storage & Networking h...@suse.de +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg)
Re: [PATCH v2 2/5] aic7xxx: fix firmware build deps
On 08/04/2017 01:28 AM, Michał Mirosław wrote: > We need to override Kbuild rules for copying shipped files, otherwise > aic7xxx_reg.h and aic7xxx_reg_print.c will be ovewritten by old versions. > > Fixes: 516b7db593f3a541e2e98867575c3c697f41a247 > Signed-off-by: Michał Mirosław> --- > drivers/scsi/aic7xxx/Makefile | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > Reviewed-by: Hannes Reinecke Cheers, Hannes -- Dr. Hannes ReineckeTeamlead Storage & Networking h...@suse.de +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg)
Re: [PATCH v2 3/5] aic7xxx: remove rules for shipped files
On 08/04/2017 01:28 AM, Michał Mirosław wrote: > There are Kbuild rules for that already. > > Signed-off-by: Michał Mirosław> --- > drivers/scsi/aic7xxx/Makefile | 4 > 1 file changed, 4 deletions(-) > Reviewed-by: Hannes Reinecke Cheers, Hannes -- Dr. Hannes ReineckeTeamlead Storage & Networking h...@suse.de +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg)
Re: [PATCH v2 1/5] aic7xxx: remove empty function
On 08/04/2017 01:28 AM, Michał Mirosław wrote: > > ahc_platform_dump_card_state() does nothing. Remove it. > > Signed-off-by: Michał Mirosław> --- > drivers/scsi/aic7xxx/aic7xxx_core.c | 1 - > drivers/scsi/aic7xxx/aic7xxx_osm.c | 5 - > drivers/scsi/aic7xxx/aic7xxx_osm.h | 1 - > 3 files changed, 7 deletions(-) > Reviewed-by: Hannes Reinecke Cheers, Hannes -- Dr. Hannes ReineckezSeries & Storage h...@suse.com +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg)
[PATCH] scsi: osst: silence underflow warning in osst_verify_frame()
The code looks like this: i = ntohl(aux->filemark_cnt); if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt || STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) { If i is negative then it's less than OS_FM_TAB_MAX so we read before the start of the STp->header_cache->dat_fm_tab.fm_tab_ent[] array. Signed-off-by: Dan Carpenter--- There is a second static checker warning that I didn't know how to address: drivers/scsi/osst.c:723 osst_verify_frame() warn: potential integer overflow from user 'blk_cnt * blk_sz' diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 97ab5f160bc6..2db87ec04f48 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -619,7 +619,7 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q os_aux_t * aux = STp->buffer->aux; os_partition_t * par = &(aux->partition); struct st_partstat * STps = &(STp->ps[STp->partition]); - int blk_cnt, blk_sz, i; + unsigned int blk_cnt, blk_sz, i; if (STp->raw) { if (STp->buffer->syscall_result) {
Re: [PATCH] scsi-mq: Always unprepare before requeuing a request
On 8/4/17 06:40, Bart Van Assche wrote: > One of the two scsi-mq functions that requeue a request unprepares > a request before requeueing (scsi_io_completion()) but the other > function not (__scsi_queue_insert()). Make sure that a request is > unprepared before requeuing it. > > Fixes: commit d285203cf647 ("scsi: add support for a blk-mq based I/O path.") > Signed-off-by: Bart Van Assche> Cc: Christoph Hellwig > Cc: Hannes Reinecke > Cc: Damien Le Moal > Cc: Johannes Thumshirn > Cc: > --- > drivers/scsi/scsi_lib.c | 10 -- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c > index 4a2f705cdb14..c7514f3b444a 100644 > --- a/drivers/scsi/scsi_lib.c > +++ b/drivers/scsi/scsi_lib.c > @@ -44,6 +44,8 @@ static struct kmem_cache *scsi_sense_cache; > static struct kmem_cache *scsi_sense_isadma_cache; > static DEFINE_MUTEX(scsi_sense_cache_mutex); > > +static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd); > + > static inline struct kmem_cache * > scsi_select_sense_cache(bool unchecked_isa_dma) > { > @@ -140,6 +142,12 @@ static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd) > { > struct scsi_device *sdev = cmd->device; > > + if (cmd->request->rq_flags & RQF_DONTPREP) { > + cmd->request->rq_flags &= ~RQF_DONTPREP; > + scsi_mq_uninit_cmd(cmd); > + } else { > + WARN_ON_ONCE(true); > + } > blk_mq_requeue_request(cmd->request, true); > put_device(>sdev_gendev); > } > @@ -995,8 +1003,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned > int good_bytes) >* A new command will be prepared and issued. >*/ > if (q->mq_ops) { > - cmd->request->rq_flags &= ~RQF_DONTPREP; > - scsi_mq_uninit_cmd(cmd); > scsi_mq_requeue_cmd(cmd); > } else { > scsi_release_buffers(cmd); > Tested-by: Damien Le Moal This patch is needed for the V2 of the series "Zoned block device support fixes" that I sent. Best regards. -- Damien Le Moal, Western Digital
[PATCH 0/2 V2] Zoned block device support fixes
This small series addresses a couple of problems with zoned block devices detected with 4.13-rc. The first patch ensures that a well behaved host managed zoned block device user (an application doing direct disk accesses, f2fs or dm-zoned) will not see unaligned write errors due to reordering of write commands at dispatch time. The second patch addresses a request dispatch deadlock that can very easily trigger with f2fs or dm-zoned when scsi-mq is enabled. The root cause of this problem is the high probability of unintended reordering of sequential writes in the dispatch queue due to concurrent requeue and insert events. This patch only fixes the deadlock problem and is not a fix for the reordering problem. This means that host managed zoned block devices cannot be reliably used under a regular asynchronous (queued) write BIO issuing pattern to a zone with scsi-mq enabled for now. The second patch requires the patch 2f2d7c92dda "scsi-mq: Always unprepare before requeuing a request" sent by Bart. Damien Le Moal (1): sd_zbc: Write unlock zone from sd_uninit_cmnd() Hannes Reinecke (1): block: Zoned block device single-threaded submission block/blk-core.c | 7 +++ drivers/scsi/sd.c| 3 +++ drivers/scsi/sd_zbc.c| 9 + include/scsi/scsi_cmnd.h | 1 + 4 files changed, 16 insertions(+), 4 deletions(-) -- 2.13.3
[PATCH 1/2] block: Zoned block device single-threaded submission
From: Hannes ReineckeThe scsi_request_fn() dispatch function internally unlocks the request queue before submitting a request to the underlying LLD. This can potentially lead to write request reordering if the context executing scsi_request_fn() is preempted before the request is submitted to the LLD and another context start the same function execution. This is not a problem for regular disks but leads to write I/O errors on host managed zoned block devices and reduce the effectivness of sequential write optimizations for host aware disks. (Note: the zone write lock in place in the scsi command init code will prevent multiple writes from being issued simultaneously to the same zone to avoid HBA level reordering issues, but this locking mechanism is ineffective to prevent reordering at the dispatch level) Prevent this from happening by limiting the number of context that can simultaneously execute the queue request_fn() function to a single thread. A similar patch was originally proposed by Hannes Reinecke in a first set of patches implementing ZBC support but ultimately not included in the final support implementation. See commit 92f5e2a295 "block: add flag for single-threaded submission" in the tree https://git.kernel.org/pub/scm/linux/kernel/git/hare/scsi-devel.git/log/?h=zac.v3 Authorship thus goes to Hannes. Signed-off-by: Hannes Reinecke Signed-off-by: Damien Le Moal --- block/blk-core.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/block/blk-core.c b/block/blk-core.c index dbecbf4a64e0..cf590cbddcfd 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -371,7 +371,14 @@ inline void __blk_run_queue_uncond(struct request_queue *q) * running such a request function concurrently. Keep track of the * number of active request_fn invocations such that blk_drain_queue() * can wait until all these request_fn calls have finished. +* +* For zoned block devices, do not allow multiple threads to +* dequeue requests as this can lead to write request reordering +* during the time the queue is unlocked. */ + if (blk_queue_is_zoned(q) && q->request_fn_active) + return; + q->request_fn_active++; q->request_fn(q); q->request_fn_active--; -- 2.13.3
[PATCH 2/2] sd_zbc: Write unlock zones from sd_uninit_cmnd()
Releasing the write lock of a zone when the write commnand that acquired the lock completes can cause deadlocks with scsi-mq due to potential queue reordering if the lock owning request is requeued and not executed. Since sd_uninit_cmnd() is always called when a request is requeued, call sd_zbc_write_unlock_zone() from that function for write requests that acquired a zone lock. Acquisition of a zone lock by a write command is indicated using the new command flag SCMD_ZONE_WRITE_LOCK. Signed-off-by: Damien Le Moal--- drivers/scsi/sd.c| 3 +++ drivers/scsi/sd_zbc.c| 9 + include/scsi/scsi_cmnd.h | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index bea36adeee17..e2647f2d4430 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1277,6 +1277,9 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt) { struct request *rq = SCpnt->request; + if (SCpnt->flags & SCMD_ZONE_WRITE_LOCK) + sd_zbc_write_unlock_zone(SCpnt); + if (rq->rq_flags & RQF_SPECIAL_PAYLOAD) __free_page(rq->special_vec.bv_page); diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 96855df9f49d..6423ae70477e 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -294,6 +294,9 @@ int sd_zbc_write_lock_zone(struct scsi_cmnd *cmd) test_and_set_bit(zno, sdkp->zones_wlock)) return BLKPREP_DEFER; + WARN_ON(cmd->flags & SCMD_ZONE_WRITE_LOCK); + cmd->flags |= SCMD_ZONE_WRITE_LOCK; + return BLKPREP_OK; } @@ -302,9 +305,10 @@ void sd_zbc_write_unlock_zone(struct scsi_cmnd *cmd) struct request *rq = cmd->request; struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); - if (sdkp->zones_wlock) { + if (sdkp->zones_wlock && cmd->flags & SCMD_ZONE_WRITE_LOCK) { unsigned int zno = sd_zbc_zone_no(sdkp, blk_rq_pos(rq)); WARN_ON_ONCE(!test_bit(zno, sdkp->zones_wlock)); + cmd->flags &= ~SCMD_ZONE_WRITE_LOCK; clear_bit_unlock(zno, sdkp->zones_wlock); smp_mb__after_atomic(); } @@ -335,9 +339,6 @@ void sd_zbc_complete(struct scsi_cmnd *cmd, case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_SAME: - /* Unlock the zone */ - sd_zbc_write_unlock_zone(cmd); - if (result && sshdr->sense_key == ILLEGAL_REQUEST && sshdr->asc == 0x21) diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index a1266d318c85..6af198d8120b 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -57,6 +57,7 @@ struct scsi_pointer { /* for scmd->flags */ #define SCMD_TAGGED(1 << 0) #define SCMD_UNCHECKED_ISA_DMA (1 << 1) +#define SCMD_ZONE_WRITE_LOCK (1 << 2) struct scsi_cmnd { struct scsi_request req; -- 2.13.3
Re: [PATCH] scsi_dh_alua: suppress errors from unsupported devices
Looks good, Reviewed-by: Johannes Thumshirn-- Johannes Thumshirn Storage jthumsh...@suse.de+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 1/5] dt-bindings: phy: Add PHY_TYPE_UFS definition
Add definition for UFS phy type. Signed-off-by: Vivek Gautam--- include/dt-bindings/phy/phy.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h index 6c901930eb3e..d16e8755f6a9 100644 --- a/include/dt-bindings/phy/phy.h +++ b/include/dt-bindings/phy/phy.h @@ -15,5 +15,6 @@ #define PHY_TYPE_PCIE 2 #define PHY_TYPE_USB2 3 #define PHY_TYPE_USB3 4 +#define PHY_TYPE_UFS 5 #endif /* _DT_BINDINGS_PHY */ -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH 2/5] phy: Add UFS PHY modes
UFS phy has two modes for each High speed generation. These modes are identified by two rates of operations - Rate A, and Rate B. Add these UFS phy modes to phy framework. Signed-off-by: Vivek Gautam--- include/linux/phy/phy.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 78bb0d7f6b11..27e25bb78bfb 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -27,6 +27,8 @@ enum phy_mode { PHY_MODE_USB_HOST, PHY_MODE_USB_DEVICE, PHY_MODE_USB_OTG, + PHY_MODE_UFS_HS_A, + PHY_MODE_UFS_HS_B, }; /** -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH 3/5] phy: qcom-ufs: Add support to set phy mode
Adding support to set desired UFS phy mode that can be set from the host controller. Signed-off-by: Vivek Gautam--- drivers/phy/qualcomm/phy-qcom-ufs-i.h| 2 ++ drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c | 14 ++ drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c | 14 ++ 3 files changed, 30 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-i.h b/drivers/phy/qualcomm/phy-qcom-ufs-i.h index 13b02b7de30b..94326ed107c3 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-i.h +++ b/drivers/phy/qualcomm/phy-qcom-ufs-i.h @@ -115,6 +115,8 @@ struct ufs_qcom_phy { int cached_regs_table_size; bool is_powered_on; struct ufs_qcom_phy_specific_ops *phy_spec_ops; + + enum phy_mode mode; }; /** diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c index 12a1b498dc4b..af65785230b5 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c @@ -53,6 +53,19 @@ static int ufs_qcom_phy_qmp_14nm_exit(struct phy *generic_phy) } static +int ufs_qcom_phy_qmp_14nm_set_mode(struct phy *generic_phy, enum phy_mode mode) +{ + struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy); + + phy_common->mode = PHY_MODE_INVALID; + + if (mode > 0) + phy_common->mode = mode; + + return 0; +} + +static void ufs_qcom_phy_qmp_14nm_power_control(struct ufs_qcom_phy *phy, bool val) { writel_relaxed(val ? 0x1 : 0x0, phy->mmio + UFS_PHY_POWER_DOWN_CONTROL); @@ -102,6 +115,7 @@ static int ufs_qcom_phy_qmp_14nm_is_pcs_ready(struct ufs_qcom_phy *phy_common) .exit = ufs_qcom_phy_qmp_14nm_exit, .power_on = ufs_qcom_phy_power_on, .power_off = ufs_qcom_phy_power_off, + .set_mode = ufs_qcom_phy_qmp_14nm_set_mode, .owner = THIS_MODULE, }; diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c index 4f68acb58b73..5c18c41dbdb4 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c @@ -72,6 +72,19 @@ static int ufs_qcom_phy_qmp_20nm_exit(struct phy *generic_phy) } static +int ufs_qcom_phy_qmp_20nm_set_mode(struct phy *generic_phy, enum phy_mode mode) +{ + struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy); + + phy_common->mode = PHY_MODE_INVALID; + + if (mode > 0) + phy_common->mode = mode; + + return 0; +} + +static void ufs_qcom_phy_qmp_20nm_power_control(struct ufs_qcom_phy *phy, bool val) { bool hibern8_exit_after_pwr_collapse = phy->quirks & @@ -160,6 +173,7 @@ static int ufs_qcom_phy_qmp_20nm_is_pcs_ready(struct ufs_qcom_phy *phy_common) .exit = ufs_qcom_phy_qmp_20nm_exit, .power_on = ufs_qcom_phy_power_on, .power_off = ufs_qcom_phy_power_off, + .set_mode = ufs_qcom_phy_qmp_20nm_set_mode, .owner = THIS_MODULE, }; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH 4/5] scsi/ufs: qcom: Set phy mode based on the controllers HS MODE
Set the phy mode based on the UFS HS PA mode. This lets the controller let phy know the mode in which the PHY Adapter is running and set the phy rates accordingly. Signed-off-by: Vivek Gautam--- drivers/scsi/ufs/ufs-qcom.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index c87d770b519a..44c21d5818ee 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -273,6 +273,9 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba) bool is_rate_B = (UFS_QCOM_LIMIT_HS_RATE == PA_HS_MODE_B) ? true : false; + if (is_rate_B) + phy_set_mode(phy, PHY_MODE_UFS_HS_B); + /* Assert PHY reset and apply PHY calibration values */ ufs_qcom_assert_reset(hba); /* provide 1ms delay to let the reset pulse propagate */ -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH 5/5] ufs/phy: qcom: Refactor to use phy_init call
Refactor ufs_qcom_power_up_sequence() to get rid of ugly exported phy APIs and use the phy_init() and phy_power_on() to do the phy initialization. Signed-off-by: Vivek Gautam--- drivers/phy/qualcomm/phy-qcom-ufs-i.h| 2 -- drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c | 9 +-- drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c | 9 +-- drivers/phy/qualcomm/phy-qcom-ufs.c | 38 drivers/scsi/ufs/ufs-qcom.c | 36 ++ include/linux/phy/phy-qcom-ufs.h | 3 --- 6 files changed, 38 insertions(+), 59 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-i.h b/drivers/phy/qualcomm/phy-qcom-ufs-i.h index 94326ed107c3..495fd5941231 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-i.h +++ b/drivers/phy/qualcomm/phy-qcom-ufs-i.h @@ -123,7 +123,6 @@ struct ufs_qcom_phy { * struct ufs_qcom_phy_specific_ops - set of pointers to functions which have a * specific implementation per phy. Each UFS phy, should implement * those functions according to its spec and requirements - * @calibrate_phy: pointer to a function that calibrate the phy * @start_serdes: pointer to a function that starts the serdes * @is_physical_coding_sublayer_ready: pointer to a function that * checks pcs readiness. returns 0 for success and non-zero for error. @@ -132,7 +131,6 @@ struct ufs_qcom_phy { * and writes to QSERDES_RX_SIGDET_CNTRL attribute */ struct ufs_qcom_phy_specific_ops { - int (*calibrate_phy)(struct ufs_qcom_phy *phy, bool is_rate_B); void (*start_serdes)(struct ufs_qcom_phy *phy); int (*is_physical_coding_sublayer_ready)(struct ufs_qcom_phy *phy); void (*set_tx_lane_enable)(struct ufs_qcom_phy *phy, u32 val); diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c index af65785230b5..c39440b56b6d 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c @@ -44,7 +44,13 @@ void ufs_qcom_phy_qmp_14nm_advertise_quirks(struct ufs_qcom_phy *phy_common) static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy) { - return 0; + struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy); + bool is_rate_B = false; + + if (phy_common->mode == PHY_MODE_UFS_HS_B) + is_rate_B = true; + + return ufs_qcom_phy_qmp_14nm_phy_calibrate(phy_common, is_rate_B); } static int ufs_qcom_phy_qmp_14nm_exit(struct phy *generic_phy) @@ -120,7 +126,6 @@ static int ufs_qcom_phy_qmp_14nm_is_pcs_ready(struct ufs_qcom_phy *phy_common) }; static struct ufs_qcom_phy_specific_ops phy_14nm_ops = { - .calibrate_phy = ufs_qcom_phy_qmp_14nm_phy_calibrate, .start_serdes = ufs_qcom_phy_qmp_14nm_start_serdes, .is_physical_coding_sublayer_ready = ufs_qcom_phy_qmp_14nm_is_pcs_ready, .set_tx_lane_enable = ufs_qcom_phy_qmp_14nm_set_tx_lane_enable, diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c index 5c18c41dbdb4..5705a2d4c6d2 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c @@ -63,7 +63,13 @@ void ufs_qcom_phy_qmp_20nm_advertise_quirks(struct ufs_qcom_phy *phy_common) static int ufs_qcom_phy_qmp_20nm_init(struct phy *generic_phy) { - return 0; + struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy); + bool is_rate_B = false; + + if (phy_common->mode == PHY_MODE_UFS_HS_B) + is_rate_B = true; + + return ufs_qcom_phy_qmp_20nm_phy_calibrate(phy_common, is_rate_B); } static int ufs_qcom_phy_qmp_20nm_exit(struct phy *generic_phy) @@ -178,7 +184,6 @@ static int ufs_qcom_phy_qmp_20nm_is_pcs_ready(struct ufs_qcom_phy *phy_common) }; static struct ufs_qcom_phy_specific_ops phy_20nm_ops = { - .calibrate_phy = ufs_qcom_phy_qmp_20nm_phy_calibrate, .start_serdes = ufs_qcom_phy_qmp_20nm_start_serdes, .is_physical_coding_sublayer_ready = ufs_qcom_phy_qmp_20nm_is_pcs_ready, .set_tx_lane_enable = ufs_qcom_phy_qmp_20nm_set_tx_lane_enable, diff --git a/drivers/phy/qualcomm/phy-qcom-ufs.c b/drivers/phy/qualcomm/phy-qcom-ufs.c index 43865ef340e2..1febe3294fe3 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs.c @@ -518,9 +518,8 @@ void ufs_qcom_phy_disable_iface_clk(struct ufs_qcom_phy *phy) } } -int ufs_qcom_phy_start_serdes(struct phy *generic_phy) +static int ufs_qcom_phy_start_serdes(struct ufs_qcom_phy *ufs_qcom_phy) { - struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy); int ret = 0; if (!ufs_qcom_phy->phy_spec_ops->start_serdes) { @@ -533,7 +532,6 @@ int ufs_qcom_phy_start_serdes(struct phy *generic_phy) return ret; }
[PATCH 0/5] qcom-ufs: phy/hcd: Refactor phy initialization code
Refactoring the qcom-ufs phy and host controller code to move further towards the generic phy usage. Right now the qcom-ufs exports a bunch of APIs that are used by the host controller to initialize the phy. With this patch series, we populate the phy_init() which was a no-op earlier. The host controller then calls the phy_init() at the designated place rather than doing it invariably in ufs_hcd_init(). As part of this series, we introduce phy modes for ufs phy. The M-PHY has two data rates defined for each generations (Gears) - Rate A and Rate B. These can serve as the two modes of ufs HS phy. Host controller can direct the phy to set the respective configurations based on the phy modes. The patch-series has been tested with necessary dt patches on db820c. Vivek Gautam (5): dt-bindings: phy: Add PHY_TYPE_UFS definition phy: Add UFS PHY modes phy: qcom-ufs: Add support to set phy mode scsi/ufs: qcom: Set phy mode based on the controllers HS MODE ufs/phy: qcom: Refactor to use phy_init call drivers/phy/qualcomm/phy-qcom-ufs-i.h| 4 +-- drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c | 23 ++-- drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c | 23 ++-- drivers/phy/qualcomm/phy-qcom-ufs.c | 38 +++ drivers/scsi/ufs/ufs-qcom.c | 39 include/dt-bindings/phy/phy.h| 1 + include/linux/phy/phy-qcom-ufs.h | 3 --- include/linux/phy/phy.h | 2 ++ 8 files changed, 74 insertions(+), 59 deletions(-) -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH] scsi_dh_alua: suppress errors from unsupported devices
ALUA is only relevant for disk-like devices, so we shouldn't be printing out warning messages for other device types. Signed-off-by: Hannes Reinecke--- drivers/scsi/device_handler/scsi_dh_alua.c | 2 ++ drivers/scsi/scsi_dh.c | 5 +++-- drivers/scsi/scsi_sysfs.c | 7 +-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 0962fd5..c3aea06 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -1100,6 +1100,8 @@ static int alua_bus_attach(struct scsi_device *sdev) err = alua_initialize(sdev, h); if (err == SCSI_DH_NOMEM) ret = -ENOMEM; + if (err == SCSI_DH_DEV_UNSUPP) + ret = -ENODEV; if (err != SCSI_DH_OK && err != SCSI_DH_DEV_OFFLINED) goto failed; diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c index 84addee..16e780d 100644 --- a/drivers/scsi/scsi_dh.c +++ b/drivers/scsi/scsi_dh.c @@ -133,8 +133,9 @@ static int scsi_dh_handler_attach(struct scsi_device *sdev, error = scsi_dh->attach(sdev); if (error) { - sdev_printk(KERN_ERR, sdev, "%s: Attach failed (%d)\n", - scsi_dh->name, error); + if (error != -ENODEV) + sdev_printk(KERN_ERR, sdev, "%s: Attach failed (%d)\n", + scsi_dh->name, error); module_put(scsi_dh->module); } else sdev->handler = scsi_dh; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index d6984df..5e8ace2 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1222,12 +1222,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) scsi_autopm_get_device(sdev); error = scsi_dh_add_device(sdev); - if (error) - /* -* device_handler is optional, so any error can be ignored -*/ - sdev_printk(KERN_INFO, sdev, - "failed to add device handler: %d\n", error); + /* device_handler is optional, so any error can be ignored */ error = device_add(>sdev_gendev); if (error) { -- 1.8.5.6