Commit a5f7337f authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: Fix NVME io abort failures causing hangs

The nvme-fc transport may call to abort an io on controller reset. If the
driver is out of resources to issue an abort command, it just gives up and
does nothing. The transport expects the lldd to always be able to terminate
an io it has issued.  At that point, the controller hangs waiting for
aborted ios to be returned.  Note: flaged by "6136" and "6176" error
messages.

Root issue was the adapter mis-allocated the number resources it allocated
for command entries for the adapter.

Convert the driver to allocate command resources based on the number of
xris supported by the FC port - 1 resource for the original command and 1
resource for the abort request.

Link: https://lore.kernel.org/r/20190922035906.10977-5-jsmart2021@gmail.comSigned-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent b7b95fb8
...@@ -872,7 +872,6 @@ struct lpfc_hba { ...@@ -872,7 +872,6 @@ struct lpfc_hba {
uint32_t cfg_aer_support; uint32_t cfg_aer_support;
uint32_t cfg_sriov_nr_virtfn; uint32_t cfg_sriov_nr_virtfn;
uint32_t cfg_request_firmware_upgrade; uint32_t cfg_request_firmware_upgrade;
uint32_t cfg_iocb_cnt;
uint32_t cfg_suppress_link_up; uint32_t cfg_suppress_link_up;
uint32_t cfg_rrq_xri_bitmap_sz; uint32_t cfg_rrq_xri_bitmap_sz;
uint32_t cfg_delay_discovery; uint32_t cfg_delay_discovery;
......
...@@ -3582,9 +3582,6 @@ lpfc_txcmplq_hw_show(struct device *dev, struct device_attribute *attr, ...@@ -3582,9 +3582,6 @@ lpfc_txcmplq_hw_show(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(txcmplq_hw, S_IRUGO, static DEVICE_ATTR(txcmplq_hw, S_IRUGO,
lpfc_txcmplq_hw_show, NULL); lpfc_txcmplq_hw_show, NULL);
LPFC_ATTR_R(iocb_cnt, 2, 1, 5,
"Number of IOCBs alloc for ELS, CT, and ABTS: 1k to 5k IOCBs");
/* /*
# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
# until the timer expires. Value range is [0,255]. Default value is 30. # until the timer expires. Value range is [0,255]. Default value is 30.
...@@ -6073,7 +6070,6 @@ struct device_attribute *lpfc_hba_attrs[] = { ...@@ -6073,7 +6070,6 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_sriov_nr_virtfn, &dev_attr_lpfc_sriov_nr_virtfn,
&dev_attr_lpfc_req_fw_upgrade, &dev_attr_lpfc_req_fw_upgrade,
&dev_attr_lpfc_suppress_link_up, &dev_attr_lpfc_suppress_link_up,
&dev_attr_lpfc_iocb_cnt,
&dev_attr_iocb_hw, &dev_attr_iocb_hw,
&dev_attr_txq_hw, &dev_attr_txq_hw,
&dev_attr_txcmplq_hw, &dev_attr_txcmplq_hw,
...@@ -7212,7 +7208,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) ...@@ -7212,7 +7208,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn); lpfc_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn);
lpfc_request_firmware_upgrade_init(phba, lpfc_req_fw_upgrade); lpfc_request_firmware_upgrade_init(phba, lpfc_req_fw_upgrade);
lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up); lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up);
lpfc_iocb_cnt_init(phba, lpfc_iocb_cnt);
lpfc_delay_discovery_init(phba, lpfc_delay_discovery); lpfc_delay_discovery_init(phba, lpfc_delay_discovery);
lpfc_sli_mode_init(phba, lpfc_sli_mode); lpfc_sli_mode_init(phba, lpfc_sli_mode);
phba->cfg_enable_dss = 1; phba->cfg_enable_dss = 1;
......
...@@ -7126,7 +7126,7 @@ lpfc_init_iocb_list(struct lpfc_hba *phba, int iocb_count) ...@@ -7126,7 +7126,7 @@ lpfc_init_iocb_list(struct lpfc_hba *phba, int iocb_count)
if (iocbq_entry == NULL) { if (iocbq_entry == NULL) {
printk(KERN_ERR "%s: only allocated %d iocbs of " printk(KERN_ERR "%s: only allocated %d iocbs of "
"expected %d count. Unloading driver.\n", "expected %d count. Unloading driver.\n",
__func__, i, LPFC_IOCB_LIST_CNT); __func__, i, iocb_count);
goto out_free_iocbq; goto out_free_iocbq;
} }
...@@ -11591,13 +11591,10 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) ...@@ -11591,13 +11591,10 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
} }
/* If the NVME FC4 type is enabled, scale the sg_seg_cnt to /* 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 * accommodate 512K and 1M IOs in a single nvme buf.
* enough NVME LS iocb buffers for larger connectivity counts.
*/ */
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)
phba->cfg_sg_seg_cnt = LPFC_MAX_NVME_SEG_CNT; 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 */ /* 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) != if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
......
...@@ -7523,9 +7523,11 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) ...@@ -7523,9 +7523,11 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
} }
phba->sli4_hba.nvmet_xri_cnt = rc; phba->sli4_hba.nvmet_xri_cnt = rc;
cnt = phba->cfg_iocb_cnt * 1024; /* We allocate an iocbq for every receive context SGL.
/* We need 1 iocbq for every SGL, for IO processing */ * The additional allocation is for abort and ls handling.
cnt += phba->sli4_hba.nvmet_xri_cnt; */
cnt = phba->sli4_hba.nvmet_xri_cnt +
phba->sli4_hba.max_cfg_param.max_xri;
} else { } else {
/* update host common xri-sgl sizes and mappings */ /* update host common xri-sgl sizes and mappings */
rc = lpfc_sli4_io_sgl_update(phba); rc = lpfc_sli4_io_sgl_update(phba);
...@@ -7547,14 +7549,17 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) ...@@ -7547,14 +7549,17 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
rc = -ENODEV; rc = -ENODEV;
goto out_destroy_queue; goto out_destroy_queue;
} }
cnt = phba->cfg_iocb_cnt * 1024; /* Each lpfc_io_buf job structure has an iocbq element.
* This cnt provides for abort, els, ct and ls requests.
*/
cnt = phba->sli4_hba.max_cfg_param.max_xri;
} }
if (!phba->sli.iocbq_lookup) { if (!phba->sli.iocbq_lookup) {
/* Initialize and populate the iocb list per host */ /* Initialize and populate the iocb list per host */
lpfc_printf_log(phba, KERN_INFO, LOG_INIT, lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"2821 initialize iocb list %d total %d\n", "2821 initialize iocb list with %d entries\n",
phba->cfg_iocb_cnt, cnt); cnt);
rc = lpfc_init_iocb_list(phba, cnt); rc = lpfc_init_iocb_list(phba, cnt);
if (rc) { if (rc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment