[PATCH v9 06/13] lpfc: vmid: Add support for vmid in mailbox command, does vmid resource allocation and vmid cleanup

Hannes Reinecke hare at suse.de
Thu Apr 8 09:32:30 BST 2021


On 4/7/21 1:06 AM, Muneendra wrote:
> From: Gaurav Srivastava <gaurav.srivastava at broadcom.com>
> 
> This patch does the following -
> 1.adds supporting datastructures for mailbox command which helps in
> determining if the firmware supports appid or not.
> 2.This patch allocates the resource for vmid and checks if the firmware
> supports the feature or not.
> 3.The patch cleans up the vmid resources and stops the timer.
> 
> Signed-off-by: Gaurav Srivastava <gaurav.srivastava at broadcom.com>
> Signed-off-by: James Smart <jsmart2021 at gmail.com>
> 
> ---
> v9:
> Modified code for use of hashtable
> 
> v8:
> Added new function declaration, return error code and
> memory allocation API changes
> 
> v7:
> No change
> 
> v6:
> Added Forward declarations and functions to static
> 
> v5:
> Merged patches 8 and 11 of v4 to this patch
> Changed Return code to non-numeric/Symbol
> 
> v4:
> No change
> 
> v3:
> No change
> 
> v2:
> Ported the patch on top of 5.10/scsi-queue
> ---
>   drivers/scsi/lpfc/lpfc_hw4.h  | 12 +++++++
>   drivers/scsi/lpfc/lpfc_init.c | 64 +++++++++++++++++++++++++++++++++++
>   drivers/scsi/lpfc/lpfc_mbox.c |  6 ++++
>   drivers/scsi/lpfc/lpfc_scsi.c | 29 ++++++++++++++++
>   drivers/scsi/lpfc/lpfc_sli.c  |  9 +++++
>   5 files changed, 120 insertions(+)
> 
> diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
> index 541b9aef6bfe..5fdafc92fc2d 100644
> --- a/drivers/scsi/lpfc/lpfc_hw4.h
> +++ b/drivers/scsi/lpfc/lpfc_hw4.h
> @@ -272,6 +272,9 @@ struct lpfc_sli4_flags {
>   #define lpfc_vfi_rsrc_rdy_MASK		0x00000001
>   #define lpfc_vfi_rsrc_rdy_WORD		word0
>   #define LPFC_VFI_RSRC_RDY		1
> +#define lpfc_ftr_ashdr_SHIFT            4
> +#define lpfc_ftr_ashdr_MASK             0x00000001
> +#define lpfc_ftr_ashdr_WORD             word0
>   };
>   
>   struct sli4_bls_rsp {
> @@ -2943,6 +2946,9 @@ struct lpfc_mbx_request_features {
>   #define lpfc_mbx_rq_ftr_rq_mrqp_SHIFT		16
>   #define lpfc_mbx_rq_ftr_rq_mrqp_MASK		0x00000001
>   #define lpfc_mbx_rq_ftr_rq_mrqp_WORD		word2
> +#define lpfc_mbx_rq_ftr_rq_ashdr_SHIFT          17
> +#define lpfc_mbx_rq_ftr_rq_ashdr_MASK           0x00000001
> +#define lpfc_mbx_rq_ftr_rq_ashdr_WORD           word2
>   	uint32_t word3;
>   #define lpfc_mbx_rq_ftr_rsp_iaab_SHIFT		0
>   #define lpfc_mbx_rq_ftr_rsp_iaab_MASK		0x00000001
> @@ -2974,6 +2980,9 @@ struct lpfc_mbx_request_features {
>   #define lpfc_mbx_rq_ftr_rsp_mrqp_SHIFT		16
>   #define lpfc_mbx_rq_ftr_rsp_mrqp_MASK		0x00000001
>   #define lpfc_mbx_rq_ftr_rsp_mrqp_WORD		word3
> +#define lpfc_mbx_rq_ftr_rsp_ashdr_SHIFT         17
> +#define lpfc_mbx_rq_ftr_rsp_ashdr_MASK          0x00000001
> +#define lpfc_mbx_rq_ftr_rsp_ashdr_WORD          word3
>   };
>   
>   struct lpfc_mbx_supp_pages {
> @@ -4391,6 +4400,9 @@ struct wqe_common {
>   #define wqe_xchg_WORD         word10
>   #define LPFC_SCSI_XCHG	      0x0
>   #define LPFC_NVME_XCHG	      0x1
> +#define wqe_appid_SHIFT       5
> +#define wqe_appid_MASK        0x00000001
> +#define wqe_appid_WORD        word10
>   #define wqe_oas_SHIFT         6
>   #define wqe_oas_MASK          0x00000001
>   #define wqe_oas_WORD          word10
> diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
> index 5ea43c527e08..a506ab453343 100644
> --- a/drivers/scsi/lpfc/lpfc_init.c
> +++ b/drivers/scsi/lpfc/lpfc_init.c
> @@ -98,6 +98,7 @@ static struct scsi_transport_template *lpfc_transport_template = NULL;
>   static struct scsi_transport_template *lpfc_vport_transport_template = NULL;
>   static DEFINE_IDR(lpfc_hba_index);
>   #define LPFC_NVMET_BUF_POST 254
> +static int lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport);
>   
>   /**
>    * lpfc_config_port_prep - Perform lpfc initialization prior to config port
> @@ -2888,6 +2889,10 @@ lpfc_cleanup(struct lpfc_vport *vport)
>   	if (phba->link_state > LPFC_LINK_DOWN)
>   		lpfc_port_link_failure(vport);
>   
> +	/* cleanup vmid resources */
> +	if (lpfc_is_vmid_enabled(phba))
> +		lpfc_vmid_vport_cleanup(vport);
> +
>   	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
>   		if (vport->port_type != LPFC_PHYSICAL_PORT &&
>   		    ndlp->nlp_DID == Fabric_DID) {
> @@ -4318,6 +4323,57 @@ lpfc_get_wwpn(struct lpfc_hba *phba)
>   		return rol64(wwn, 32);
>   }
>   
> +/**
> + * lpfc_vmid_res_alloc - Allocates resources for VMID
> + * @phba: pointer to lpfc hba data structure.
> + * @vport: pointer to vport data structure
> + *
> + * This routine allocated the resources needed for the vmid.
> + *
> + * Return codes
> + *	0 on Succeess
> + *	Non-0 on Failure
> + */
> +static int
> +lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport)
> +{
> +	/* vmid feature is supported only on SLI4 */
> +	if (phba->sli_rev == LPFC_SLI_REV3) {
> +		phba->cfg_vmid_app_header = 0;
> +		phba->cfg_vmid_priority_tagging = 0;
> +	}
> +
> +	/* if enabled, then allocated the resources */
> +	if (lpfc_is_vmid_enabled(phba)) {
> +		vport->vmid =
> +		    kcalloc(phba->cfg_max_vmid, sizeof(struct lpfc_vmid),
> +			    GFP_KERNEL);
> +		if (!vport->vmid)
> +			return -ENOMEM;
> +
> +		rwlock_init(&vport->vmid_lock);
> +
> +		/* setting the VMID parameters for the vport */
> +		vport->vmid_priority_tagging = phba->cfg_vmid_priority_tagging;
> +		vport->vmid_inactivity_timeout =
> +		    phba->cfg_vmid_inactivity_timeout;
> +		vport->max_vmid = phba->cfg_max_vmid;
> +		vport->cur_vmid_cnt = 0;
> +
> +		vport->vmid_priority_range = bitmap_zalloc
> +			(LPFC_VMID_MAX_PRIORITY_RANGE, GFP_KERNEL);
> +
> +		if (!vport->vmid_priority_range) {
> +			kfree(vport->vmid);
> +			return -ENOMEM;
> +		}
> +
> +		/* Initialize the hashtable */
> +		hash_init(vport->hash_table);
> +	}
> +	return 0;
> +}
> +
>   /**
>    * lpfc_create_port - Create an FC port
>    * @phba: pointer to lpfc hba data structure.
> @@ -4470,6 +4526,12 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
>   			vport->port_type, shost->sg_tablesize,
>   			phba->cfg_scsi_seg_cnt, phba->cfg_sg_seg_cnt);
>   
> +	/* allocate the resources for vmid */
> +	rc = lpfc_vmid_res_alloc(phba, vport);
> +
> +	if (rc)
> +		goto out;
> +
>   	/* Initialize all internally managed lists. */
>   	INIT_LIST_HEAD(&vport->fc_nodes);
>   	INIT_LIST_HEAD(&vport->rcv_buffer_list);
> @@ -4494,6 +4556,8 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
>   	return vport;
>   
>   out_put_shost:
> +	kfree(vport->vmid);
> +	bitmap_free(vport->vmid_priority_range);
>   	scsi_host_put(shost);
>   out:
>   	return NULL;
> diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
> index c03a7f12dd65..7a15986ed586 100644
> --- a/drivers/scsi/lpfc/lpfc_mbox.c
> +++ b/drivers/scsi/lpfc/lpfc_mbox.c
> @@ -2100,6 +2100,12 @@ lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq)
>   		bf_set(lpfc_mbx_rq_ftr_rq_iaab, &mboxq->u.mqe.un.req_ftrs, 0);
>   		bf_set(lpfc_mbx_rq_ftr_rq_iaar, &mboxq->u.mqe.un.req_ftrs, 0);
>   	}
> +
> +	/* Enable Application Services Header for apphedr VMID */
> +	if (phba->cfg_vmid_app_header) {
> +		bf_set(lpfc_mbx_rq_ftr_rq_ashdr, &mboxq->u.mqe.un.req_ftrs, 1);
> +		bf_set(lpfc_ftr_ashdr, &phba->sli4_hba.sli4_flags, 1);
> +	}
>   	return;
>   }
>   
> diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
> index 85f6a066de5a..0868cb38d5b0 100644
> --- a/drivers/scsi/lpfc/lpfc_scsi.c
> +++ b/drivers/scsi/lpfc/lpfc_scsi.c
> @@ -5384,6 +5384,35 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
>   	return 0;
>   }
>   
> +/*
> + * lpfc_vmid_vport_cleanup - cleans up the resources associated with a vports
> + * @vport: The virtual port for which this call is being executed.
> + */
> +void lpfc_vmid_vport_cleanup(struct lpfc_vport *vport)
> +{
> +	u32 bucket;
> +	struct lpfc_vmid *cur;
> +
> +	/* delete the timer */
> +	if (vport->port_type == LPFC_PHYSICAL_PORT)
> +		del_timer_sync(&vport->phba->inactive_vmid_poll);
> +
> +	/* free the resources */
> +	kfree(vport->qfpa_res);
> +	kfree(vport->vmid_priority.vmid_range);
> +	kfree(vport->vmid);
> +
> +	/* for all elements in the hash table */
> +	if (!hash_empty(vport->hash_table))
> +		hash_for_each(vport->hash_table, bucket, cur, hnode)
> +			hash_del(&cur->hnode);
> +
> +	/* reset variables */
> +	vport->qfpa_res = NULL;
> +	vport->vmid_priority.vmid_range = NULL;
> +	vport->vmid = NULL;
> +	vport->cur_vmid_cnt = 0;
> +}
>   
>   /**
>    * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point
> diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
> index f6e1e36eabdc..3f212555f3ac 100644
> --- a/drivers/scsi/lpfc/lpfc_sli.c
> +++ b/drivers/scsi/lpfc/lpfc_sli.c
> @@ -7698,6 +7698,15 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
>   		goto out_free_mbox;
>   	}
>   
> +	/* Disable vmid if app header is not supported */
> +	if (phba->cfg_vmid_app_header && !(bf_get(lpfc_mbx_rq_ftr_rsp_ashdr,
> +						  &mqe->un.req_ftrs))) {
> +		bf_set(lpfc_ftr_ashdr, &phba->sli4_hba.sli4_flags, 0);
> +		phba->cfg_vmid_app_header = 0;
> +		lpfc_printf_log(phba, KERN_DEBUG, LOG_SLI,
> +				"1242 vmid feature not supported\n");
> +	}
> +
>   	/*
>   	 * The port must support FCP initiator mode as this is the
>   	 * only mode running in the host.
> 
I would have thought that the forward declaration for 
lpfc_vport_cleanup() should be present in this patch (and not the 
previous one).
But that's largely cosmetical, so:

Reviewed-by: Hannes Reinecke <hare at suse.de>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke                Kernel Storage Architect
hare at suse.de                              +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer



More information about the Linux-nvme mailing list