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

scsi: lpfc: Fix eh_deadline setting for sli3 adapters.

A previous change unilaterally removed the hba reset entry point
from the sli3 host template. This was done to allow tape devices
being used for back up from being removed. Why was this done ?
When there was non-responding device on the fabric, the error
escalation policy would escalate to the reset handler. When the
reset handler was called, it would reset the adapter, dropping
link, thus logging out and terminating all i/o's - on any target.
If there was a tape device on the same adapter that wasn't in
error, it would kill the tape i/o's, effectively killing the
tape device state.  With the reset point removed, the adapter
reset avoided the fabric logout, allowing the other devices to
continue to operate unaffected. A hack - yes. Hint: we really
need a transport I_T nexus reset callback added to the eh process
(in between the SCSI target reset and hba reset points), so a
fc logout could occur to the one bad target only and stop the error
escalation process.

This patch commonizes the approach so it can be used for sli3 and sli4
adapters, but mandates the admin, via module parameter, specifically
identify which adapters the resets are to be removed for. Additionally,
bus_reset, which sends Target Reset TMFs to all targets, is also removed
from the template as it too has the same effect as the adapter reset.
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Reviewed-by: default avatarLaurence Oberman <loberman@redhat.com>
Tested-by: default avatarLaurence Oberman <loberman@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 318083ad
...@@ -99,6 +99,7 @@ struct lpfc_sli2_slim; ...@@ -99,6 +99,7 @@ struct lpfc_sli2_slim;
#define FC_MAX_ADPTMSG 64 #define FC_MAX_ADPTMSG 64
#define MAX_HBAEVT 32 #define MAX_HBAEVT 32
#define MAX_HBAS_NO_RESET 16
/* Number of MSI-X vectors the driver uses */ /* Number of MSI-X vectors the driver uses */
#define LPFC_MSIX_VECTORS 2 #define LPFC_MSIX_VECTORS 2
......
...@@ -3010,6 +3010,12 @@ MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:" ...@@ -3010,6 +3010,12 @@ MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"
static DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR, static DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR,
lpfc_poll_show, lpfc_poll_store); lpfc_poll_show, lpfc_poll_store);
int lpfc_no_hba_reset_cnt;
unsigned long lpfc_no_hba_reset[MAX_HBAS_NO_RESET] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
module_param_array(lpfc_no_hba_reset, ulong, &lpfc_no_hba_reset_cnt, 0444);
MODULE_PARM_DESC(lpfc_no_hba_reset, "WWPN of HBAs that should not be reset");
LPFC_ATTR(sli_mode, 0, 0, 3, LPFC_ATTR(sli_mode, 0, 0, 3,
"SLI mode selector:" "SLI mode selector:"
" 0 - auto (SLI-3 if supported)," " 0 - auto (SLI-3 if supported),"
......
...@@ -384,7 +384,7 @@ void lpfc_free_sysfs_attr(struct lpfc_vport *); ...@@ -384,7 +384,7 @@ void lpfc_free_sysfs_attr(struct lpfc_vport *);
extern struct device_attribute *lpfc_hba_attrs[]; extern struct device_attribute *lpfc_hba_attrs[];
extern struct device_attribute *lpfc_vport_attrs[]; extern struct device_attribute *lpfc_vport_attrs[];
extern struct scsi_host_template lpfc_template; extern struct scsi_host_template lpfc_template;
extern struct scsi_host_template lpfc_template_s3; extern struct scsi_host_template lpfc_template_no_hr;
extern struct scsi_host_template lpfc_template_nvme; extern struct scsi_host_template lpfc_template_nvme;
extern struct scsi_host_template lpfc_vport_template; extern struct scsi_host_template lpfc_vport_template;
extern struct fc_function_template lpfc_transport_functions; extern struct fc_function_template lpfc_transport_functions;
...@@ -554,3 +554,5 @@ void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba, ...@@ -554,3 +554,5 @@ void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba,
struct lpfc_wcqe_complete *abts_cmpl); struct lpfc_wcqe_complete *abts_cmpl);
extern int lpfc_enable_nvmet_cnt; extern int lpfc_enable_nvmet_cnt;
extern unsigned long long lpfc_enable_nvmet[]; extern unsigned long long lpfc_enable_nvmet[];
extern int lpfc_no_hba_reset_cnt;
extern unsigned long lpfc_no_hba_reset[];
...@@ -3555,6 +3555,44 @@ lpfc_sli4_scsi_sgl_update(struct lpfc_hba *phba) ...@@ -3555,6 +3555,44 @@ lpfc_sli4_scsi_sgl_update(struct lpfc_hba *phba)
return rc; return rc;
} }
static uint64_t
lpfc_get_wwpn(struct lpfc_hba *phba)
{
uint64_t wwn;
int rc;
LPFC_MBOXQ_t *mboxq;
MAILBOX_t *mb;
mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
GFP_KERNEL);
if (!mboxq)
return (uint64_t)-1;
/* First get WWN of HBA instance */
lpfc_read_nv(phba, mboxq);
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
if (rc != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"6019 Mailbox failed , mbxCmd x%x "
"READ_NV, mbxStatus x%x\n",
bf_get(lpfc_mqe_command, &mboxq->u.mqe),
bf_get(lpfc_mqe_status, &mboxq->u.mqe));
mempool_free(mboxq, phba->mbox_mem_pool);
return (uint64_t) -1;
}
mb = &mboxq->u.mb;
memcpy(&wwn, (char *)mb->un.varRDnvp.portname, sizeof(uint64_t));
/* wwn is WWPN of HBA instance */
mempool_free(mboxq, phba->mbox_mem_pool);
if (phba->sli_rev == LPFC_SLI_REV4)
return be64_to_cpu(wwn);
else
return (((wwn & 0xffffffff00000000) >> 32) |
((wwn & 0x00000000ffffffff) << 32));
}
/** /**
* lpfc_sli4_nvme_sgl_update - update xri-sgl sizing and mapping * lpfc_sli4_nvme_sgl_update - update xri-sgl sizing and mapping
* @phba: pointer to lpfc hba data structure. * @phba: pointer to lpfc hba data structure.
...@@ -3676,17 +3714,32 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) ...@@ -3676,17 +3714,32 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
struct lpfc_vport *vport; struct lpfc_vport *vport;
struct Scsi_Host *shost = NULL; struct Scsi_Host *shost = NULL;
int error = 0; int error = 0;
int i;
uint64_t wwn;
bool use_no_reset_hba = false;
wwn = lpfc_get_wwpn(phba);
for (i = 0; i < lpfc_no_hba_reset_cnt; i++) {
if (wwn == lpfc_no_hba_reset[i]) {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"6020 Setting use_no_reset port=%llx\n",
wwn);
use_no_reset_hba = true;
break;
}
}
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) { if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) {
if (dev != &phba->pcidev->dev) { if (dev != &phba->pcidev->dev) {
shost = scsi_host_alloc(&lpfc_vport_template, shost = scsi_host_alloc(&lpfc_vport_template,
sizeof(struct lpfc_vport)); sizeof(struct lpfc_vport));
} else { } else {
if (phba->sli_rev == LPFC_SLI_REV4) if (!use_no_reset_hba)
shost = scsi_host_alloc(&lpfc_template, shost = scsi_host_alloc(&lpfc_template,
sizeof(struct lpfc_vport)); sizeof(struct lpfc_vport));
else else
shost = scsi_host_alloc(&lpfc_template_s3, shost = scsi_host_alloc(&lpfc_template_no_hr,
sizeof(struct lpfc_vport)); sizeof(struct lpfc_vport));
} }
} else if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { } else if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
...@@ -5472,7 +5525,8 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) ...@@ -5472,7 +5525,8 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba)
/* Initialize the host templates the configured values. */ /* Initialize the host templates the configured values. */
lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt;
lpfc_template_s3.sg_tablesize = phba->cfg_sg_seg_cnt; lpfc_template_no_hr.sg_tablesize = phba->cfg_sg_seg_cnt;
lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt;
/* There are going to be 2 reserved BDEs: 1 FCP cmnd + 1 FCP rsp */ /* There are going to be 2 reserved BDEs: 1 FCP cmnd + 1 FCP rsp */
if (phba->cfg_enable_bg) { if (phba->cfg_enable_bg) {
...@@ -5693,6 +5747,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) ...@@ -5693,6 +5747,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
/* Initialize the host templates with the updated values. */ /* Initialize the host templates with the updated values. */
lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt;
lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt; lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt;
lpfc_template_no_hr.sg_tablesize = phba->cfg_sg_seg_cnt;
if (phba->cfg_sg_dma_buf_size <= LPFC_MIN_SG_SLI4_BUF_SZ) 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; phba->cfg_sg_dma_buf_size = LPFC_MIN_SG_SLI4_BUF_SZ;
......
...@@ -5953,7 +5953,7 @@ struct scsi_host_template lpfc_template_nvme = { ...@@ -5953,7 +5953,7 @@ struct scsi_host_template lpfc_template_nvme = {
.track_queue_depth = 0, .track_queue_depth = 0,
}; };
struct scsi_host_template lpfc_template_s3 = { struct scsi_host_template lpfc_template_no_hr = {
.module = THIS_MODULE, .module = THIS_MODULE,
.name = LPFC_DRIVER_NAME, .name = LPFC_DRIVER_NAME,
.proc_name = LPFC_DRIVER_NAME, .proc_name = LPFC_DRIVER_NAME,
...@@ -6015,7 +6015,6 @@ struct scsi_host_template lpfc_vport_template = { ...@@ -6015,7 +6015,6 @@ struct scsi_host_template lpfc_vport_template = {
.eh_abort_handler = lpfc_abort_handler, .eh_abort_handler = lpfc_abort_handler,
.eh_device_reset_handler = lpfc_device_reset_handler, .eh_device_reset_handler = lpfc_device_reset_handler,
.eh_target_reset_handler = lpfc_target_reset_handler, .eh_target_reset_handler = lpfc_target_reset_handler,
.eh_bus_reset_handler = lpfc_bus_reset_handler,
.slave_alloc = lpfc_slave_alloc, .slave_alloc = lpfc_slave_alloc,
.slave_configure = lpfc_slave_configure, .slave_configure = lpfc_slave_configure,
.slave_destroy = lpfc_slave_destroy, .slave_destroy = lpfc_slave_destroy,
......
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