diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 926 | 
1 files changed, 429 insertions, 497 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 1ac98becb5ba..e91377a4cafe 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -39,6 +39,7 @@  #include <linux/msi.h>  #include <linux/irq.h>  #include <linux/bitops.h> +#include <linux/crash_dump.h>  #include <scsi/scsi.h>  #include <scsi/scsi_device.h> @@ -65,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; @@ -1081,8 +1076,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) { @@ -1093,29 +1088,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); @@ -1261,6 +1238,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; @@ -1274,20 +1252,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; @@ -1535,6 +1522,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_io_rings(phba);  	lpfc_offline(phba);  	lpfc_hba_down_post(phba);  	lpfc_unblock_mgmt_io(phba); @@ -1796,6 +1784,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_io_rings(phba);  	lpfc_offline(phba);  	/* release interrupt for possible resource change */  	lpfc_sli4_disable_intr(phba); @@ -1915,7 +1904,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: @@ -1989,9 +1978,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: @@ -2863,7 +2851,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, @@ -3067,7 +3055,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);  		} @@ -3252,12 +3240,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; @@ -3491,7 +3475,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, @@ -3636,6 +3620,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--;  		} @@ -3649,6 +3636,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--;  		} @@ -4097,18 +4087,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;  		/* @@ -4124,22 +4105,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, @@ -4318,7 +4307,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. @@ -6336,6 +6329,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. @@ -6354,6 +6365,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;  }  /** @@ -6414,6 +6432,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  	 */ @@ -6448,102 +6471,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; @@ -6552,11 +6479,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 */ @@ -6764,6 +6689,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 */ @@ -6775,12 +6825,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); @@ -6871,6 +6921,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: @@ -6997,12 +7053,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;  } @@ -7563,7 +7613,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 " @@ -7600,56 +7649,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 0x%p\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=0x%p" -		       "\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 0x%p\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=0x%p\n", -		       _dump_buf_dif);  }  /** @@ -8309,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 = @@ -8382,11 +8385,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)) { @@ -8643,51 +8641,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, @@ -8700,15 +8661,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) ? @@ -8723,13 +8684,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;  } @@ -8793,12 +8754,13 @@ 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); +			spin_lock_init(&qp->hdwq_lock);  		}  	} @@ -8864,7 +8826,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 */ @@ -8895,41 +8857,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;  		}  	} @@ -8960,7 +8912,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; @@ -8978,7 +8930,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;  	/* @@ -8994,7 +8946,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); @@ -9008,7 +8960,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; @@ -9021,7 +8973,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);  	} @@ -9164,15 +9116,13 @@ 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]);  	}  	/* Loop thru all IRQ vectors */  	for (idx = 0; idx < phba->cfg_irq_chann; idx++) { @@ -9372,8 +9322,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;  		} @@ -9499,31 +9448,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]; @@ -9531,14 +9455,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;  		} @@ -9838,10 +9763,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++) { @@ -10711,7 +10634,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; @@ -10753,8 +10676,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; @@ -10812,17 +10735,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);  		}  	} @@ -10936,69 +10859,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 @@ -11089,10 +11046,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 @@ -11103,20 +11060,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; @@ -11282,11 +11240,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 @@ -11300,32 +11257,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, @@ -11334,12 +11280,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) @@ -11355,24 +11296,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( @@ -11616,6 +11548,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)); @@ -11646,6 +11581,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)) @@ -11654,6 +11590,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))) @@ -11718,6 +11663,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;  } @@ -12146,7 +12099,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); @@ -12176,7 +12129,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);  }  /** @@ -12948,12 +12901,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); @@ -12984,12 +12933,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);  }  /** @@ -13530,19 +13475,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 0x%p\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", -				(1L << _dump_buf_dif_order), _dump_buf_dif); -		free_pages((unsigned long)_dump_buf_dif, _dump_buf_dif_order); -	}  	idr_destroy(&lpfc_hba_index);  }  |