[PATCH 11/20] lpfc: Fix eh_deadline setting for sli3 adapters.

Laurence Oberman loberman at redhat.com
Sat Mar 4 15:51:58 PST 2017



----- Original Message -----
> From: jsmart2021 at gmail.com
> To: linux-scsi at vger.kernel.org, linux-nvme at lists.infradead.org
> Cc: "James Smart" <jsmart2021 at gmail.com>, "Dick Kennedy" <dick.kennedy at broadcom.com>, "James Smart"
> <james.smart at broadcom.com>
> Sent: Saturday, March 4, 2017 12:30:31 PM
> Subject: [PATCH 11/20] lpfc: Fix eh_deadline setting for sli3 adapters.
> 
> From: James Smart <jsmart2021 at gmail.com>
> 
> 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: Dick Kennedy <dick.kennedy at broadcom.com>
> Signed-off-by: James Smart <james.smart at broadcom.com>
> ---
>  drivers/scsi/lpfc/lpfc.h      |  1 +
>  drivers/scsi/lpfc/lpfc_attr.c |  6 +++++
>  drivers/scsi/lpfc/lpfc_crtn.h |  4 ++-
>  drivers/scsi/lpfc/lpfc_init.c | 61
>  ++++++++++++++++++++++++++++++++++++++++---
>  drivers/scsi/lpfc/lpfc_scsi.c |  3 +--
>  5 files changed, 69 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
> index de6cd57..763f32d 100644
> --- a/drivers/scsi/lpfc/lpfc.h
> +++ b/drivers/scsi/lpfc/lpfc.h
> @@ -99,6 +99,7 @@ struct lpfc_sli2_slim;
>  #define FC_MAX_ADPTMSG		64
>  
>  #define MAX_HBAEVT	32
> +#define MAX_HBAS_NO_RESET 16
>  
>  /* Number of MSI-X vectors the driver uses */
>  #define LPFC_MSIX_VECTORS	2
> diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
> index 4114cf4..b741dcb 100644
> --- a/drivers/scsi/lpfc/lpfc_attr.c
> +++ b/drivers/scsi/lpfc/lpfc_attr.c
> @@ -3010,6 +3010,12 @@ MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode
> control:"
>  static DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR,
>  		   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,
>  	"SLI mode selector:"
>  	" 0 - auto (SLI-3 if supported),"
> diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
> index 843dd73..54e6ac4 100644
> --- a/drivers/scsi/lpfc/lpfc_crtn.h
> +++ b/drivers/scsi/lpfc/lpfc_crtn.h
> @@ -384,7 +384,7 @@ void lpfc_free_sysfs_attr(struct lpfc_vport *);
>  extern struct device_attribute *lpfc_hba_attrs[];
>  extern struct device_attribute *lpfc_vport_attrs[];
>  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_vport_template;
>  extern struct fc_function_template lpfc_transport_functions;
> @@ -554,3 +554,5 @@ void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba,
>  				struct lpfc_wcqe_complete *abts_cmpl);
>  extern int lpfc_enable_nvmet_cnt;
>  extern unsigned long long lpfc_enable_nvmet[];
> +extern int lpfc_no_hba_reset_cnt;
> +extern unsigned long lpfc_no_hba_reset[];
> diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
> index b754887..ecb8e1c 100644
> --- a/drivers/scsi/lpfc/lpfc_init.c
> +++ b/drivers/scsi/lpfc/lpfc_init.c
> @@ -3555,6 +3555,44 @@ lpfc_sli4_scsi_sgl_update(struct lpfc_hba *phba)
>  	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
>   * @phba: pointer to lpfc hba data structure.
> @@ -3676,17 +3714,32 @@ lpfc_create_port(struct lpfc_hba *phba, int instance,
> struct device *dev)
>  	struct lpfc_vport *vport;
>  	struct Scsi_Host  *shost = NULL;
>  	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 (dev != &phba->pcidev->dev) {
>  			shost = scsi_host_alloc(&lpfc_vport_template,
>  						sizeof(struct lpfc_vport));
>  		} else {
> -			if (phba->sli_rev == LPFC_SLI_REV4)
> +			if (!use_no_reset_hba)
>  				shost = scsi_host_alloc(&lpfc_template,
>  						sizeof(struct lpfc_vport));
>  			else
> -				shost = scsi_host_alloc(&lpfc_template_s3,
> +				shost = scsi_host_alloc(&lpfc_template_no_hr,
>  						sizeof(struct lpfc_vport));
>  		}
>  	} else if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
> @@ -5482,7 +5535,8 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba)
>  
>  	/* Initialize the host templates the configured values. */
>  	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 */
>  	if (phba->cfg_enable_bg) {
> @@ -5706,6 +5760,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
>  	/* Initialize the host templates with the updated values. */
>  	lpfc_vport_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)
>  		phba->cfg_sg_dma_buf_size = LPFC_MIN_SG_SLI4_BUF_SZ;
> diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
> index 9d6384a..bcfd6d6 100644
> --- a/drivers/scsi/lpfc/lpfc_scsi.c
> +++ b/drivers/scsi/lpfc/lpfc_scsi.c
> @@ -5953,7 +5953,7 @@ struct scsi_host_template lpfc_template_nvme = {
>  	.track_queue_depth	= 0,
>  };
>  
> -struct scsi_host_template lpfc_template_s3 = {
> +struct scsi_host_template lpfc_template_no_hr = {
>  	.module			= THIS_MODULE,
>  	.name			= LPFC_DRIVER_NAME,
>  	.proc_name		= LPFC_DRIVER_NAME,
> @@ -6015,7 +6015,6 @@ struct scsi_host_template lpfc_vport_template = {
>  	.eh_abort_handler	= lpfc_abort_handler,
>  	.eh_device_reset_handler = lpfc_device_reset_handler,
>  	.eh_target_reset_handler = lpfc_target_reset_handler,
> -	.eh_bus_reset_handler	= lpfc_bus_reset_handler,
>  	.slave_alloc		= lpfc_slave_alloc,
>  	.slave_configure	= lpfc_slave_configure,
>  	.slave_destroy		= lpfc_slave_destroy,
> --
> 2.5.0
> 
> 

This patch was implemented and tested in the Red Hat lab and validated for a customer requiring eh_deadline.

Reviewed-by: Laurence Oberman <loberman at redhat.com>
Tested-by:   Laurence Oberman <loberman at redhat.com>



More information about the Linux-nvme mailing list