From 4e71dcae0c4cd1e9d19b8b3d80214a4bcdca5a42 Mon Sep 17 00:00:00 2001 From: Himanshu Madhani Date: Tue, 3 Dec 2019 14:36:55 -0800 Subject: scsi: qla2xxx: Correctly retrieve and interpret active flash region ISP27XX/28XX supports multiple flash regions. This patch fixes issue where active flash region was not interpreted correctly during secure flash update process. [mkp: typo] Fixes: 5fa8774c7f38c ("scsi: qla2xxx: Add 28xx flash primary/secondary status/image mechanism") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191203223657.22109-2-hmadhani@marvell.com Signed-off-by: Michael Hernandez Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_attr.c | 1 + drivers/scsi/qla2xxx/qla_bsg.c | 2 +- drivers/scsi/qla2xxx/qla_sup.c | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index ae97e2f310a3..d7e7043f9eab 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -178,6 +178,7 @@ qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj, faddr = ha->flt_region_nvram; if (IS_QLA28XX(ha)) { + qla28xx_get_aux_images(vha, &active_regions); if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE) faddr = ha->flt_region_nvram_sec; } diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 99f0a1a08143..cbaf178fc979 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -2399,7 +2399,7 @@ qla2x00_get_flash_image_status(struct bsg_job *bsg_job) struct qla_active_regions regions = { }; struct active_regions active_regions = { }; - qla28xx_get_aux_images(vha, &active_regions); + qla27xx_get_active_image(vha, &active_regions); regions.global_image = active_regions.global; if (IS_QLA28XX(ha)) { diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index f2d5115b2d8d..b93a0d99e573 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -847,15 +847,15 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) ha->flt_region_img_status_pri = start; break; case FLT_REG_IMG_SEC_27XX: - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ha->flt_region_img_status_sec = start; break; case FLT_REG_FW_SEC_27XX: - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ha->flt_region_fw_sec = start; break; case FLT_REG_BOOTLOAD_SEC_27XX: - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ha->flt_region_boot_sec = start; break; case FLT_REG_AUX_IMG_PRI_28XX: -- cgit v1.2.3 From a530bf691f0e4691214562c165e6c8889dc51e57 Mon Sep 17 00:00:00 2001 From: Michael Hernandez Date: Tue, 3 Dec 2019 14:36:56 -0800 Subject: scsi: qla2xxx: Added support for MPI and PEP regions for ISP28XX This patch adds support for MPI/PEP region updates which is required with secure flash updates for ISP28XX. Fixes: 3f006ac342c0 ("scsi: qla2xxx: Secure flash update support for ISP28XX") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191203223657.22109-3-hmadhani@marvell.com Signed-off-by: Michael Hernandez Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_fw.h | 4 ++++ drivers/scsi/qla2xxx/qla_sup.c | 27 ++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 59f6903e5abe..9dc09c117416 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -1523,6 +1523,10 @@ struct qla_flt_header { #define FLT_REG_NVRAM_SEC_28XX_1 0x10F #define FLT_REG_NVRAM_SEC_28XX_2 0x111 #define FLT_REG_NVRAM_SEC_28XX_3 0x113 +#define FLT_REG_MPI_PRI_28XX 0xD3 +#define FLT_REG_MPI_SEC_28XX 0xF0 +#define FLT_REG_PEP_PRI_28XX 0xD1 +#define FLT_REG_PEP_SEC_28XX 0xF1 struct qla_flt_region { uint16_t code; diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index b93a0d99e573..ae9d7422e78b 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -2725,8 +2725,11 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, "Region %x is secure\n", region.code); - if (region.code == FLT_REG_FW || - region.code == FLT_REG_FW_SEC_27XX) { + switch (region.code) { + case FLT_REG_FW: + case FLT_REG_FW_SEC_27XX: + case FLT_REG_MPI_PRI_28XX: + case FLT_REG_MPI_SEC_28XX: fw_array = dwptr; /* 1st fw array */ @@ -2757,9 +2760,23 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, buf_size_without_sfub += risc_size; fw_array += risc_size; } - } else { - ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, - "Secure region %x not supported\n", + break; + + case FLT_REG_PEP_PRI_28XX: + case FLT_REG_PEP_SEC_28XX: + fw_array = dwptr; + + /* 1st fw array */ + risc_size = be32_to_cpu(fw_array[3]); + risc_attr = be32_to_cpu(fw_array[9]); + + buf_size_without_sfub = risc_size; + fw_array += risc_size; + break; + + default: + ql_log(ql_log_warn + ql_dbg_verbose, vha, + 0xffff, "Secure region %x not supported\n", region.code); rval = QLA_COMMAND_ERROR; goto done; -- cgit v1.2.3 From c868907e1ac6a08a17f8fa9ce482c0a496896e9e Mon Sep 17 00:00:00 2001 From: Michael Hernandez Date: Tue, 3 Dec 2019 14:36:57 -0800 Subject: scsi: qla2xxx: Fix incorrect SFUB length used for Secure Flash Update MB Cmd SFUB length should be in DWORDs when passed to FW. Fixes: 3f006ac342c03 ("scsi: qla2xxx: Secure flash update support for ISP28XX") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191203223657.22109-4-hmadhani@marvell.com Signed-off-by: Michael Hernandez Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_sup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index ae9d7422e78b..bbe90354f49b 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -2897,7 +2897,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, "Sending Secure Flash MB Cmd\n"); rval = qla28xx_secure_flash_update(vha, 0, region.code, buf_size_without_sfub, sfub_dma, - sizeof(struct secure_flash_update_block)); + sizeof(struct secure_flash_update_block) >> 2); if (rval != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0xffff, "Secure Flash MB Cmd failed %x.", rval); -- cgit v1.2.3 From 9a1b0b9a6dab452fb0e39fe96880c4faf3878369 Mon Sep 17 00:00:00 2001 From: Bo Wu Date: Sat, 7 Dec 2019 03:22:46 +0000 Subject: scsi: lpfc: Fix memory leak on lpfc_bsg_write_ebuf_set func When phba->mbox_ext_buf_ctx.seqNum != phba->mbox_ext_buf_ctx.numBuf, dd_data should be freed before return SLI_CONFIG_HANDLED. When lpfc_sli_issue_mbox func return fails, pmboxq should be also freed in job_error tag. Link: https://lore.kernel.org/r/EDBAAA0BBBA2AC4E9C8B6B81DEEE1D6915E7A966@DGGEML525-MBS.china.huawei.com Signed-off-by: Bo Wu Reviewed-by: Zhiqiang Liu Reviewed-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_bsg.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index d4e1b120cc9e..0ea03ae93d91 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -4489,12 +4489,6 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct bsg_job *job, phba->mbox_ext_buf_ctx.seqNum++; nemb_tp = phba->mbox_ext_buf_ctx.nembType; - dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); - if (!dd_data) { - rc = -ENOMEM; - goto job_error; - } - pbuf = (uint8_t *)dmabuf->virt; size = job->request_payload.payload_len; sg_copy_to_buffer(job->request_payload.sg_list, @@ -4531,6 +4525,13 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct bsg_job *job, "2968 SLI_CONFIG ext-buffer wr all %d " "ebuffers received\n", phba->mbox_ext_buf_ctx.numBuf); + + dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); + if (!dd_data) { + rc = -ENOMEM; + goto job_error; + } + /* mailbox command structure for base driver */ pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmboxq) { @@ -4579,6 +4580,8 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct bsg_job *job, return SLI_CONFIG_HANDLED; job_error: + if (pmboxq) + mempool_free(pmboxq, phba->mbox_mem_pool); lpfc_bsg_dma_page_free(phba, dmabuf); kfree(dd_data); -- cgit v1.2.3 From f2c9ee54a56995a293efef290657d8a1d80e14ab Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 25 Nov 2019 19:56:50 +0300 Subject: scsi: qla2xxx: Ignore NULL pointer in tcm_qla2xxx_free_mcmd If ABTS cannot be completed in target mode, the driver attempts to free related management command and crashes: NIP [d000000019181ee8] tcm_qla2xxx_free_mcmd+0x40/0x80 [tcm_qla2xxx] LR [d00000001dc1e6f8] qlt_response_pkt+0x190/0xa10 [qla2xxx] Call Trace: [c000003fff27bb50] [c000003fff27bc10] 0xc000003fff27bc10 (unreliable) [c000003fff27bb70] [d00000001dc1e6f8] qlt_response_pkt+0x190/0xa10 [qla2xxx] [c000003fff27bc10] [d00000001dbc2be0] qla24xx_process_response_queue+0x5d8/0xbd0 [qla2xxx] [c000003fff27bd50] [d00000001dbc632c] qla24xx_msix_rsp_q+0x64/0x150 [qla2xxx] [c000003fff27bde0] [c000000000187200] __handle_irq_event_percpu+0x90/0x310 [c000003fff27bea0] [c0000000001874b8] handle_irq_event_percpu+0x38/0x90 [c000003fff27bee0] [c000000000187574] handle_irq_event+0x64/0xb0 [c000003fff27bf10] [c00000000018cd38] handle_fasteoi_irq+0xe8/0x280 [c000003fff27bf40] [c000000000185ccc] generic_handle_irq+0x4c/0x70 [c000003fff27bf60] [c000000000016cec] __do_irq+0x7c/0x1d0 [c000003fff27bf90] [c00000000002a530] call_do_irq+0x14/0x24 [c00000207d2cba90] [c000000000016edc] do_IRQ+0x9c/0x130 [c00000207d2cbae0] [c000000000008bf4] hardware_interrupt_common+0x114/0x120 --- interrupt: 501 at arch_local_irq_restore+0x74/0x90 LR = arch_local_irq_restore+0x74/0x90 [c00000207d2cbdd0] [c0000000001c64fc] tick_broadcast_oneshot_control+0x4c/0x60 (unreliable) [c00000207d2cbdf0] [c0000000007ac840] cpuidle_enter_state+0xf0/0x450 [c00000207d2cbe50] [c00000000016b81c] call_cpuidle+0x4c/0x90 [c00000207d2cbe70] [c00000000016bc30] do_idle+0x2b0/0x330 [c00000207d2cbec0] [c00000000016beec] cpu_startup_entry+0x3c/0x50 [c00000207d2cbef0] [c00000000004a06c] start_secondary+0x63c/0x670 [c00000207d2cbf90] [c00000000000aa6c] start_secondary_prolog+0x10/0x14 The crash can be triggered by ACL deletion when there's active I/O. During ACL deletion, qla2xxx performs implicit LOGO that's invisible for the initiator. Only the driver and firmware are aware of the logout. Therefore the initiator continues to send SCSI commands and the target always responds with SAM STATUS BUSY as it can't find the session. The command times out after a while and initiator invokes ABORT TASK TMF for the command. The TMF is mapped to ABTS-LS in FCP. The target can't find session for S_ID originating ABTS-LS so it never allocates mcmd. And since N_Port handle was deleted after LOGO, it is no longer valid and ABTS Response IOCB is returned from firmware with status 31. Then free_mcmd is invoked on NULL pointer and the kernel crashes. [ 7734.578642] qla2xxx [0000:00:0c.0]-e837:6: ABTS_RECV_24XX: instance 0 [ 7734.578644] qla2xxx [0000:00:0c.0]-f811:6: qla_target(0): task abort (s_id=1:2:0, tag=1209504, param=0) [ 7734.578645] find_sess_by_s_id: 0x010200 [ 7734.578645] Unable to locate s_id: 0x010200 [ 7734.578646] qla2xxx [0000:00:0c.0]-f812:6: qla_target(0): task abort for non-existent session [ 7734.578648] qla2xxx [0000:00:0c.0]-e806:6: Sending task mgmt ABTS response (ha=c0000000d5819000, atio=c0000000d3fd4700, status=4 [ 7734.578730] qla2xxx [0000:00:0c.0]-e838:6: ABTS_RESP_24XX: compl_status 31 [ 7734.578732] qla2xxx [0000:00:0c.0]-e863:6: qla_target(0): ABTS_RESP_24XX failed 31 (subcode 19:a) [ 7734.578740] Unable to handle kernel paging request for data at address 0x00000200 Fixes: 6b0431d6fa20b ("scsi: qla2xxx: Fix out of order Termination and ABTS response") Cc: Quinn Tran Cc: Bart Van Assche Cc: Thomas Abraham Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191125165702.1013-2-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Reviewed-by: Bart Van Assche Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 042a24314edc..bab2073c1f72 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -246,6 +246,8 @@ static void tcm_qla2xxx_complete_mcmd(struct work_struct *work) */ static void tcm_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd) { + if (!mcmd) + return; INIT_WORK(&mcmd->free_work, tcm_qla2xxx_complete_mcmd); queue_work(tcm_qla2xxx_free_wq, &mcmd->free_work); } -- cgit v1.2.3 From 86196a8fa8a84af1395a28ea0548f2ce6ae9bc22 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 25 Nov 2019 19:56:51 +0300 Subject: scsi: qla2xxx: Use explicit LOGO in target mode Target makes implicit LOGO on session teardown. LOGO ELS is not send on the wire and initiator is not aware that target no longer wants talking to it. Initiator keeps sending I/O requests, target responds with BA_RJT, they time out and then initiator sends ABORT TASK (ABTS-LS). Current behaviour incurs unneeded I/O timeout and can be fixed for some initiators by making explicit LOGO on session deletion. Link: https://lore.kernel.org/r/20191125165702.1013-3-r.bolshakov@yadro.com Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 1 + drivers/scsi/qla2xxx/qla_iocb.c | 16 ++++++++++++---- drivers/scsi/qla2xxx/qla_target.c | 1 + drivers/scsi/qla2xxx/tcm_qla2xxx.c | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 460f443f6471..2edd9f7b3074 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2401,6 +2401,7 @@ typedef struct fc_port { unsigned int id_changed:1; unsigned int scan_needed:1; unsigned int n2n_flag:1; + unsigned int explicit_logout:1; struct completion nvme_del_done; uint32_t nvme_prli_service_param; diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index b25f87ff8cde..c5a7736c45be 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -2405,11 +2405,19 @@ qla2x00_login_iocb(srb_t *sp, struct mbx_entry *mbx) static void qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio) { + u16 control_flags = LCF_COMMAND_LOGO; logio->entry_type = LOGINOUT_PORT_IOCB_TYPE; - logio->control_flags = - cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO); - if (!sp->fcport->keep_nport_handle) - logio->control_flags |= cpu_to_le16(LCF_FREE_NPORT); + + if (sp->fcport->explicit_logout) { + control_flags |= LCF_EXPL_LOGO|LCF_FREE_NPORT; + } else { + control_flags |= LCF_IMPL_LOGO; + + if (!sp->fcport->keep_nport_handle) + control_flags |= LCF_FREE_NPORT; + } + + logio->control_flags = cpu_to_le16(control_flags); logio->nport_handle = cpu_to_le16(sp->fcport->loop_id); logio->port_id[0] = sp->fcport->d_id.b.al_pa; logio->port_id[1] = sp->fcport->d_id.b.area; diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 51b275a575a5..f94afb3fe448 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1104,6 +1104,7 @@ void qlt_free_session_done(struct work_struct *work) } } + sess->explicit_logout = 0; spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); sess->free_pending = 0; diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index bab2073c1f72..abe7f79bb789 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -350,6 +350,7 @@ static void tcm_qla2xxx_close_session(struct se_session *se_sess) target_sess_cmd_list_set_waiting(se_sess); spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); + sess->explicit_logout = 1; tcm_qla2xxx_put_sess(sess); } -- cgit v1.2.3 From 4c86b037a6db3ad2922ef3ba8a8989eb7794e040 Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 25 Nov 2019 19:56:52 +0300 Subject: scsi: qla2xxx: Initialize free_work before flushing it Target creation triggers a new BUG_ON introduced in in commit 4d43d395fed1 ("workqueue: Try to catch flush_work() without INIT_WORK()."). The BUG_ON reveals an attempt to flush free_work in qla24xx_do_nack_work before it's initialized in qlt_unreg_sess: WARNING: CPU: 7 PID: 211 at kernel/workqueue.c:3031 __flush_work.isra.38+0x40/0x2e0 CPU: 7 PID: 211 Comm: kworker/7:1 Kdump: loaded Tainted: G E 5.3.0-rc7-vanilla+ #2 Workqueue: qla2xxx_wq qla2x00_iocb_work_fn [qla2xxx] NIP: c000000000159620 LR: c0080000009d91b0 CTR: c0000000001598c0 REGS: c000000005f3f730 TRAP: 0700 Tainted: G E (5.3.0-rc7-vanilla+) MSR: 800000000282b033 CR: 24002222 XER: 00000000 CFAR: c0000000001598d0 IRQMASK: 0 GPR00: c0080000009d91b0 c000000005f3f9c0 c000000001670a00 c0000003f8655ca8 GPR04: c0000003f8655c00 000000000000ffff 0000000000000011 ffffffffffffffff GPR08: c008000000949228 0000000000000000 0000000000000001 c0080000009e7780 GPR12: 0000000000002200 c00000003fff6200 c000000000161bc8 0000000000000004 GPR16: c0000003f9d68280 0000000002000000 0000000000000005 0000000000000003 GPR20: 0000000000000002 000000000000ffff 0000000000000000 fffffffffffffef7 GPR24: c000000004f73848 c000000004f73838 c000000004f73f28 c000000005f3fb60 GPR28: c000000004f73e48 c000000004f73c80 c000000004f73818 c0000003f9d68280 NIP [c000000000159620] __flush_work.isra.38+0x40/0x2e0 LR [c0080000009d91b0] qla24xx_do_nack_work+0x88/0x180 [qla2xxx] Call Trace: [c000000005f3f9c0] [c000000000159644] __flush_work.isra.38+0x64/0x2e0 (unreliable) [c000000005f3fa50] [c0080000009d91a0] qla24xx_do_nack_work+0x78/0x180 [qla2xxx] [c000000005f3fae0] [c0080000009496ec] qla2x00_do_work+0x604/0xb90 [qla2xxx] [c000000005f3fc40] [c008000000949cd8] qla2x00_iocb_work_fn+0x60/0xe0 [qla2xxx] [c000000005f3fc80] [c000000000157bb8] process_one_work+0x2c8/0x5b0 [c000000005f3fd10] [c000000000157f28] worker_thread+0x88/0x660 [c000000005f3fdb0] [c000000000161d64] kthread+0x1a4/0x1b0 [c000000005f3fe20] [c00000000000b960] ret_from_kernel_thread+0x5c/0x7c Instruction dump: 3d22001d 892966b1 7d908026 91810008 f821ff71 69290001 0b090000 2e290000 40920200 e9230018 7d2a0074 794ad182 <0b0a0000> 2fa90000 419e01e8 7c0802a6 ---[ end trace 5ccf335d4f90fcb8 ]--- Fixes: 1021f0bc2f3d6 ("scsi: qla2xxx: allow session delete to finish before create.") Cc: Quinn Tran Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191125165702.1013-4-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Reviewed-by: Bart Van Assche Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 1 + drivers/scsi/qla2xxx/qla_target.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 6c28f38f8021..b42be42ff1a6 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4852,6 +4852,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) } INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn); + INIT_WORK(&fcport->free_work, qlt_free_session_done); INIT_WORK(&fcport->reg_work, qla_register_fcport_fn); INIT_LIST_HEAD(&fcport->gnl_entry); INIT_LIST_HEAD(&fcport->list); diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index f94afb3fe448..74cfcb13fe8a 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1161,7 +1161,6 @@ void qlt_unreg_sess(struct fc_port *sess) sess->last_rscn_gen = sess->rscn_gen; sess->last_login_gen = sess->login_gen; - INIT_WORK(&sess->free_work, qlt_free_session_done); queue_work(sess->vha->hw->wq, &sess->free_work); } EXPORT_SYMBOL(qlt_unreg_sess); -- cgit v1.2.3 From 600954e6f2df695434887dfc6a99a098859990cf Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 25 Nov 2019 19:56:53 +0300 Subject: scsi: qla2xxx: Drop superfluous INIT_WORK of del_work del_work is already initialized inside qla2x00_alloc_fcport, there's no need to overwrite it. Indeed, it might prevent complete traversal of workqueue list. Fixes: a01c77d2cbc45 ("scsi: qla2xxx: Move session delete to driver work queue") Cc: Quinn Tran Link: https://lore.kernel.org/r/20191125165702.1013-5-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Reviewed-by: Bart Van Assche Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_target.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 74cfcb13fe8a..eeb069d52f3d 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1265,7 +1265,6 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) "Scheduling sess %p for deletion %8phC\n", sess, sess->port_name); - INIT_WORK(&sess->del_work, qla24xx_delete_sess_fn); WARN_ON(!queue_work(sess->vha->hw->wq, &sess->del_work)); } -- cgit v1.2.3 From 58e39a2ce4be08162c0368030cdc405f7fd849aa Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 25 Nov 2019 19:56:54 +0300 Subject: scsi: qla2xxx: Change discovery state before PLOGI When a port sends PLOGI, discovery state should be changed to login pending, otherwise RELOGIN_NEEDED bit is set in qla24xx_handle_plogi_done_event(). RELOGIN_NEEDED triggers another PLOGI, and it never goes out of the loop until login timer expires. Fixes: 8777e4314d397 ("scsi: qla2xxx: Migrate NVME N2N handling into state machine") Fixes: 8b5292bcfcacf ("scsi: qla2xxx: Fix Relogin to prevent modifying scan_state flag") Cc: Quinn Tran Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191125165702.1013-6-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index b42be42ff1a6..fc2ff169dc5a 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -533,6 +533,7 @@ static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport) e->u.fcport.fcport = fcport; fcport->flags |= FCF_ASYNC_ACTIVE; + fcport->disc_state = DSC_LOGIN_PEND; return qla2x00_post_work(vha, e); } -- cgit v1.2.3 From a9ed06d4e640a8dc978a4649ab78dac8b16d2db6 Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 25 Nov 2019 19:56:55 +0300 Subject: scsi: qla2xxx: Allow PLOGI in target mode According to FC-LS-3 (Fibre Channel Link Services) 6.3.2.4 "N_Port Login - No Fabric present", if both parties in the point-to-point connection know N_Port_Names of each other, Nx_Port with the highest N_Port_name shall transmit PLOGI. The specification sets no restrictions on the port role that should send PLOGI. However, FCP-4 (Fibre Channel Protocol for SCSI, Fourth Version) 6.2 "Overview of Process Login and Process Logout", instructs that in point-to-point topology, initiator shall send explicit PRLI ELS. The change fixes stuck P2P login, when target WWPN is higher than initiator WWPN. Cc: Quinn Tran Cc: Himanshu Madhani Link: https://lore.kernel.org/r/20191125165702.1013-7-r.bolshakov@yadro.com Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index fc2ff169dc5a..d2c1f8080b9e 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1527,8 +1527,8 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) } } - /* for pure Target Mode. Login will not be initiated */ - if (vha->host->active_mode == MODE_TARGET) + /* Target won't initiate port login if fabric is present */ + if (vha->host->active_mode == MODE_TARGET && !N2N_TOPO(vha->hw)) return 0; if (fcport->flags & FCF_ASYNC_SENT) { @@ -1720,6 +1720,10 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea) { + /* for pure Target Mode, PRLI will not be initiated */ + if (vha->host->active_mode == MODE_TARGET) + return; + ql_dbg(ql_dbg_disc, vha, 0x2118, "%s %d %8phC post PRLI\n", __func__, __LINE__, ea->fcport->port_name); -- cgit v1.2.3 From 2c2f4bed9b6299e6430a65a29b5d27b8763fdf25 Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 25 Nov 2019 19:56:56 +0300 Subject: scsi: qla2xxx: Don't call qlt_async_event twice MBA_PORT_UPDATE generates duplicate log lines in target mode because qlt_async_event is called twice. Drop the calls within the case as the function will be called right after the switch statement. Cc: Quinn Tran Link: https://lore.kernel.org/r/20191125165702.1013-8-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Acked-by: Himanshu Madhani Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_isr.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 2601d7673c37..7b8a6bfcf08d 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1061,8 +1061,6 @@ global_port_update: ql_dbg(ql_dbg_async, vha, 0x5011, "Asynchronous PORT UPDATE ignored %04x/%04x/%04x.\n", mb[1], mb[2], mb[3]); - - qlt_async_event(mb[0], vha, mb); break; } @@ -1079,8 +1077,6 @@ global_port_update: set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); set_bit(VP_CONFIG_OK, &vha->vp_flags); - - qlt_async_event(mb[0], vha, mb); break; case MBA_RSCN_UPDATE: /* State Change Registration */ -- cgit v1.2.3 From 0334cdea1fba36fad8bdf9516f267ce01de625f7 Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 25 Nov 2019 19:56:57 +0300 Subject: scsi: qla2xxx: Fix PLOGI payload and ELS IOCB dump length The size of the buffer is hardcoded as 0x70 or 112 bytes, while the size of ELS IOCB is 0x40 and the size of PLOGI payload returned by Get Parameters command is 0x74. Cc: Quinn Tran Link: https://lore.kernel.org/r/20191125165702.1013-9-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_iocb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index c5a7736c45be..53ccbd6b71ed 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -2684,7 +2684,8 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073, "PLOGI ELS IOCB:\n"); ql_dump_buffer(ql_log_info, vha, 0x0109, - (uint8_t *)els_iocb, 0x70); + (uint8_t *)els_iocb, + sizeof(*els_iocb)); } else { els_iocb->control_flags = 1 << 13; els_iocb->tx_byte_count = @@ -2942,7 +2943,8 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3073, "PLOGI buffer:\n"); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x0109, - (uint8_t *)elsio->u.els_plogi.els_plogi_pyld, 0x70); + (uint8_t *)elsio->u.els_plogi.els_plogi_pyld, + sizeof(*elsio->u.els_plogi.els_plogi_pyld)); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { -- cgit v1.2.3 From fd1de5830a5abaf444cc4312871e02c41e24fdc1 Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 25 Nov 2019 19:56:58 +0300 Subject: scsi: qla2xxx: Configure local loop for N2N target qla2x00_configure_local_loop initializes PLOGI payload for PLOGI ELS using Get Parameters mailbox command. In the case when the driver is running in target mode, the topology is N2N and the target port has higher WWPN, LOCAL_LOOP_UPDATE bit is cleared too early and PLOGI payload is not initialized by the Get Parameters command. That causes a failure of ELS IOCB carrying the PLOGI with 0x15 aka Data Underrun error. LOCAL_LOOP_UPDATE has to be set to initialize PLOGI payload. Fixes: 48acad099074 ("scsi: qla2xxx: Fix N2N link re-connect") Link: https://lore.kernel.org/r/20191125165702.1013-10-r.bolshakov@yadro.com Acked-by: Quinn Tran Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index d2c1f8080b9e..c893d89ed936 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4936,14 +4936,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) set_bit(RSCN_UPDATE, &flags); clear_bit(LOCAL_LOOP_UPDATE, &flags); - } else if (ha->current_topology == ISP_CFG_N) { - clear_bit(RSCN_UPDATE, &flags); - if (qla_tgt_mode_enabled(vha)) { - /* allow the other side to start the login */ - clear_bit(LOCAL_LOOP_UPDATE, &flags); - set_bit(RELOGIN_NEEDED, &vha->dpc_flags); - } - } else if (ha->current_topology == ISP_CFG_NL) { + } else if (ha->current_topology == ISP_CFG_NL || + ha->current_topology == ISP_CFG_N) { clear_bit(RSCN_UPDATE, &flags); set_bit(LOCAL_LOOP_UPDATE, &flags); } else if (!vha->flags.online || -- cgit v1.2.3 From 5e6b01d84b9d20bcd77fc7c4733a2a4149bf220a Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 25 Nov 2019 19:56:59 +0300 Subject: scsi: qla2xxx: Send Notify ACK after N2N PLOGI qlt_handle_login schedules session for deletion even if a login is in progress. That causes login bouncing, i.e. a few logins are made before it settles down. Complete the first login by sending Notify Acknowledge IOCB via qlt_plogi_ack_unref if the session is pending login completion. Fixes: 9cd883f07a54 ("scsi: qla2xxx: Fix session cleanup for N2N") Cc: Krishna Kant Cc: Alexei Potashnik Link: https://lore.kernel.org/r/20191125165702.1013-11-r.bolshakov@yadro.com Acked-by: Quinn Tran Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_target.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index eeb069d52f3d..68c14143e50e 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -4803,6 +4803,7 @@ static int qlt_handle_login(struct scsi_qla_host *vha, switch (sess->disc_state) { case DSC_DELETED: + case DSC_LOGIN_PEND: qlt_plogi_ack_unref(vha, pla); break; -- cgit v1.2.3 From dabc5ec915f3a2c657ecfb529cd3d4ec303a4412 Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 25 Nov 2019 19:57:00 +0300 Subject: scsi: qla2xxx: Don't defer relogin unconditonally qla2x00_configure_local_loop sets RELOGIN_NEEDED bit and calls qla24xx_fcport_handle_login to perform the login. This bit triggers a wake up of DPC later after a successful login. The deferred call is not needed if login succeeds, and it's set in qla24xx_fcport_handle_login in case of errors, hence it should be safe to drop. Link: https://lore.kernel.org/r/20191125165702.1013-12-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Acked-by: Quinn Tran Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index c893d89ed936..aa5204163bec 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5054,7 +5054,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) memcpy(&ha->plogi_els_payld.data, (void *)ha->init_cb, sizeof(ha->plogi_els_payld.data)); - set_bit(RELOGIN_NEEDED, &vha->dpc_flags); } else { ql_dbg(ql_dbg_init, vha, 0x00d1, "PLOGI ELS param read fail.\n"); -- cgit v1.2.3 From af22f0c7b052c5c203207f1e5ebd6aa65f87c538 Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 25 Nov 2019 19:57:01 +0300 Subject: scsi: qla2xxx: Ignore PORT UPDATE after N2N PLOGI PORT UPDATE asynchronous event is generated on the host that issues PLOGI ELS (in the case of higher WWPN). In that case, the event shouldn't be handled as it sets unwanted DPC flags (i.e. LOOP_RESYNC_NEEDED) that trigger link flap. Ignore the event if the host has higher WWPN, but handle otherwise. Cc: Quinn Tran Link: https://lore.kernel.org/r/20191125165702.1013-13-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_mbx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 0cf94f05f008..b7c1108c48e2 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -3921,6 +3921,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, vha->d_id.b24 = 0; vha->d_id.b.al_pa = 1; ha->flags.n2n_bigger = 1; + ha->flags.n2n_ae = 0; id.b.al_pa = 2; ql_dbg(ql_dbg_async, vha, 0x5075, @@ -3931,6 +3932,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, "Format 1: Remote login - Waiting for WWPN %8phC.\n", rptid_entry->u.f1.port_name); ha->flags.n2n_bigger = 0; + ha->flags.n2n_ae = 1; } qla24xx_post_newsess_work(vha, &id, rptid_entry->u.f1.port_name, @@ -3942,7 +3944,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, /* if our portname is higher then initiate N2N login */ set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags); - ha->flags.n2n_ae = 1; return; break; case TOPO_FL: -- cgit v1.2.3 From 9545767db3cde2d4f9ca581d096d97ed00754282 Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 25 Nov 2019 19:57:02 +0300 Subject: scsi: qla2xxx: Add debug dump of LOGO payload and ELS IOCB The change adds a way to debug LOGO ELS, likewise PLOGI. Link: https://lore.kernel.org/r/20191125165702.1013-14-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Acked-by: Quinn Tran Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Reviewed-by: Bart Van Assche Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_iocb.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 53ccbd6b71ed..8b050f0b4333 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -2625,6 +2625,10 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode, memcpy(elsio->u.els_logo.els_logo_pyld, &logo_pyld, sizeof(struct els_logo_payload)); + ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3075, "LOGO buffer:"); + ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x010a, + elsio->u.els_logo.els_logo_pyld, + sizeof(*elsio->u.els_logo.els_logo_pyld)); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { @@ -2697,6 +2701,11 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) els_iocb->rx_byte_count = 0; els_iocb->rx_address = 0; els_iocb->rx_len = 0; + ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3076, + "LOGO ELS IOCB:"); + ql_dump_buffer(ql_log_info, vha, 0x010b, + els_iocb, + sizeof(*els_iocb)); } sp->vha->qla_stats.control_requests++; -- cgit v1.2.3 From 8c850a0296004409e7bcb9464712fb2807da656a Mon Sep 17 00:00:00 2001 From: Can Guo Date: Tue, 3 Dec 2019 06:58:40 +0000 Subject: scsi: ufs: Give an unique ID to each ufs-bsg Considering there can be multiple UFS hosts in SoC, give each ufs-bsg an unique ID by appending the scsi host number to its device name. Link: https://lore.kernel.org/r/0101016eca8dc9d7-d24468d3-04d2-4ef3-a906-abe8b8cbcd3d-000000@us-west-2.amazonses.com Fixes: df032bf27a41 ("scsi: ufs: Add a bsg endpoint that supports UPIUs") Signed-off-by: Can Guo Reviewed-by: Avri Altman Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs_bsg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/scsi/ufs/ufs_bsg.c index baeecee35d1e..53dd87628cbe 100644 --- a/drivers/scsi/ufs/ufs_bsg.c +++ b/drivers/scsi/ufs/ufs_bsg.c @@ -203,7 +203,7 @@ int ufs_bsg_probe(struct ufs_hba *hba) bsg_dev->parent = get_device(parent); bsg_dev->release = ufs_bsg_node_release; - dev_set_name(bsg_dev, "ufs-bsg"); + dev_set_name(bsg_dev, "ufs-bsg%u", shost->host_no); ret = device_add(bsg_dev); if (ret) -- cgit v1.2.3 From fee92f25777789d73e1936b91472e9c4644457c8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 3 Dec 2019 12:45:09 +0300 Subject: scsi: iscsi: qla4xxx: fix double free in probe On this error path we call qla4xxx_mem_free() and then the caller also calls qla4xxx_free_adapter() which calls qla4xxx_mem_free(). It leads to a couple double frees: drivers/scsi/qla4xxx/ql4_os.c:8856 qla4xxx_probe_adapter() warn: 'ha->chap_dma_pool' double freed drivers/scsi/qla4xxx/ql4_os.c:8856 qla4xxx_probe_adapter() warn: 'ha->fw_ddb_dma_pool' double freed Fixes: afaf5a2d341d ("[SCSI] Initial Commit of qla4xxx") Link: https://lore.kernel.org/r/20191203094421.hw7ex7qr3j2rbsmx@kili.mountain Signed-off-by: Dan Carpenter Signed-off-by: Martin K. Petersen --- drivers/scsi/qla4xxx/ql4_os.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 8c674eca09f1..2323432a0edb 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -4275,7 +4275,6 @@ static int qla4xxx_mem_alloc(struct scsi_qla_host *ha) return QLA_SUCCESS; mem_alloc_error_exit: - qla4xxx_mem_free(ha); return QLA_ERROR; } -- cgit v1.2.3 From d168001d14eccfda229b4a41a2c31a21e3c379da Mon Sep 17 00:00:00 2001 From: sheebab Date: Tue, 3 Dec 2019 11:07:15 +0100 Subject: scsi: ufs: Disable autohibern8 feature in Cadence UFS This patch disables autohibern8 feature in Cadence UFS. The autohibern8 feature has issues due to which unexpected interrupt trigger is happening. After the interrupt issue is sorted out, autohibern8 feature will be re-enabled Link: https://lore.kernel.org/r/1575367635-22662-1-git-send-email-sheebab@cadence.com Cc: Signed-off-by: sheebab Reviewed-by: Alim Akhtar Tested-by: Vignesh Raghavendra Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/cdns-pltfrm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c index b2af04c57a39..6feeb0faf123 100644 --- a/drivers/scsi/ufs/cdns-pltfrm.c +++ b/drivers/scsi/ufs/cdns-pltfrm.c @@ -99,6 +99,12 @@ static int cdns_ufs_link_startup_notify(struct ufs_hba *hba, */ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0); + /* + * Disabling Autohibern8 feature in cadence UFS + * to mask unexpected interrupt trigger. + */ + hba->ahit = 0; + return 0; } -- cgit v1.2.3 From f70267f379b5e5e11bdc5d72a56bf17e5feed01f Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Fri, 6 Dec 2019 09:11:18 +0800 Subject: scsi: libsas: stop discovering if oob mode is disconnected The discovering of sas port is driven by workqueue in libsas. When libsas is processing port events or phy events in workqueue, new events may rise up and change the state of some structures such as asd_sas_phy. This may cause some problems such as follows: ==>thread 1 ==>thread 2 ==>phy up ==>phy_up_v3_hw() ==>oob_mode = SATA_OOB_MODE; ==>phy down quickly ==>hisi_sas_phy_down() ==>sas_ha->notify_phy_event() ==>sas_phy_disconnected() ==>oob_mode = OOB_NOT_CONNECTED ==>workqueue wakeup ==>sas_form_port() ==>sas_discover_domain() ==>sas_get_port_device() ==>oob_mode is OOB_NOT_CONNECTED and device is wrongly taken as expander This at last lead to the panic when libsas trying to issue a command to discover the device. [183047.614035] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000058 [183047.622896] Mem abort info: [183047.625762] ESR = 0x96000004 [183047.628893] Exception class = DABT (current EL), IL = 32 bits [183047.634888] SET = 0, FnV = 0 [183047.638015] EA = 0, S1PTW = 0 [183047.641232] Data abort info: [183047.644189] ISV = 0, ISS = 0x00000004 [183047.648100] CM = 0, WnR = 0 [183047.651145] user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000b7df67be [183047.657834] [0000000000000058] pgd=0000000000000000 [183047.662789] Internal error: Oops: 96000004 [#1] SMP [183047.667740] Process kworker/u16:2 (pid: 31291, stack limit = 0x00000000417c4974) [183047.675208] CPU: 0 PID: 3291 Comm: kworker/u16:2 Tainted: G W OE 4.19.36-vhulk1907.1.0.h410.eulerosv2r8.aarch64 #1 [183047.687015] Hardware name: N/A N/A/Kunpeng Desktop Board D920S10, BIOS 0.15 10/22/2019 [183047.695007] Workqueue: 0000:74:02.0_disco_q sas_discover_domain [183047.700999] pstate: 20c00009 (nzCv daif +PAN +UAO) [183047.705864] pc : prep_ata_v3_hw+0xf8/0x230 [hisi_sas_v3_hw] [183047.711510] lr : prep_ata_v3_hw+0xb0/0x230 [hisi_sas_v3_hw] [183047.717153] sp : ffff00000f28ba60 [183047.720541] x29: ffff00000f28ba60 x28: ffff8026852d7228 [183047.725925] x27: ffff8027dba3e0a8 x26: ffff8027c05fc200 [183047.731310] x25: 0000000000000000 x24: ffff8026bafa8dc0 [183047.736695] x23: ffff8027c05fc218 x22: ffff8026852d7228 [183047.742079] x21: ffff80007c2f2940 x20: ffff8027c05fc200 [183047.747464] x19: 0000000000f80800 x18: 0000000000000010 [183047.752848] x17: 0000000000000000 x16: 0000000000000000 [183047.758232] x15: ffff000089a5a4ff x14: 0000000000000005 [183047.763617] x13: ffff000009a5a50e x12: ffff8026bafa1e20 [183047.769001] x11: ffff0000087453b8 x10: ffff00000f28b870 [183047.774385] x9 : 0000000000000000 x8 : ffff80007e58f9b0 [183047.779770] x7 : 0000000000000000 x6 : 000000000000003f [183047.785154] x5 : 0000000000000040 x4 : ffffffffffffffe0 [183047.790538] x3 : 00000000000000f8 x2 : 0000000002000007 [183047.795922] x1 : 0000000000000008 x0 : 0000000000000000 [183047.801307] Call trace: [183047.803827] prep_ata_v3_hw+0xf8/0x230 [hisi_sas_v3_hw] [183047.809127] hisi_sas_task_prep+0x750/0x888 [hisi_sas_main] [183047.814773] hisi_sas_task_exec.isra.7+0x88/0x1f0 [hisi_sas_main] [183047.820939] hisi_sas_queue_command+0x28/0x38 [hisi_sas_main] [183047.826757] smp_execute_task_sg+0xec/0x218 [183047.831013] smp_execute_task+0x74/0xa0 [183047.834921] sas_discover_expander.part.7+0x9c/0x5f8 [183047.839959] sas_discover_root_expander+0x90/0x160 [183047.844822] sas_discover_domain+0x1b8/0x1e8 [183047.849164] process_one_work+0x1b4/0x3f8 [183047.853246] worker_thread+0x54/0x470 [183047.856981] kthread+0x134/0x138 [183047.860283] ret_from_fork+0x10/0x18 [183047.863931] Code: f9407a80 528000e2 39409281 72a04002 (b9405800) [183047.870097] kernel fault(0x1) notification starting on CPU 0 [183047.875828] kernel fault(0x1) notification finished on CPU 0 [183047.881559] Modules linked in: unibsp(OE) hns3(OE) hclge(OE) hnae3(OE) mem_drv(OE) hisi_sas_v3_hw(OE) hisi_sas_main(OE) [183047.892418] ---[ end trace 4cc26083fc11b783 ]--- [183047.897107] Kernel panic - not syncing: Fatal exception [183047.902403] kernel fault(0x5) notification starting on CPU 0 [183047.908134] kernel fault(0x5) notification finished on CPU 0 [183047.913865] SMP: stopping secondary CPUs [183047.917861] Kernel Offset: disabled [183047.921422] CPU features: 0x2,a2a00a38 [183047.925243] Memory Limit: none [183047.928372] kernel reboot(0x2) notification starting on CPU 0 [183047.934190] kernel reboot(0x2) notification finished on CPU 0 [183047.940008] ---[ end Kernel panic - not syncing: Fatal exception ]--- Fixes: 2908d778ab3e ("[SCSI] aic94xx: new driver") Link: https://lore.kernel.org/r/20191206011118.46909-1-yanaijie@huawei.com Reported-by: Gao Chuan Reviewed-by: John Garry Signed-off-by: Jason Yan Signed-off-by: Martin K. Petersen --- drivers/scsi/libsas/sas_discover.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index f47b4b281b14..d7302c2052f9 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -81,12 +81,21 @@ static int sas_get_port_device(struct asd_sas_port *port) else dev->dev_type = SAS_SATA_DEV; dev->tproto = SAS_PROTOCOL_SATA; - } else { + } else if (port->oob_mode == SAS_OOB_MODE) { struct sas_identify_frame *id = (struct sas_identify_frame *) dev->frame_rcvd; dev->dev_type = id->dev_type; dev->iproto = id->initiator_bits; dev->tproto = id->target_bits; + } else { + /* If the oob mode is OOB_NOT_CONNECTED, the port is + * disconnected due to race with PHY down. We cannot + * continue to discover this port + */ + sas_put_device(dev); + pr_warn("Port %016llx is disconnected when discovering\n", + SAS_ADDR(port->attached_sas_addr)); + return -ENODEV; } sas_init_dev(dev); -- cgit v1.2.3 From a2bdd0c904da12b223c8d7218e98138d4e6d9f4f Mon Sep 17 00:00:00 2001 From: Paul Menzel Date: Mon, 9 Dec 2019 16:06:53 +0100 Subject: scsi: smartpqi: Update attribute name to `driver_version` The file name in the documentation is currently incorrect, so fix it. Link: https://lore.kernel.org/r/fe264d62-0371-ea59-b66a-6d855290ce65@molgen.mpg.de Fixes: 6d90615f1346 ("scsi: smartpqi: add sysfs entries") Signed-off-by: Paul Menzel Signed-off-by: Martin K. Petersen --- Documentation/scsi/smartpqi.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/scsi/smartpqi.txt b/Documentation/scsi/smartpqi.txt index 201f80c7c050..df129f55ace5 100644 --- a/Documentation/scsi/smartpqi.txt +++ b/Documentation/scsi/smartpqi.txt @@ -29,7 +29,7 @@ smartpqi specific entries in /sys smartpqi host attributes: ------------------------- /sys/class/scsi_host/host*/rescan - /sys/class/scsi_host/host*/version + /sys/class/scsi_host/host*/driver_version The host rescan attribute is a write only attribute. Writing to this attribute will trigger the driver to scan for new, changed, or removed -- cgit v1.2.3 From 5480e299b5ae57956af01d4839c9fc88a465eeab Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Dec 2019 09:34:57 -0800 Subject: scsi: iscsi: Fix a potential deadlock in the timeout handler Some time ago the block layer was modified such that timeout handlers are called from thread context instead of interrupt context. Make it safe to run the iSCSI timeout handler in thread context. This patch fixes the following lockdep complaint: ================================ WARNING: inconsistent lock state 5.5.1-dbg+ #11 Not tainted -------------------------------- inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage. kworker/7:1H/206 [HC0[0]:SC0[0]:HE1:SE1] takes: ffff88802d9827e8 (&(&session->frwd_lock)->rlock){+.?.}, at: iscsi_eh_cmd_timed_out+0xa6/0x6d0 [libiscsi] {IN-SOFTIRQ-W} state was registered at: lock_acquire+0x106/0x240 _raw_spin_lock+0x38/0x50 iscsi_check_transport_timeouts+0x3e/0x210 [libiscsi] call_timer_fn+0x132/0x470 __run_timers.part.0+0x39f/0x5b0 run_timer_softirq+0x63/0xc0 __do_softirq+0x12d/0x5fd irq_exit+0xb3/0x110 smp_apic_timer_interrupt+0x131/0x3d0 apic_timer_interrupt+0xf/0x20 default_idle+0x31/0x230 arch_cpu_idle+0x13/0x20 default_idle_call+0x53/0x60 do_idle+0x38a/0x3f0 cpu_startup_entry+0x24/0x30 start_secondary+0x222/0x290 secondary_startup_64+0xa4/0xb0 irq event stamp: 1383705 hardirqs last enabled at (1383705): [] _raw_spin_unlock_irq+0x2c/0x50 hardirqs last disabled at (1383704): [] _raw_spin_lock_irq+0x18/0x50 softirqs last enabled at (1383690): [] iscsi_queuecommand+0x76a/0xa20 [libiscsi] softirqs last disabled at (1383682): [] iscsi_queuecommand+0x118/0xa20 [libiscsi] other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&(&session->frwd_lock)->rlock); lock(&(&session->frwd_lock)->rlock); *** DEADLOCK *** 2 locks held by kworker/7:1H/206: #0: ffff8880d57bf928 ((wq_completion)kblockd){+.+.}, at: process_one_work+0x472/0xab0 #1: ffff88802b9c7de8 ((work_completion)(&q->timeout_work)){+.+.}, at: process_one_work+0x476/0xab0 stack backtrace: CPU: 7 PID: 206 Comm: kworker/7:1H Not tainted 5.5.1-dbg+ #11 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 Workqueue: kblockd blk_mq_timeout_work Call Trace: dump_stack+0xa5/0xe6 print_usage_bug.cold+0x232/0x23b mark_lock+0x8dc/0xa70 __lock_acquire+0xcea/0x2af0 lock_acquire+0x106/0x240 _raw_spin_lock+0x38/0x50 iscsi_eh_cmd_timed_out+0xa6/0x6d0 [libiscsi] scsi_times_out+0xf4/0x440 [scsi_mod] scsi_timeout+0x1d/0x20 [scsi_mod] blk_mq_check_expired+0x365/0x3a0 bt_iter+0xd6/0xf0 blk_mq_queue_tag_busy_iter+0x3de/0x650 blk_mq_timeout_work+0x1af/0x380 process_one_work+0x56d/0xab0 worker_thread+0x7a/0x5d0 kthread+0x1bc/0x210 ret_from_fork+0x24/0x30 Fixes: 287922eb0b18 ("block: defer timeouts to a workqueue") Cc: Christoph Hellwig Cc: Keith Busch Cc: Lee Duncan Cc: Chris Leech Cc: Link: https://lore.kernel.org/r/20191209173457.187370-1-bvanassche@acm.org Signed-off-by: Bart Van Assche Reviewed-by: Lee Duncan Signed-off-by: Martin K. Petersen --- drivers/scsi/libiscsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index ebd47c0cf9e9..70b99c0e2e67 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1945,7 +1945,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) ISCSI_DBG_EH(session, "scsi cmd %p timedout\n", sc); - spin_lock(&session->frwd_lock); + spin_lock_bh(&session->frwd_lock); task = (struct iscsi_task *)sc->SCp.ptr; if (!task) { /* @@ -2072,7 +2072,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) done: if (task) task->last_timeout = jiffies; - spin_unlock(&session->frwd_lock); + spin_unlock_bh(&session->frwd_lock); ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ? "timer reset" : "shutdown or nh"); return rc; -- cgit v1.2.3 From bba340c79bfe3644829db5c852fdfa9e33837d6d Mon Sep 17 00:00:00 2001 From: Bo Wu Date: Wed, 20 Nov 2019 13:26:17 +0000 Subject: scsi: iscsi: Avoid potential deadlock in iscsi_if_rx func In iscsi_if_rx func, after receiving one request through iscsi_if_recv_msg func, iscsi_if_send_reply will be called to try to reply to the request in a do-while loop. If the iscsi_if_send_reply function keeps returning -EAGAIN, a deadlock will occur. For example, a client only send msg without calling recvmsg func, then it will result in the watchdog soft lockup. The details are given as follows: sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ISCSI); retval = bind(sock_fd, (struct sock addr*) & src_addr, sizeof(src_addr); while (1) { state_msg = sendmsg(sock_fd, &msg, 0); //Note: recvmsg(sock_fd, &msg, 0) is not processed here. } close(sock_fd); watchdog: BUG: soft lockup - CPU#7 stuck for 22s! [netlink_test:253305] Sample time: 4000897528 ns(HZ: 250) Sample stat: curr: user: 675503481560, nice: 321724050, sys: 448689506750, idle: 4654054240530, iowait: 40885550700, irq: 14161174020, softirq: 8104324140, st: 0 deta: user: 0, nice: 0, sys: 3998210100, idle: 0, iowait: 0, irq: 1547170, softirq: 242870, st: 0 Sample softirq: TIMER: 992 SCHED: 8 Sample irqstat: irq 2: delta 1003, curr: 3103802, arch_timer CPU: 7 PID: 253305 Comm: netlink_test Kdump: loaded Tainted: G OE Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 pstate: 40400005 (nZcv daif +PAN -UAO) pc : __alloc_skb+0x104/0x1b0 lr : __alloc_skb+0x9c/0x1b0 sp : ffff000033603a30 x29: ffff000033603a30 x28: 00000000000002dd x27: ffff800b34ced810 x26: ffff800ba7569f00 x25: 00000000ffffffff x24: 0000000000000000 x23: ffff800f7c43f600 x22: 0000000000480020 x21: ffff0000091d9000 x20: ffff800b34eff200 x19: ffff800ba7569f00 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 x14: 0001000101000100 x13: 0000000101010000 x12: 0101000001010100 x11: 0001010101010001 x10: 00000000000002dd x9 : ffff000033603d58 x8 : ffff800b34eff400 x7 : ffff800ba7569200 x6 : ffff800b34eff400 x5 : 0000000000000000 x4 : 00000000ffffffff x3 : 0000000000000000 x2 : 0000000000000001 x1 : ffff800b34eff2c0 x0 : 0000000000000300 Call trace: __alloc_skb+0x104/0x1b0 iscsi_if_rx+0x144/0x12bc [scsi_transport_iscsi] netlink_unicast+0x1e0/0x258 netlink_sendmsg+0x310/0x378 sock_sendmsg+0x4c/0x70 sock_write_iter+0x90/0xf0 __vfs_write+0x11c/0x190 vfs_write+0xac/0x1c0 ksys_write+0x6c/0xd8 __arm64_sys_write+0x24/0x30 el0_svc_common+0x78/0x130 el0_svc_handler+0x38/0x78 el0_svc+0x8/0xc Link: https://lore.kernel.org/r/EDBAAA0BBBA2AC4E9C8B6B81DEEE1D6915E3D4D2@dggeml505-mbx.china.huawei.com Signed-off-by: Bo Wu Reviewed-by: Zhiqiang Liu Reviewed-by: Lee Duncan Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_transport_iscsi.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 417b868d8735..ed8d9709b9b9 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -24,6 +24,8 @@ #define ISCSI_TRANSPORT_VERSION "2.0-870" +#define ISCSI_SEND_MAX_ALLOWED 10 + #define CREATE_TRACE_POINTS #include @@ -3682,6 +3684,7 @@ iscsi_if_rx(struct sk_buff *skb) struct nlmsghdr *nlh; struct iscsi_uevent *ev; uint32_t group; + int retries = ISCSI_SEND_MAX_ALLOWED; nlh = nlmsg_hdr(skb); if (nlh->nlmsg_len < sizeof(*nlh) + sizeof(*ev) || @@ -3712,6 +3715,10 @@ iscsi_if_rx(struct sk_buff *skb) break; err = iscsi_if_send_reply(portid, nlh->nlmsg_type, ev, sizeof(*ev)); + if (err == -EAGAIN && --retries < 0) { + printk(KERN_WARNING "Send reply failed, error %d\n", err); + break; + } } while (err < 0 && err != -ECONNREFUSED && err != -ESRCH); skb_pull(skb, rlen); } -- cgit v1.2.3