From 31f06d2e73726160645f8d9976a0b3f42e136da7 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:56:31 -0700 Subject: scsi: lpfc: Limit xri count for kdump environment scsi-mq operation inherently performs pre-allocation of resources for blk-mq request queues. Even though the kdump environment reduces the configuration to a single CPU, thus 1 hardware queue, which helps significantly, the resources are still rather large due to the per request allocations. blk-mq pre-allocations can be over 4KB per request. With adapter can_queue values in the 4k or 8k range, this can easily be 32MBs before any other driver memory is factored in. Driver SGL DMA buffer allocation can be up to 8KB per request as well adding an additional 64MB. Totals are well over 100MB for a single shost. Given kdump memory auto-sizing utilities don't accommodate this amount of memory well, it's very possible for kdump to fail due to lack of memory. Fix by having the driver recognize that it is booting within a kdump context and reduce the number of requests it will support to a more reasonable value. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index faf43b1d3dbe..a109895bf360 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -8307,6 +8308,10 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) bf_get(lpfc_mbx_rd_conf_extnts_inuse, rd_config); phba->sli4_hba.max_cfg_param.max_xri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config); + /* Reduce resource usage in kdump environment */ + if (is_kdump_kernel() && + phba->sli4_hba.max_cfg_param.max_xri > 512) + phba->sli4_hba.max_cfg_param.max_xri = 512; phba->sli4_hba.max_cfg_param.xri_base = bf_get(lpfc_mbx_rd_conf_xri_base, rd_config); phba->sli4_hba.max_cfg_param.max_vpi = -- cgit v1.2.3-59-g8ed1b From 3cee98db2610fb633fcbdd0f85385f60dabbaf75 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:56:34 -0700 Subject: scsi: lpfc: Fix crash on driver unload in wq free If a timer routine uses workqueues, it could fire before the workqueue is allocated. Fix by allocating the workqueue before the timer routines are setup Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index a109895bf360..f9986efa0aa3 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -6413,6 +6413,11 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) if (rc) return -ENODEV; + /* Allocate all driver workqueues here */ + + /* The lpfc_wq workqueue for deferred irq use */ + phba->wq = alloc_workqueue("lpfc_wq", WQ_MEM_RECLAIM, 0); + /* * Initialize timers used by driver */ @@ -6996,12 +7001,6 @@ lpfc_setup_driver_resource_phase2(struct lpfc_hba *phba) return error; } - /* The lpfc_wq workqueue for deferred irq use, is only used for SLI4 */ - if (phba->sli_rev == LPFC_SLI_REV4) - phba->wq = alloc_workqueue("lpfc_wq", WQ_MEM_RECLAIM, 0); - else - phba->wq = NULL; - return 0; } -- cgit v1.2.3-59-g8ed1b From 8d34a59caecda9a7ce0cad108ee64c37aa0c9812 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:56:35 -0700 Subject: scsi: lpfc: Fix failure to clear non-zero eq_delay after io rate reduction Unusually high IO latency can be observed with little IO in progress. The latency may remain high regardless of amount of IO and can only be cleared by forcing lpfc_fcp_imax values to non-zero and then back to zero. The driver's eq_delay mechanism that scales the interrupt coalescing based on io completion load failed to reduce or turn off coalescing when load decreased. Specifically, if no io completed on a cpu within an eq_delay polling window, the eq delay processing was skipped and no change was made to the coalescing values. This left the coalescing values set when they were no longer applicable. Fix by always clearing the percpu counters for each time period and always run the eq_delay calculations if an eq has a non-zero coalescing value. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index f9986efa0aa3..d04d00dea901 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1262,6 +1262,7 @@ lpfc_hb_eq_delay_work(struct work_struct *work) unsigned char *eqcnt = NULL; uint32_t usdelay; int i; + bool update = false; if (!phba->cfg_auto_imax || phba->pport->load_flag & FC_UNLOADING) return; @@ -1275,20 +1276,29 @@ lpfc_hb_eq_delay_work(struct work_struct *work) if (!eqcnt) goto requeue; - /* Loop thru all IRQ vectors */ - for (i = 0; i < phba->cfg_irq_chann; i++) { - /* Get the EQ corresponding to the IRQ vector */ - eq = phba->sli4_hba.hba_eq_hdl[i].eq; - if (eq && eqcnt[eq->last_cpu] < 2) - eqcnt[eq->last_cpu]++; - continue; - } + if (phba->cfg_irq_chann > 1) { + /* Loop thru all IRQ vectors */ + for (i = 0; i < phba->cfg_irq_chann; i++) { + /* Get the EQ corresponding to the IRQ vector */ + eq = phba->sli4_hba.hba_eq_hdl[i].eq; + if (!eq) + continue; + if (eq->q_mode) { + update = true; + break; + } + if (eqcnt[eq->last_cpu] < 2) + eqcnt[eq->last_cpu]++; + } + } else + update = true; for_each_present_cpu(i) { - if (phba->cfg_irq_chann > 1 && eqcnt[i] < 2) - continue; - eqi = per_cpu_ptr(phba->sli4_hba.eq_info, i); + if (!update && eqcnt[i] < 2) { + eqi->icnt = 0; + continue; + } usdelay = (eqi->icnt / LPFC_IMAX_THRESHOLD) * LPFC_EQ_DELAY_STEP; -- cgit v1.2.3-59-g8ed1b From 3ad348d94452d6ab3aa0316105fb9f34f8ed3140 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:56:43 -0700 Subject: scsi: lpfc: Fix oops when fewer hdwqs than cpus When tearing down the adapter for a reset, online/offline, or driver unload, the queue free routine would hit a GPF oops. This only occurs on conditions where the number of hardware queues created is fewer than the number of cpus in the system. In this condition cpus share a hardware queue. And of course, it's the 2nd cpu that shares a hardware that attempted to free it a second time and hit the oops. Fix by reworking the cpu to hardware queue mapping such that: Assignment of hardware queues to cpus occur in two passes: first pass: is first time assignment of a hardware queue to a cpu. This will set the LPFC_CPU_FIRST_IRQ flag for the cpu. second pass: for cpus that did not get a hardware queue they will be assigned one from a primary cpu (one set in first pass). Deletion of hardware queues is driven by cpu itteration, and queues will only be deleted if the LPFC_CPU_FIRST_IRQ flag is set. Also contains a few small cleanup fixes and a little better logging. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 144 ++++++++++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 55 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d04d00dea901..8e889ea26203 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -8876,7 +8876,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) } qdesc->qe_valid = 1; qdesc->hdwq = cpup->hdwq; - qdesc->chann = cpu; /* First CPU this EQ is affinitised to */ + qdesc->chann = cpu; /* First CPU this EQ is affinitized to */ qdesc->last_cpu = qdesc->chann; /* Save the allocated EQ in the Hardware Queue */ @@ -10723,7 +10723,7 @@ lpfc_find_hyper(struct lpfc_hba *phba, int cpu, static void lpfc_cpu_affinity_check(struct lpfc_hba *phba, int vectors) { - int i, cpu, idx, new_cpu, start_cpu, first_cpu; + int i, cpu, idx, next_idx, new_cpu, start_cpu, first_cpu; int max_phys_id, min_phys_id; int max_core_id, min_core_id; struct lpfc_vector_map_info *cpup; @@ -10765,8 +10765,8 @@ lpfc_cpu_affinity_check(struct lpfc_hba *phba, int vectors) #endif lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3328 CPU physid %d coreid %d\n", - cpup->phys_id, cpup->core_id); + "3328 CPU %d physid %d coreid %d flag x%x\n", + cpu, cpup->phys_id, cpup->core_id, cpup->flag); if (cpup->phys_id > max_phys_id) max_phys_id = cpup->phys_id; @@ -10805,17 +10805,17 @@ lpfc_cpu_affinity_check(struct lpfc_hba *phba, int vectors) cpup->eq = idx; cpup->irq = pci_irq_vector(phba->pcidev, idx); - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3336 Set Affinity: CPU %d " - "irq %d eq %d\n", - cpu, cpup->irq, cpup->eq); - /* If this is the first CPU thats assigned to this * vector, set LPFC_CPU_FIRST_IRQ. */ if (!i) cpup->flag |= LPFC_CPU_FIRST_IRQ; i++; + + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "3336 Set Affinity: CPU %d " + "irq %d eq %d flag x%x\n", + cpu, cpup->irq, cpup->eq, cpup->flag); } } @@ -10929,69 +10929,103 @@ found_any: } } + /* Assign hdwq indices that are unique across all cpus in the map + * that are also FIRST_CPUs. + */ + idx = 0; + for_each_present_cpu(cpu) { + cpup = &phba->sli4_hba.cpu_map[cpu]; + + /* Only FIRST IRQs get a hdwq index assignment. */ + if (!(cpup->flag & LPFC_CPU_FIRST_IRQ)) + continue; + + /* 1 to 1, the first LPFC_CPU_FIRST_IRQ cpus to a unique hdwq */ + cpup->hdwq = idx; + idx++; + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "3333 Set Affinity: CPU %d (phys %d core %d): " + "hdwq %d eq %d irq %d flg x%x\n", + cpu, cpup->phys_id, cpup->core_id, + cpup->hdwq, cpup->eq, cpup->irq, cpup->flag); + } /* Finally we need to associate a hdwq with each cpu_map entry * This will be 1 to 1 - hdwq to cpu, unless there are less * hardware queues then CPUs. For that case we will just round-robin * the available hardware queues as they get assigned to CPUs. + * The next_idx is the idx from the FIRST_CPU loop above to account + * for irq_chann < hdwq. The idx is used for round-robin assignments + * and needs to start at 0. */ - idx = 0; + next_idx = idx; start_cpu = 0; + idx = 0; for_each_present_cpu(cpu) { cpup = &phba->sli4_hba.cpu_map[cpu]; - if (idx >= phba->cfg_hdw_queue) { - /* We need to reuse a Hardware Queue for another CPU, - * so be smart about it and pick one that has its - * IRQ/EQ mapped to the same phys_id (CPU package). - * and core_id. - */ - new_cpu = start_cpu; - for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) { - new_cpup = &phba->sli4_hba.cpu_map[new_cpu]; - if ((new_cpup->hdwq != LPFC_VECTOR_MAP_EMPTY) && - (new_cpup->phys_id == cpup->phys_id) && - (new_cpup->core_id == cpup->core_id)) - goto found_hdwq; - new_cpu = cpumask_next( - new_cpu, cpu_present_mask); - if (new_cpu == nr_cpumask_bits) - new_cpu = first_cpu; - } - /* If we can't match both phys_id and core_id, - * settle for just a phys_id match. - */ - new_cpu = start_cpu; - for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) { - new_cpup = &phba->sli4_hba.cpu_map[new_cpu]; - if ((new_cpup->hdwq != LPFC_VECTOR_MAP_EMPTY) && - (new_cpup->phys_id == cpup->phys_id)) - goto found_hdwq; - new_cpu = cpumask_next( - new_cpu, cpu_present_mask); - if (new_cpu == nr_cpumask_bits) - new_cpu = first_cpu; + /* FIRST cpus are already mapped. */ + if (cpup->flag & LPFC_CPU_FIRST_IRQ) + continue; + + /* If the cfg_irq_chann < cfg_hdw_queue, set the hdwq + * of the unassigned cpus to the next idx so that all + * hdw queues are fully utilized. + */ + if (next_idx < phba->cfg_hdw_queue) { + cpup->hdwq = next_idx; + next_idx++; + continue; + } + + /* Not a First CPU and all hdw_queues are used. Reuse a + * Hardware Queue for another CPU, so be smart about it + * and pick one that has its IRQ/EQ mapped to the same phys_id + * (CPU package) and core_id. + */ + new_cpu = start_cpu; + for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) { + new_cpup = &phba->sli4_hba.cpu_map[new_cpu]; + if (new_cpup->hdwq != LPFC_VECTOR_MAP_EMPTY && + new_cpup->phys_id == cpup->phys_id && + new_cpup->core_id == cpup->core_id) { + goto found_hdwq; } + new_cpu = cpumask_next(new_cpu, cpu_present_mask); + if (new_cpu == nr_cpumask_bits) + new_cpu = first_cpu; + } - /* Otherwise just round robin on cfg_hdw_queue */ - cpup->hdwq = idx % phba->cfg_hdw_queue; - goto logit; -found_hdwq: - /* We found an available entry, copy the IRQ info */ - start_cpu = cpumask_next(new_cpu, cpu_present_mask); - if (start_cpu == nr_cpumask_bits) - start_cpu = first_cpu; - cpup->hdwq = new_cpup->hdwq; - } else { - /* 1 to 1, CPU to hdwq */ - cpup->hdwq = idx; + /* If we can't match both phys_id and core_id, + * settle for just a phys_id match. + */ + new_cpu = start_cpu; + for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) { + new_cpup = &phba->sli4_hba.cpu_map[new_cpu]; + if (new_cpup->hdwq != LPFC_VECTOR_MAP_EMPTY && + new_cpup->phys_id == cpup->phys_id) + goto found_hdwq; + + new_cpu = cpumask_next(new_cpu, cpu_present_mask); + if (new_cpu == nr_cpumask_bits) + new_cpu = first_cpu; } -logit: + + /* Otherwise just round robin on cfg_hdw_queue */ + cpup->hdwq = idx % phba->cfg_hdw_queue; + idx++; + goto logit; + found_hdwq: + /* We found an available entry, copy the IRQ info */ + start_cpu = cpumask_next(new_cpu, cpu_present_mask); + if (start_cpu == nr_cpumask_bits) + start_cpu = first_cpu; + cpup->hdwq = new_cpup->hdwq; + logit: lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "3335 Set Affinity: CPU %d (phys %d core %d): " "hdwq %d eq %d irq %d flg x%x\n", cpu, cpup->phys_id, cpup->core_id, cpup->hdwq, cpup->eq, cpup->irq, cpup->flag); - idx++; } /* The cpu_map array will be used later during initialization -- cgit v1.2.3-59-g8ed1b From c26c265b168bb09013922846a51447603bcdfdc4 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:56:49 -0700 Subject: scsi: lpfc: Fix sg_seg_cnt for HBAs that don't support NVME On an SLI-3 adapter which does not support NVMe, but with the driver global attribute to enable nvme on any adapter if it does support NVMe (e.g. module parameter lpfc_enable_fc4_type=3), the SGL and total SGE values are being munged by the protocol enablement when it shouldn't be. Correct by changing the location of where the NVME sgl information is being applied, which will avoid any SLI-3-based adapter. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 10 ---------- drivers/scsi/lpfc/lpfc_init.c | 9 +++++++++ 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index b527cc60e939..7bfebecf03bb 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -7181,16 +7181,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_ras_fwlog_level_init(phba, lpfc_ras_fwlog_level); lpfc_ras_fwlog_func_init(phba, lpfc_ras_fwlog_func); - - /* If the NVME FC4 type is enabled, scale the sg_seg_cnt to - * accommodate 512K and 1M IOs in a single nvme buf and supply - * enough NVME LS iocb buffers for larger connectivity counts. - */ - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { - phba->cfg_sg_seg_cnt = LPFC_MAX_NVME_SEG_CNT; - phba->cfg_iocb_cnt = 5; - } - return; } diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 8e889ea26203..8429de65d490 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -11681,6 +11681,15 @@ fcponly: } } + /* If the NVME FC4 type is enabled, scale the sg_seg_cnt to + * accommodate 512K and 1M IOs in a single nvme buf and supply + * enough NVME LS iocb buffers for larger connectivity counts. + */ + if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { + phba->cfg_sg_seg_cnt = LPFC_MAX_NVME_SEG_CNT; + phba->cfg_iocb_cnt = 5; + } + /* Only embed PBDE for if_type 6, PBDE support requires xib be set */ if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != LPFC_SLI_INTF_IF_TYPE_6) || (!bf_get(cfg_xib, mbx_sli4_parameters))) -- cgit v1.2.3-59-g8ed1b From 8c24a4f643edbcc7c8281b1f7527568f565dfbf8 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:56:53 -0700 Subject: scsi: lpfc: Fix crash due to port reset racing vs adapter error handling If the adapter encounters a condition which causes the adapter to fail (driver must detect the failure) simultaneously to a request to the driver to reset the adapter (such as a host_reset), the reset path will be racing with the asynchronously-detect adapter failure path. In the failing situation, one path has started to tear down the adapter data structures (io_wq's) while the other path has initiated a repeat of the teardown and is in the lpfc_sli_flush_xxx_rings path and attempting to access the just-freed data structures. Fix by the following: - In cases where an adapter failure is detected, rather than explicitly calling offline_eratt() to start the teardown, change the adapter state and let the later calls of posted work to the slowpath thread invoke the adapter recovery. In essence, this means all requests to reset are serialized on the slowpath thread. - Clean up the routine that restarts the adapter. If there is a failure from brdreset, don't immediately error and leave things in a partial state. Instead, ensure the adapter state is set and finish the teardown of structures before returning. - If in the scsi host reset handler and the board fails to reset and restart (which can be due to parallel reset/recovery paths), instead of hard failing and explicitly calling offline_eratt() (which gets into the redundant path), just fail out and let the asynchronous path resolve the adapter state. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 7 +++---- drivers/scsi/lpfc/lpfc_scsi.c | 16 +++++++++------- drivers/scsi/lpfc/lpfc_sli.c | 6 ++++-- 3 files changed, 16 insertions(+), 13 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 8429de65d490..c549212a2b49 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1926,7 +1926,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "7624 Firmware not ready: Failing UE recovery," " waited %dSec", i); - lpfc_sli4_offline_eratt(phba); + phba->link_state = LPFC_HBA_ERROR; break; case LPFC_SLI_INTF_IF_TYPE_2: @@ -2000,9 +2000,8 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) } /* fall through for not able to recover */ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "3152 Unrecoverable error, bring the port " - "offline\n"); - lpfc_sli4_offline_eratt(phba); + "3152 Unrecoverable error\n"); + phba->link_state = LPFC_HBA_ERROR; break; case LPFC_SLI_INTF_IF_TYPE_1: default: diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index f9df800e7067..720a98266986 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5295,18 +5295,20 @@ lpfc_host_reset_handler(struct scsi_cmnd *cmnd) lpfc_offline(phba); rc = lpfc_sli_brdrestart(phba); if (rc) - ret = FAILED; + goto error; + rc = lpfc_online(phba); if (rc) - ret = FAILED; + goto error; + lpfc_unblock_mgmt_io(phba); - if (ret == FAILED) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, - "3323 Failed host reset, bring it offline\n"); - lpfc_sli4_offline_eratt(phba); - } return ret; +error: + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, + "3323 Failed host reset\n"); + lpfc_unblock_mgmt_io(phba); + return FAILED; } /** diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 8449f7f9cb64..be89a86f9649 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -4509,7 +4509,7 @@ lpfc_sli_brdreset(struct lpfc_hba *phba) * checking during resets the device. The caller is not required to hold * any locks. * - * This function returns 0 always. + * This function returns 0 on success else returns negative error code. **/ int lpfc_sli4_brdreset(struct lpfc_hba *phba) @@ -4667,7 +4667,7 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba) rc = lpfc_sli4_brdreset(phba); if (rc) - return rc; + goto error; spin_lock_irq(&phba->hbalock); phba->pport->stopped = 0; @@ -4682,6 +4682,8 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba) if (hba_aer_enabled) pci_disable_pcie_error_reporting(phba->pcidev); +error: + phba->link_state = LPFC_HBA_ERROR; lpfc_hba_down_post(phba); lpfc_sli4_queue_destroy(phba); -- cgit v1.2.3-59-g8ed1b From 84f2ddf8cf317afcfd92e06ed5a25aea48dc200e Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:56:55 -0700 Subject: scsi: lpfc: Fix hang when downloading fw on port enabled for nvme As part of firmware download, the adapter is reset. On the adapter the reset causes the function to stop and all outstanding io is terminated (without responses). The reset path then starts teardown of the adapter, starting with deregistration of the remote ports with the nvme-fc transport. The local port is then deregistered and the driver waits for local port deregistration. This never finishes. The remote port deregistrations terminated the nvme controllers, causing them to send aborts for all the outstanding io. The aborts were serviced in the driver, but stalled due to its state. The nvme layer then stops to reclaim it's outstanding io before continuing. The io must be returned before the reset on the controller is deemed complete and the controller delete performed. The remote port deregistration won't complete until all the controllers are terminated. And the local port deregistration won't complete until all controllers and remote ports are terminated. Thus things hang. The issue is the reset which stopped the adapter also stopped all the responses that would drive i/o completions, and the aborts were also stopped that stopped i/o completions. The driver, when resetting the adapter like this, needs to be generating the completions as part of the adapter reset so that I/O complete (in error), and any aborts are not queued. Fix by adding flush routines whenever the adapter port has been reset or discovered in error. The flush routines will generate the completions for the scsi and nvme outstanding io. The abort ios, if waiting, will be caught and flushed as well. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_crtn.h | 1 + drivers/scsi/lpfc/lpfc_init.c | 4 ++++ drivers/scsi/lpfc/lpfc_nvme.c | 47 +++++++++++++++++++++++++++++++++++++++++++ drivers/scsi/lpfc/lpfc_sli.c | 9 ++++++--- 4 files changed, 58 insertions(+), 3 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 68e9f96242d3..bee27bb7123c 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -595,6 +595,7 @@ void lpfc_release_io_buf(struct lpfc_hba *phba, struct lpfc_io_buf *ncmd, struct lpfc_sli4_hdw_queue *qp); void lpfc_nvme_cmd_template(void); void lpfc_nvmet_cmd_template(void); +void lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn); extern int lpfc_enable_nvmet_cnt; extern unsigned long long lpfc_enable_nvmet[]; extern int lpfc_no_hba_reset_cnt; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index c549212a2b49..8c0fb9baf723 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1546,6 +1546,8 @@ lpfc_sli4_offline_eratt(struct lpfc_hba *phba) spin_unlock_irq(&phba->hbalock); lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT); + lpfc_sli_flush_fcp_rings(phba); + lpfc_sli_flush_nvme_rings(phba); lpfc_offline(phba); lpfc_hba_down_post(phba); lpfc_unblock_mgmt_io(phba); @@ -1807,6 +1809,8 @@ lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action, "2887 Reset Needed: Attempting Port " "Recovery...\n"); lpfc_offline_prep(phba, mbx_action); + lpfc_sli_flush_fcp_rings(phba); + lpfc_sli_flush_nvme_rings(phba); lpfc_offline(phba); /* release interrupt for possible resource change */ lpfc_sli4_disable_intr(phba); diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 103708503592..c7f5b50c3820 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -2668,3 +2668,50 @@ lpfc_nvme_wait_for_io_drain(struct lpfc_hba *phba) } } } + +void +lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn) +{ +#if (IS_ENABLED(CONFIG_NVME_FC)) + struct lpfc_io_buf *lpfc_ncmd; + struct nvmefc_fcp_req *nCmd; + struct lpfc_nvme_fcpreq_priv *freqpriv; + + if (!pwqeIn->context1) { + lpfc_sli_release_iocbq(phba, pwqeIn); + return; + } + /* For abort iocb just return, IO iocb will do a done call */ + if (bf_get(wqe_cmnd, &pwqeIn->wqe.gen_req.wqe_com) == + CMD_ABORT_XRI_CX) { + lpfc_sli_release_iocbq(phba, pwqeIn); + return; + } + lpfc_ncmd = (struct lpfc_io_buf *)pwqeIn->context1; + + spin_lock(&lpfc_ncmd->buf_lock); + if (!lpfc_ncmd->nvmeCmd) { + spin_unlock(&lpfc_ncmd->buf_lock); + lpfc_release_nvme_buf(phba, lpfc_ncmd); + return; + } + + nCmd = lpfc_ncmd->nvmeCmd; + lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR, + "6194 NVME Cancel xri %x\n", + lpfc_ncmd->cur_iocbq.sli4_xritag); + + nCmd->transferred_length = 0; + nCmd->rcv_rsplen = 0; + nCmd->status = NVME_SC_INTERNAL; + freqpriv = nCmd->private; + freqpriv->nvme_buf = NULL; + lpfc_ncmd->nvmeCmd = NULL; + + spin_unlock(&lpfc_ncmd->buf_lock); + nCmd->done(nCmd); + + /* Call release with XB=1 to queue the IO into the abort list. */ + lpfc_release_nvme_buf(phba, lpfc_ncmd); +#endif +} diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index be89a86f9649..c8db7ec31afb 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1391,9 +1391,12 @@ lpfc_sli_cancel_iocbs(struct lpfc_hba *phba, struct list_head *iocblist, while (!list_empty(iocblist)) { list_remove_head(iocblist, piocb, struct lpfc_iocbq, list); - if (!piocb->iocb_cmpl) - lpfc_sli_release_iocbq(phba, piocb); - else { + if (!piocb->iocb_cmpl) { + if (piocb->iocb_flag & LPFC_IO_NVME) + lpfc_nvme_cancel_iocb(phba, piocb); + else + lpfc_sli_release_iocbq(phba, piocb); + } else { piocb->iocb.ulpStatus = ulpstatus; piocb->iocb.un.ulpWord[4] = ulpWord4; (piocb->iocb_cmpl) (phba, piocb, piocb); -- cgit v1.2.3-59-g8ed1b From 6a224b47fd019d299037e14381ddff438f2d34c8 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:56:57 -0700 Subject: scsi: lpfc: Fix nvme sg_seg_cnt display if HBA does not support NVME The driver is currently reporting a non-zero nvme sg_seg_cnt value of 256 when nvme is disabled. It should be zero. Fix by ensuring the value is cleared. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 8c0fb9baf723..f1e1e8faaec1 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -11676,6 +11676,7 @@ fcponly: phba->nvme_support = 0; phba->nvmet_support = 0; phba->cfg_nvmet_mrq = 0; + phba->cfg_nvme_seg_cnt = 0; /* If no FC4 type support, move to just SCSI support */ if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP)) -- cgit v1.2.3-59-g8ed1b From 07b1b91412c801030752da3d32a543c5522a79d6 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:56:58 -0700 Subject: scsi: lpfc: Fix sli4 adapter initialization with MSI When forcing the use of MSI (vs MSI-X) the driver is crashing in pci_irq_get_affinity. The driver was not using the new pci_alloc_irq_vectors interface in the MSI path. Fix by using pci_alloc_irq_vectors() with PCI_RQ_MSI in the MSI path. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index f1e1e8faaec1..82a5166afe18 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -11119,10 +11119,10 @@ vec_fail_out: * @phba: pointer to lpfc hba data structure. * * This routine is invoked to enable the MSI interrupt mode to device with - * SLI-4 interface spec. The kernel function pci_enable_msi() is called - * to enable the MSI vector. The device driver is responsible for calling - * the request_irq() to register MSI vector with a interrupt the handler, - * which is done in this function. + * SLI-4 interface spec. The kernel function pci_alloc_irq_vectors() is + * called to enable the MSI vector. The device driver is responsible for + * calling the request_irq() to register MSI vector with a interrupt the + * handler, which is done in this function. * * Return codes * 0 - successful @@ -11133,20 +11133,21 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba) { int rc, index; - rc = pci_enable_msi(phba->pcidev); - if (!rc) + rc = pci_alloc_irq_vectors(phba->pcidev, 1, 1, + PCI_IRQ_MSI | PCI_IRQ_AFFINITY); + if (rc > 0) lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0487 PCI enable MSI mode success.\n"); else { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0488 PCI enable MSI mode failed (%d)\n", rc); - return rc; + return rc ? rc : -1; } rc = request_irq(phba->pcidev->irq, lpfc_sli4_intr_handler, 0, LPFC_DRIVER_NAME, phba); if (rc) { - pci_disable_msi(phba->pcidev); + pci_free_irq_vectors(phba->pcidev); lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, "0490 MSI request_irq failed (%d)\n", rc); return rc; -- cgit v1.2.3-59-g8ed1b From 32350664497279f4ddd96164caafc8a1b573ca2a Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:57:06 -0700 Subject: scsi: lpfc: Migrate to %px and %pf in kernel print calls In order to see real addresses, convert %p with %px for kernel addresses and replace %p with %pf for functions. While converting, standardize on "x%px" throughout (not %px or 0x%px). Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_bsg.c | 2 +- drivers/scsi/lpfc/lpfc_ct.c | 5 ++- drivers/scsi/lpfc/lpfc_debugfs.c | 4 +- drivers/scsi/lpfc/lpfc_els.c | 4 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 78 +++++++++++++++++---------------- drivers/scsi/lpfc/lpfc_init.c | 18 ++++---- drivers/scsi/lpfc/lpfc_nportdisc.c | 2 +- drivers/scsi/lpfc/lpfc_nvme.c | 90 +++++++++++++++++++------------------- drivers/scsi/lpfc/lpfc_nvmet.c | 10 ++--- drivers/scsi/lpfc/lpfc_scsi.c | 16 +++---- drivers/scsi/lpfc/lpfc_sli.c | 16 +++---- 11 files changed, 125 insertions(+), 120 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 0d2535c177e9..39a736b887b1 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -1040,7 +1040,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, if (!dmabuf) { lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, "2616 No dmabuf " - "found for iocbq 0x%p\n", + "found for iocbq x%px\n", iocbq); kfree(evt_dat->data); kfree(evt_dat); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 1717f3403a97..25e86706e207 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -1227,8 +1227,9 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (fc4_data_1 & LPFC_FC4_TYPE_BITMASK) ndlp->nlp_fc4_type |= NLP_FC4_NVME; lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "3064 Setting ndlp %p, DID x%06x with " - "FC4 x%08x, Data: x%08x x%08x %d\n", + "3064 Setting ndlp x%px, DID x%06x " + "with FC4 x%08x, Data: x%08x x%08x " + "%d\n", ndlp, did, ndlp->nlp_fc4_type, FC_TYPE_FCP, FC_TYPE_NVME, ndlp->nlp_state); diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 1ee857d9d165..75055ee59e91 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -361,7 +361,7 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff); if (phys == le32_to_cpu(hbqe->bde.addrLow)) { len += scnprintf(buf+len, size-len, - "Buf%d: %p %06x\n", i, + "Buf%d: x%px %06x\n", i, hbq_buf->dbuf.virt, hbq_buf->tag); found = 1; break; @@ -2210,7 +2210,7 @@ lpfc_debugfs_dumpDif_open(struct inode *inode, struct file *file) goto out; /* Round to page boundary */ - pr_err("9060 BLKGRD: %s: _dump_buf_dif=0x%p file=%pD\n", + pr_err("9060 BLKGRD: %s: _dump_buf_dif=x%px file=%pD\n", __func__, _dump_buf_dif, file); debug->buffer = _dump_buf_dif; if (!debug->buffer) { diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 54ec7f0822e5..aaad1c74bb98 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2140,7 +2140,7 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) !(vport->fc_flag & FC_OFFLINE_MODE)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "4110 Issue PLOGI x%x deferred " - "on NPort x%x rpi x%x Data: %p\n", + "on NPort x%x rpi x%x Data: x%px\n", ndlp->nlp_defer_did, ndlp->nlp_DID, ndlp->nlp_rpi, ndlp); @@ -4236,7 +4236,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) mempool_free(pmb, phba->mbox_mem_pool); if (ndlp) { lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, - "0006 rpi%x DID:%x flg:%x %d map:%x %p\n", + "0006 rpi%x DID:%x flg:%x %d map:%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, kref_read(&ndlp->kref), ndlp->nlp_usg_map, ndlp); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index dc3763114d76..e7463d561f30 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -133,7 +133,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, - "3181 dev_loss_callbk x%06x, rport %p flg x%x\n", + "3181 dev_loss_callbk x%06x, rport x%px flg x%x\n", ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag); /* Don't defer this if we are in the process of deleting the vport @@ -237,7 +237,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id); lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, - "3182 dev_loss_tmo_handler x%06x, rport %p flg x%x\n", + "3182 dev_loss_tmo_handler x%06x, rport x%px flg x%x\n", ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag); /* @@ -3323,7 +3323,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) out: lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, - "0263 Discovery Mailbox error: state: 0x%x : %p %p\n", + "0263 Discovery Mailbox error: state: 0x%x : x%px x%px\n", vport->port_state, sparam_mbox, cfglink_mbox); lpfc_issue_clear_la(phba, vport); return; @@ -3535,7 +3535,7 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) pmb->ctx_ndlp = NULL; lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, - "0002 rpi:%x DID:%x flg:%x %d map:%x %p\n", + "0002 rpi:%x DID:%x flg:%x %d map:%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, kref_read(&ndlp->kref), ndlp->nlp_usg_map, ndlp); @@ -4047,7 +4047,7 @@ out: ndlp->nlp_type |= NLP_FABRIC; lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, - "0003 rpi:%x DID:%x flg:%x %d map%x %p\n", + "0003 rpi:%x DID:%x flg:%x %d map%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, kref_read(&ndlp->kref), ndlp->nlp_usg_map, ndlp); @@ -4166,7 +4166,7 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) fc_remote_port_rolechg(rport, rport_ids.roles); lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, - "3183 rport register x%06x, rport %p role x%x\n", + "3183 rport register x%06x, rport x%px role x%x\n", ndlp->nlp_DID, rport, rport_ids.roles); if ((rport->scsi_target_id != -1) && @@ -4190,7 +4190,7 @@ lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, - "3184 rport unregister x%06x, rport %p\n", + "3184 rport unregister x%06x, rport x%px\n", ndlp->nlp_DID, rport); fc_remote_port_delete(rport); @@ -4509,9 +4509,9 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, if (NLP_CHK_FREE_REQ(ndlp)) { spin_unlock_irqrestore(&phba->ndlp_lock, flags); lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, - "0277 lpfc_enable_node: ndlp:x%p " + "0277 %s: ndlp:x%px " "usgmap:x%x refcnt:%d\n", - (void *)ndlp, ndlp->nlp_usg_map, + __func__, (void *)ndlp, ndlp->nlp_usg_map, kref_read(&ndlp->kref)); goto free_rpi; } @@ -4519,9 +4519,9 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, if (NLP_CHK_NODE_ACT(ndlp)) { spin_unlock_irqrestore(&phba->ndlp_lock, flags); lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, - "0278 lpfc_enable_node: ndlp:x%p " + "0278 %s: ndlp:x%px " "usgmap:x%x refcnt:%d\n", - (void *)ndlp, ndlp->nlp_usg_map, + __func__, (void *)ndlp, ndlp->nlp_usg_map, kref_read(&ndlp->kref)); goto free_rpi; } @@ -4551,7 +4551,7 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ndlp->nlp_rpi = rpi; lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, "0008 rpi:%x DID:%x flg:%x refcnt:%d " - "map:%x %p\n", ndlp->nlp_rpi, ndlp->nlp_DID, + "map:%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, kref_read(&ndlp->kref), ndlp->nlp_usg_map, ndlp); @@ -4824,7 +4824,7 @@ lpfc_nlp_logo_unreg(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) (ndlp->nlp_defer_did != NLP_EVT_NOTHING_PENDING)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "1434 UNREG cmpl deferred logo x%x " - "on NPort x%x Data: x%x %p\n", + "on NPort x%x Data: x%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_defer_did, ndlp); @@ -4874,7 +4874,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "1436 unreg_rpi SKIP UNREG x%x on " "NPort x%x deferred x%x flg x%x " - "Data: %p\n", + "Data: x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_defer_did, ndlp->nlp_flag, ndlp); @@ -4924,7 +4924,8 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "1433 unreg_rpi UNREG x%x on " - "NPort x%x deferred flg x%x Data:%p\n", + "NPort x%x deferred flg x%x " + "Data:x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, ndlp); @@ -5065,16 +5066,16 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) ndlp->nlp_state, ndlp->nlp_rpi); if (NLP_CHK_FREE_REQ(ndlp)) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, - "0280 lpfc_cleanup_node: ndlp:x%p " + "0280 %s: ndlp:x%px " "usgmap:x%x refcnt:%d\n", - (void *)ndlp, ndlp->nlp_usg_map, + __func__, (void *)ndlp, ndlp->nlp_usg_map, kref_read(&ndlp->kref)); lpfc_dequeue_node(vport, ndlp); } else { lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, - "0281 lpfc_cleanup_node: ndlp:x%p " + "0281 %s: ndlp:x%px " "usgmap:x%x refcnt:%d\n", - (void *)ndlp, ndlp->nlp_usg_map, + __func__, (void *)ndlp, ndlp->nlp_usg_map, kref_read(&ndlp->kref)); lpfc_disable_node(vport, ndlp); } @@ -5165,7 +5166,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) * allocated by the firmware. */ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, - "0005 rpi:%x DID:%x flg:%x %d map:%x %p\n", + "0005 rpi:%x DID:%x flg:%x %d map:%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, kref_read(&ndlp->kref), ndlp->nlp_usg_map, ndlp); @@ -5201,8 +5202,8 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) * for registered rport so need to cleanup rport */ lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, - "0940 removed node x%p DID x%x " - " rport not null %p\n", + "0940 removed node x%px DID x%x " + " rport not null x%px\n", ndlp, ndlp->nlp_DID, ndlp->rport); rport = ndlp->rport; rdata = rport->dd_data; @@ -5329,7 +5330,7 @@ lpfc_findnode_mapped(struct lpfc_vport *vport) spin_unlock_irqrestore(shost->host_lock, iflags); lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, "2025 FIND node DID " - "Data: x%p x%x x%x x%x %p\n", + "Data: x%px x%x x%x x%x x%px\n", ndlp, ndlp->nlp_DID, ndlp->nlp_flag, data1, ndlp->active_rrqs_xri_bitmap); @@ -5996,7 +5997,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ndlp->nlp_type |= NLP_FABRIC; lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, - "0004 rpi:%x DID:%x flg:%x %d map:%x %p\n", + "0004 rpi:%x DID:%x flg:%x %d map:%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, kref_read(&ndlp->kref), ndlp->nlp_usg_map, ndlp); @@ -6050,8 +6051,8 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { if (filter(ndlp, param)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, - "3185 FIND node filter %p DID " - "ndlp %p did x%x flg x%x st x%x " + "3185 FIND node filter %pf DID " + "ndlp x%px did x%x flg x%x st x%x " "xri x%x type x%x rpi x%x\n", filter, ndlp, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, @@ -6061,7 +6062,7 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) } } lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, - "3186 FIND node filter %p NOT FOUND.\n", filter); + "3186 FIND node filter %pf NOT FOUND.\n", filter); return NULL; } @@ -6186,7 +6187,7 @@ lpfc_nlp_init(struct lpfc_vport *vport, uint32_t did) ndlp->nlp_rpi = rpi; lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, "0007 rpi:%x DID:%x flg:%x refcnt:%d " - "map:%x %p\n", ndlp->nlp_rpi, ndlp->nlp_DID, + "map:%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, kref_read(&ndlp->kref), ndlp->nlp_usg_map, ndlp); @@ -6224,8 +6225,9 @@ lpfc_nlp_release(struct kref *kref) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, - "0279 lpfc_nlp_release: ndlp:x%p did %x " + "0279 %s: ndlp:x%px did %x " "usgmap:x%x refcnt:%d rpi:%x\n", + __func__, (void *)ndlp, ndlp->nlp_DID, ndlp->nlp_usg_map, kref_read(&ndlp->kref), ndlp->nlp_rpi); @@ -6272,9 +6274,9 @@ lpfc_nlp_get(struct lpfc_nodelist *ndlp) if (!NLP_CHK_NODE_ACT(ndlp) || NLP_CHK_FREE_ACK(ndlp)) { spin_unlock_irqrestore(&phba->ndlp_lock, flags); lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE, - "0276 lpfc_nlp_get: ndlp:x%p " + "0276 %s: ndlp:x%px " "usgmap:x%x refcnt:%d\n", - (void *)ndlp, ndlp->nlp_usg_map, + __func__, (void *)ndlp, ndlp->nlp_usg_map, kref_read(&ndlp->kref)); return NULL; } else @@ -6300,9 +6302,9 @@ lpfc_nlp_put(struct lpfc_nodelist *ndlp) return 1; lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, - "node put: did:x%x flg:x%x refcnt:x%x", - ndlp->nlp_DID, ndlp->nlp_flag, - kref_read(&ndlp->kref)); + "node put: did:x%x flg:x%x refcnt:x%x", + ndlp->nlp_DID, ndlp->nlp_flag, + kref_read(&ndlp->kref)); phba = ndlp->phba; spin_lock_irqsave(&phba->ndlp_lock, flags); /* Check the ndlp memory free acknowledge flag to avoid the @@ -6312,9 +6314,9 @@ lpfc_nlp_put(struct lpfc_nodelist *ndlp) if (NLP_CHK_FREE_ACK(ndlp)) { spin_unlock_irqrestore(&phba->ndlp_lock, flags); lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE, - "0274 lpfc_nlp_put: ndlp:x%p " + "0274 %s: ndlp:x%px " "usgmap:x%x refcnt:%d\n", - (void *)ndlp, ndlp->nlp_usg_map, + __func__, (void *)ndlp, ndlp->nlp_usg_map, kref_read(&ndlp->kref)); return 1; } @@ -6325,9 +6327,9 @@ lpfc_nlp_put(struct lpfc_nodelist *ndlp) if (NLP_CHK_IACT_REQ(ndlp)) { spin_unlock_irqrestore(&phba->ndlp_lock, flags); lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE, - "0275 lpfc_nlp_put: ndlp:x%p " + "0275 %s: ndlp:x%px " "usgmap:x%x refcnt:%d\n", - (void *)ndlp, ndlp->nlp_usg_map, + __func__, (void *)ndlp, ndlp->nlp_usg_map, kref_read(&ndlp->kref)); return 1; } diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 82a5166afe18..6b39bfb73104 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -2877,7 +2877,7 @@ lpfc_cleanup(struct lpfc_vport *vport) &vport->fc_nodes, nlp_listp) { lpfc_printf_vlog(ndlp->vport, KERN_ERR, LOG_NODE, - "0282 did:x%x ndlp:x%p " + "0282 did:x%x ndlp:x%px " "usgmap:x%x refcnt:%d\n", ndlp->nlp_DID, (void *)ndlp, ndlp->nlp_usg_map, @@ -3081,7 +3081,7 @@ lpfc_sli4_node_prep(struct lpfc_hba *phba) ndlp->nlp_rpi = rpi; lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, "0009 rpi:%x DID:%x " - "flg:%x map:%x %p\n", ndlp->nlp_rpi, + "flg:%x map:%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_usg_map, ndlp); } @@ -3505,7 +3505,7 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, "0011 lpfc_offline: " - "ndlp:x%p did %x " + "ndlp:x%px did %x " "usgmap:x%x rpi:%x\n", ndlp, ndlp->nlp_DID, ndlp->nlp_usg_map, @@ -7620,7 +7620,7 @@ lpfc_setup_bg(struct lpfc_hba *phba, struct Scsi_Host *shost) if (_dump_buf_data) { lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9043 BLKGRD: allocated %d pages for " - "_dump_buf_data at 0x%p\n", + "_dump_buf_data at x%px\n", (1 << pagecnt), _dump_buf_data); _dump_buf_data_order = pagecnt; memset(_dump_buf_data, 0, @@ -7635,7 +7635,7 @@ lpfc_setup_bg(struct lpfc_hba *phba, struct Scsi_Host *shost) "memory for hexdump\n"); } else lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9045 BLKGRD: already allocated _dump_buf_data=0x%p" + "9045 BLKGRD: already allocated _dump_buf_data=x%px" "\n", _dump_buf_data); if (!_dump_buf_dif) { while (pagecnt) { @@ -7644,7 +7644,7 @@ lpfc_setup_bg(struct lpfc_hba *phba, struct Scsi_Host *shost) if (_dump_buf_dif) { lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9046 BLKGRD: allocated %d pages for " - "_dump_buf_dif at 0x%p\n", + "_dump_buf_dif at x%px\n", (1 << pagecnt), _dump_buf_dif); _dump_buf_dif_order = pagecnt; memset(_dump_buf_dif, 0, @@ -7659,7 +7659,7 @@ lpfc_setup_bg(struct lpfc_hba *phba, struct Scsi_Host *shost) "memory for hexdump\n"); } else lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9048 BLKGRD: already allocated _dump_buf_dif=0x%p\n", + "9048 BLKGRD: already allocated _dump_buf_dif=x%px\n", _dump_buf_dif); } @@ -13573,14 +13573,14 @@ lpfc_exit(void) fc_release_transport(lpfc_vport_transport_template); if (_dump_buf_data) { printk(KERN_ERR "9062 BLKGRD: freeing %lu pages for " - "_dump_buf_data at 0x%p\n", + "_dump_buf_data at x%px\n", (1L << _dump_buf_data_order), _dump_buf_data); free_pages((unsigned long)_dump_buf_data, _dump_buf_data_order); } if (_dump_buf_dif) { printk(KERN_ERR "9049 BLKGRD: freeing %lu pages for " - "_dump_buf_dif at 0x%p\n", + "_dump_buf_dif at x%px\n", (1L << _dump_buf_dif_order), _dump_buf_dif); free_pages((unsigned long)_dump_buf_dif, _dump_buf_dif_order); } diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index f4eea52c66f5..41ac07b99739 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -885,7 +885,7 @@ lpfc_release_rpi(struct lpfc_hba *phba, struct lpfc_vport *vport, lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "1435 release_rpi SKIP UNREG x%x on " "NPort x%x deferred x%x flg x%x " - "Data: %p\n", + "Data: x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_defer_did, ndlp->nlp_flag, ndlp); diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 106aef82620d..b599ddc40c6b 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -247,7 +247,7 @@ lpfc_nvme_create_queue(struct nvme_fc_local_port *pnvme_lport, lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, "6073 Binding %s HdwQueue %d (cpu %d) to " - "hdw_queue %d qhandle %p\n", str, + "hdw_queue %d qhandle x%px\n", str, qidx, qhandle->cpu_id, qhandle->index, qhandle); *handle = (void *)qhandle; return 0; @@ -282,7 +282,7 @@ lpfc_nvme_delete_queue(struct nvme_fc_local_port *pnvme_lport, vport = lport->vport; lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, - "6001 ENTER. lpfc_pnvme %p, qidx x%x qhandle %p\n", + "6001 ENTER. lpfc_pnvme x%px, qidx x%x qhandle x%px\n", lport, qidx, handle); kfree(handle); } @@ -293,7 +293,7 @@ lpfc_nvme_localport_delete(struct nvme_fc_local_port *localport) struct lpfc_nvme_lport *lport = localport->private; lpfc_printf_vlog(lport->vport, KERN_INFO, LOG_NVME, - "6173 localport %p delete complete\n", + "6173 localport x%px delete complete\n", lport); /* release any threads waiting for the unreg to complete */ @@ -332,7 +332,7 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport) * calling state machine to remove the node. */ lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, - "6146 remoteport delete of remoteport %p\n", + "6146 remoteport delete of remoteport x%px\n", remoteport); spin_lock_irq(&vport->phba->hbalock); @@ -383,8 +383,8 @@ lpfc_nvme_cmpl_gen_req(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, ndlp = (struct lpfc_nodelist *)cmdwqe->context1; lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, "6047 nvme cmpl Enter " - "Data %p DID %x Xri: %x status %x reason x%x cmd:%p " - "lsreg:%p bmp:%p ndlp:%p\n", + "Data %px DID %x Xri: %x status %x reason x%x " + "cmd:x%px lsreg:x%px bmp:x%px ndlp:x%px\n", pnvme_lsreq, ndlp ? ndlp->nlp_DID : 0, cmdwqe->sli4_xritag, status, (wcqe->parameter & 0xffff), @@ -404,7 +404,7 @@ lpfc_nvme_cmpl_gen_req(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, else lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC, "6046 nvme cmpl without done call back? " - "Data %p DID %x Xri: %x status %x\n", + "Data %px DID %x Xri: %x status %x\n", pnvme_lsreq, ndlp ? ndlp->nlp_DID : 0, cmdwqe->sli4_xritag, status); if (ndlp) { @@ -517,7 +517,8 @@ lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, /* Issue GEN REQ WQE for NPORT */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "6050 Issue GEN REQ WQE to NPORT x%x " - "Data: x%x x%x wq:%p lsreq:%p bmp:%p xmit:%d 1st:%d\n", + "Data: x%x x%x wq:x%px lsreq:x%px bmp:x%px " + "xmit:%d 1st:%d\n", ndlp->nlp_DID, genwqe->iotag, vport->port_state, genwqe, pnvme_lsreq, bmp, xmit_len, first_len); @@ -595,7 +596,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport, ndlp = rport->ndlp; if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR, - "6051 Remoteport %p, rport has invalid ndlp. " + "6051 Remoteport x%px, rport has invalid ndlp. " "Failing LS Req\n", pnvme_rport); return -ENODEV; } @@ -647,10 +648,10 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport, /* Expand print to include key fields. */ lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, - "6149 Issue LS Req to DID 0x%06x lport %p, rport %p " - "lsreq%p rqstlen:%d rsplen:%d %pad %pad\n", - ndlp->nlp_DID, - pnvme_lport, pnvme_rport, + "6149 Issue LS Req to DID 0x%06x lport x%px, " + "rport x%px lsreq x%px rqstlen:%d rsplen:%d " + "%pad %pad\n", + ndlp->nlp_DID, pnvme_lport, pnvme_rport, pnvme_lsreq, pnvme_lsreq->rqstlen, pnvme_lsreq->rsplen, &pnvme_lsreq->rqstdma, &pnvme_lsreq->rspdma); @@ -666,8 +667,8 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport, if (ret != WQE_SUCCESS) { atomic_inc(&lport->xmt_ls_err); lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC, - "6052 EXIT. issue ls wqe failed lport %p, " - "rport %p lsreq%p Status %x DID %x\n", + "6052 EXIT. issue ls wqe failed lport x%px, " + "rport x%px lsreq x%px Status %x DID %x\n", pnvme_lport, pnvme_rport, pnvme_lsreq, ret, ndlp->nlp_DID); lpfc_mbuf_free(vport->phba, bmp->virt, bmp->phys); @@ -724,7 +725,7 @@ lpfc_nvme_ls_abort(struct nvme_fc_local_port *pnvme_lport, /* Expand print to include key fields. */ lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_ABTS, - "6040 ENTER. lport %p, rport %p lsreq %p rqstlen:%d " + "6040 ENTER. lport x%px, rport x%px lsreq x%px rqstlen:%d " "rsplen:%d %pad %pad\n", pnvme_lport, pnvme_rport, pnvme_lsreq, pnvme_lsreq->rqstlen, @@ -985,8 +986,8 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, if (!lpfc_ncmd->nvmeCmd) { spin_unlock(&lpfc_ncmd->buf_lock); lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR, - "6066 Missing cmpl ptrs: lpfc_ncmd %p, " - "nvmeCmd %p\n", + "6066 Missing cmpl ptrs: lpfc_ncmd x%px, " + "nvmeCmd x%px\n", lpfc_ncmd, lpfc_ncmd->nvmeCmd); /* Release the lpfc_ncmd regardless of the missing elements. */ @@ -1101,8 +1102,8 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, if (lpfc_ncmd->result == IOERR_ABORT_REQUESTED) lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR, - "6032 Delay Aborted cmd %p " - "nvme cmd %p, xri x%x, " + "6032 Delay Aborted cmd x%px " + "nvme cmd x%px, xri x%x, " "xb %d\n", lpfc_ncmd, nCmd, lpfc_ncmd->cur_iocbq.sli4_xritag, @@ -1506,8 +1507,8 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, ndlp = rport->ndlp; if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE | LOG_NVME_IOERR, - "6053 Fail IO, ndlp not ready: rport %p " - "ndlp %p, DID x%06x\n", + "6053 Busy IO, ndlp not ready: rport x%px " + "ndlp x%px, DID x%06x\n", rport, ndlp, pnvme_rport->port_id); atomic_inc(&lport->xmt_fcp_err); ret = -EBUSY; @@ -1759,7 +1760,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, /* Announce entry to new IO submit field. */ lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_ABTS, "6002 Abort Request to rport DID x%06x " - "for nvme_fc_req %p\n", + "for nvme_fc_req x%px\n", pnvme_rport->port_id, pnvme_fcreq); @@ -1806,8 +1807,8 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, if (lpfc_nbuf->nvmeCmd != pnvme_fcreq) { lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_ABTS, "6143 NVME req mismatch: " - "lpfc_nbuf %p nvmeCmd %p, " - "pnvme_fcreq %p. Skipping Abort xri x%x\n", + "lpfc_nbuf x%px nvmeCmd x%px, " + "pnvme_fcreq x%px. Skipping Abort xri x%x\n", lpfc_nbuf, lpfc_nbuf->nvmeCmd, pnvme_fcreq, nvmereq_wqe->sli4_xritag); goto out_unlock; @@ -1816,7 +1817,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, /* Don't abort IOs no longer on the pending queue. */ if (!(nvmereq_wqe->iocb_flag & LPFC_IO_ON_TXCMPLQ)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_ABTS, - "6142 NVME IO req %p not queued - skipping " + "6142 NVME IO req x%px not queued - skipping " "abort req xri x%x\n", pnvme_fcreq, nvmereq_wqe->sli4_xritag); goto out_unlock; @@ -1831,8 +1832,8 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, if (nvmereq_wqe->iocb_flag & LPFC_DRIVER_ABORTED) { lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_ABTS, "6144 Outstanding NVME I/O Abort Request " - "still pending on nvme_fcreq %p, " - "lpfc_ncmd %p xri x%x\n", + "still pending on nvme_fcreq x%px, " + "lpfc_ncmd %px xri x%x\n", pnvme_fcreq, lpfc_nbuf, nvmereq_wqe->sli4_xritag); goto out_unlock; @@ -1842,7 +1843,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, if (!abts_buf) { lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_ABTS, "6136 No available abort wqes. Skipping " - "Abts req for nvme_fcreq %p xri x%x\n", + "Abts req for nvme_fcreq x%px xri x%x\n", pnvme_fcreq, nvmereq_wqe->sli4_xritag); goto out_unlock; } @@ -1893,7 +1894,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, 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", + "for nvme_fcreq x%px.\n", ret_val, pnvme_fcreq); lpfc_sli_release_iocbq(phba, abts_buf); return; @@ -2096,8 +2097,8 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport) if (!ret) { lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME | LOG_NVME_DISC, "6005 Successfully registered local " - "NVME port num %d, localP %p, private %p, " - "sg_seg %d\n", + "NVME port num %d, localP x%px, private " + "x%px, sg_seg %d\n", localport->port_num, localport, localport->private, lpfc_nvme_template.max_sgl_segments); @@ -2165,7 +2166,7 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport, pending += pring->txcmplq_cnt; } lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_IOERR, - "6176 Lport %p Localport %p wait " + "6176 Lport x%px Localport x%px wait " "timed out. Pending %d. Renewing.\n", lport, vport->localport, pending); continue; @@ -2173,7 +2174,7 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport, break; } lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR, - "6177 Lport %p Localport %p Complete Success\n", + "6177 Lport x%px Localport x%px Complete Success\n", lport, vport->localport); } #endif @@ -2204,7 +2205,7 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport) lport = (struct lpfc_nvme_lport *)localport->private; lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, - "6011 Destroying NVME localport %p\n", + "6011 Destroying NVME localport x%px\n", localport); /* lport's rport list is clear. Unregister @@ -2254,12 +2255,12 @@ lpfc_nvme_update_localport(struct lpfc_vport *vport) lport = (struct lpfc_nvme_lport *)localport->private; if (!lport) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_NVME, - "6171 Update NVME fail. localP %p, No lport\n", + "6171 Update NVME fail. localP x%px, No lport\n", localport); return; } lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, - "6012 Update NVME lport %p did x%x\n", + "6012 Update NVME lport x%px did x%x\n", localport, vport->fc_myDID); localport->port_id = vport->fc_myDID; @@ -2269,7 +2270,7 @@ lpfc_nvme_update_localport(struct lpfc_vport *vport) localport->port_role = FC_PORT_ROLE_NVME_INITIATOR; lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, - "6030 bound lport %p to DID x%06x\n", + "6030 bound lport x%px to DID x%06x\n", lport, localport->port_id); #endif } @@ -2350,8 +2351,9 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NVME_DISC, "6014 Rebind lport to current " - "remoteport %p wwpn 0x%llx, " - "Data: x%x x%x %p %p x%x x%06x\n", + "remoteport x%px wwpn 0x%llx, " + "Data: x%x x%x x%px x%px x%x " + " x%06x\n", remote_port, remote_port->port_name, remote_port->port_id, @@ -2406,7 +2408,7 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) "6022 Bind lport x%px to remoteport x%px " "rport x%px WWNN 0x%llx, " "Rport WWPN 0x%llx DID " - "x%06x Role x%x, ndlp %p prev_ndlp %p\n", + "x%06x Role x%x, ndlp %p prev_ndlp x%px\n", lport, remote_port, rport, rpinfo.node_name, rpinfo.port_name, rpinfo.port_id, rpinfo.port_role, @@ -2515,7 +2517,7 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) goto input_err; lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, - "6033 Unreg nvme remoteport %p, portname x%llx, " + "6033 Unreg nvme remoteport x%px, portname x%llx, " "port_id x%06x, portstate x%x port type x%x\n", remoteport, remoteport->port_name, remoteport->port_id, remoteport->port_state, @@ -2553,7 +2555,7 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) input_err: #endif lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC, - "6168 State error: lport %p, rport%p FCID x%06x\n", + "6168 State error: lport x%px, rport x%px FCID x%06x\n", vport->localport, ndlp->rport, ndlp->nlp_DID); } @@ -2597,7 +2599,7 @@ lpfc_sli4_nvme_xri_aborted(struct lpfc_hba *phba, lpfc_sli4_abts_err_handler(phba, ndlp, axri); lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, - "6311 nvme_cmd %p xri x%x tag x%x " + "6311 nvme_cmd x%px xri x%x tag x%x " "abort complete and xri released\n", lpfc_ncmd->nvmeCmd, xri, lpfc_ncmd->cur_iocbq.iotag); diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index f42cc3150c6f..253a9fdd245e 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -1437,7 +1437,7 @@ lpfc_nvmet_setup_io_context(struct lpfc_hba *phba) infop = lpfc_get_ctx_list(phba, i, j); lpfc_printf_log(phba, KERN_INFO, LOG_NVME | LOG_INIT, "6408 TOTAL NVMET ctx for CPU %d " - "MRQ %d: cnt %d nextcpu %p\n", + "MRQ %d: cnt %d nextcpu x%px\n", i, j, infop->nvmet_ctx_list_cnt, infop->nvmet_ctx_next_cpu); } @@ -1500,7 +1500,7 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba) lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC, "6026 Registered NVME " - "targetport: %p, private %p " + "targetport: x%px, private x%px " "portnm %llx nodenm %llx segs %d qs %d\n", phba->targetport, tgtp, pinfo.port_name, pinfo.node_name, @@ -1555,7 +1555,7 @@ lpfc_nvmet_update_targetport(struct lpfc_hba *phba) return 0; lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, - "6007 Update NVMET port %p did x%x\n", + "6007 Update NVMET port x%px did x%x\n", phba->targetport, vport->fc_myDID); phba->targetport->port_id = vport->fc_myDID; @@ -1926,7 +1926,7 @@ lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba) if (!wait_for_completion_timeout(tgtp->tport_unreg_cmp, msecs_to_jiffies(LPFC_NVMET_WAIT_TMO))) lpfc_printf_log(phba, KERN_ERR, LOG_NVME, - "6179 Unreg targetport %p timeout " + "6179 Unreg targetport x%px timeout " "reached.\n", phba->targetport); lpfc_nvmet_cleanup_io_context(phba); } @@ -3109,7 +3109,7 @@ lpfc_nvmet_xmt_ls_abort_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, atomic_inc(&tgtp->xmt_ls_abort_cmpl); lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, - "6083 Abort cmpl: ctx %p WCQE:%08x %08x %08x %08x\n", + "6083 Abort cmpl: ctx x%px WCQE:%08x %08x %08x %08x\n", ctxp, wcqe->word0, wcqe->total_data_placed, result, wcqe->word3); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 8ae24500806e..95ba5000d0ec 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -1775,7 +1775,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, if (!sgpe || !sgde) { lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "9020 Invalid s/g entry: data=0x%p prot=0x%p\n", + "9020 Invalid s/g entry: data=x%px prot=x%px\n", sgpe, sgde); return 0; } @@ -2154,7 +2154,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, if (!sgpe || !sgde) { lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "9082 Invalid s/g entry: data=0x%p prot=0x%p\n", + "9082 Invalid s/g entry: data=x%px prot=x%px\n", sgpe, sgde); return 0; } @@ -3873,7 +3873,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, uint32_t *lp = (uint32_t *)cmd->sense_buffer; lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, - "0710 Iodone <%d/%llu> cmd %p, error " + "0710 Iodone <%d/%llu> cmd x%px, error " "x%x SNS x%x x%x Data: x%x x%x\n", cmd->device->id, cmd->device->lun, cmd, cmd->result, *lp, *(lp + 3), cmd->retries, @@ -4997,7 +4997,7 @@ lpfc_chk_tgt_mapped(struct lpfc_vport *vport, struct scsi_cmnd *cmnd) rdata = lpfc_rport_data_from_scsi_device(cmnd->device); if (!rdata) { lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, - "0797 Tgt Map rport failure: rdata x%p\n", rdata); + "0797 Tgt Map rport failure: rdata x%px\n", rdata); return FAILED; } pnode = rdata->pnode; @@ -5095,7 +5095,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) rdata = lpfc_rport_data_from_scsi_device(cmnd->device); if (!rdata || !rdata->pnode) { lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, - "0798 Device Reset rdata failure: rdata x%p\n", + "0798 Device Reset rdata failure: rdata x%px\n", rdata); return FAILED; } @@ -5107,7 +5107,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) status = lpfc_chk_tgt_mapped(vport, cmnd); if (status == FAILED) { lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, - "0721 Device Reset rport failure: rdata x%p\n", rdata); + "0721 Device Reset rport failure: rdata x%px\n", rdata); return FAILED; } @@ -5166,7 +5166,7 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) rdata = lpfc_rport_data_from_scsi_device(cmnd->device); if (!rdata || !rdata->pnode) { lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, - "0799 Target Reset rdata failure: rdata x%p\n", + "0799 Target Reset rdata failure: rdata x%px\n", rdata); return FAILED; } @@ -5178,7 +5178,7 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) status = lpfc_chk_tgt_mapped(vport, cmnd); if (status == FAILED) { lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, - "0722 Target Reset rport failure: rdata x%p\n", rdata); + "0722 Target Reset rport failure: rdata x%px\n", rdata); if (pnode) { spin_lock_irq(shost->host_lock); pnode->nlp_flag &= ~NLP_NPR_ADISC; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index a21fe4612a4e..03404dbd6ddf 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -2514,7 +2514,7 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) vport, KERN_INFO, LOG_MBOX | LOG_DISCOVERY, "1438 UNREG cmpl deferred mbox x%x " - "on NPort x%x Data: x%x x%x %p\n", + "on NPort x%x Data: x%x x%x %px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_defer_did, ndlp); @@ -2572,7 +2572,7 @@ lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) vport, KERN_INFO, LOG_MBOX | LOG_SLI, "0010 UNREG_LOGIN vpi:%x " "rpi:%x DID:%x defer x%x flg x%x " - "map:%x %p\n", + "map:%x %px\n", vport->vpi, ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_defer_did, ndlp->nlp_flag, @@ -2590,7 +2590,7 @@ lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) vport, KERN_INFO, LOG_DISCOVERY, "4111 UNREG cmpl deferred " "clr x%x on " - "NPort x%x Data: x%x %p\n", + "NPort x%x Data: x%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_defer_did, ndlp); ndlp->nlp_flag &= ~NLP_UNREG_INP; @@ -2712,7 +2712,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) /* Mailbox cmd Cmpl */ lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, - "(%d):0307 Mailbox cmd x%x (x%x/x%x) Cmpl x%p " + "(%d):0307 Mailbox cmd x%x (x%x/x%x) Cmpl %pf " "Data: x%x x%x x%x x%x x%x x%x x%x x%x x%x " "x%x x%x x%x\n", pmb->vport ? pmb->vport->vpi : 0, @@ -7991,7 +7991,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) /* Mbox cmd timeout */ lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, - "0310 Mailbox command x%x timeout Data: x%x x%x x%p\n", + "0310 Mailbox command x%x timeout Data: x%x x%x x%px\n", mb->mbxCommand, phba->pport->port_state, phba->sli.sli_flag, @@ -10998,7 +10998,7 @@ lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, spin_unlock_irq(&phba->hbalock); lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0402 Cannot find virtual addr for buffer tag on " - "ring %d Data x%lx x%p x%p x%x\n", + "ring %d Data x%lx x%px x%px x%x\n", pring->ringno, (unsigned long) tag, slp->next, slp->prev, pring->postbufq_cnt); @@ -11042,7 +11042,7 @@ lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, spin_unlock_irq(&phba->hbalock); lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0410 Cannot find virtual addr for mapped buf on " - "ring %d Data x%llx x%p x%p x%x\n", + "ring %d Data x%llx x%px x%px x%x\n", pring->ringno, (unsigned long long)phys, slp->next, slp->prev, pring->postbufq_cnt); return NULL; @@ -11097,7 +11097,7 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, abort_iocb = phba->sli.iocbq_lookup[abort_context]; lpfc_printf_log(phba, KERN_WARNING, LOG_ELS | LOG_SLI, - "0327 Cannot abort els iocb %p " + "0327 Cannot abort els iocb x%px " "with tag %x context %x, abort status %x, " "abort code %x\n", abort_iocb, abort_iotag, abort_context, -- cgit v1.2.3-59-g8ed1b From d79c9e9d4b3d9330ee38f392a7c98e0fc494f7f8 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:57:09 -0700 Subject: scsi: lpfc: Support dynamic unbounded SGL lists on G7 hardware. Typical SLI-4 hardware supports up to 2 4KB pages to be registered per XRI to contain the exchanges Scatter/Gather List. This caps the number of SGL elements that can be in the SGL. There are not extensions to extend the list out of the 2 pages. The G7 hardware adds a SGE type that allows the SGL to be vectored to a different scatter/gather list segment. And that segment can contain a SGE to go to another segment and so on. The initial segment must still be pre-registered for the XRI, but it can be a much smaller amount (256Bytes) as it can now be dynamically grown. This much smaller allocation can handle the SG list for most normal I/O, and the dynamic aspect allows it to support many MB's if needed. The implementation creates a pool which contains "segments" and which is initially sized to hold the initial small segment per xri. If an I/O requires additional segments, they are allocated from the pool. If the pool has no more segments, the pool is grown based on what is now needed. After the I/O completes, the additional segments are returned to the pool for use by other I/Os. Once allocated, the additional segments are not released under the assumption of "if needed once, it will be needed again". Pools are kept on a per-hardware queue basis, which is typically 1:1 per cpu, but may be shared by multiple cpus. The switch to the smaller initial allocation significantly reduces the memory footprint of the driver (which only grows if large ios are issued). Based on the several K of XRIs for the adapter, the 8KB->256B reduction can conserve 32MBs or more. It has been observed with per-cpu resource pools that allocating a resource on CPU A, may be put back on CPU B. While the get routines are distributed evenly, only a limited subset of CPUs may be handling the put routines. This can put a strain on the lpfc_put_cmd_rsp_buf_per_cpu routine because all the resources are being put on a limited subset of CPUs. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc.h | 5 + drivers/scsi/lpfc/lpfc_hw4.h | 20 +++ drivers/scsi/lpfc/lpfc_init.c | 313 +++++++++++++++++++++++-------------- drivers/scsi/lpfc/lpfc_mem.c | 44 ++---- drivers/scsi/lpfc/lpfc_nvme.c | 94 ++++++++--- drivers/scsi/lpfc/lpfc_scsi.c | 355 ++++++++++++++++++++++++++++++++---------- drivers/scsi/lpfc/lpfc_sli.c | 292 ++++++++++++++++++++++++++++++++++ drivers/scsi/lpfc/lpfc_sli.h | 11 +- drivers/scsi/lpfc/lpfc_sli4.h | 18 +++ 9 files changed, 904 insertions(+), 248 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 2c3bb8a966e5..b738639fdf3f 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -51,6 +51,8 @@ struct lpfc_sli2_slim; cmnd for menlo needs nearly twice as for firmware downloads using bsg */ +#define LPFC_DEFAULT_XPSGL_SIZE 256 +#define LPFC_MAX_SG_TABLESIZE 0xffff #define LPFC_MIN_SG_SLI4_BUF_SZ 0x800 /* based on LPFC_DEFAULT_SG_SEG_CNT */ #define LPFC_MAX_BG_SLI4_SEG_CNT_DIF 128 /* sg element count for BlockGuard */ #define LPFC_MAX_SG_SEG_CNT_DIF 512 /* sg element count per scsi cmnd */ @@ -799,6 +801,7 @@ struct lpfc_hba { /* HBA Config Parameters */ uint32_t cfg_ack0; uint32_t cfg_xri_rebalancing; + uint32_t cfg_xpsgl; uint32_t cfg_enable_npiv; uint32_t cfg_enable_rrq; uint32_t cfg_topology; @@ -904,6 +907,7 @@ struct lpfc_hba { wait_queue_head_t work_waitq; struct task_struct *worker_thread; unsigned long data_flags; + uint32_t border_sge_num; uint32_t hbq_in_use; /* HBQs in use flag */ uint32_t hbq_count; /* Count of configured HBQs */ @@ -986,6 +990,7 @@ struct lpfc_hba { struct dma_pool *lpfc_nvmet_drb_pool; /* data receive buffer pool */ struct dma_pool *lpfc_hbq_pool; /* SLI3 hbq buffer pool */ struct dma_pool *txrdy_payload_pool; + struct dma_pool *lpfc_cmd_rsp_buf_pool; struct lpfc_dma_pool lpfc_mbuf_safety_pool; mempool_t *mbox_mem_pool; diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index d89480b9eade..e198de8eda32 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -2050,6 +2050,23 @@ struct sli4_sge { /* SLI-4 */ uint32_t sge_len; }; +struct sli4_hybrid_sgl { + struct list_head list_node; + struct sli4_sge *dma_sgl; + dma_addr_t dma_phys_sgl; +}; + +struct fcp_cmd_rsp_buf { + struct list_head list_node; + + /* for storing cmd/rsp dma alloc'ed virt_addr */ + struct fcp_cmnd *fcp_cmnd; + struct fcp_rsp *fcp_rsp; + + /* for storing this cmd/rsp's dma mapped phys addr from per CPU pool */ + dma_addr_t fcp_cmd_rsp_dma_handle; +}; + struct sli4_sge_diseed { /* SLI-4 */ uint32_t ref_tag; uint32_t ref_tag_tran; @@ -3449,6 +3466,9 @@ struct lpfc_sli4_parameters { #define cfg_xib_SHIFT 4 #define cfg_xib_MASK 0x00000001 #define cfg_xib_WORD word19 +#define cfg_xpsgl_SHIFT 6 +#define cfg_xpsgl_MASK 0x00000001 +#define cfg_xpsgl_WORD word19 #define cfg_eqdr_SHIFT 8 #define cfg_eqdr_MASK 0x00000001 #define cfg_eqdr_WORD word19 diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 6b39bfb73104..fa3741f12089 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3650,6 +3650,9 @@ lpfc_io_free(struct lpfc_hba *phba) qp->put_io_bufs--; dma_pool_free(phba->lpfc_sg_dma_buf_pool, lpfc_ncmd->data, lpfc_ncmd->dma_handle); + if (phba->cfg_xpsgl && !phba->nvmet_support) + lpfc_put_sgl_per_hdwq(phba, lpfc_ncmd); + lpfc_put_cmd_rsp_buf_per_hdwq(phba, lpfc_ncmd); kfree(lpfc_ncmd); qp->total_io_bufs--; } @@ -3663,6 +3666,9 @@ lpfc_io_free(struct lpfc_hba *phba) qp->get_io_bufs--; dma_pool_free(phba->lpfc_sg_dma_buf_pool, lpfc_ncmd->data, lpfc_ncmd->dma_handle); + if (phba->cfg_xpsgl && !phba->nvmet_support) + lpfc_put_sgl_per_hdwq(phba, lpfc_ncmd); + lpfc_put_cmd_rsp_buf_per_hdwq(phba, lpfc_ncmd); kfree(lpfc_ncmd); qp->total_io_bufs--; } @@ -4138,22 +4144,30 @@ lpfc_new_io_buf(struct lpfc_hba *phba, int num_to_alloc) break; } - /* - * 4K Page alignment is CRITICAL to BlockGuard, double check - * to be sure. - */ - if ((phba->sli3_options & LPFC_SLI3_BG_ENABLED) && - (((unsigned long)(lpfc_ncmd->data) & - (unsigned long)(SLI4_PAGE_SIZE - 1)) != 0)) { - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "3369 Memory alignment err: addr=%lx\n", - (unsigned long)lpfc_ncmd->data); - dma_pool_free(phba->lpfc_sg_dma_buf_pool, - lpfc_ncmd->data, lpfc_ncmd->dma_handle); - kfree(lpfc_ncmd); - break; + if (phba->cfg_xpsgl && !phba->nvmet_support) { + INIT_LIST_HEAD(&lpfc_ncmd->dma_sgl_xtra_list); + } else { + /* + * 4K Page alignment is CRITICAL to BlockGuard, double + * check to be sure. + */ + if ((phba->sli3_options & LPFC_SLI3_BG_ENABLED) && + (((unsigned long)(lpfc_ncmd->data) & + (unsigned long)(SLI4_PAGE_SIZE - 1)) != 0)) { + lpfc_printf_log(phba, KERN_ERR, LOG_FCP, + "3369 Memory alignment err: " + "addr=%lx\n", + (unsigned long)lpfc_ncmd->data); + dma_pool_free(phba->lpfc_sg_dma_buf_pool, + lpfc_ncmd->data, + lpfc_ncmd->dma_handle); + kfree(lpfc_ncmd); + break; + } } + INIT_LIST_HEAD(&lpfc_ncmd->dma_cmd_rsp_list); + lxri = lpfc_sli4_next_xritag(phba); if (lxri == NO_XRI) { dma_pool_free(phba->lpfc_sg_dma_buf_pool, @@ -4330,7 +4344,11 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) shost->dma_boundary = phba->sli4_hba.pc_sli4_params.sge_supp_len-1; - shost->sg_tablesize = phba->cfg_scsi_seg_cnt; + + if (phba->cfg_xpsgl && !phba->nvmet_support) + shost->sg_tablesize = LPFC_MAX_SG_TABLESIZE; + else + shost->sg_tablesize = phba->cfg_scsi_seg_cnt; } else /* SLI-3 has a limited number of hardware queues (3), * thus there is only one for FCP processing. @@ -6348,6 +6366,24 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) if (lpfc_mem_alloc(phba, BPL_ALIGN_SZ)) return -ENOMEM; + phba->lpfc_sg_dma_buf_pool = + dma_pool_create("lpfc_sg_dma_buf_pool", + &phba->pcidev->dev, phba->cfg_sg_dma_buf_size, + BPL_ALIGN_SZ, 0); + + if (!phba->lpfc_sg_dma_buf_pool) + goto fail_free_mem; + + phba->lpfc_cmd_rsp_buf_pool = + dma_pool_create("lpfc_cmd_rsp_buf_pool", + &phba->pcidev->dev, + sizeof(struct fcp_cmnd) + + sizeof(struct fcp_rsp), + BPL_ALIGN_SZ, 0); + + if (!phba->lpfc_cmd_rsp_buf_pool) + goto fail_free_dma_buf_pool; + /* * Enable sr-iov virtual functions if supported and configured * through the module parameter. @@ -6366,6 +6402,13 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) } return 0; + +fail_free_dma_buf_pool: + dma_pool_destroy(phba->lpfc_sg_dma_buf_pool); + phba->lpfc_sg_dma_buf_pool = NULL; +fail_free_mem: + lpfc_mem_free(phba); + return -ENOMEM; } /** @@ -6465,102 +6508,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) * The WQ create will allocate the ring. */ - /* - * 1 for cmd, 1 for rsp, NVME adds an extra one - * for boundary conditions in its max_sgl_segment template. - */ - extra = 2; - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) - extra++; - - /* - * It doesn't matter what family our adapter is in, we are - * limited to 2 Pages, 512 SGEs, for our SGL. - * There are going to be 2 reserved SGEs: 1 FCP cmnd + 1 FCP rsp - */ - max_buf_size = (2 * SLI4_PAGE_SIZE); - - /* - * Since lpfc_sg_seg_cnt is module param, the sg_dma_buf_size - * used to create the sg_dma_buf_pool must be calculated. - */ - if (phba->sli3_options & LPFC_SLI3_BG_ENABLED) { - /* - * The scsi_buf for a T10-DIF I/O holds the FCP cmnd, - * the FCP rsp, and a SGE. Sice we have no control - * over how many protection segments the SCSI Layer - * will hand us (ie: there could be one for every block - * in the IO), just allocate enough SGEs to accomidate - * our max amount and we need to limit lpfc_sg_seg_cnt - * to minimize the risk of running out. - */ - phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + - sizeof(struct fcp_rsp) + max_buf_size; - - /* Total SGEs for scsi_sg_list and scsi_sg_prot_list */ - phba->cfg_total_seg_cnt = LPFC_MAX_SGL_SEG_CNT; - - /* - * If supporting DIF, reduce the seg count for scsi to - * allow room for the DIF sges. - */ - if (phba->cfg_enable_bg && - phba->cfg_sg_seg_cnt > LPFC_MAX_BG_SLI4_SEG_CNT_DIF) - phba->cfg_scsi_seg_cnt = LPFC_MAX_BG_SLI4_SEG_CNT_DIF; - else - phba->cfg_scsi_seg_cnt = phba->cfg_sg_seg_cnt; - - } else { - /* - * The scsi_buf for a regular I/O holds the FCP cmnd, - * the FCP rsp, a SGE for each, and a SGE for up to - * cfg_sg_seg_cnt data segments. - */ - phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + - sizeof(struct fcp_rsp) + - ((phba->cfg_sg_seg_cnt + extra) * - sizeof(struct sli4_sge)); - - /* Total SGEs for scsi_sg_list */ - phba->cfg_total_seg_cnt = phba->cfg_sg_seg_cnt + extra; - phba->cfg_scsi_seg_cnt = phba->cfg_sg_seg_cnt; - - /* - * NOTE: if (phba->cfg_sg_seg_cnt + extra) <= 256 we only - * need to post 1 page for the SGL. - */ - } - - /* Limit to LPFC_MAX_NVME_SEG_CNT for NVME. */ - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { - if (phba->cfg_sg_seg_cnt > LPFC_MAX_NVME_SEG_CNT) { - lpfc_printf_log(phba, KERN_INFO, LOG_NVME | LOG_INIT, - "6300 Reducing NVME sg segment " - "cnt to %d\n", - LPFC_MAX_NVME_SEG_CNT); - phba->cfg_nvme_seg_cnt = LPFC_MAX_NVME_SEG_CNT; - } else - phba->cfg_nvme_seg_cnt = phba->cfg_sg_seg_cnt; - } - - /* Initialize the host templates with the updated values. */ - lpfc_vport_template.sg_tablesize = phba->cfg_scsi_seg_cnt; - lpfc_template.sg_tablesize = phba->cfg_scsi_seg_cnt; - lpfc_template_no_hr.sg_tablesize = phba->cfg_scsi_seg_cnt; - - if (phba->cfg_sg_dma_buf_size <= LPFC_MIN_SG_SLI4_BUF_SZ) - phba->cfg_sg_dma_buf_size = LPFC_MIN_SG_SLI4_BUF_SZ; - else - phba->cfg_sg_dma_buf_size = - SLI4_PAGE_ALIGN(phba->cfg_sg_dma_buf_size); - - lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_FCP, - "9087 sg_seg_cnt:%d dmabuf_size:%d " - "total:%d scsi:%d nvme:%d\n", - phba->cfg_sg_seg_cnt, phba->cfg_sg_dma_buf_size, - phba->cfg_total_seg_cnt, phba->cfg_scsi_seg_cnt, - phba->cfg_nvme_seg_cnt); - /* Initialize buffer queue management fields */ INIT_LIST_HEAD(&phba->hbqs[LPFC_ELS_HBQ].hbq_buffer_list); phba->hbqs[LPFC_ELS_HBQ].hbq_alloc_buffer = lpfc_sli4_rb_alloc; @@ -6781,6 +6728,131 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) } } + /* + * 1 for cmd, 1 for rsp, NVME adds an extra one + * for boundary conditions in its max_sgl_segment template. + */ + extra = 2; + if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) + extra++; + + /* + * It doesn't matter what family our adapter is in, we are + * limited to 2 Pages, 512 SGEs, for our SGL. + * There are going to be 2 reserved SGEs: 1 FCP cmnd + 1 FCP rsp + */ + max_buf_size = (2 * SLI4_PAGE_SIZE); + + /* + * Since lpfc_sg_seg_cnt is module param, the sg_dma_buf_size + * used to create the sg_dma_buf_pool must be calculated. + */ + if (phba->sli3_options & LPFC_SLI3_BG_ENABLED) { + /* Both cfg_enable_bg and cfg_external_dif code paths */ + + /* + * The scsi_buf for a T10-DIF I/O holds the FCP cmnd, + * the FCP rsp, and a SGE. Sice we have no control + * over how many protection segments the SCSI Layer + * will hand us (ie: there could be one for every block + * in the IO), just allocate enough SGEs to accomidate + * our max amount and we need to limit lpfc_sg_seg_cnt + * to minimize the risk of running out. + */ + phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + + sizeof(struct fcp_rsp) + max_buf_size; + + /* Total SGEs for scsi_sg_list and scsi_sg_prot_list */ + phba->cfg_total_seg_cnt = LPFC_MAX_SGL_SEG_CNT; + + /* + * If supporting DIF, reduce the seg count for scsi to + * allow room for the DIF sges. + */ + if (phba->cfg_enable_bg && + phba->cfg_sg_seg_cnt > LPFC_MAX_BG_SLI4_SEG_CNT_DIF) + phba->cfg_scsi_seg_cnt = LPFC_MAX_BG_SLI4_SEG_CNT_DIF; + else + phba->cfg_scsi_seg_cnt = phba->cfg_sg_seg_cnt; + + } else { + /* + * The scsi_buf for a regular I/O holds the FCP cmnd, + * the FCP rsp, a SGE for each, and a SGE for up to + * cfg_sg_seg_cnt data segments. + */ + phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + + sizeof(struct fcp_rsp) + + ((phba->cfg_sg_seg_cnt + extra) * + sizeof(struct sli4_sge)); + + /* Total SGEs for scsi_sg_list */ + phba->cfg_total_seg_cnt = phba->cfg_sg_seg_cnt + extra; + phba->cfg_scsi_seg_cnt = phba->cfg_sg_seg_cnt; + + /* + * NOTE: if (phba->cfg_sg_seg_cnt + extra) <= 256 we only + * need to post 1 page for the SGL. + */ + } + + if (phba->cfg_xpsgl && !phba->nvmet_support) + phba->cfg_sg_dma_buf_size = LPFC_DEFAULT_XPSGL_SIZE; + else if (phba->cfg_sg_dma_buf_size <= LPFC_MIN_SG_SLI4_BUF_SZ) + phba->cfg_sg_dma_buf_size = LPFC_MIN_SG_SLI4_BUF_SZ; + else + phba->cfg_sg_dma_buf_size = + SLI4_PAGE_ALIGN(phba->cfg_sg_dma_buf_size); + + phba->border_sge_num = phba->cfg_sg_dma_buf_size / + sizeof(struct sli4_sge); + + /* Limit to LPFC_MAX_NVME_SEG_CNT for NVME. */ + if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { + if (phba->cfg_sg_seg_cnt > LPFC_MAX_NVME_SEG_CNT) { + lpfc_printf_log(phba, KERN_INFO, LOG_NVME | LOG_INIT, + "6300 Reducing NVME sg segment " + "cnt to %d\n", + LPFC_MAX_NVME_SEG_CNT); + phba->cfg_nvme_seg_cnt = LPFC_MAX_NVME_SEG_CNT; + } else + phba->cfg_nvme_seg_cnt = phba->cfg_sg_seg_cnt; + } + + /* Initialize the host templates with the updated values. */ + lpfc_vport_template.sg_tablesize = phba->cfg_scsi_seg_cnt; + lpfc_template.sg_tablesize = phba->cfg_scsi_seg_cnt; + lpfc_template_no_hr.sg_tablesize = phba->cfg_scsi_seg_cnt; + + lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_FCP, + "9087 sg_seg_cnt:%d dmabuf_size:%d " + "total:%d scsi:%d nvme:%d\n", + phba->cfg_sg_seg_cnt, phba->cfg_sg_dma_buf_size, + phba->cfg_total_seg_cnt, phba->cfg_scsi_seg_cnt, + phba->cfg_nvme_seg_cnt); + + if (phba->cfg_sg_dma_buf_size < SLI4_PAGE_SIZE) + i = phba->cfg_sg_dma_buf_size; + else + i = SLI4_PAGE_SIZE; + + phba->lpfc_sg_dma_buf_pool = + dma_pool_create("lpfc_sg_dma_buf_pool", + &phba->pcidev->dev, + phba->cfg_sg_dma_buf_size, + i, 0); + if (!phba->lpfc_sg_dma_buf_pool) + goto out_free_bsmbx; + + phba->lpfc_cmd_rsp_buf_pool = + dma_pool_create("lpfc_cmd_rsp_buf_pool", + &phba->pcidev->dev, + sizeof(struct fcp_cmnd) + + sizeof(struct fcp_rsp), + i, 0); + if (!phba->lpfc_cmd_rsp_buf_pool) + goto out_free_sg_dma_buf; + mempool_free(mboxq, phba->mbox_mem_pool); /* Verify OAS is supported */ @@ -6792,12 +6864,12 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) /* Verify all the SLI4 queues */ rc = lpfc_sli4_queue_verify(phba); if (rc) - goto out_free_bsmbx; + goto out_free_cmd_rsp_buf; /* Create driver internal CQE event pool */ rc = lpfc_sli4_cq_event_pool_create(phba); if (rc) - goto out_free_bsmbx; + goto out_free_cmd_rsp_buf; /* Initialize sgl lists per host */ lpfc_init_sgl_list(phba); @@ -6888,6 +6960,12 @@ out_free_active_sgl: lpfc_free_active_sgl(phba); out_destroy_cq_event_pool: lpfc_sli4_cq_event_pool_destroy(phba); +out_free_cmd_rsp_buf: + dma_pool_destroy(phba->lpfc_cmd_rsp_buf_pool); + phba->lpfc_cmd_rsp_buf_pool = NULL; +out_free_sg_dma_buf: + dma_pool_destroy(phba->lpfc_sg_dma_buf_pool); + phba->lpfc_sg_dma_buf_pool = NULL; out_free_bsmbx: lpfc_destroy_bootstrap_mbox(phba); out_free_mem: @@ -8814,6 +8892,9 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) spin_lock_init(&qp->abts_nvme_buf_list_lock); INIT_LIST_HEAD(&qp->lpfc_abts_nvme_buf_list); qp->abts_nvme_io_bufs = 0; + INIT_LIST_HEAD(&qp->sgl_list); + INIT_LIST_HEAD(&qp->cmd_rsp_buf_list); + spin_lock_init(&qp->hdwq_lock); } } @@ -9188,6 +9269,9 @@ lpfc_sli4_release_hdwq(struct lpfc_hba *phba) hdwq[idx].nvme_cq = NULL; hdwq[idx].fcp_wq = NULL; hdwq[idx].nvme_wq = NULL; + if (phba->cfg_xpsgl && !phba->nvmet_support) + lpfc_free_sgl_per_hdwq(phba, &hdwq[idx]); + lpfc_free_cmd_rsp_buf_per_hdwq(phba, &hdwq[idx]); } /* Loop thru all IRQ vectors */ for (idx = 0; idx < phba->cfg_irq_chann; idx++) { @@ -11647,6 +11731,9 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) phba->sli4_hba.extents_in_use = bf_get(cfg_ext, mbx_sli4_parameters); phba->sli4_hba.rpi_hdrs_in_use = bf_get(cfg_hdrr, mbx_sli4_parameters); + /* Check for Extended Pre-Registered SGL support */ + phba->cfg_xpsgl = bf_get(cfg_xpsgl, mbx_sli4_parameters); + /* Check for firmware nvme support */ rc = (bf_get(cfg_nvme, mbx_sli4_parameters) && bf_get(cfg_xib, mbx_sli4_parameters)); diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 9bdb4a0a9f24..ae09bb863497 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -72,8 +72,8 @@ lpfc_mem_alloc_active_rrq_pool_s4(struct lpfc_hba *phba) { * lpfc_mem_alloc - create and allocate all PCI and memory pools * @phba: HBA to allocate pools for * - * Description: Creates and allocates PCI pools lpfc_sg_dma_buf_pool, - * lpfc_mbuf_pool, lpfc_hrb_pool. Creates and allocates kmalloc-backed mempools + * Description: Creates and allocates PCI pools lpfc_mbuf_pool, + * lpfc_hrb_pool. Creates and allocates kmalloc-backed mempools * for LPFC_MBOXQ_t and lpfc_nodelist. Also allocates the VPI bitmask. * * Notes: Not interrupt-safe. Must be called with no locks held. If any @@ -89,36 +89,12 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align) struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; int i; - if (phba->sli_rev == LPFC_SLI_REV4) { - /* Calculate alignment */ - if (phba->cfg_sg_dma_buf_size < SLI4_PAGE_SIZE) - i = phba->cfg_sg_dma_buf_size; - else - i = SLI4_PAGE_SIZE; - - phba->lpfc_sg_dma_buf_pool = - dma_pool_create("lpfc_sg_dma_buf_pool", - &phba->pcidev->dev, - phba->cfg_sg_dma_buf_size, - i, 0); - if (!phba->lpfc_sg_dma_buf_pool) - goto fail; - - } else { - phba->lpfc_sg_dma_buf_pool = - dma_pool_create("lpfc_sg_dma_buf_pool", - &phba->pcidev->dev, phba->cfg_sg_dma_buf_size, - align, 0); - - if (!phba->lpfc_sg_dma_buf_pool) - goto fail; - } phba->lpfc_mbuf_pool = dma_pool_create("lpfc_mbuf_pool", &phba->pcidev->dev, LPFC_BPL_SIZE, align, 0); if (!phba->lpfc_mbuf_pool) - goto fail_free_dma_buf_pool; + goto fail; pool->elements = kmalloc_array(LPFC_MBUF_POOL_SIZE, sizeof(struct lpfc_dmabuf), @@ -208,9 +184,6 @@ fail_free_drb_pool: fail_free_lpfc_mbuf_pool: dma_pool_destroy(phba->lpfc_mbuf_pool); phba->lpfc_mbuf_pool = NULL; - fail_free_dma_buf_pool: - dma_pool_destroy(phba->lpfc_sg_dma_buf_pool); - phba->lpfc_sg_dma_buf_pool = NULL; fail: return -ENOMEM; } @@ -287,10 +260,6 @@ lpfc_mem_free(struct lpfc_hba *phba) dma_pool_destroy(phba->lpfc_mbuf_pool); phba->lpfc_mbuf_pool = NULL; - /* Free DMA buffer memory pool */ - dma_pool_destroy(phba->lpfc_sg_dma_buf_pool); - phba->lpfc_sg_dma_buf_pool = NULL; - /* Free Device Data memory pool */ if (phba->device_data_mem_pool) { /* Ensure all objects have been returned to the pool */ @@ -363,6 +332,13 @@ lpfc_mem_free_all(struct lpfc_hba *phba) /* Free and destroy all the allocated memory pools */ lpfc_mem_free(phba); + /* Free DMA buffer memory pool */ + dma_pool_destroy(phba->lpfc_sg_dma_buf_pool); + phba->lpfc_sg_dma_buf_pool = NULL; + + dma_pool_destroy(phba->lpfc_cmd_rsp_buf_pool); + phba->lpfc_cmd_rsp_buf_pool = NULL; + /* Free the iocb lookup array */ kfree(psli->iocbq_lookup); psli->iocbq_lookup = NULL; diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index b599ddc40c6b..5e48318eb7a9 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1306,14 +1306,16 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport, struct nvmefc_fcp_req *nCmd = lpfc_ncmd->nvmeCmd; union lpfc_wqe128 *wqe = &lpfc_ncmd->cur_iocbq.wqe; struct sli4_sge *sgl = lpfc_ncmd->dma_sgl; + struct sli4_hybrid_sgl *sgl_xtra = NULL; struct scatterlist *data_sg; struct sli4_sge *first_data_sgl; struct ulp_bde64 *bde; - dma_addr_t physaddr; + dma_addr_t physaddr = 0; uint32_t num_bde = 0; - uint32_t dma_len; + uint32_t dma_len = 0; uint32_t dma_offset = 0; - int nseg, i; + int nseg, i, j; + bool lsp_just_set = false; /* Fix up the command and response DMA stuff. */ lpfc_nvme_adj_fcp_sgls(vport, lpfc_ncmd, nCmd); @@ -1350,6 +1352,9 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport, */ nseg = nCmd->sg_cnt; data_sg = nCmd->first_sgl; + + /* for tracking the segment boundaries */ + j = 2; for (i = 0; i < nseg; i++) { if (data_sg == NULL) { lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, @@ -1358,23 +1363,76 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport, lpfc_ncmd->seg_cnt = 0; return 1; } - physaddr = data_sg->dma_address; - dma_len = data_sg->length; - sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr)); - sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr)); - sgl->word2 = le32_to_cpu(sgl->word2); - if ((num_bde + 1) == nseg) + + sgl->word2 = 0; + if ((num_bde + 1) == nseg) { bf_set(lpfc_sli4_sge_last, sgl, 1); - else + bf_set(lpfc_sli4_sge_type, sgl, + LPFC_SGE_TYPE_DATA); + } else { bf_set(lpfc_sli4_sge_last, sgl, 0); - bf_set(lpfc_sli4_sge_offset, sgl, dma_offset); - bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA); - sgl->word2 = cpu_to_le32(sgl->word2); - sgl->sge_len = cpu_to_le32(dma_len); - - dma_offset += dma_len; - data_sg = sg_next(data_sg); - sgl++; + + /* expand the segment */ + if (!lsp_just_set && + !((j + 1) % phba->border_sge_num) && + ((nseg - 1) != i)) { + /* set LSP type */ + bf_set(lpfc_sli4_sge_type, sgl, + LPFC_SGE_TYPE_LSP); + + sgl_xtra = lpfc_get_sgl_per_hdwq( + phba, lpfc_ncmd); + + if (unlikely(!sgl_xtra)) { + lpfc_ncmd->seg_cnt = 0; + return 1; + } + sgl->addr_lo = cpu_to_le32(putPaddrLow( + sgl_xtra->dma_phys_sgl)); + sgl->addr_hi = cpu_to_le32(putPaddrHigh( + sgl_xtra->dma_phys_sgl)); + + } else { + bf_set(lpfc_sli4_sge_type, sgl, + LPFC_SGE_TYPE_DATA); + } + } + + if (!(bf_get(lpfc_sli4_sge_type, sgl) & + LPFC_SGE_TYPE_LSP)) { + if ((nseg - 1) == i) + bf_set(lpfc_sli4_sge_last, sgl, 1); + + physaddr = data_sg->dma_address; + dma_len = data_sg->length; + sgl->addr_lo = cpu_to_le32( + putPaddrLow(physaddr)); + sgl->addr_hi = cpu_to_le32( + putPaddrHigh(physaddr)); + + bf_set(lpfc_sli4_sge_offset, sgl, dma_offset); + sgl->word2 = cpu_to_le32(sgl->word2); + sgl->sge_len = cpu_to_le32(dma_len); + + dma_offset += dma_len; + data_sg = sg_next(data_sg); + + sgl++; + + lsp_just_set = false; + } else { + sgl->word2 = cpu_to_le32(sgl->word2); + + sgl->sge_len = cpu_to_le32( + phba->cfg_sg_dma_buf_size); + + sgl = (struct sli4_sge *)sgl_xtra->dma_sgl; + i = i - 1; + + lsp_just_set = true; + } + + j++; } if (phba->cfg_enable_pbde) { /* Use PBDE support for first SGL only, offset == 0 */ diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 95ba5000d0ec..fb7df209c0aa 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -685,8 +685,9 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, IOCB_t *iocb; dma_addr_t pdma_phys_fcp_rsp; dma_addr_t pdma_phys_fcp_cmd; - uint32_t sgl_size, cpu, idx; + uint32_t cpu, idx; int tag; + struct fcp_cmd_rsp_buf *tmp = NULL; cpu = raw_smp_processor_id(); if (cmnd && phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_HDWQ) { @@ -704,9 +705,6 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, return NULL; } - sgl_size = phba->cfg_sg_dma_buf_size - - (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); - /* Setup key fields in buffer that may have been changed * if other protocols used this buffer. */ @@ -721,9 +719,12 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, #ifdef CONFIG_SCSI_LPFC_DEBUG_FS lpfc_cmd->prot_data_type = 0; #endif - lpfc_cmd->fcp_cmnd = (lpfc_cmd->data + sgl_size); - lpfc_cmd->fcp_rsp = (struct fcp_rsp *)((uint8_t *)lpfc_cmd->fcp_cmnd + - sizeof(struct fcp_cmnd)); + tmp = lpfc_get_cmd_rsp_buf_per_hdwq(phba, lpfc_cmd); + if (!tmp) + return NULL; + + lpfc_cmd->fcp_cmnd = tmp->fcp_cmnd; + lpfc_cmd->fcp_rsp = tmp->fcp_rsp; /* * The first two SGEs are the FCP_CMD and FCP_RSP. @@ -731,7 +732,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, * first two and leave the rest for queuecommand. */ sgl = (struct sli4_sge *)lpfc_cmd->dma_sgl; - pdma_phys_fcp_cmd = (lpfc_cmd->dma_handle + sgl_size); + pdma_phys_fcp_cmd = tmp->fcp_cmd_rsp_dma_handle; sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_cmd)); sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_cmd)); sgl->word2 = le32_to_cpu(sgl->word2); @@ -1990,7 +1991,8 @@ out: **/ static int lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, - struct sli4_sge *sgl, int datasegcnt) + struct sli4_sge *sgl, int datasegcnt, + struct lpfc_io_buf *lpfc_cmd) { struct scatterlist *sgde = NULL; /* s/g data entry */ struct sli4_sge_diseed *diseed = NULL; @@ -2004,6 +2006,9 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, uint32_t checking = 1; uint32_t dma_len; uint32_t dma_offset = 0; + struct sli4_hybrid_sgl *sgl_xtra = NULL; + int j; + bool lsp_just_set = false; status = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop); if (status) @@ -2063,23 +2068,64 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, sgl++; /* assumption: caller has already run dma_map_sg on command data */ - scsi_for_each_sg(sc, sgde, datasegcnt, i) { - physaddr = sg_dma_address(sgde); - dma_len = sg_dma_len(sgde); - sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr)); - sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr)); - if ((i + 1) == datasegcnt) - bf_set(lpfc_sli4_sge_last, sgl, 1); - else - bf_set(lpfc_sli4_sge_last, sgl, 0); - bf_set(lpfc_sli4_sge_offset, sgl, dma_offset); - bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA); + sgde = scsi_sglist(sc); + j = 3; + for (i = 0; i < datasegcnt; i++) { + /* clear it */ + sgl->word2 = 0; - sgl->sge_len = cpu_to_le32(dma_len); - dma_offset += dma_len; + /* do we need to expand the segment */ + if (!lsp_just_set && !((j + 1) % phba->border_sge_num) && + ((datasegcnt - 1) != i)) { + /* set LSP type */ + bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_LSP); + + sgl_xtra = lpfc_get_sgl_per_hdwq(phba, lpfc_cmd); + + if (unlikely(!sgl_xtra)) { + lpfc_cmd->seg_cnt = 0; + return 0; + } + sgl->addr_lo = cpu_to_le32(putPaddrLow( + sgl_xtra->dma_phys_sgl)); + sgl->addr_hi = cpu_to_le32(putPaddrHigh( + sgl_xtra->dma_phys_sgl)); + + } else { + bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA); + } + + if (!(bf_get(lpfc_sli4_sge_type, sgl) & LPFC_SGE_TYPE_LSP)) { + if ((datasegcnt - 1) == i) + bf_set(lpfc_sli4_sge_last, sgl, 1); + physaddr = sg_dma_address(sgde); + dma_len = sg_dma_len(sgde); + sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr)); + sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr)); + + bf_set(lpfc_sli4_sge_offset, sgl, dma_offset); + sgl->word2 = cpu_to_le32(sgl->word2); + sgl->sge_len = cpu_to_le32(dma_len); + + dma_offset += dma_len; + sgde = sg_next(sgde); + + sgl++; + num_sge++; + lsp_just_set = false; + + } else { + sgl->word2 = cpu_to_le32(sgl->word2); + sgl->sge_len = cpu_to_le32(phba->cfg_sg_dma_buf_size); + + sgl = (struct sli4_sge *)sgl_xtra->dma_sgl; + i = i - 1; + + lsp_just_set = true; + } + + j++; - sgl++; - num_sge++; } out: @@ -2125,7 +2171,8 @@ out: **/ static int lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, - struct sli4_sge *sgl, int datacnt, int protcnt) + struct sli4_sge *sgl, int datacnt, int protcnt, + struct lpfc_io_buf *lpfc_cmd) { struct scatterlist *sgde = NULL; /* s/g data entry */ struct scatterlist *sgpe = NULL; /* s/g prot entry */ @@ -2147,7 +2194,8 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, #endif uint32_t checking = 1; uint32_t dma_offset = 0; - int num_sge = 0; + int num_sge = 0, j = 2; + struct sli4_hybrid_sgl *sgl_xtra = NULL; sgpe = scsi_prot_sglist(sc); sgde = scsi_sglist(sc); @@ -2180,9 +2228,37 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, split_offset = 0; do { /* Check to see if we ran out of space */ - if (num_sge >= (phba->cfg_total_seg_cnt - 2)) + if ((num_sge >= (phba->cfg_total_seg_cnt - 2)) && + !(phba->cfg_xpsgl)) return num_sge + 3; + /* DISEED and DIF have to be together */ + if (!((j + 1) % phba->border_sge_num) || + !((j + 2) % phba->border_sge_num) || + !((j + 3) % phba->border_sge_num)) { + sgl->word2 = 0; + + /* set LSP type */ + bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_LSP); + + sgl_xtra = lpfc_get_sgl_per_hdwq(phba, lpfc_cmd); + + if (unlikely(!sgl_xtra)) { + goto out; + } else { + sgl->addr_lo = cpu_to_le32(putPaddrLow( + sgl_xtra->dma_phys_sgl)); + sgl->addr_hi = cpu_to_le32(putPaddrHigh( + sgl_xtra->dma_phys_sgl)); + } + + sgl->word2 = cpu_to_le32(sgl->word2); + sgl->sge_len = cpu_to_le32(phba->cfg_sg_dma_buf_size); + + sgl = (struct sli4_sge *)sgl_xtra->dma_sgl; + j = 0; + } + /* setup DISEED with what we have */ diseed = (struct sli4_sge_diseed *) sgl; memset(diseed, 0, sizeof(struct sli4_sge_diseed)); @@ -2229,7 +2305,9 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, /* advance sgl and increment bde count */ num_sge++; + sgl++; + j++; /* setup the first BDE that points to protection buffer */ protphysaddr = sg_dma_address(sgpe) + protgroup_offset; @@ -2244,6 +2322,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, sgl->addr_hi = le32_to_cpu(putPaddrHigh(protphysaddr)); sgl->addr_lo = le32_to_cpu(putPaddrLow(protphysaddr)); sgl->word2 = cpu_to_le32(sgl->word2); + sgl->sge_len = 0; protgrp_blks = protgroup_len / 8; protgrp_bytes = protgrp_blks * blksize; @@ -2264,9 +2343,14 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, /* setup SGE's for data blocks associated with DIF data */ pgdone = 0; subtotal = 0; /* total bytes processed for current prot grp */ + + sgl++; + j++; + while (!pgdone) { /* Check to see if we ran out of space */ - if (num_sge >= phba->cfg_total_seg_cnt) + if ((num_sge >= phba->cfg_total_seg_cnt) && + !phba->cfg_xpsgl) return num_sge + 1; if (!sgde) { @@ -2275,60 +2359,101 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, __func__); return 0; } - sgl++; - dataphysaddr = sg_dma_address(sgde) + split_offset; - remainder = sg_dma_len(sgde) - split_offset; + if (!((j + 1) % phba->border_sge_num)) { + sgl->word2 = 0; - if ((subtotal + remainder) <= protgrp_bytes) { - /* we can use this whole buffer */ - dma_len = remainder; - split_offset = 0; + /* set LSP type */ + bf_set(lpfc_sli4_sge_type, sgl, + LPFC_SGE_TYPE_LSP); - if ((subtotal + remainder) == protgrp_bytes) - pgdone = 1; + sgl_xtra = lpfc_get_sgl_per_hdwq(phba, + lpfc_cmd); + + if (unlikely(!sgl_xtra)) { + goto out; + } else { + sgl->addr_lo = cpu_to_le32( + putPaddrLow(sgl_xtra->dma_phys_sgl)); + sgl->addr_hi = cpu_to_le32( + putPaddrHigh(sgl_xtra->dma_phys_sgl)); + } + + sgl->word2 = cpu_to_le32(sgl->word2); + sgl->sge_len = cpu_to_le32( + phba->cfg_sg_dma_buf_size); + + sgl = (struct sli4_sge *)sgl_xtra->dma_sgl; } else { - /* must split this buffer with next prot grp */ - dma_len = protgrp_bytes - subtotal; - split_offset += dma_len; - } + dataphysaddr = sg_dma_address(sgde) + + split_offset; - subtotal += dma_len; + remainder = sg_dma_len(sgde) - split_offset; - sgl->addr_lo = cpu_to_le32(putPaddrLow(dataphysaddr)); - sgl->addr_hi = cpu_to_le32(putPaddrHigh(dataphysaddr)); - bf_set(lpfc_sli4_sge_last, sgl, 0); - bf_set(lpfc_sli4_sge_offset, sgl, dma_offset); - bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA); + if ((subtotal + remainder) <= protgrp_bytes) { + /* we can use this whole buffer */ + dma_len = remainder; + split_offset = 0; - sgl->sge_len = cpu_to_le32(dma_len); - dma_offset += dma_len; + if ((subtotal + remainder) == + protgrp_bytes) + pgdone = 1; + } else { + /* must split this buffer with next + * prot grp + */ + dma_len = protgrp_bytes - subtotal; + split_offset += dma_len; + } - num_sge++; - curr_data++; + subtotal += dma_len; - if (split_offset) - break; + sgl->word2 = 0; + sgl->addr_lo = cpu_to_le32(putPaddrLow( + dataphysaddr)); + sgl->addr_hi = cpu_to_le32(putPaddrHigh( + dataphysaddr)); + bf_set(lpfc_sli4_sge_last, sgl, 0); + bf_set(lpfc_sli4_sge_offset, sgl, dma_offset); + bf_set(lpfc_sli4_sge_type, sgl, + LPFC_SGE_TYPE_DATA); - /* Move to the next s/g segment if possible */ - sgde = sg_next(sgde); + sgl->sge_len = cpu_to_le32(dma_len); + dma_offset += dma_len; + + num_sge++; + curr_data++; + + if (split_offset) { + sgl++; + j++; + break; + } + + /* Move to the next s/g segment if possible */ + sgde = sg_next(sgde); + + sgl++; + } + + j++; } if (protgroup_offset) { /* update the reference tag */ reftag += protgrp_blks; - sgl++; continue; } /* are we done ? */ if (curr_prot == protcnt) { + /* mark the last SGL */ + sgl--; bf_set(lpfc_sli4_sge_last, sgl, 1); alldone = 1; } else if (curr_prot < protcnt) { /* advance to next prot buffer */ sgpe = sg_next(sgpe); - sgl++; /* update the reference tag */ reftag += protgrp_blks; @@ -2995,8 +3120,10 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) uint32_t num_bde = 0; uint32_t dma_len; uint32_t dma_offset = 0; - int nseg; + int nseg, i, j; struct ulp_bde64 *bde; + bool lsp_just_set = false; + struct sli4_hybrid_sgl *sgl_xtra = NULL; /* * There are three possibilities here - use scatter-gather segment, use @@ -3023,7 +3150,8 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) sgl += 1; first_data_sgl = sgl; lpfc_cmd->seg_cnt = nseg; - if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { + if (!phba->cfg_xpsgl && + lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9074 BLKGRD:" " %s: Too many sg segments from " "dma_map_sg. Config %d, seg_cnt %d\n", @@ -3044,22 +3172,80 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) * the IOCB. If it can't then the BDEs get added to a BPL as it * does for SLI-2 mode. */ - scsi_for_each_sg(scsi_cmnd, sgel, nseg, num_bde) { - physaddr = sg_dma_address(sgel); - dma_len = sg_dma_len(sgel); - sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr)); - sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr)); - sgl->word2 = le32_to_cpu(sgl->word2); - if ((num_bde + 1) == nseg) + + /* for tracking segment boundaries */ + sgel = scsi_sglist(scsi_cmnd); + j = 2; + for (i = 0; i < nseg; i++) { + sgl->word2 = 0; + if ((num_bde + 1) == nseg) { bf_set(lpfc_sli4_sge_last, sgl, 1); - else + bf_set(lpfc_sli4_sge_type, sgl, + LPFC_SGE_TYPE_DATA); + } else { bf_set(lpfc_sli4_sge_last, sgl, 0); - bf_set(lpfc_sli4_sge_offset, sgl, dma_offset); - bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA); - sgl->word2 = cpu_to_le32(sgl->word2); - sgl->sge_len = cpu_to_le32(dma_len); - dma_offset += dma_len; - sgl++; + + /* do we need to expand the segment */ + if (!lsp_just_set && + !((j + 1) % phba->border_sge_num) && + ((nseg - 1) != i)) { + /* set LSP type */ + bf_set(lpfc_sli4_sge_type, sgl, + LPFC_SGE_TYPE_LSP); + + sgl_xtra = lpfc_get_sgl_per_hdwq( + phba, lpfc_cmd); + + if (unlikely(!sgl_xtra)) { + lpfc_cmd->seg_cnt = 0; + scsi_dma_unmap(scsi_cmnd); + return 1; + } + sgl->addr_lo = cpu_to_le32(putPaddrLow( + sgl_xtra->dma_phys_sgl)); + sgl->addr_hi = cpu_to_le32(putPaddrHigh( + sgl_xtra->dma_phys_sgl)); + + } else { + bf_set(lpfc_sli4_sge_type, sgl, + LPFC_SGE_TYPE_DATA); + } + } + + if (!(bf_get(lpfc_sli4_sge_type, sgl) & + LPFC_SGE_TYPE_LSP)) { + if ((nseg - 1) == i) + bf_set(lpfc_sli4_sge_last, sgl, 1); + + physaddr = sg_dma_address(sgel); + dma_len = sg_dma_len(sgel); + sgl->addr_lo = cpu_to_le32(putPaddrLow( + physaddr)); + sgl->addr_hi = cpu_to_le32(putPaddrHigh( + physaddr)); + + bf_set(lpfc_sli4_sge_offset, sgl, dma_offset); + sgl->word2 = cpu_to_le32(sgl->word2); + sgl->sge_len = cpu_to_le32(dma_len); + + dma_offset += dma_len; + sgel = sg_next(sgel); + + sgl++; + lsp_just_set = false; + + } else { + sgl->word2 = cpu_to_le32(sgl->word2); + sgl->sge_len = cpu_to_le32( + phba->cfg_sg_dma_buf_size); + + sgl = (struct sli4_sge *)sgl_xtra->dma_sgl; + i = i - 1; + + lsp_just_set = true; + } + + j++; } /* * Setup the first Payload BDE. For FCoE we just key off @@ -3175,7 +3361,8 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, lpfc_cmd->seg_cnt = datasegcnt; /* First check if data segment count from SCSI Layer is good */ - if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { + if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt && + !phba->cfg_xpsgl) { WARN_ON_ONCE(lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt); ret = 2; goto err; @@ -3186,13 +3373,15 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, switch (prot_group_type) { case LPFC_PG_TYPE_NO_DIF: /* Here we need to add a DISEED to the count */ - if ((lpfc_cmd->seg_cnt + 1) > phba->cfg_total_seg_cnt) { + if (((lpfc_cmd->seg_cnt + 1) > + phba->cfg_total_seg_cnt) && + !phba->cfg_xpsgl) { ret = 2; goto err; } num_sge = lpfc_bg_setup_sgl(phba, scsi_cmnd, sgl, - datasegcnt); + datasegcnt, lpfc_cmd); /* we should have 2 or more entries in buffer list */ if (num_sge < 2) { @@ -3220,18 +3409,20 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, * There is a minimun of 3 SGEs used for every * protection data segment. */ - if ((lpfc_cmd->prot_seg_cnt * 3) > - (phba->cfg_total_seg_cnt - 2)) { + if (((lpfc_cmd->prot_seg_cnt * 3) > + (phba->cfg_total_seg_cnt - 2)) && + !phba->cfg_xpsgl) { ret = 2; goto err; } num_sge = lpfc_bg_setup_sgl_prot(phba, scsi_cmnd, sgl, - datasegcnt, protsegcnt); + datasegcnt, protsegcnt, lpfc_cmd); /* we should have 3 or more entries in buffer list */ - if ((num_sge < 3) || - (num_sge > phba->cfg_total_seg_cnt)) { + if (num_sge < 3 || + (num_sge > phba->cfg_total_seg_cnt && + !phba->cfg_xpsgl)) { ret = 2; goto err; } @@ -5913,7 +6104,7 @@ struct scsi_host_template lpfc_template_no_hr = { .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, .cmd_per_lun = LPFC_CMD_PER_LUN, .shost_attrs = lpfc_hba_attrs, - .max_sectors = 0xFFFF, + .max_sectors = 0xFFFFFFFF, .vendor_id = LPFC_NL_VENDOR_ID, .change_queue_depth = scsi_change_queue_depth, .track_queue_depth = 1, diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 940dd82a265b..f4beb9104d3a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -20233,6 +20233,13 @@ void lpfc_release_io_buf(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_ncmd, spin_unlock_irqrestore(&qp->io_buf_list_put_lock, iflag); } + + if (phba->cfg_xpsgl && !phba->nvmet_support && + !list_empty(&lpfc_ncmd->dma_sgl_xtra_list)) + lpfc_put_sgl_per_hdwq(phba, lpfc_ncmd); + + if (!list_empty(&lpfc_ncmd->dma_cmd_rsp_list)) + lpfc_put_cmd_rsp_buf_per_hdwq(phba, lpfc_ncmd); } /** @@ -20447,3 +20454,288 @@ struct lpfc_io_buf *lpfc_get_io_buf(struct lpfc_hba *phba, return lpfc_cmd; } + +/** + * lpfc_get_sgl_per_hdwq - Get one SGL chunk from hdwq's pool + * @phba: The HBA for which this call is being executed. + * @lpfc_buf: IO buf structure to append the SGL chunk + * + * This routine gets one SGL chunk buffer from hdwq's SGL chunk pool, + * and will allocate an SGL chunk if the pool is empty. + * + * Return codes: + * NULL - Error + * Pointer to sli4_hybrid_sgl - Success + **/ +struct sli4_hybrid_sgl * +lpfc_get_sgl_per_hdwq(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_buf) +{ + struct sli4_hybrid_sgl *list_entry = NULL; + struct sli4_hybrid_sgl *tmp = NULL; + struct sli4_hybrid_sgl *allocated_sgl = NULL; + struct lpfc_sli4_hdw_queue *hdwq = lpfc_buf->hdwq; + struct list_head *buf_list = &hdwq->sgl_list; + + spin_lock_irq(&hdwq->hdwq_lock); + + if (likely(!list_empty(buf_list))) { + /* break off 1 chunk from the sgl_list */ + list_for_each_entry_safe(list_entry, tmp, + buf_list, list_node) { + list_move_tail(&list_entry->list_node, + &lpfc_buf->dma_sgl_xtra_list); + break; + } + } else { + /* allocate more */ + spin_unlock_irq(&hdwq->hdwq_lock); + tmp = kmalloc_node(sizeof(*tmp), GFP_ATOMIC, + cpu_to_node(smp_processor_id())); + if (!tmp) { + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "8353 error kmalloc memory for HDWQ " + "%d %s\n", + lpfc_buf->hdwq_no, __func__); + return NULL; + } + + tmp->dma_sgl = dma_pool_alloc(phba->lpfc_sg_dma_buf_pool, + GFP_ATOMIC, &tmp->dma_phys_sgl); + if (!tmp->dma_sgl) { + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "8354 error pool_alloc memory for HDWQ " + "%d %s\n", + lpfc_buf->hdwq_no, __func__); + kfree(tmp); + return NULL; + } + + spin_lock_irq(&hdwq->hdwq_lock); + list_add_tail(&tmp->list_node, &lpfc_buf->dma_sgl_xtra_list); + } + + allocated_sgl = list_last_entry(&lpfc_buf->dma_sgl_xtra_list, + struct sli4_hybrid_sgl, + list_node); + + spin_unlock_irq(&hdwq->hdwq_lock); + + return allocated_sgl; +} + +/** + * lpfc_put_sgl_per_hdwq - Put one SGL chunk into hdwq pool + * @phba: The HBA for which this call is being executed. + * @lpfc_buf: IO buf structure with the SGL chunk + * + * This routine puts one SGL chunk buffer into hdwq's SGL chunk pool. + * + * Return codes: + * 0 - Success + * -EINVAL - Error + **/ +int +lpfc_put_sgl_per_hdwq(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_buf) +{ + int rc = 0; + struct sli4_hybrid_sgl *list_entry = NULL; + struct sli4_hybrid_sgl *tmp = NULL; + struct lpfc_sli4_hdw_queue *hdwq = lpfc_buf->hdwq; + struct list_head *buf_list = &hdwq->sgl_list; + + spin_lock_irq(&hdwq->hdwq_lock); + + if (likely(!list_empty(&lpfc_buf->dma_sgl_xtra_list))) { + list_for_each_entry_safe(list_entry, tmp, + &lpfc_buf->dma_sgl_xtra_list, + list_node) { + list_move_tail(&list_entry->list_node, + buf_list); + } + } else { + rc = -EINVAL; + } + + spin_unlock_irq(&hdwq->hdwq_lock); + return rc; +} + +/** + * lpfc_free_sgl_per_hdwq - Free all SGL chunks of hdwq pool + * @phba: phba object + * @hdwq: hdwq to cleanup sgl buff resources on + * + * This routine frees all SGL chunks of hdwq SGL chunk pool. + * + * Return codes: + * None + **/ +void +lpfc_free_sgl_per_hdwq(struct lpfc_hba *phba, + struct lpfc_sli4_hdw_queue *hdwq) +{ + struct list_head *buf_list = &hdwq->sgl_list; + struct sli4_hybrid_sgl *list_entry = NULL; + struct sli4_hybrid_sgl *tmp = NULL; + + spin_lock_irq(&hdwq->hdwq_lock); + + /* Free sgl pool */ + list_for_each_entry_safe(list_entry, tmp, + buf_list, list_node) { + dma_pool_free(phba->lpfc_sg_dma_buf_pool, + list_entry->dma_sgl, + list_entry->dma_phys_sgl); + list_del(&list_entry->list_node); + kfree(list_entry); + } + + spin_unlock_irq(&hdwq->hdwq_lock); +} + +/** + * lpfc_get_cmd_rsp_buf_per_hdwq - Get one CMD/RSP buffer from hdwq + * @phba: The HBA for which this call is being executed. + * @lpfc_buf: IO buf structure to attach the CMD/RSP buffer + * + * This routine gets one CMD/RSP buffer from hdwq's CMD/RSP pool, + * and will allocate an CMD/RSP buffer if the pool is empty. + * + * Return codes: + * NULL - Error + * Pointer to fcp_cmd_rsp_buf - Success + **/ +struct fcp_cmd_rsp_buf * +lpfc_get_cmd_rsp_buf_per_hdwq(struct lpfc_hba *phba, + struct lpfc_io_buf *lpfc_buf) +{ + struct fcp_cmd_rsp_buf *list_entry = NULL; + struct fcp_cmd_rsp_buf *tmp = NULL; + struct fcp_cmd_rsp_buf *allocated_buf = NULL; + struct lpfc_sli4_hdw_queue *hdwq = lpfc_buf->hdwq; + struct list_head *buf_list = &hdwq->cmd_rsp_buf_list; + + spin_lock_irq(&hdwq->hdwq_lock); + + if (likely(!list_empty(buf_list))) { + /* break off 1 chunk from the list */ + list_for_each_entry_safe(list_entry, tmp, + buf_list, + list_node) { + list_move_tail(&list_entry->list_node, + &lpfc_buf->dma_cmd_rsp_list); + break; + } + } else { + /* allocate more */ + spin_unlock_irq(&hdwq->hdwq_lock); + tmp = kmalloc_node(sizeof(*tmp), GFP_ATOMIC, + cpu_to_node(smp_processor_id())); + if (!tmp) { + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "8355 error kmalloc memory for HDWQ " + "%d %s\n", + lpfc_buf->hdwq_no, __func__); + return NULL; + } + + tmp->fcp_cmnd = dma_pool_alloc(phba->lpfc_cmd_rsp_buf_pool, + GFP_ATOMIC, + &tmp->fcp_cmd_rsp_dma_handle); + + if (!tmp->fcp_cmnd) { + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "8356 error pool_alloc memory for HDWQ " + "%d %s\n", + lpfc_buf->hdwq_no, __func__); + kfree(tmp); + return NULL; + } + + tmp->fcp_rsp = (struct fcp_rsp *)((uint8_t *)tmp->fcp_cmnd + + sizeof(struct fcp_cmnd)); + + spin_lock_irq(&hdwq->hdwq_lock); + list_add_tail(&tmp->list_node, &lpfc_buf->dma_cmd_rsp_list); + } + + allocated_buf = list_last_entry(&lpfc_buf->dma_cmd_rsp_list, + struct fcp_cmd_rsp_buf, + list_node); + + spin_unlock_irq(&hdwq->hdwq_lock); + + return allocated_buf; +} + +/** + * lpfc_put_cmd_rsp_buf_per_hdwq - Put one CMD/RSP buffer into hdwq pool + * @phba: The HBA for which this call is being executed. + * @lpfc_buf: IO buf structure with the CMD/RSP buf + * + * This routine puts one CMD/RSP buffer into executing CPU's CMD/RSP pool. + * + * Return codes: + * 0 - Success + * -EINVAL - Error + **/ +int +lpfc_put_cmd_rsp_buf_per_hdwq(struct lpfc_hba *phba, + struct lpfc_io_buf *lpfc_buf) +{ + int rc = 0; + struct fcp_cmd_rsp_buf *list_entry = NULL; + struct fcp_cmd_rsp_buf *tmp = NULL; + struct lpfc_sli4_hdw_queue *hdwq = lpfc_buf->hdwq; + struct list_head *buf_list = &hdwq->cmd_rsp_buf_list; + + spin_lock_irq(&hdwq->hdwq_lock); + + if (likely(!list_empty(&lpfc_buf->dma_cmd_rsp_list))) { + list_for_each_entry_safe(list_entry, tmp, + &lpfc_buf->dma_cmd_rsp_list, + list_node) { + list_move_tail(&list_entry->list_node, + buf_list); + } + } else { + rc = -EINVAL; + } + + spin_unlock_irq(&hdwq->hdwq_lock); + return rc; +} + +/** + * lpfc_free_cmd_rsp_buf_per_hdwq - Free all CMD/RSP chunks of hdwq pool + * @phba: phba object + * @hdwq: hdwq to cleanup cmd rsp buff resources on + * + * This routine frees all CMD/RSP buffers of hdwq's CMD/RSP buf pool. + * + * Return codes: + * None + **/ +void +lpfc_free_cmd_rsp_buf_per_hdwq(struct lpfc_hba *phba, + struct lpfc_sli4_hdw_queue *hdwq) +{ + struct list_head *buf_list = &hdwq->cmd_rsp_buf_list; + struct fcp_cmd_rsp_buf *list_entry = NULL; + struct fcp_cmd_rsp_buf *tmp = NULL; + + spin_lock_irq(&hdwq->hdwq_lock); + + /* Free cmd_rsp buf pool */ + list_for_each_entry_safe(list_entry, tmp, + buf_list, + list_node) { + dma_pool_free(phba->lpfc_cmd_rsp_buf_pool, + list_entry->fcp_cmnd, + list_entry->fcp_cmd_rsp_dma_handle); + list_del(&list_entry->list_node); + kfree(list_entry); + } + + spin_unlock_irq(&hdwq->hdwq_lock); +} diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 467b8270f7fd..37fbcb46387e 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h @@ -365,9 +365,18 @@ struct lpfc_io_buf { /* Common fields */ struct list_head list; void *data; + dma_addr_t dma_handle; dma_addr_t dma_phys_sgl; - struct sli4_sge *dma_sgl; + + struct sli4_sge *dma_sgl; /* initial segment chunk */ + + /* linked list of extra sli4_hybrid_sge */ + struct list_head dma_sgl_xtra_list; + + /* list head for fcp_cmd_rsp buf */ + struct list_head dma_cmd_rsp_list; + struct lpfc_iocbq cur_iocbq; struct lpfc_sli4_hdw_queue *hdwq; uint16_t hdwq_no; diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 3aeca387b22a..3ec9cf4c6427 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -680,6 +680,13 @@ struct lpfc_sli4_hdw_queue { uint32_t cpucheck_xmt_io[LPFC_CHECK_CPU_CNT]; uint32_t cpucheck_cmpl_io[LPFC_CHECK_CPU_CNT]; #endif + + /* Per HDWQ pool resources */ + struct list_head sgl_list; + struct list_head cmd_rsp_buf_list; + + /* Lock for syncing Per HDWQ pool resources */ + spinlock_t hdwq_lock; }; #ifdef LPFC_HDWQ_LOCK_STAT @@ -1089,6 +1096,17 @@ int lpfc_sli4_post_status_check(struct lpfc_hba *); uint8_t lpfc_sli_config_mbox_subsys_get(struct lpfc_hba *, LPFC_MBOXQ_t *); uint8_t lpfc_sli_config_mbox_opcode_get(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_sli4_ras_dma_free(struct lpfc_hba *phba); +struct sli4_hybrid_sgl *lpfc_get_sgl_per_hdwq(struct lpfc_hba *phba, + struct lpfc_io_buf *buf); +struct fcp_cmd_rsp_buf *lpfc_get_cmd_rsp_buf_per_hdwq(struct lpfc_hba *phba, + struct lpfc_io_buf *buf); +int lpfc_put_sgl_per_hdwq(struct lpfc_hba *phba, struct lpfc_io_buf *buf); +int lpfc_put_cmd_rsp_buf_per_hdwq(struct lpfc_hba *phba, + struct lpfc_io_buf *buf); +void lpfc_free_sgl_per_hdwq(struct lpfc_hba *phba, + struct lpfc_sli4_hdw_queue *hdwq); +void lpfc_free_cmd_rsp_buf_per_hdwq(struct lpfc_hba *phba, + struct lpfc_sli4_hdw_queue *hdwq); static inline void *lpfc_sli4_qe(struct lpfc_queue *q, uint16_t idx) { return q->q_pgs[idx / q->entry_cnt_per_pg] + -- cgit v1.2.3-59-g8ed1b From 0d8af096430ed810aacade5f564e5b98347137d4 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:57:10 -0700 Subject: scsi: lpfc: Add NVMe sequence level error recovery support FC-NVMe-2 added support for sequence level error recovery in the FC-NVME protocol. This allows for the detection of errors and lost frames and immediate retransmission of data to avoid exchange termination, which escalates into NVMeoFC connection and association failures. A significant RAS improvement. The driver is modified to indicate support for SLER in the NVMe PRLI is issues and to check for support in the PRLI response. When both sides support it, the driver will set a bit in the WQE to enable the recovery behavior on the exchange. The adapter will take care of all detection and retransmission. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc.h | 1 + drivers/scsi/lpfc/lpfc_disc.h | 2 ++ drivers/scsi/lpfc/lpfc_els.c | 4 ++++ drivers/scsi/lpfc/lpfc_hw4.h | 8 ++++++++ drivers/scsi/lpfc/lpfc_init.c | 8 ++++++++ drivers/scsi/lpfc/lpfc_nportdisc.c | 13 ++++++++++++- drivers/scsi/lpfc/lpfc_nvme.c | 3 +++ 7 files changed, 38 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index b738639fdf3f..c21d61ea82d9 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -797,6 +797,7 @@ struct lpfc_hba { uint8_t mds_diags_support; uint8_t bbcredit_support; uint8_t enab_exp_wqcq_pages; + u8 nsler; /* Firmware supports FC-NVMe-2 SLER */ /* HBA Config Parameters */ uint32_t cfg_ack0; diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 49bb0b180b19..482e4a888dae 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h @@ -112,6 +112,8 @@ struct lpfc_nodelist { uint8_t nlp_retry; /* used for ELS retries */ uint8_t nlp_fcp_info; /* class info, bits 0-3 */ #define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */ + u8 nlp_nvme_info; /* NVME NSLER Support */ +#define NLP_NVME_NSLER 0x1 /* NVME NSLER device */ uint16_t nlp_usg_map; /* ndlp management usage bitmap */ #define NLP_USG_NODE_ACT_BIT 0x1 /* Indicate ndlp is actively used */ diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 30bbfa3f6086..d5303994bfd6 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2435,6 +2435,10 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, npr_nvme = (struct lpfc_nvme_prli *)pcmd; bf_set(prli_type_code, npr_nvme, PRLI_NVME_TYPE); bf_set(prli_estabImagePair, npr_nvme, 0); /* Should be 0 */ + if (phba->nsler) { + bf_set(prli_nsler, npr_nvme, 1); + bf_set(prli_conf, npr_nvme, 1); + } /* Only initiators request first burst. */ if ((phba->cfg_nvme_enable_fb) && diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index e198de8eda32..bd533475c86a 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -3480,6 +3480,10 @@ struct lpfc_sli4_parameters { #define cfg_bv1s_MASK 0x00000001 #define cfg_bv1s_WORD word19 +#define cfg_nsler_SHIFT 12 +#define cfg_nsler_MASK 0x00000001 +#define cfg_nsler_WORD word19 + uint32_t word20; #define cfg_max_tow_xri_SHIFT 0 #define cfg_max_tow_xri_MASK 0x0000ffff @@ -4621,6 +4625,7 @@ struct lpfc_nvme_prli { #define prli_type_code_WORD word1 uint32_t word_rsvd2; uint32_t word_rsvd3; + uint32_t word4; #define prli_fba_SHIFT 0 #define prli_fba_MASK 0x00000001 @@ -4637,6 +4642,9 @@ struct lpfc_nvme_prli { #define prli_conf_SHIFT 7 #define prli_conf_MASK 0x00000001 #define prli_conf_WORD word4 +#define prli_nsler_SHIFT 8 +#define prli_nsler_MASK 0x00000001 +#define prli_nsler_WORD word4 uint32_t word5; #define prli_fb_sz_SHIFT 0 #define prli_fb_sz_MASK 0x0000ffff diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index fa3741f12089..d71f1b066e30 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -11846,6 +11846,14 @@ fcponly: else phba->mds_diags_support = 0; + /* + * Check if the SLI port supports NSLER + */ + if (bf_get(cfg_nsler, mbx_sli4_parameters)) + phba->nsler = 1; + else + phba->nsler = 0; + return 0; } diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 41ac07b99739..f4b879d25fe9 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -799,9 +799,15 @@ lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, if (npr->writeXferRdyDis) ndlp->nlp_flag |= NLP_FIRSTBURST; } - if (npr->Retry) + if (npr->Retry && ndlp->nlp_type & + (NLP_FCP_INITIATOR | NLP_FCP_TARGET)) ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; + if (npr->Retry && phba->nsler && + ndlp->nlp_type & (NLP_NVME_INITIATOR | NLP_NVME_TARGET)) + ndlp->nlp_nvme_info |= NLP_NVME_NSLER; + + /* If this driver is in nvme target mode, set the ndlp's fc4 * type to NVME provided the PRLI response claims NVME FC4 * type. Target mode does not issue gft_id so doesn't get @@ -2024,6 +2030,11 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, if (bf_get_be32(prli_init, nvpr)) ndlp->nlp_type |= NLP_NVME_INITIATOR; + if (phba->nsler && bf_get_be32(prli_nsler, nvpr)) + ndlp->nlp_nvme_info |= NLP_NVME_NSLER; + else + ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER; + /* Target driver cannot solicit NVME FB. */ if (bf_get_be32(prli_tgt, nvpr)) { /* Complete the nvme target roles. The transport diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 5e48318eb7a9..f66859d928ac 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1255,6 +1255,9 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport, sizeof(uint32_t) * 8); cstat->control_requests++; } + + if (pnode->nlp_nvme_info & NLP_NVME_NSLER) + bf_set(wqe_erp, &wqe->generic.wqe_com, 1); /* * Finish initializing those WQE fields that are independent * of the nvme_cmnd request_buffer -- cgit v1.2.3-59-g8ed1b From c00f62e6c5468ed0673c583f1ff284274e817410 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 14 Aug 2019 16:57:11 -0700 Subject: scsi: lpfc: Merge per-protocol WQ/CQ pairs into single per-cpu pair Currently, each hardware queue, typically allocated per-cpu, consists of a WQ/CQ pair per protocol. Meaning if both SCSI and NVMe are supported 2 WQ/CQ pairs will exist for the hardware queue. Separate queues are unnecessary. The current implementation wastes memory backing the 2nd set of queues, and the use of double the SLI-4 WQ/CQ's means less hardware queues can be supported which means there may not always be enough to have a pair per cpu. If there is only 1 pair per cpu, more cpu's may get their own WQ/CQ. Rework the implementation to use a single WQ/CQ pair by both protocols. Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc.h | 3 +- drivers/scsi/lpfc/lpfc_crtn.h | 2 +- drivers/scsi/lpfc/lpfc_debugfs.c | 92 ++---------- drivers/scsi/lpfc/lpfc_debugfs.h | 61 +++----- drivers/scsi/lpfc/lpfc_init.c | 296 ++++++++++----------------------------- drivers/scsi/lpfc/lpfc_nvme.c | 85 ++++------- drivers/scsi/lpfc/lpfc_nvmet.c | 8 +- drivers/scsi/lpfc/lpfc_scsi.c | 54 ++++--- drivers/scsi/lpfc/lpfc_sli.c | 145 +++++-------------- drivers/scsi/lpfc/lpfc_sli4.h | 29 ++-- 10 files changed, 218 insertions(+), 557 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index c21d61ea82d9..11873f0d521c 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -734,14 +734,13 @@ struct lpfc_hba { #define HBA_AER_ENABLED 0x1000 /* AER enabled with HBA */ #define HBA_DEVLOSS_TMO 0x2000 /* HBA in devloss timeout */ #define HBA_RRQ_ACTIVE 0x4000 /* process the rrq active list */ -#define HBA_FCP_IOQ_FLUSH 0x8000 /* FCP I/O queues being flushed */ +#define HBA_IOQ_FLUSH 0x8000 /* FCP/NVME I/O queues being flushed */ #define HBA_FW_DUMP_OP 0x10000 /* Skips fn reset before FW dump */ #define HBA_RECOVERABLE_UE 0x20000 /* Firmware supports recoverable UE */ #define HBA_FORCED_LINK_SPEED 0x40000 /* * Firmware supports Forced Link Speed * capability */ -#define HBA_NVME_IOQ_FLUSH 0x80000 /* NVME IO queues flushed. */ #define HBA_FLOGI_ISSUED 0x100000 /* FLOGI was issued */ uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/ diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index bee27bb7123c..8b84acc95a07 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -326,7 +326,7 @@ void lpfc_sli_bemem_bcopy(void *, void *, uint32_t); void lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *); void lpfc_sli_abort_fcp_rings(struct lpfc_hba *phba); void lpfc_sli_hba_iocb_abort(struct lpfc_hba *); -void lpfc_sli_flush_fcp_rings(struct lpfc_hba *); +void lpfc_sli_flush_io_rings(struct lpfc_hba *phba); int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_dmabuf *); struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *, diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 75055ee59e91..45f431fbe0d2 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -416,8 +416,7 @@ lpfc_debugfs_commonxripools_data(struct lpfc_hba *phba, char *buf, int size) qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_xripool]; len += scnprintf(buf + len, size - len, "HdwQ %d Info ", i); - spin_lock_irqsave(&qp->abts_scsi_buf_list_lock, iflag); - spin_lock(&qp->abts_nvme_buf_list_lock); + spin_lock_irqsave(&qp->abts_io_buf_list_lock, iflag); spin_lock(&qp->io_buf_list_get_lock); spin_lock(&qp->io_buf_list_put_lock); out = qp->total_io_bufs - (qp->get_io_bufs + qp->put_io_bufs + @@ -430,8 +429,7 @@ lpfc_debugfs_commonxripools_data(struct lpfc_hba *phba, char *buf, int size) qp->abts_nvme_io_bufs, out); spin_unlock(&qp->io_buf_list_put_lock); spin_unlock(&qp->io_buf_list_get_lock); - spin_unlock(&qp->abts_nvme_buf_list_lock); - spin_unlock_irqrestore(&qp->abts_scsi_buf_list_lock, iflag); + spin_unlock_irqrestore(&qp->abts_io_buf_list_lock, iflag); lpfc_debugfs_last_xripool++; if (lpfc_debugfs_last_xripool >= phba->cfg_hdw_queue) @@ -533,9 +531,7 @@ lpfc_debugfs_multixripools_data(struct lpfc_hba *phba, char *buf, int size) continue; pbl_pool = &multixri_pool->pbl_pool; pvt_pool = &multixri_pool->pvt_pool; - txcmplq_cnt = qp->fcp_wq->pring->txcmplq_cnt; - if (qp->nvme_wq) - txcmplq_cnt += qp->nvme_wq->pring->txcmplq_cnt; + txcmplq_cnt = qp->io_wq->pring->txcmplq_cnt; scnprintf(tmp, sizeof(tmp), "%03d: %4d %4d %4d %4d | %10d %10d ", @@ -3786,23 +3782,13 @@ lpfc_idiag_wqs_for_cq(struct lpfc_hba *phba, char *wqtype, char *pbuffer, int qidx; for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { - qp = phba->sli4_hba.hdwq[qidx].fcp_wq; + qp = phba->sli4_hba.hdwq[qidx].io_wq; if (qp->assoc_qid != cq_id) continue; *len = __lpfc_idiag_print_wq(qp, wqtype, pbuffer, *len); if (*len >= max_cnt) return 1; } - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { - for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { - qp = phba->sli4_hba.hdwq[qidx].nvme_wq; - if (qp->assoc_qid != cq_id) - continue; - *len = __lpfc_idiag_print_wq(qp, wqtype, pbuffer, *len); - if (*len >= max_cnt) - return 1; - } - } return 0; } @@ -3868,9 +3854,9 @@ lpfc_idiag_cqs_for_eq(struct lpfc_hba *phba, char *pbuffer, struct lpfc_queue *qp; int rc; - qp = phba->sli4_hba.hdwq[eqidx].fcp_cq; + qp = phba->sli4_hba.hdwq[eqidx].io_cq; - *len = __lpfc_idiag_print_cq(qp, "FCP", pbuffer, *len); + *len = __lpfc_idiag_print_cq(qp, "IO", pbuffer, *len); /* Reset max counter */ qp->CQ_max_cqe = 0; @@ -3878,28 +3864,11 @@ lpfc_idiag_cqs_for_eq(struct lpfc_hba *phba, char *pbuffer, if (*len >= max_cnt) return 1; - rc = lpfc_idiag_wqs_for_cq(phba, "FCP", pbuffer, len, + rc = lpfc_idiag_wqs_for_cq(phba, "IO", pbuffer, len, max_cnt, qp->queue_id); if (rc) return 1; - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { - qp = phba->sli4_hba.hdwq[eqidx].nvme_cq; - - *len = __lpfc_idiag_print_cq(qp, "NVME", pbuffer, *len); - - /* Reset max counter */ - qp->CQ_max_cqe = 0; - - if (*len >= max_cnt) - return 1; - - rc = lpfc_idiag_wqs_for_cq(phba, "NVME", pbuffer, len, - max_cnt, qp->queue_id); - if (rc) - return 1; - } - if ((eqidx < phba->cfg_nvmet_mrq) && phba->nvmet_support) { /* NVMET CQset */ qp = phba->sli4_hba.nvmet_cqset[eqidx]; @@ -4348,7 +4317,7 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, if (phba->sli4_hba.hdwq) { for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { - qp = phba->sli4_hba.hdwq[qidx].fcp_cq; + qp = phba->sli4_hba.hdwq[qidx].io_cq; if (qp && qp->queue_id == queid) { /* Sanity check */ rc = lpfc_idiag_que_param_check( @@ -4360,22 +4329,6 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, } } } - /* NVME complete queue */ - if (phba->sli4_hba.hdwq) { - qidx = 0; - do { - qp = phba->sli4_hba.hdwq[qidx].nvme_cq; - if (qp && qp->queue_id == queid) { - /* Sanity check */ - rc = lpfc_idiag_que_param_check( - qp, index, count); - if (rc) - goto error_out; - idiag.ptr_private = qp; - goto pass_check; - } - } while (++qidx < phba->cfg_hdw_queue); - } goto error_out; break; case LPFC_IDIAG_MQ: @@ -4419,20 +4372,7 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, if (phba->sli4_hba.hdwq) { /* FCP/SCSI work queue */ for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { - qp = phba->sli4_hba.hdwq[qidx].fcp_wq; - if (qp && qp->queue_id == queid) { - /* Sanity check */ - rc = lpfc_idiag_que_param_check( - qp, index, count); - if (rc) - goto error_out; - idiag.ptr_private = qp; - goto pass_check; - } - } - /* NVME work queue */ - for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { - qp = phba->sli4_hba.hdwq[qidx].nvme_wq; + qp = phba->sli4_hba.hdwq[qidx].io_wq; if (qp && qp->queue_id == queid) { /* Sanity check */ rc = lpfc_idiag_que_param_check( @@ -6442,12 +6382,7 @@ lpfc_debug_dump_all_queues(struct lpfc_hba *phba) lpfc_debug_dump_wq(phba, DUMP_NVMELS, 0); for (idx = 0; idx < phba->cfg_hdw_queue; idx++) - lpfc_debug_dump_wq(phba, DUMP_FCP, idx); - - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { - for (idx = 0; idx < phba->cfg_hdw_queue; idx++) - lpfc_debug_dump_wq(phba, DUMP_NVME, idx); - } + lpfc_debug_dump_wq(phba, DUMP_IO, idx); lpfc_debug_dump_hdr_rq(phba); lpfc_debug_dump_dat_rq(phba); @@ -6459,12 +6394,7 @@ lpfc_debug_dump_all_queues(struct lpfc_hba *phba) lpfc_debug_dump_cq(phba, DUMP_NVMELS, 0); for (idx = 0; idx < phba->cfg_hdw_queue; idx++) - lpfc_debug_dump_cq(phba, DUMP_FCP, idx); - - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { - for (idx = 0; idx < phba->cfg_hdw_queue; idx++) - lpfc_debug_dump_cq(phba, DUMP_NVME, idx); - } + lpfc_debug_dump_cq(phba, DUMP_IO, idx); /* * Dump Event Queues (EQs) diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h index 34070874616d..20f2537af511 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.h +++ b/drivers/scsi/lpfc/lpfc_debugfs.h @@ -291,8 +291,7 @@ struct lpfc_idiag { #define LPFC_DUMP_MULTIXRIPOOL_SIZE 8192 enum { - DUMP_FCP, - DUMP_NVME, + DUMP_IO, DUMP_MBX, DUMP_ELS, DUMP_NVMELS, @@ -415,12 +414,9 @@ lpfc_debug_dump_wq(struct lpfc_hba *phba, int qtype, int wqidx) struct lpfc_queue *wq; char *qtypestr; - if (qtype == DUMP_FCP) { - wq = phba->sli4_hba.hdwq[wqidx].fcp_wq; - qtypestr = "FCP"; - } else if (qtype == DUMP_NVME) { - wq = phba->sli4_hba.hdwq[wqidx].nvme_wq; - qtypestr = "NVME"; + if (qtype == DUMP_IO) { + wq = phba->sli4_hba.hdwq[wqidx].io_wq; + qtypestr = "IO"; } else if (qtype == DUMP_MBX) { wq = phba->sli4_hba.mbx_wq; qtypestr = "MBX"; @@ -433,7 +429,7 @@ lpfc_debug_dump_wq(struct lpfc_hba *phba, int qtype, int wqidx) } else return; - if (qtype == DUMP_FCP || qtype == DUMP_NVME) + if (qtype == DUMP_IO) pr_err("%s WQ: WQ[Idx:%d|Qid:%d]\n", qtypestr, wqidx, wq->queue_id); else @@ -459,17 +455,13 @@ lpfc_debug_dump_cq(struct lpfc_hba *phba, int qtype, int wqidx) char *qtypestr; int eqidx; - /* fcp/nvme wq and cq are 1:1, thus same indexes */ + /* io wq and cq are 1:1, thus same indexes */ eq = NULL; - if (qtype == DUMP_FCP) { - wq = phba->sli4_hba.hdwq[wqidx].fcp_wq; - cq = phba->sli4_hba.hdwq[wqidx].fcp_cq; - qtypestr = "FCP"; - } else if (qtype == DUMP_NVME) { - wq = phba->sli4_hba.hdwq[wqidx].nvme_wq; - cq = phba->sli4_hba.hdwq[wqidx].nvme_cq; - qtypestr = "NVME"; + if (qtype == DUMP_IO) { + wq = phba->sli4_hba.hdwq[wqidx].io_wq; + cq = phba->sli4_hba.hdwq[wqidx].io_cq; + qtypestr = "IO"; } else if (qtype == DUMP_MBX) { wq = phba->sli4_hba.mbx_wq; cq = phba->sli4_hba.mbx_cq; @@ -496,7 +488,7 @@ lpfc_debug_dump_cq(struct lpfc_hba *phba, int qtype, int wqidx) eq = phba->sli4_hba.hdwq[0].hba_eq; } - if (qtype == DUMP_FCP || qtype == DUMP_NVME) + if (qtype == DUMP_IO) pr_err("%s CQ: WQ[Idx:%d|Qid%d]->CQ[Idx%d|Qid%d]" "->EQ[Idx:%d|Qid:%d]:\n", qtypestr, wqidx, wq->queue_id, wqidx, cq->queue_id, @@ -572,20 +564,11 @@ lpfc_debug_dump_wq_by_id(struct lpfc_hba *phba, int qid) int wq_idx; for (wq_idx = 0; wq_idx < phba->cfg_hdw_queue; wq_idx++) - if (phba->sli4_hba.hdwq[wq_idx].fcp_wq->queue_id == qid) + if (phba->sli4_hba.hdwq[wq_idx].io_wq->queue_id == qid) break; if (wq_idx < phba->cfg_hdw_queue) { - pr_err("FCP WQ[Idx:%d|Qid:%d]\n", wq_idx, qid); - lpfc_debug_dump_q(phba->sli4_hba.hdwq[wq_idx].fcp_wq); - return; - } - - for (wq_idx = 0; wq_idx < phba->cfg_hdw_queue; wq_idx++) - if (phba->sli4_hba.hdwq[wq_idx].nvme_wq->queue_id == qid) - break; - if (wq_idx < phba->cfg_hdw_queue) { - pr_err("NVME WQ[Idx:%d|Qid:%d]\n", wq_idx, qid); - lpfc_debug_dump_q(phba->sli4_hba.hdwq[wq_idx].nvme_wq); + pr_err("IO WQ[Idx:%d|Qid:%d]\n", wq_idx, qid); + lpfc_debug_dump_q(phba->sli4_hba.hdwq[wq_idx].io_wq); return; } @@ -654,22 +637,12 @@ lpfc_debug_dump_cq_by_id(struct lpfc_hba *phba, int qid) int cq_idx; for (cq_idx = 0; cq_idx < phba->cfg_hdw_queue; cq_idx++) - if (phba->sli4_hba.hdwq[cq_idx].fcp_cq->queue_id == qid) - break; - - if (cq_idx < phba->cfg_hdw_queue) { - pr_err("FCP CQ[Idx:%d|Qid:%d]\n", cq_idx, qid); - lpfc_debug_dump_q(phba->sli4_hba.hdwq[cq_idx].fcp_cq); - return; - } - - for (cq_idx = 0; cq_idx < phba->cfg_hdw_queue; cq_idx++) - if (phba->sli4_hba.hdwq[cq_idx].nvme_cq->queue_id == qid) + if (phba->sli4_hba.hdwq[cq_idx].io_cq->queue_id == qid) break; if (cq_idx < phba->cfg_hdw_queue) { - pr_err("NVME CQ[Idx:%d|Qid:%d]\n", cq_idx, qid); - lpfc_debug_dump_q(phba->sli4_hba.hdwq[cq_idx].nvme_cq); + pr_err("IO CQ[Idx:%d|Qid:%d]\n", cq_idx, qid); + lpfc_debug_dump_q(phba->sli4_hba.hdwq[cq_idx].io_cq); return; } diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d71f1b066e30..0bc04af1d2fb 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1082,8 +1082,8 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { qp = &phba->sli4_hba.hdwq[idx]; - spin_lock(&qp->abts_scsi_buf_list_lock); - list_splice_init(&qp->lpfc_abts_scsi_buf_list, + spin_lock(&qp->abts_io_buf_list_lock); + list_splice_init(&qp->lpfc_abts_io_buf_list, &aborts); list_for_each_entry_safe(psb, psb_next, &aborts, list) { @@ -1094,29 +1094,11 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) spin_lock(&qp->io_buf_list_put_lock); list_splice_init(&aborts, &qp->lpfc_io_buf_list_put); qp->put_io_bufs += qp->abts_scsi_io_bufs; + qp->put_io_bufs += qp->abts_nvme_io_bufs; qp->abts_scsi_io_bufs = 0; + qp->abts_nvme_io_bufs = 0; spin_unlock(&qp->io_buf_list_put_lock); - spin_unlock(&qp->abts_scsi_buf_list_lock); - - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { - spin_lock(&qp->abts_nvme_buf_list_lock); - list_splice_init(&qp->lpfc_abts_nvme_buf_list, - &nvme_aborts); - list_for_each_entry_safe(psb, psb_next, &nvme_aborts, - list) { - psb->pCmd = NULL; - psb->status = IOSTAT_SUCCESS; - cnt++; - } - spin_lock(&qp->io_buf_list_put_lock); - qp->put_io_bufs += qp->abts_nvme_io_bufs; - qp->abts_nvme_io_bufs = 0; - list_splice_init(&nvme_aborts, - &qp->lpfc_io_buf_list_put); - spin_unlock(&qp->io_buf_list_put_lock); - spin_unlock(&qp->abts_nvme_buf_list_lock); - - } + spin_unlock(&qp->abts_io_buf_list_lock); } spin_unlock_irq(&phba->hbalock); @@ -1546,8 +1528,7 @@ lpfc_sli4_offline_eratt(struct lpfc_hba *phba) spin_unlock_irq(&phba->hbalock); lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT); - lpfc_sli_flush_fcp_rings(phba); - lpfc_sli_flush_nvme_rings(phba); + lpfc_sli_flush_io_rings(phba); lpfc_offline(phba); lpfc_hba_down_post(phba); lpfc_unblock_mgmt_io(phba); @@ -1809,8 +1790,7 @@ lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action, "2887 Reset Needed: Attempting Port " "Recovery...\n"); lpfc_offline_prep(phba, mbx_action); - lpfc_sli_flush_fcp_rings(phba); - lpfc_sli_flush_nvme_rings(phba); + lpfc_sli_flush_io_rings(phba); lpfc_offline(phba); /* release interrupt for possible resource change */ lpfc_sli4_disable_intr(phba); @@ -3266,12 +3246,8 @@ static void lpfc_destroy_multixri_pools(struct lpfc_hba *phba) if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) lpfc_destroy_expedite_pool(phba); - if (!(phba->pport->load_flag & FC_UNLOADING)) { - lpfc_sli_flush_fcp_rings(phba); - - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) - lpfc_sli_flush_nvme_rings(phba); - } + if (!(phba->pport->load_flag & FC_UNLOADING)) + lpfc_sli_flush_io_rings(phba); hwq_count = phba->cfg_hdw_queue; @@ -6516,11 +6492,9 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) /* * Initialize the SLI Layer to run with lpfc SLI4 HBAs. */ - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) { - /* Initialize the Abort scsi buffer list used by driver */ - spin_lock_init(&phba->sli4_hba.abts_scsi_buf_list_lock); - INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_scsi_buf_list); - } + /* Initialize the Abort buffer list used by driver */ + spin_lock_init(&phba->sli4_hba.abts_io_buf_list_lock); + INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_io_buf_list); if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { /* Initialize the Abort nvme buffer list used by driver */ @@ -8475,11 +8449,6 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) */ qmin -= 4; - /* If NVME is configured, double the number of CQ/WQs needed */ - if ((phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) && - !phba->nvmet_support) - qmin /= 2; - /* Check to see if there is enough for NVME */ if ((phba->cfg_irq_chann > qmin) || (phba->cfg_hdw_queue > qmin)) { @@ -8736,51 +8705,14 @@ lpfc_sli4_queue_verify(struct lpfc_hba *phba) } static int -lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx) -{ - struct lpfc_queue *qdesc; - int cpu; - - cpu = lpfc_find_cpu_handle(phba, wqidx, LPFC_FIND_BY_HDWQ); - qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, - phba->sli4_hba.cq_esize, - LPFC_CQE_EXP_COUNT, cpu); - if (!qdesc) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0508 Failed allocate fast-path NVME CQ (%d)\n", - wqidx); - return 1; - } - qdesc->qe_valid = 1; - qdesc->hdwq = wqidx; - qdesc->chann = cpu; - phba->sli4_hba.hdwq[wqidx].nvme_cq = qdesc; - - qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, - LPFC_WQE128_SIZE, LPFC_WQE_EXP_COUNT, - cpu); - if (!qdesc) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0509 Failed allocate fast-path NVME WQ (%d)\n", - wqidx); - return 1; - } - qdesc->hdwq = wqidx; - qdesc->chann = wqidx; - phba->sli4_hba.hdwq[wqidx].nvme_wq = qdesc; - list_add_tail(&qdesc->wq_list, &phba->sli4_hba.lpfc_wq_list); - return 0; -} - -static int -lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) +lpfc_alloc_io_wq_cq(struct lpfc_hba *phba, int idx) { struct lpfc_queue *qdesc; - uint32_t wqesize; + u32 wqesize; int cpu; - cpu = lpfc_find_cpu_handle(phba, wqidx, LPFC_FIND_BY_HDWQ); - /* Create Fast Path FCP CQs */ + cpu = lpfc_find_cpu_handle(phba, idx, LPFC_FIND_BY_HDWQ); + /* Create Fast Path IO CQs */ if (phba->enab_exp_wqcq_pages) /* Increase the CQ size when WQEs contain an embedded cdb */ qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, @@ -8793,15 +8725,15 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) phba->sli4_hba.cq_ecount, cpu); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx); + "0499 Failed allocate fast-path IO CQ (%d)\n", idx); return 1; } qdesc->qe_valid = 1; - qdesc->hdwq = wqidx; + qdesc->hdwq = idx; qdesc->chann = cpu; - phba->sli4_hba.hdwq[wqidx].fcp_cq = qdesc; + phba->sli4_hba.hdwq[idx].io_cq = qdesc; - /* Create Fast Path FCP WQs */ + /* Create Fast Path IO WQs */ if (phba->enab_exp_wqcq_pages) { /* Increase the WQ size when WQEs contain an embedded cdb */ wqesize = (phba->fcp_embed_io) ? @@ -8816,13 +8748,13 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0503 Failed allocate fast-path FCP WQ (%d)\n", - wqidx); + "0503 Failed allocate fast-path IO WQ (%d)\n", + idx); return 1; } - qdesc->hdwq = wqidx; - qdesc->chann = wqidx; - phba->sli4_hba.hdwq[wqidx].fcp_wq = qdesc; + qdesc->hdwq = idx; + qdesc->chann = cpu; + phba->sli4_hba.hdwq[idx].io_wq = qdesc; list_add_tail(&qdesc->wq_list, &phba->sli4_hba.lpfc_wq_list); return 0; } @@ -8886,11 +8818,9 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) qp->get_io_bufs = 0; qp->put_io_bufs = 0; qp->total_io_bufs = 0; - spin_lock_init(&qp->abts_scsi_buf_list_lock); - INIT_LIST_HEAD(&qp->lpfc_abts_scsi_buf_list); + spin_lock_init(&qp->abts_io_buf_list_lock); + INIT_LIST_HEAD(&qp->lpfc_abts_io_buf_list); qp->abts_scsi_io_bufs = 0; - spin_lock_init(&qp->abts_nvme_buf_list_lock); - INIT_LIST_HEAD(&qp->lpfc_abts_nvme_buf_list); qp->abts_nvme_io_bufs = 0; INIT_LIST_HEAD(&qp->sgl_list); INIT_LIST_HEAD(&qp->cmd_rsp_buf_list); @@ -8991,41 +8921,31 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) qp->hba_eq = phba->sli4_hba.hdwq[eqcpup->hdwq].hba_eq; } - /* Allocate SCSI SLI4 CQ/WQs */ + /* Allocate IO Path SLI4 CQ/WQs */ for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { - if (lpfc_alloc_fcp_wq_cq(phba, idx)) + if (lpfc_alloc_io_wq_cq(phba, idx)) goto out_error; } - /* Allocate NVME SLI4 CQ/WQs */ - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { - for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { - if (lpfc_alloc_nvme_wq_cq(phba, idx)) - goto out_error; - } - - if (phba->nvmet_support) { - for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) { - cpu = lpfc_find_cpu_handle(phba, idx, - LPFC_FIND_BY_HDWQ); - qdesc = lpfc_sli4_queue_alloc( - phba, + if (phba->nvmet_support) { + for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) { + cpu = lpfc_find_cpu_handle(phba, idx, + LPFC_FIND_BY_HDWQ); + qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, phba->sli4_hba.cq_esize, phba->sli4_hba.cq_ecount, cpu); - if (!qdesc) { - lpfc_printf_log( - phba, KERN_ERR, LOG_INIT, + if (!qdesc) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "3142 Failed allocate NVME " "CQ Set (%d)\n", idx); - goto out_error; - } - qdesc->qe_valid = 1; - qdesc->hdwq = idx; - qdesc->chann = cpu; - phba->sli4_hba.nvmet_cqset[idx] = qdesc; + goto out_error; } + qdesc->qe_valid = 1; + qdesc->hdwq = idx; + qdesc->chann = cpu; + phba->sli4_hba.nvmet_cqset[idx] = qdesc; } } @@ -9056,7 +8976,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) goto out_error; } qdesc->qe_valid = 1; - qdesc->chann = 0; + qdesc->chann = cpu; phba->sli4_hba.els_cq = qdesc; @@ -9074,7 +8994,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) "0505 Failed allocate slow-path MQ\n"); goto out_error; } - qdesc->chann = 0; + qdesc->chann = cpu; phba->sli4_hba.mbx_wq = qdesc; /* @@ -9090,7 +9010,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) "0504 Failed allocate slow-path ELS WQ\n"); goto out_error; } - qdesc->chann = 0; + qdesc->chann = cpu; phba->sli4_hba.els_wq = qdesc; list_add_tail(&qdesc->wq_list, &phba->sli4_hba.lpfc_wq_list); @@ -9104,7 +9024,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) "6079 Failed allocate NVME LS CQ\n"); goto out_error; } - qdesc->chann = 0; + qdesc->chann = cpu; qdesc->qe_valid = 1; phba->sli4_hba.nvmels_cq = qdesc; @@ -9117,7 +9037,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) "6080 Failed allocate NVME LS WQ\n"); goto out_error; } - qdesc->chann = 0; + qdesc->chann = cpu; phba->sli4_hba.nvmels_wq = qdesc; list_add_tail(&qdesc->wq_list, &phba->sli4_hba.lpfc_wq_list); } @@ -9260,15 +9180,10 @@ lpfc_sli4_release_hdwq(struct lpfc_hba *phba) /* Loop thru all Hardware Queues */ for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { /* Free the CQ/WQ corresponding to the Hardware Queue */ - lpfc_sli4_queue_free(hdwq[idx].fcp_cq); - lpfc_sli4_queue_free(hdwq[idx].nvme_cq); - lpfc_sli4_queue_free(hdwq[idx].fcp_wq); - lpfc_sli4_queue_free(hdwq[idx].nvme_wq); - hdwq[idx].hba_eq = NULL; - hdwq[idx].fcp_cq = NULL; - hdwq[idx].nvme_cq = NULL; - hdwq[idx].fcp_wq = NULL; - hdwq[idx].nvme_wq = NULL; + lpfc_sli4_queue_free(hdwq[idx].io_cq); + lpfc_sli4_queue_free(hdwq[idx].io_wq); + hdwq[idx].io_cq = NULL; + hdwq[idx].io_wq = NULL; if (phba->cfg_xpsgl && !phba->nvmet_support) lpfc_free_sgl_per_hdwq(phba, &hdwq[idx]); lpfc_free_cmd_rsp_buf_per_hdwq(phba, &hdwq[idx]); @@ -9471,8 +9386,7 @@ lpfc_setup_cq_lookup(struct lpfc_hba *phba) list_for_each_entry(childq, &eq->child_list, list) { if (childq->queue_id > phba->sli4_hba.cq_max) continue; - if ((childq->subtype == LPFC_FCP) || - (childq->subtype == LPFC_NVME)) + if (childq->subtype == LPFC_IO) phba->sli4_hba.cq_lookup[childq->queue_id] = childq; } @@ -9598,31 +9512,6 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) } /* Loop thru all Hardware Queues */ - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { - for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { - cpu = lpfc_find_cpu_handle(phba, qidx, - LPFC_FIND_BY_HDWQ); - cpup = &phba->sli4_hba.cpu_map[cpu]; - - /* Create the CQ/WQ corresponding to the - * Hardware Queue - */ - rc = lpfc_create_wq_cq(phba, - phba->sli4_hba.hdwq[cpup->hdwq].hba_eq, - qp[qidx].nvme_cq, - qp[qidx].nvme_wq, - &phba->sli4_hba.hdwq[qidx].nvme_cq_map, - qidx, LPFC_NVME); - if (rc) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "6123 Failed to setup fastpath " - "NVME WQ/CQ (%d), rc = 0x%x\n", - qidx, (uint32_t)rc); - goto out_destroy; - } - } - } - for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { cpu = lpfc_find_cpu_handle(phba, qidx, LPFC_FIND_BY_HDWQ); cpup = &phba->sli4_hba.cpu_map[cpu]; @@ -9630,14 +9519,15 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) /* Create the CQ/WQ corresponding to the Hardware Queue */ rc = lpfc_create_wq_cq(phba, phba->sli4_hba.hdwq[cpup->hdwq].hba_eq, - qp[qidx].fcp_cq, - qp[qidx].fcp_wq, - &phba->sli4_hba.hdwq[qidx].fcp_cq_map, - qidx, LPFC_FCP); + qp[qidx].io_cq, + qp[qidx].io_wq, + &phba->sli4_hba.hdwq[qidx].io_cq_map, + qidx, + LPFC_IO); if (rc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0535 Failed to setup fastpath " - "FCP WQ/CQ (%d), rc = 0x%x\n", + "IO WQ/CQ (%d), rc = 0x%x\n", qidx, (uint32_t)rc); goto out_destroy; } @@ -9937,10 +9827,8 @@ lpfc_sli4_queue_unset(struct lpfc_hba *phba) for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { /* Destroy the CQ/WQ corresponding to Hardware Queue */ qp = &phba->sli4_hba.hdwq[qidx]; - lpfc_wq_destroy(phba, qp->fcp_wq); - lpfc_wq_destroy(phba, qp->nvme_wq); - lpfc_cq_destroy(phba, qp->fcp_cq); - lpfc_cq_destroy(phba, qp->nvme_cq); + lpfc_wq_destroy(phba, qp->io_wq); + lpfc_cq_destroy(phba, qp->io_cq); } /* Loop thru all IRQ vectors */ for (qidx = 0; qidx < phba->cfg_irq_chann; qidx++) { @@ -11397,11 +11285,10 @@ static void lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba) { struct lpfc_sli4_hdw_queue *qp; - int idx, ccnt, fcnt; + int idx, ccnt; int wait_time = 0; int io_xri_cmpl = 1; int nvmet_xri_cmpl = 1; - int fcp_xri_cmpl = 1; int els_xri_cmpl = list_empty(&phba->sli4_hba.lpfc_abts_els_sgl_list); /* Driver just aborted IOs during the hba_unset process. Pause @@ -11415,32 +11302,21 @@ lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba) lpfc_nvme_wait_for_io_drain(phba); ccnt = 0; - fcnt = 0; for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { qp = &phba->sli4_hba.hdwq[idx]; - fcp_xri_cmpl = list_empty( - &qp->lpfc_abts_scsi_buf_list); - if (!fcp_xri_cmpl) /* if list is NOT empty */ - fcnt++; - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { - io_xri_cmpl = list_empty( - &qp->lpfc_abts_nvme_buf_list); - if (!io_xri_cmpl) /* if list is NOT empty */ - ccnt++; - } + io_xri_cmpl = list_empty(&qp->lpfc_abts_io_buf_list); + if (!io_xri_cmpl) /* if list is NOT empty */ + ccnt++; } if (ccnt) io_xri_cmpl = 0; - if (fcnt) - fcp_xri_cmpl = 0; if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { nvmet_xri_cmpl = list_empty(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list); } - while (!fcp_xri_cmpl || !els_xri_cmpl || !io_xri_cmpl || - !nvmet_xri_cmpl) { + while (!els_xri_cmpl || !io_xri_cmpl || !nvmet_xri_cmpl) { if (wait_time > LPFC_XRI_EXCH_BUSY_WAIT_TMO) { if (!nvmet_xri_cmpl) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -11449,12 +11325,7 @@ lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba) wait_time/1000); if (!io_xri_cmpl) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "6100 NVME XRI exchange busy " - "wait time: %d seconds.\n", - wait_time/1000); - if (!fcp_xri_cmpl) - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "2877 FCP XRI exchange busy " + "6100 IO XRI exchange busy " "wait time: %d seconds.\n", wait_time/1000); if (!els_xri_cmpl) @@ -11470,24 +11341,15 @@ lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba) } ccnt = 0; - fcnt = 0; for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { qp = &phba->sli4_hba.hdwq[idx]; - fcp_xri_cmpl = list_empty( - &qp->lpfc_abts_scsi_buf_list); - if (!fcp_xri_cmpl) /* if list is NOT empty */ - fcnt++; - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { - io_xri_cmpl = list_empty( - &qp->lpfc_abts_nvme_buf_list); - if (!io_xri_cmpl) /* if list is NOT empty */ - ccnt++; - } + io_xri_cmpl = list_empty( + &qp->lpfc_abts_io_buf_list); + if (!io_xri_cmpl) /* if list is NOT empty */ + ccnt++; } if (ccnt) io_xri_cmpl = 0; - if (fcnt) - fcp_xri_cmpl = 0; if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { nvmet_xri_cmpl = list_empty( @@ -12282,7 +12144,7 @@ lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba) lpfc_scsi_dev_block(phba); /* Flush all driver's outstanding SCSI I/Os as we are to reset */ - lpfc_sli_flush_fcp_rings(phba); + lpfc_sli_flush_io_rings(phba); /* stop all timers */ lpfc_stop_hba_timers(phba); @@ -12312,7 +12174,7 @@ lpfc_sli_prep_dev_for_perm_failure(struct lpfc_hba *phba) lpfc_stop_hba_timers(phba); /* Clean up all driver's outstanding SCSI I/Os */ - lpfc_sli_flush_fcp_rings(phba); + lpfc_sli_flush_io_rings(phba); } /** @@ -13084,12 +12946,8 @@ lpfc_sli4_prep_dev_for_reset(struct lpfc_hba *phba) /* Block all SCSI devices' I/Os on the host */ lpfc_scsi_dev_block(phba); - /* Flush all driver's outstanding SCSI I/Os as we are to reset */ - lpfc_sli_flush_fcp_rings(phba); - - /* Flush the outstanding NVME IOs if fc4 type enabled. */ - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) - lpfc_sli_flush_nvme_rings(phba); + /* Flush all driver's outstanding I/Os as we are to reset */ + lpfc_sli_flush_io_rings(phba); /* stop all timers */ lpfc_stop_hba_timers(phba); @@ -13120,12 +12978,8 @@ lpfc_sli4_prep_dev_for_perm_failure(struct lpfc_hba *phba) /* stop all timers */ lpfc_stop_hba_timers(phba); - /* Clean up all driver's outstanding SCSI I/Os */ - lpfc_sli_flush_fcp_rings(phba); - - /* Flush the outstanding NVME IOs if fc4 type enabled. */ - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) - lpfc_sli_flush_nvme_rings(phba); + /* Clean up all driver's outstanding I/Os */ + lpfc_sli_flush_io_rings(phba); } /** diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index f66859d928ac..a227e36cbdc2 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1830,7 +1830,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, */ spin_lock_irqsave(&phba->hbalock, flags); /* driver queued commands are in process of being flushed */ - if (phba->hba_flag & HBA_NVME_IOQ_FLUSH) { + if (phba->hba_flag & HBA_IOQ_FLUSH) { spin_unlock_irqrestore(&phba->hbalock, flags); lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_ABTS, "6139 Driver in reset cleanup - flushing " @@ -2091,11 +2091,11 @@ lpfc_release_nvme_buf(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_ncmd) lpfc_ncmd->cur_iocbq.sli4_xritag, lpfc_ncmd->cur_iocbq.iotag); - spin_lock_irqsave(&qp->abts_nvme_buf_list_lock, iflag); + spin_lock_irqsave(&qp->abts_io_buf_list_lock, iflag); list_add_tail(&lpfc_ncmd->list, - &qp->lpfc_abts_nvme_buf_list); + &qp->lpfc_abts_io_buf_list); qp->abts_nvme_io_bufs++; - spin_unlock_irqrestore(&qp->abts_nvme_buf_list_lock, iflag); + spin_unlock_irqrestore(&qp->abts_io_buf_list_lock, iflag); } else lpfc_release_io_buf(phba, (struct lpfc_io_buf *)lpfc_ncmd, qp); } @@ -2220,7 +2220,7 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport, if (unlikely(!ret)) { pending = 0; for (i = 0; i < phba->cfg_hdw_queue; i++) { - pring = phba->sli4_hba.hdwq[i].nvme_wq->pring; + pring = phba->sli4_hba.hdwq[i].io_wq->pring; if (!pring) continue; if (pring->txcmplq_cnt) @@ -2624,6 +2624,7 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) * lpfc_sli4_nvme_xri_aborted - Fast-path process of NVME xri abort * @phba: pointer to lpfc hba data structure. * @axri: pointer to the fcp xri abort wcqe structure. + * @lpfc_ncmd: The nvme job structure for the request being aborted. * * This routine is invoked by the worker thread to process a SLI4 fast-path * NVME aborted xri. Aborted NVME IO commands are completed to the transport @@ -2631,59 +2632,33 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) **/ void lpfc_sli4_nvme_xri_aborted(struct lpfc_hba *phba, - struct sli4_wcqe_xri_aborted *axri, int idx) + struct sli4_wcqe_xri_aborted *axri, + struct lpfc_io_buf *lpfc_ncmd) { uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); - struct lpfc_io_buf *lpfc_ncmd, *next_lpfc_ncmd; struct nvmefc_fcp_req *nvme_cmd = NULL; - struct lpfc_nodelist *ndlp; - struct lpfc_sli4_hdw_queue *qp; - unsigned long iflag = 0; + struct lpfc_nodelist *ndlp = lpfc_ncmd->ndlp; - if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) - return; - qp = &phba->sli4_hba.hdwq[idx]; - spin_lock_irqsave(&phba->hbalock, iflag); - spin_lock(&qp->abts_nvme_buf_list_lock); - list_for_each_entry_safe(lpfc_ncmd, next_lpfc_ncmd, - &qp->lpfc_abts_nvme_buf_list, list) { - if (lpfc_ncmd->cur_iocbq.sli4_xritag == xri) { - list_del_init(&lpfc_ncmd->list); - qp->abts_nvme_io_bufs--; - lpfc_ncmd->flags &= ~LPFC_SBUF_XBUSY; - lpfc_ncmd->status = IOSTAT_SUCCESS; - spin_unlock(&qp->abts_nvme_buf_list_lock); - - spin_unlock_irqrestore(&phba->hbalock, iflag); - ndlp = lpfc_ncmd->ndlp; - if (ndlp) - lpfc_sli4_abts_err_handler(phba, ndlp, axri); - - lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, - "6311 nvme_cmd x%px xri x%x tag x%x " - "abort complete and xri released\n", - lpfc_ncmd->nvmeCmd, xri, - lpfc_ncmd->cur_iocbq.iotag); - - /* Aborted NVME commands are required to not complete - * before the abort exchange command fully completes. - * Once completed, it is available via the put list. - */ - if (lpfc_ncmd->nvmeCmd) { - nvme_cmd = lpfc_ncmd->nvmeCmd; - nvme_cmd->done(nvme_cmd); - lpfc_ncmd->nvmeCmd = NULL; - } - lpfc_release_nvme_buf(phba, lpfc_ncmd); - return; - } - } - spin_unlock(&qp->abts_nvme_buf_list_lock); - spin_unlock_irqrestore(&phba->hbalock, iflag); - lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, - "6312 XRI Aborted xri x%x not found\n", xri); + if (ndlp) + lpfc_sli4_abts_err_handler(phba, ndlp, axri); + lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, + "6311 nvme_cmd %p xri x%x tag x%x abort complete and " + "xri released\n", + lpfc_ncmd->nvmeCmd, xri, + lpfc_ncmd->cur_iocbq.iotag); + + /* Aborted NVME commands are required to not complete + * before the abort exchange command fully completes. + * Once completed, it is available via the put list. + */ + if (lpfc_ncmd->nvmeCmd) { + nvme_cmd = lpfc_ncmd->nvmeCmd; + nvme_cmd->done(nvme_cmd); + lpfc_ncmd->nvmeCmd = NULL; + } + lpfc_release_nvme_buf(phba, lpfc_ncmd); } /** @@ -2705,13 +2680,13 @@ lpfc_nvme_wait_for_io_drain(struct lpfc_hba *phba) if (phba->sli_rev < LPFC_SLI_REV4 || !phba->sli4_hba.hdwq) return; - /* Cycle through all NVME rings and make sure all outstanding + /* Cycle through all IO rings and make sure all outstanding * WQEs have been removed from the txcmplqs. */ for (i = 0; i < phba->cfg_hdw_queue; i++) { - if (!phba->sli4_hba.hdwq[i].nvme_wq) + if (!phba->sli4_hba.hdwq[i].io_wq) continue; - pring = phba->sli4_hba.hdwq[i].nvme_wq->pring; + pring = phba->sli4_hba.hdwq[i].io_wq->pring; if (!pring) continue; diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 253a9fdd245e..9884228800a5 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -1026,7 +1026,7 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport, * WQE release CQE */ ctxp->flag |= LPFC_NVMET_DEFER_WQFULL; - wq = ctxp->hdwq->nvme_wq; + wq = ctxp->hdwq->io_wq; pring = wq->pring; spin_lock_irqsave(&pring->ring_lock, iflags); list_add_tail(&nvmewqeq->list, &wq->wqfull_list); @@ -1104,7 +1104,7 @@ lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port *tgtport, spin_unlock_irqrestore(&ctxp->ctxlock, flags); lpfc_nvmet_unsol_fcp_issue_abort(phba, ctxp, ctxp->sid, ctxp->oxid); - wq = ctxp->hdwq->nvme_wq; + wq = ctxp->hdwq->io_wq; lpfc_nvmet_wqfull_flush(phba, wq, ctxp); return; } @@ -1918,7 +1918,7 @@ lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba) if (phba->targetport) { tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { - wq = phba->sli4_hba.hdwq[qidx].nvme_wq; + wq = phba->sli4_hba.hdwq[qidx].io_wq; lpfc_nvmet_wqfull_flush(phba, wq, NULL); } tgtp->tport_unreg_cmp = &tport_unreg_cmp; @@ -3295,7 +3295,7 @@ lpfc_nvmet_sol_fcp_issue_abort(struct lpfc_hba *phba, */ spin_lock_irqsave(&phba->hbalock, flags); /* driver queued commands are in process of being flushed */ - if (phba->hba_flag & HBA_NVME_IOQ_FLUSH) { + if (phba->hba_flag & HBA_IOQ_FLUSH) { spin_unlock_irqrestore(&phba->hbalock, flags); atomic_inc(&tgtp->xmt_abort_rsp_error); lpfc_printf_log(phba, KERN_ERR, LOG_NVME, diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index fb7df209c0aa..7c65bd652c4d 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -537,29 +537,32 @@ lpfc_sli4_vport_delete_fcp_xri_aborted(struct lpfc_vport *vport) for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { qp = &phba->sli4_hba.hdwq[idx]; - spin_lock(&qp->abts_scsi_buf_list_lock); + spin_lock(&qp->abts_io_buf_list_lock); list_for_each_entry_safe(psb, next_psb, - &qp->lpfc_abts_scsi_buf_list, list) { + &qp->lpfc_abts_io_buf_list, list) { + if (psb->cur_iocbq.iocb_flag == LPFC_IO_NVME) + continue; + if (psb->rdata && psb->rdata->pnode && psb->rdata->pnode->vport == vport) psb->rdata = NULL; } - spin_unlock(&qp->abts_scsi_buf_list_lock); + spin_unlock(&qp->abts_io_buf_list_lock); } spin_unlock_irqrestore(&phba->hbalock, iflag); } /** - * lpfc_sli4_fcp_xri_aborted - Fast-path process of fcp xri abort + * lpfc_sli4_io_xri_aborted - Fast-path process of fcp xri abort * @phba: pointer to lpfc hba data structure. * @axri: pointer to the fcp xri abort wcqe structure. * * This routine is invoked by the worker thread to process a SLI4 fast-path - * FCP aborted xri. + * FCP or NVME aborted xri. **/ void -lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba, - struct sli4_wcqe_xri_aborted *axri, int idx) +lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, + struct sli4_wcqe_xri_aborted *axri, int idx) { uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri); @@ -577,16 +580,25 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba, qp = &phba->sli4_hba.hdwq[idx]; spin_lock_irqsave(&phba->hbalock, iflag); - spin_lock(&qp->abts_scsi_buf_list_lock); + spin_lock(&qp->abts_io_buf_list_lock); list_for_each_entry_safe(psb, next_psb, - &qp->lpfc_abts_scsi_buf_list, list) { + &qp->lpfc_abts_io_buf_list, list) { if (psb->cur_iocbq.sli4_xritag == xri) { - list_del(&psb->list); - qp->abts_scsi_io_bufs--; + list_del_init(&psb->list); psb->exch_busy = 0; psb->status = IOSTAT_SUCCESS; - spin_unlock( - &qp->abts_scsi_buf_list_lock); +#ifdef BUILD_NVME + if (psb->cur_iocbq.iocb_flag == LPFC_IO_NVME) { + qp->abts_nvme_io_bufs--; + spin_unlock(&qp->abts_io_buf_list_lock); + spin_unlock_irqrestore(&phba->hbalock, iflag); + lpfc_sli4_nvme_xri_aborted(phba, axri, psb); + return; + } +#endif + qp->abts_scsi_io_bufs--; + spin_unlock(&qp->abts_io_buf_list_lock); + if (psb->rdata && psb->rdata->pnode) ndlp = psb->rdata->pnode; else @@ -605,12 +617,12 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba, return; } } - spin_unlock(&qp->abts_scsi_buf_list_lock); + spin_unlock(&qp->abts_io_buf_list_lock); for (i = 1; i <= phba->sli.last_iotag; i++) { iocbq = phba->sli.iocbq_lookup[i]; - if (!(iocbq->iocb_flag & LPFC_IO_FCP) || - (iocbq->iocb_flag & LPFC_IO_LIBDFC)) + if (!(iocbq->iocb_flag & LPFC_IO_FCP) || + (iocbq->iocb_flag & LPFC_IO_LIBDFC)) continue; if (iocbq->sli4_xritag != xri) continue; @@ -836,11 +848,11 @@ lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *psb) qp = psb->hdwq; if (psb->exch_busy) { - spin_lock_irqsave(&qp->abts_scsi_buf_list_lock, iflag); + spin_lock_irqsave(&qp->abts_io_buf_list_lock, iflag); psb->pCmd = NULL; - list_add_tail(&psb->list, &qp->lpfc_abts_scsi_buf_list); + list_add_tail(&psb->list, &qp->lpfc_abts_io_buf_list); qp->abts_scsi_io_bufs++; - spin_unlock_irqrestore(&qp->abts_scsi_buf_list_lock, iflag); + spin_unlock_irqrestore(&qp->abts_io_buf_list_lock, iflag); } else { lpfc_release_io_buf(phba, (struct lpfc_io_buf *)psb, qp); } @@ -4800,7 +4812,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) spin_lock_irqsave(&phba->hbalock, flags); /* driver queued commands are in process of being flushed */ - if (phba->hba_flag & HBA_FCP_IOQ_FLUSH) { + if (phba->hba_flag & HBA_IOQ_FLUSH) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, "3168 SCSI Layer abort requested I/O has been " "flushed by LLD.\n"); @@ -4821,7 +4833,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) iocb = &lpfc_cmd->cur_iocbq; if (phba->sli_rev == LPFC_SLI_REV4) { - pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].fcp_wq->pring; + pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring; if (!pring_s4) { ret = FAILED; goto out_unlock_buf; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index f4beb9104d3a..0dfd30aa4d99 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -3978,7 +3978,7 @@ lpfc_sli_abort_fcp_rings(struct lpfc_hba *phba) /* Look on all the FCP Rings for the iotag */ if (phba->sli_rev >= LPFC_SLI_REV4) { for (i = 0; i < phba->cfg_hdw_queue; i++) { - pring = phba->sli4_hba.hdwq[i].fcp_wq->pring; + pring = phba->sli4_hba.hdwq[i].io_wq->pring; lpfc_sli_abort_iocb_ring(phba, pring); } } else { @@ -3988,17 +3988,17 @@ lpfc_sli_abort_fcp_rings(struct lpfc_hba *phba) } /** - * lpfc_sli_flush_fcp_rings - flush all iocbs in the fcp ring + * lpfc_sli_flush_io_rings - flush all iocbs in the IO ring * @phba: Pointer to HBA context object. * - * This function flushes all iocbs in the fcp ring and frees all the iocb + * This function flushes all iocbs in the IO ring and frees all the iocb * objects in txq and txcmplq. This function will not issue abort iocbs * for all the iocb commands in txcmplq, they will just be returned with * IOERR_SLI_DOWN. This function is invoked with EEH when device's PCI * slot has been permanently disabled. **/ void -lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba) +lpfc_sli_flush_io_rings(struct lpfc_hba *phba) { LIST_HEAD(txq); LIST_HEAD(txcmplq); @@ -4009,13 +4009,13 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba) spin_lock_irq(&phba->hbalock); /* Indicate the I/O queues are flushed */ - phba->hba_flag |= HBA_FCP_IOQ_FLUSH; + phba->hba_flag |= HBA_IOQ_FLUSH; spin_unlock_irq(&phba->hbalock); /* Look on all the FCP Rings for the iotag */ if (phba->sli_rev >= LPFC_SLI_REV4) { for (i = 0; i < phba->cfg_hdw_queue; i++) { - pring = phba->sli4_hba.hdwq[i].fcp_wq->pring; + pring = phba->sli4_hba.hdwq[i].io_wq->pring; spin_lock_irq(&pring->ring_lock); /* Retrieve everything on txq */ @@ -4062,56 +4062,6 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba) } } -/** - * lpfc_sli_flush_nvme_rings - flush all wqes in the nvme rings - * @phba: Pointer to HBA context object. - * - * This function flushes all wqes in the nvme rings and frees all resources - * in the txcmplq. This function does not issue abort wqes for the IO - * commands in txcmplq, they will just be returned with - * IOERR_SLI_DOWN. This function is invoked with EEH when device's PCI - * slot has been permanently disabled. - **/ -void -lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba) -{ - LIST_HEAD(txcmplq); - struct lpfc_sli_ring *pring; - uint32_t i; - struct lpfc_iocbq *piocb, *next_iocb; - - if ((phba->sli_rev < LPFC_SLI_REV4) || - !(phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) - return; - - /* Hint to other driver operations that a flush is in progress. */ - spin_lock_irq(&phba->hbalock); - phba->hba_flag |= HBA_NVME_IOQ_FLUSH; - spin_unlock_irq(&phba->hbalock); - - /* Cycle through all NVME rings and complete each IO with - * a local driver reason code. This is a flush so no - * abort exchange to FW. - */ - for (i = 0; i < phba->cfg_hdw_queue; i++) { - pring = phba->sli4_hba.hdwq[i].nvme_wq->pring; - - spin_lock_irq(&pring->ring_lock); - list_for_each_entry_safe(piocb, next_iocb, - &pring->txcmplq, list) - piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ; - /* Retrieve everything on the txcmplq */ - list_splice_init(&pring->txcmplq, &txcmplq); - pring->txcmplq_cnt = 0; - spin_unlock_irq(&pring->ring_lock); - - /* Flush the txcmpq &&&PAE */ - lpfc_sli_cancel_iocbs(phba, &txcmplq, - IOSTAT_LOCAL_REJECT, - IOERR_SLI_DOWN); - } -} - /** * lpfc_sli_brdready_s3 - Check for sli3 host ready status * @phba: Pointer to HBA context object. @@ -5603,10 +5553,8 @@ lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba) for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { qp = &sli4_hba->hdwq[qidx]; /* ARM the corresponding CQ */ - sli4_hba->sli4_write_cq_db(phba, qp->fcp_cq, 0, - LPFC_QUEUE_REARM); - sli4_hba->sli4_write_cq_db(phba, qp->nvme_cq, 0, - LPFC_QUEUE_REARM); + sli4_hba->sli4_write_cq_db(phba, qp[qidx].io_cq, 0, + LPFC_QUEUE_REARM); } /* Loop thru all IRQ vectors */ @@ -7262,7 +7210,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) else phba->hba_flag &= ~HBA_FIP_SUPPORT; - phba->hba_flag &= ~HBA_FCP_IOQ_FLUSH; + phba->hba_flag &= ~HBA_IOQ_FLUSH; if (phba->sli_rev != LPFC_SLI_REV4) { lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, @@ -9930,7 +9878,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, /* Get the WQ */ if ((piocb->iocb_flag & LPFC_IO_FCP) || (piocb->iocb_flag & LPFC_USE_FCPWQIDX)) { - wq = phba->sli4_hba.hdwq[piocb->hba_wqidx].fcp_wq; + wq = phba->sli4_hba.hdwq[piocb->hba_wqidx].io_wq; } else { wq = phba->sli4_hba.els_wq; } @@ -10077,7 +10025,7 @@ lpfc_sli4_calc_ring(struct lpfc_hba *phba, struct lpfc_iocbq *piocb) lpfc_cmd = (struct lpfc_io_buf *)piocb->context1; piocb->hba_wqidx = lpfc_cmd->hdwq_no; } - return phba->sli4_hba.hdwq[piocb->hba_wqidx].fcp_wq->pring; + return phba->sli4_hba.hdwq[piocb->hba_wqidx].io_wq->pring; } else { if (unlikely(!phba->sli4_hba.els_wq)) return NULL; @@ -10530,7 +10478,7 @@ lpfc_sli4_queue_init(struct lpfc_hba *phba) INIT_LIST_HEAD(&psli->mboxq_cmpl); /* Initialize list headers for txq and txcmplq as double linked lists */ for (i = 0; i < phba->cfg_hdw_queue; i++) { - pring = phba->sli4_hba.hdwq[i].fcp_wq->pring; + pring = phba->sli4_hba.hdwq[i].io_wq->pring; pring->flag = 0; pring->ringno = LPFC_FCP_RING; pring->txcmplq_cnt = 0; @@ -10549,16 +10497,6 @@ lpfc_sli4_queue_init(struct lpfc_hba *phba) spin_lock_init(&pring->ring_lock); if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { - for (i = 0; i < phba->cfg_hdw_queue; i++) { - pring = phba->sli4_hba.hdwq[i].nvme_wq->pring; - pring->flag = 0; - pring->ringno = LPFC_FCP_RING; - pring->txcmplq_cnt = 0; - INIT_LIST_HEAD(&pring->txq); - INIT_LIST_HEAD(&pring->txcmplq); - INIT_LIST_HEAD(&pring->iocb_continueq); - spin_lock_init(&pring->ring_lock); - } pring = phba->sli4_hba.nvmels_wq->pring; pring->flag = 0; pring->ringno = LPFC_ELS_RING; @@ -11522,7 +11460,7 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, int i; /* all I/Os are in process of being flushed */ - if (phba->hba_flag & HBA_FCP_IOQ_FLUSH) + if (phba->hba_flag & HBA_IOQ_FLUSH) return errcnt; for (i = 1; i <= phba->sli.last_iotag; i++) { @@ -11632,7 +11570,7 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, spin_lock_irqsave(&phba->hbalock, iflags); /* all I/Os are in process of being flushed */ - if (phba->hba_flag & HBA_FCP_IOQ_FLUSH) { + if (phba->hba_flag & HBA_IOQ_FLUSH) { spin_unlock_irqrestore(&phba->hbalock, iflags); return 0; } @@ -11656,7 +11594,7 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, if (phba->sli_rev == LPFC_SLI_REV4) { pring_s4 = - phba->sli4_hba.hdwq[iocbq->hba_wqidx].fcp_wq->pring; + phba->sli4_hba.hdwq[iocbq->hba_wqidx].io_wq->pring; if (!pring_s4) { spin_unlock(&lpfc_cmd->buf_lock); continue; @@ -13365,8 +13303,13 @@ lpfc_sli4_sp_handle_abort_xri_wcqe(struct lpfc_hba *phba, unsigned long iflags; switch (cq->subtype) { - case LPFC_FCP: - lpfc_sli4_fcp_xri_aborted(phba, wcqe, cq->hdwq); + case LPFC_IO: + lpfc_sli4_io_xri_aborted(phba, wcqe, cq->hdwq); + if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { + /* Notify aborted XRI for NVME work queue */ + if (phba->nvmet_support) + lpfc_sli4_nvmet_xri_aborted(phba, wcqe); + } workposted = false; break; case LPFC_NVME_LS: /* NVME LS uses ELS resources */ @@ -13384,15 +13327,6 @@ lpfc_sli4_sp_handle_abort_xri_wcqe(struct lpfc_hba *phba, spin_unlock_irqrestore(&phba->hbalock, iflags); workposted = true; break; - case LPFC_NVME: - /* Notify aborted XRI for NVME work queue */ - if (phba->nvmet_support) - lpfc_sli4_nvmet_xri_aborted(phba, wcqe); - else - lpfc_sli4_nvme_xri_aborted(phba, wcqe, cq->hdwq); - - workposted = false; - break; default: lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "0603 Invalid CQ subtype %d: " @@ -13720,7 +13654,7 @@ __lpfc_sli4_sp_process_cq(struct lpfc_queue *cq) &delay); break; case LPFC_WCQ: - if (cq->subtype == LPFC_FCP || cq->subtype == LPFC_NVME) + if (cq->subtype == LPFC_IO) workposted |= __lpfc_sli4_process_cq(phba, cq, lpfc_sli4_fp_handle_cqe, &delay); @@ -14037,10 +13971,7 @@ lpfc_sli4_fp_handle_cqe(struct lpfc_hba *phba, struct lpfc_queue *cq, cq->CQ_wq++; /* Process the WQ complete event */ phba->last_completion_time = jiffies; - if ((cq->subtype == LPFC_FCP) || (cq->subtype == LPFC_NVME)) - lpfc_sli4_fp_handle_fcp_wcqe(phba, cq, - (struct lpfc_wcqe_complete *)&wcqe); - if (cq->subtype == LPFC_NVME_LS) + if (cq->subtype == LPFC_IO || cq->subtype == LPFC_NVME_LS) lpfc_sli4_fp_handle_fcp_wcqe(phba, cq, (struct lpfc_wcqe_complete *)&wcqe); break; @@ -19506,7 +19437,7 @@ lpfc_drain_txq(struct lpfc_hba *phba) if (phba->link_flag & LS_MDS_LOOPBACK) { /* MDS WQE are posted only to first WQ*/ - wq = phba->sli4_hba.hdwq[0].fcp_wq; + wq = phba->sli4_hba.hdwq[0].io_wq; if (unlikely(!wq)) return 0; pring = wq->pring; @@ -19757,10 +19688,10 @@ lpfc_sli4_issue_wqe(struct lpfc_hba *phba, struct lpfc_sli4_hdw_queue *qp, /* NVME_FCREQ and NVME_ABTS requests */ if (pwqe->iocb_flag & LPFC_IO_NVME) { /* Get the IO distribution (hba_wqidx) for WQ assignment. */ - wq = qp->nvme_wq; + wq = qp->io_wq; pring = wq->pring; - bf_set(wqe_cqid, &wqe->generic.wqe_com, qp->nvme_cq_map); + bf_set(wqe_cqid, &wqe->generic.wqe_com, qp->io_cq_map); lpfc_qp_spin_lock_irqsave(&pring->ring_lock, iflags, qp, wq_access); @@ -19777,7 +19708,7 @@ lpfc_sli4_issue_wqe(struct lpfc_hba *phba, struct lpfc_sli4_hdw_queue *qp, /* NVMET requests */ if (pwqe->iocb_flag & LPFC_IO_NVMET) { /* Get the IO distribution (hba_wqidx) for WQ assignment. */ - wq = qp->nvme_wq; + wq = qp->io_wq; pring = wq->pring; ctxp = pwqe->context2; @@ -19788,7 +19719,7 @@ lpfc_sli4_issue_wqe(struct lpfc_hba *phba, struct lpfc_sli4_hdw_queue *qp, } bf_set(wqe_xri_tag, &pwqe->wqe.xmit_bls_rsp.wqe_com, pwqe->sli4_xritag); - bf_set(wqe_cqid, &wqe->generic.wqe_com, qp->nvme_cq_map); + bf_set(wqe_cqid, &wqe->generic.wqe_com, qp->io_cq_map); lpfc_qp_spin_lock_irqsave(&pring->ring_lock, iflags, qp, wq_access); @@ -19835,9 +19766,7 @@ void lpfc_snapshot_mxp(struct lpfc_hba *phba, u32 hwqid) if (multixri_pool->stat_snapshot_taken == LPFC_MXP_SNAPSHOT_TAKEN) { pvt_pool = &qp->p_multixri_pool->pvt_pool; pbl_pool = &qp->p_multixri_pool->pbl_pool; - txcmplq_cnt = qp->fcp_wq->pring->txcmplq_cnt; - if (qp->nvme_wq) - txcmplq_cnt += qp->nvme_wq->pring->txcmplq_cnt; + txcmplq_cnt = qp->io_wq->pring->txcmplq_cnt; multixri_pool->stat_pbl_count = pbl_pool->count; multixri_pool->stat_pvt_count = pvt_pool->count; @@ -19907,12 +19836,9 @@ void lpfc_adjust_high_watermark(struct lpfc_hba *phba, u32 hwqid) watermark_max = xri_limit; watermark_min = xri_limit / 2; - txcmplq_cnt = qp->fcp_wq->pring->txcmplq_cnt; + txcmplq_cnt = qp->io_wq->pring->txcmplq_cnt; abts_io_bufs = qp->abts_scsi_io_bufs; - if (qp->nvme_wq) { - txcmplq_cnt += qp->nvme_wq->pring->txcmplq_cnt; - abts_io_bufs += qp->abts_nvme_io_bufs; - } + abts_io_bufs += qp->abts_nvme_io_bufs; new_watermark = txcmplq_cnt + abts_io_bufs; new_watermark = min(watermark_max, new_watermark); @@ -20187,12 +20113,9 @@ void lpfc_release_io_buf(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_ncmd, pbl_pool = &qp->p_multixri_pool->pbl_pool; pvt_pool = &qp->p_multixri_pool->pvt_pool; - txcmplq_cnt = qp->fcp_wq->pring->txcmplq_cnt; + txcmplq_cnt = qp->io_wq->pring->txcmplq_cnt; abts_io_bufs = qp->abts_scsi_io_bufs; - if (qp->nvme_wq) { - txcmplq_cnt += qp->nvme_wq->pring->txcmplq_cnt; - abts_io_bufs += qp->abts_nvme_io_bufs; - } + abts_io_bufs += qp->abts_nvme_io_bufs; xri_owned = pvt_pool->count + txcmplq_cnt + abts_io_bufs; xri_limit = qp->p_multixri_pool->xri_limit; diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 3ec9cf4c6427..11a72bbef8f7 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -109,9 +109,8 @@ enum lpfc_sli4_queue_type { enum lpfc_sli4_queue_subtype { LPFC_NONE, LPFC_MBOX, - LPFC_FCP, + LPFC_IO, LPFC_ELS, - LPFC_NVME, LPFC_NVMET, LPFC_NVME_LS, LPFC_USOL @@ -641,22 +640,17 @@ struct lpfc_eq_intr_info { struct lpfc_sli4_hdw_queue { /* Pointers to the constructed SLI4 queues */ struct lpfc_queue *hba_eq; /* Event queues for HBA */ - struct lpfc_queue *fcp_cq; /* Fast-path FCP compl queue */ - struct lpfc_queue *nvme_cq; /* Fast-path NVME compl queue */ - struct lpfc_queue *fcp_wq; /* Fast-path FCP work queue */ - struct lpfc_queue *nvme_wq; /* Fast-path NVME work queue */ - uint16_t fcp_cq_map; - uint16_t nvme_cq_map; + struct lpfc_queue *io_cq; /* Fast-path FCP & NVME compl queue */ + struct lpfc_queue *io_wq; /* Fast-path FCP & NVME work queue */ + uint16_t io_cq_map; /* Keep track of IO buffers for this hardware queue */ spinlock_t io_buf_list_get_lock; /* Common buf alloc list lock */ struct list_head lpfc_io_buf_list_get; spinlock_t io_buf_list_put_lock; /* Common buf free list lock */ struct list_head lpfc_io_buf_list_put; - spinlock_t abts_scsi_buf_list_lock; /* list of aborted SCSI IOs */ - struct list_head lpfc_abts_scsi_buf_list; - spinlock_t abts_nvme_buf_list_lock; /* list of aborted NVME IOs */ - struct list_head lpfc_abts_nvme_buf_list; + spinlock_t abts_io_buf_list_lock; /* list of aborted IOs */ + struct list_head lpfc_abts_io_buf_list; uint32_t total_io_bufs; uint32_t get_io_bufs; uint32_t put_io_bufs; @@ -852,8 +846,8 @@ struct lpfc_sli4_hba { struct lpfc_queue **cq_lookup; struct list_head lpfc_els_sgl_list; struct list_head lpfc_abts_els_sgl_list; - spinlock_t abts_scsi_buf_list_lock; /* list of aborted SCSI IOs */ - struct list_head lpfc_abts_scsi_buf_list; + spinlock_t abts_io_buf_list_lock; /* list of aborted SCSI IOs */ + struct list_head lpfc_abts_io_buf_list; struct list_head lpfc_nvmet_sgl_list; spinlock_t abts_nvmet_buf_list_lock; /* list of aborted NVMET IOs */ struct list_head lpfc_abts_nvmet_ctx_list; @@ -1058,10 +1052,11 @@ int lpfc_sli4_resume_rpi(struct lpfc_nodelist *, void (*)(struct lpfc_hba *, LPFC_MBOXQ_t *), void *); void lpfc_sli4_fcp_xri_abort_event_proc(struct lpfc_hba *); void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *); -void lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *, - struct sli4_wcqe_xri_aborted *, int); void lpfc_sli4_nvme_xri_aborted(struct lpfc_hba *phba, - struct sli4_wcqe_xri_aborted *axri, int idx); + struct sli4_wcqe_xri_aborted *axri, + struct lpfc_io_buf *lpfc_ncmd); +void lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, + struct sli4_wcqe_xri_aborted *axri, int idx); void lpfc_sli4_nvmet_xri_aborted(struct lpfc_hba *phba, struct sli4_wcqe_xri_aborted *axri); void lpfc_sli4_els_xri_aborted(struct lpfc_hba *, -- cgit v1.2.3-59-g8ed1b From 7f9989bace91a7a36051d64cbf46f7760c52bbf0 Mon Sep 17 00:00:00 2001 From: James Smart Date: Tue, 27 Aug 2019 14:27:46 -0700 Subject: scsi: lpfc: Resolve checker warning for lpfc_new_io_buf() Per Dan Carpenter: The patch d79c9e9d4b3d: "scsi: lpfc: Support dynamic unbounded SGL lists on G7 hardware." from Aug 14, 2019, leads to the following static checker warning: drivers/scsi/lpfc/lpfc_init.c:4107 lpfc_new_io_buf() error: not allocating enough data 784 vs 768 There was no need to compare sizes nor to allocate size based on a define. Change allocation to use actual structure length Signed-off-by: Dick Kennedy Signed-off-by: James Smart CC: Dan Carpenter Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 11 +---------- drivers/scsi/lpfc/lpfc_sli4.h | 3 --- 2 files changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 0bc04af1d2fb..de92eb86579a 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -4093,18 +4093,9 @@ lpfc_new_io_buf(struct lpfc_hba *phba, int num_to_alloc) LIST_HEAD(post_nblist); LIST_HEAD(nvme_nblist); - /* Sanity check to ensure our sizing is right for both SCSI and NVME */ - if (sizeof(struct lpfc_io_buf) > LPFC_COMMON_IO_BUF_SZ) { - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "6426 Common buffer size %zd exceeds %d\n", - sizeof(struct lpfc_io_buf), - LPFC_COMMON_IO_BUF_SZ); - return 0; - } - phba->sli4_hba.io_xri_cnt = 0; for (bcnt = 0; bcnt < num_to_alloc; bcnt++) { - lpfc_ncmd = kzalloc(LPFC_COMMON_IO_BUF_SZ, GFP_KERNEL); + lpfc_ncmd = kzalloc(sizeof(*lpfc_ncmd), GFP_KERNEL); if (!lpfc_ncmd) break; /* diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 11a72bbef8f7..4bdd58de4692 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -44,9 +44,6 @@ #define LPFC_HBA_HDWQ_MAX 128 #define LPFC_HBA_HDWQ_DEF 0 -/* Common buffer size to accomidate SCSI and NVME IO buffers */ -#define LPFC_COMMON_IO_BUF_SZ 768 - /* * Provide the default FCF Record attributes used by the driver * when nonFIP mode is configured and there is no other default -- cgit v1.2.3-59-g8ed1b From 9db6c14c36fc8f7824ade95f53bcdad43df678b4 Mon Sep 17 00:00:00 2001 From: James Smart Date: Tue, 27 Aug 2019 14:28:05 -0700 Subject: scsi: lpfc: Remove bg debugfs buffers Capturing and downloading dif command data and dif data was done a dozen years ago and no longer being used. Also creates a potential security hole. Remove the debugfs buffer for dif debugging. Signed-off-by: Dick Kennedy Signed-off-by: James Smart CC: KyleMahlkuch CC: Hannes Reinecke Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc.h | 2 - drivers/scsi/lpfc/lpfc_crtn.h | 10 --- drivers/scsi/lpfc/lpfc_debugfs.c | 134 --------------------------------------- drivers/scsi/lpfc/lpfc_init.c | 70 -------------------- drivers/scsi/lpfc/lpfc_scsi.c | 79 ----------------------- 5 files changed, 295 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 11873f0d521c..d890564f00cc 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -1038,8 +1038,6 @@ struct lpfc_hba { struct dentry *debug_hbqinfo; struct dentry *debug_dumpHostSlim; struct dentry *debug_dumpHBASlim; - struct dentry *debug_dumpData; /* BlockGuard BPL */ - struct dentry *debug_dumpDif; /* BlockGuard BPL */ struct dentry *debug_InjErrLBA; /* LBA to inject errors at */ struct dentry *debug_InjErrNPortID; /* NPortID to inject errors at */ struct dentry *debug_InjErrWWPN; /* WWPN to inject errors at */ diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 8b84acc95a07..b2ad8c750486 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -433,16 +433,6 @@ int lpfc_sli4_get_allocated_extnts(struct lpfc_hba *, uint16_t, int lpfc_sli4_get_avail_extnt_rsrc(struct lpfc_hba *, uint16_t, uint16_t *, uint16_t *); -/* externs BlockGuard */ -extern char *_dump_buf_data; -extern unsigned long _dump_buf_data_order; -extern char *_dump_buf_dif; -extern unsigned long _dump_buf_dif_order; -extern spinlock_t _dump_buf_lock; -extern int _dump_buf_done; -extern spinlock_t pgcnt_lock; -extern unsigned int pgcnt; - /* Interface exported by fabric iocb scheduler */ void lpfc_fabric_abort_nport(struct lpfc_nodelist *); void lpfc_fabric_abort_hba(struct lpfc_hba *); diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 45f431fbe0d2..8d34be60d379 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -2162,89 +2162,6 @@ out: return rc; } -static int -lpfc_debugfs_dumpData_open(struct inode *inode, struct file *file) -{ - struct lpfc_debug *debug; - int rc = -ENOMEM; - - if (!_dump_buf_data) - return -EBUSY; - - debug = kmalloc(sizeof(*debug), GFP_KERNEL); - if (!debug) - goto out; - - /* Round to page boundary */ - pr_err("9059 BLKGRD: %s: _dump_buf_data=0x%p\n", - __func__, _dump_buf_data); - debug->buffer = _dump_buf_data; - if (!debug->buffer) { - kfree(debug); - goto out; - } - - debug->len = (1 << _dump_buf_data_order) << PAGE_SHIFT; - file->private_data = debug; - - rc = 0; -out: - return rc; -} - -static int -lpfc_debugfs_dumpDif_open(struct inode *inode, struct file *file) -{ - struct lpfc_debug *debug; - int rc = -ENOMEM; - - if (!_dump_buf_dif) - return -EBUSY; - - debug = kmalloc(sizeof(*debug), GFP_KERNEL); - if (!debug) - goto out; - - /* Round to page boundary */ - pr_err("9060 BLKGRD: %s: _dump_buf_dif=x%px file=%pD\n", - __func__, _dump_buf_dif, file); - debug->buffer = _dump_buf_dif; - if (!debug->buffer) { - kfree(debug); - goto out; - } - - debug->len = (1 << _dump_buf_dif_order) << PAGE_SHIFT; - file->private_data = debug; - - rc = 0; -out: - return rc; -} - -static ssize_t -lpfc_debugfs_dumpDataDif_write(struct file *file, const char __user *buf, - size_t nbytes, loff_t *ppos) -{ - /* - * The Data/DIF buffers only save one failing IO - * The write op is used as a reset mechanism after an IO has - * already been saved to the next one can be saved - */ - spin_lock(&_dump_buf_lock); - - memset((void *)_dump_buf_data, 0, - ((1 << PAGE_SHIFT) << _dump_buf_data_order)); - memset((void *)_dump_buf_dif, 0, - ((1 << PAGE_SHIFT) << _dump_buf_dif_order)); - - _dump_buf_done = 0; - - spin_unlock(&_dump_buf_lock); - - return nbytes; -} - static ssize_t lpfc_debugfs_dif_err_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) @@ -2457,17 +2374,6 @@ lpfc_debugfs_release(struct inode *inode, struct file *file) return 0; } -static int -lpfc_debugfs_dumpDataDif_release(struct inode *inode, struct file *file) -{ - struct lpfc_debug *debug = file->private_data; - - debug->buffer = NULL; - kfree(debug); - - return 0; -} - /** * lpfc_debugfs_multixripools_write - Clear multi-XRI pools statistics * @file: The file pointer to read from. @@ -5448,26 +5354,6 @@ static const struct file_operations lpfc_debugfs_op_cpucheck = { .release = lpfc_debugfs_release, }; -#undef lpfc_debugfs_op_dumpData -static const struct file_operations lpfc_debugfs_op_dumpData = { - .owner = THIS_MODULE, - .open = lpfc_debugfs_dumpData_open, - .llseek = lpfc_debugfs_lseek, - .read = lpfc_debugfs_read, - .write = lpfc_debugfs_dumpDataDif_write, - .release = lpfc_debugfs_dumpDataDif_release, -}; - -#undef lpfc_debugfs_op_dumpDif -static const struct file_operations lpfc_debugfs_op_dumpDif = { - .owner = THIS_MODULE, - .open = lpfc_debugfs_dumpDif_open, - .llseek = lpfc_debugfs_lseek, - .read = lpfc_debugfs_read, - .write = lpfc_debugfs_dumpDataDif_write, - .release = lpfc_debugfs_dumpDataDif_release, -}; - #undef lpfc_debugfs_op_dif_err static const struct file_operations lpfc_debugfs_op_dif_err = { .owner = THIS_MODULE, @@ -5864,20 +5750,6 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) } else phba->debug_dumpHostSlim = NULL; - /* Setup dumpData */ - snprintf(name, sizeof(name), "dumpData"); - phba->debug_dumpData = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_op_dumpData); - - /* Setup dumpDif */ - snprintf(name, sizeof(name), "dumpDif"); - phba->debug_dumpDif = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_op_dumpDif); - /* Setup DIF Error Injections */ snprintf(name, sizeof(name), "InjErrLBA"); phba->debug_InjErrLBA = @@ -6255,12 +6127,6 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */ phba->debug_dumpHostSlim = NULL; - debugfs_remove(phba->debug_dumpData); /* dumpData */ - phba->debug_dumpData = NULL; - - debugfs_remove(phba->debug_dumpDif); /* dumpDif */ - phba->debug_dumpDif = NULL; - debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */ phba->debug_InjErrLBA = NULL; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index de92eb86579a..de64880c6c60 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -66,12 +66,6 @@ #include "lpfc_version.h" #include "lpfc_ids.h" -char *_dump_buf_data; -unsigned long _dump_buf_data_order; -char *_dump_buf_dif; -unsigned long _dump_buf_dif_order; -spinlock_t _dump_buf_lock; - /* Used when mapping IRQ vectors in a driver centric manner */ static uint32_t lpfc_present_cpu; @@ -7617,7 +7611,6 @@ lpfc_setup_bg(struct lpfc_hba *phba, struct Scsi_Host *shost) uint32_t old_mask; uint32_t old_guard; - int pagecnt = 10; if (phba->cfg_prot_mask && phba->cfg_prot_guard) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "1478 Registering BlockGuard with the " @@ -7654,56 +7647,6 @@ lpfc_setup_bg(struct lpfc_hba *phba, struct Scsi_Host *shost) "layer, Bad protection parameters: %d %d\n", old_mask, old_guard); } - - if (!_dump_buf_data) { - while (pagecnt) { - spin_lock_init(&_dump_buf_lock); - _dump_buf_data = - (char *) __get_free_pages(GFP_KERNEL, pagecnt); - if (_dump_buf_data) { - lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9043 BLKGRD: allocated %d pages for " - "_dump_buf_data at x%px\n", - (1 << pagecnt), _dump_buf_data); - _dump_buf_data_order = pagecnt; - memset(_dump_buf_data, 0, - ((1 << PAGE_SHIFT) << pagecnt)); - break; - } else - --pagecnt; - } - if (!_dump_buf_data_order) - lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9044 BLKGRD: ERROR unable to allocate " - "memory for hexdump\n"); - } else - lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9045 BLKGRD: already allocated _dump_buf_data=x%px" - "\n", _dump_buf_data); - if (!_dump_buf_dif) { - while (pagecnt) { - _dump_buf_dif = - (char *) __get_free_pages(GFP_KERNEL, pagecnt); - if (_dump_buf_dif) { - lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9046 BLKGRD: allocated %d pages for " - "_dump_buf_dif at x%px\n", - (1 << pagecnt), _dump_buf_dif); - _dump_buf_dif_order = pagecnt; - memset(_dump_buf_dif, 0, - ((1 << PAGE_SHIFT) << pagecnt)); - break; - } else - --pagecnt; - } - if (!_dump_buf_dif_order) - lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9047 BLKGRD: ERROR unable to allocate " - "memory for hexdump\n"); - } else - lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9048 BLKGRD: already allocated _dump_buf_dif=x%px\n", - _dump_buf_dif); } /** @@ -13511,19 +13454,6 @@ lpfc_exit(void) pci_unregister_driver(&lpfc_driver); fc_release_transport(lpfc_transport_template); fc_release_transport(lpfc_vport_transport_template); - if (_dump_buf_data) { - printk(KERN_ERR "9062 BLKGRD: freeing %lu pages for " - "_dump_buf_data at x%px\n", - (1L << _dump_buf_data_order), _dump_buf_data); - free_pages((unsigned long)_dump_buf_data, _dump_buf_data_order); - } - - if (_dump_buf_dif) { - printk(KERN_ERR "9049 BLKGRD: freeing %lu pages for " - "_dump_buf_dif at x%px\n", - (1L << _dump_buf_dif_order), _dump_buf_dif); - free_pages((unsigned long)_dump_buf_dif, _dump_buf_dif_order); - } idr_destroy(&lpfc_hba_index); } diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 7c65bd652c4d..fe1097666de4 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -53,8 +53,6 @@ #define LPFC_RESET_WAIT 2 #define LPFC_ABORT_WAIT 2 -int _dump_buf_done = 1; - static char *dif_op_str[] = { "PROT_NORMAL", "PROT_READ_INSERT", @@ -89,63 +87,6 @@ lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_io_buf *psb); static int lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc); -static void -lpfc_debug_save_data(struct lpfc_hba *phba, struct scsi_cmnd *cmnd) -{ - void *src, *dst; - struct scatterlist *sgde = scsi_sglist(cmnd); - - if (!_dump_buf_data) { - lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9050 BLKGRD: ERROR %s _dump_buf_data is NULL\n", - __func__); - return; - } - - - if (!sgde) { - lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9051 BLKGRD: ERROR: data scatterlist is null\n"); - return; - } - - dst = (void *) _dump_buf_data; - while (sgde) { - src = sg_virt(sgde); - memcpy(dst, src, sgde->length); - dst += sgde->length; - sgde = sg_next(sgde); - } -} - -static void -lpfc_debug_save_dif(struct lpfc_hba *phba, struct scsi_cmnd *cmnd) -{ - void *src, *dst; - struct scatterlist *sgde = scsi_prot_sglist(cmnd); - - if (!_dump_buf_dif) { - lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9052 BLKGRD: ERROR %s _dump_buf_data is NULL\n", - __func__); - return; - } - - if (!sgde) { - lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9053 BLKGRD: ERROR: prot scatterlist is null\n"); - return; - } - - dst = _dump_buf_dif; - while (sgde) { - src = sg_virt(sgde); - memcpy(dst, src, sgde->length); - dst += sgde->length; - sgde = sg_next(sgde); - } -} - static inline unsigned lpfc_cmd_blksize(struct scsi_cmnd *sc) { @@ -2962,26 +2903,6 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, uint32_t bgstat = bgf->bgstat; uint64_t failing_sector = 0; - spin_lock(&_dump_buf_lock); - if (!_dump_buf_done) { - lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9070 BLKGRD: Saving" - " Data for %u blocks to debugfs\n", - (cmd->cmnd[7] << 8 | cmd->cmnd[8])); - lpfc_debug_save_data(phba, cmd); - - /* If we have a prot sgl, save the DIF buffer */ - if (lpfc_prot_group_type(phba, cmd) == - LPFC_PG_TYPE_DIF_BUF) { - lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9071 BLKGRD: " - "Saving DIF for %u blocks to debugfs\n", - (cmd->cmnd[7] << 8 | cmd->cmnd[8])); - lpfc_debug_save_dif(phba, cmd); - } - - _dump_buf_done = 1; - } - spin_unlock(&_dump_buf_lock); - if (lpfc_bgs_get_invalid_prof(bgstat)) { cmd->result = DID_ERROR << 16; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, -- cgit v1.2.3-59-g8ed1b