Commit c490850a authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: Adapt partitioned XRI lists to efficient sharing



The XRI get/put lists were partitioned per hardware queue. However, the
adapter rarely had sufficient resources to give a large number of resources
per queue. As such, it became common for a cpu to encounter a lack of XRI
resource and request the upper io stack to retry after returning a BUSY
condition. This occurred even though other cpus were idle and not using
their resources.

Create as efficient a scheme as possible to move resources to the cpus that
need them. Each cpu maintains a small private pool which it allocates from
for io. There is a watermark that the cpu attempts to keep in the private
pool.  The private pool, when empty, pulls from a global pool from the
cpu. When the cpu's global pool is empty it will pull from other cpu's
global pool. As there many cpu global pools (1 per cpu or hardware queue
count) and as each cpu selects what cpu to pull from at different rates and
at different times, it creates a radomizing effect that minimizes the
number of cpu's that will contend with each other when the steal XRI's from
another cpu's global pool.

On io completion, a cpu will push the XRI back on to its private pool.  A
watermark level is maintained for the private pool such that when it is
exceeded it will move XRI's to the CPU global pool so that other cpu's may
allocate them.

On NVME, as heartbeat commands are critical to get placed on the wire, a
single expedite pool is maintained. When a heartbeat is to be sent, it will
allocate an XRI from the expedite pool rather than the normal cpu
private/global pools. On any io completion, if a reduction in the expedite
pools is seen, it will be replenished before the XRI is placed on the cpu
private pool.

Statistics are added to aid understanding the XRI levels on each cpu and
their behaviors.

Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent ace44e48
Loading
Loading
Loading
Loading
+18 −8
Original line number Original line Diff line number Diff line
@@ -235,8 +235,6 @@ typedef struct lpfc_vpd {
	} sli3Feat;
	} sli3Feat;
} lpfc_vpd_t;
} lpfc_vpd_t;


struct lpfc_scsi_buf;



/*
/*
 * lpfc stat counters
 * lpfc stat counters
@@ -597,6 +595,13 @@ struct lpfc_mbox_ext_buf_ctx {
	struct list_head ext_dmabuf_list;
	struct list_head ext_dmabuf_list;
};
};


struct lpfc_epd_pool {
	/* Expedite pool */
	struct list_head list;
	u32 count;
	spinlock_t lock;	/* lock for expedite pool */
};

struct lpfc_ras_fwlog {
struct lpfc_ras_fwlog {
	uint8_t *fwlog_buff;
	uint8_t *fwlog_buff;
	uint32_t fw_buffcount; /* Buffer size posted to FW */
	uint32_t fw_buffcount; /* Buffer size posted to FW */
@@ -618,19 +623,19 @@ struct lpfc_ras_fwlog {


struct lpfc_hba {
struct lpfc_hba {
	/* SCSI interface function jump table entries */
	/* SCSI interface function jump table entries */
	struct lpfc_scsi_buf * (*lpfc_get_scsi_buf)
	struct lpfc_io_buf * (*lpfc_get_scsi_buf)
		(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
		(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
		struct scsi_cmnd *cmnd);
		struct scsi_cmnd *cmnd);
	int (*lpfc_scsi_prep_dma_buf)
	int (*lpfc_scsi_prep_dma_buf)
		(struct lpfc_hba *, struct lpfc_scsi_buf *);
		(struct lpfc_hba *, struct lpfc_io_buf *);
	void (*lpfc_scsi_unprep_dma_buf)
	void (*lpfc_scsi_unprep_dma_buf)
		(struct lpfc_hba *, struct lpfc_scsi_buf *);
		(struct lpfc_hba *, struct lpfc_io_buf *);
	void (*lpfc_release_scsi_buf)
	void (*lpfc_release_scsi_buf)
		(struct lpfc_hba *, struct lpfc_scsi_buf *);
		(struct lpfc_hba *, struct lpfc_io_buf *);
	void (*lpfc_rampdown_queue_depth)
	void (*lpfc_rampdown_queue_depth)
		(struct lpfc_hba *);
		(struct lpfc_hba *);
	void (*lpfc_scsi_prep_cmnd)
	void (*lpfc_scsi_prep_cmnd)
		(struct lpfc_vport *, struct lpfc_scsi_buf *,
		(struct lpfc_vport *, struct lpfc_io_buf *,
		 struct lpfc_nodelist *);
		 struct lpfc_nodelist *);


	/* IOCB interface function jump table entries */
	/* IOCB interface function jump table entries */
@@ -673,9 +678,12 @@ struct lpfc_hba {
		(struct lpfc_hba *);
		(struct lpfc_hba *);


	int (*lpfc_bg_scsi_prep_dma_buf)
	int (*lpfc_bg_scsi_prep_dma_buf)
		(struct lpfc_hba *, struct lpfc_scsi_buf *);
		(struct lpfc_hba *, struct lpfc_io_buf *);
	/* Add new entries here */
	/* Add new entries here */


	/* expedite pool */
	struct lpfc_epd_pool epd_pool;

	/* SLI4 specific HBA data structure */
	/* SLI4 specific HBA data structure */
	struct lpfc_sli4_hba sli4_hba;
	struct lpfc_sli4_hba sli4_hba;


@@ -789,6 +797,7 @@ struct lpfc_hba {


	/* HBA Config Parameters */
	/* HBA Config Parameters */
	uint32_t cfg_ack0;
	uint32_t cfg_ack0;
	uint32_t cfg_xri_rebalancing;
	uint32_t cfg_enable_npiv;
	uint32_t cfg_enable_npiv;
	uint32_t cfg_enable_rrq;
	uint32_t cfg_enable_rrq;
	uint32_t cfg_topology;
	uint32_t cfg_topology;
@@ -1014,6 +1023,7 @@ struct lpfc_hba {
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
	struct dentry *hba_debugfs_root;
	struct dentry *hba_debugfs_root;
	atomic_t debugfs_vport_count;
	atomic_t debugfs_vport_count;
	struct dentry *debug_multixri_pools;
	struct dentry *debug_hbqinfo;
	struct dentry *debug_hbqinfo;
	struct dentry *debug_dumpHostSlim;
	struct dentry *debug_dumpHostSlim;
	struct dentry *debug_dumpHBASlim;
	struct dentry *debug_dumpHBASlim;
+9 −0
Original line number Original line Diff line number Diff line
@@ -5266,6 +5266,12 @@ static DEVICE_ATTR_RW(lpfc_max_scsicmpl_time);
*/
*/
LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");


/*
# lpfc_xri_rebalancing: enable or disable XRI rebalancing feature
# range is [0,1]. Default value is 1.
*/
LPFC_ATTR_R(xri_rebalancing, 1, 0, 1, "Enable/Disable XRI rebalancing");

/*
/*
 * lpfc_io_sched: Determine scheduling algrithmn for issuing FCP cmds
 * lpfc_io_sched: Determine scheduling algrithmn for issuing FCP cmds
 * range is [0,1]. Default value is 0.
 * range is [0,1]. Default value is 0.
@@ -5723,6 +5729,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
	&dev_attr_lpfc_use_adisc,
	&dev_attr_lpfc_use_adisc,
	&dev_attr_lpfc_first_burst_size,
	&dev_attr_lpfc_first_burst_size,
	&dev_attr_lpfc_ack0,
	&dev_attr_lpfc_ack0,
	&dev_attr_lpfc_xri_rebalancing,
	&dev_attr_lpfc_topology,
	&dev_attr_lpfc_topology,
	&dev_attr_lpfc_scan_down,
	&dev_attr_lpfc_scan_down,
	&dev_attr_lpfc_link_speed,
	&dev_attr_lpfc_link_speed,
@@ -6788,6 +6795,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
	lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
	lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
	lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
	lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
	lpfc_ack0_init(phba, lpfc_ack0);
	lpfc_ack0_init(phba, lpfc_ack0);
	lpfc_xri_rebalancing_init(phba, lpfc_xri_rebalancing);
	lpfc_topology_init(phba, lpfc_topology);
	lpfc_topology_init(phba, lpfc_topology);
	lpfc_link_speed_init(phba, lpfc_link_speed);
	lpfc_link_speed_init(phba, lpfc_link_speed);
	lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
	lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
@@ -6846,6 +6854,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
		phba->nvmet_support = 0;
		phba->nvmet_support = 0;
		phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
		phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
		phba->cfg_enable_bbcr = 0;
		phba->cfg_enable_bbcr = 0;
		phba->cfg_xri_rebalancing = 0;
	} else {
	} else {
		/* We MUST have FCP support */
		/* We MUST have FCP support */
		if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
		if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
+16 −0
Original line number Original line Diff line number Diff line
@@ -521,6 +521,7 @@ int lpfc_sli4_io_sgl_update(struct lpfc_hba *phba);
int lpfc_sli4_post_io_sgl_list(struct lpfc_hba *phba,
int lpfc_sli4_post_io_sgl_list(struct lpfc_hba *phba,
		struct list_head *blist, int xricnt);
		struct list_head *blist, int xricnt);
int lpfc_new_io_buf(struct lpfc_hba *phba, int num_to_alloc);
int lpfc_new_io_buf(struct lpfc_hba *phba, int num_to_alloc);
void lpfc_io_free(struct lpfc_hba *phba);
void lpfc_free_sgl_list(struct lpfc_hba *, struct list_head *);
void lpfc_free_sgl_list(struct lpfc_hba *, struct list_head *);
uint32_t lpfc_sli_port_speed_get(struct lpfc_hba *);
uint32_t lpfc_sli_port_speed_get(struct lpfc_hba *);
int lpfc_sli4_request_firmware_update(struct lpfc_hba *, uint8_t);
int lpfc_sli4_request_firmware_update(struct lpfc_hba *, uint8_t);
@@ -573,6 +574,21 @@ void lpfc_nvme_mod_param_dep(struct lpfc_hba *phba);
void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba,
void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba,
				struct lpfc_iocbq *cmdiocb,
				struct lpfc_iocbq *cmdiocb,
				struct lpfc_wcqe_complete *abts_cmpl);
				struct lpfc_wcqe_complete *abts_cmpl);
void lpfc_create_multixri_pools(struct lpfc_hba *phba);
void lpfc_create_destroy_pools(struct lpfc_hba *phba);
void lpfc_move_xri_pvt_to_pbl(struct lpfc_hba *phba, u32 hwqid);
void lpfc_move_xri_pbl_to_pvt(struct lpfc_hba *phba, u32 hwqid, u32 cnt);
void lpfc_adjust_high_watermark(struct lpfc_hba *phba, u32 hwqid);
void lpfc_keep_pvt_pool_above_lowwm(struct lpfc_hba *phba, u32 hwqid);
void lpfc_adjust_pvt_pool_count(struct lpfc_hba *phba, u32 hwqid);
#ifdef LPFC_MXP_STAT
void lpfc_snapshot_mxp(struct lpfc_hba *, u32);
#endif
struct lpfc_io_buf *lpfc_get_io_buf(struct lpfc_hba *phba,
				struct lpfc_nodelist *ndlp, u32 hwqid,
				int);
void lpfc_release_io_buf(struct lpfc_hba *phba, struct lpfc_io_buf *ncmd,
			 struct lpfc_sli4_hdw_queue *qp);
void lpfc_nvme_cmd_template(void);
void lpfc_nvme_cmd_template(void);
void lpfc_nvmet_cmd_template(void);
void lpfc_nvmet_cmd_template(void);
extern int lpfc_enable_nvmet_cnt;
extern int lpfc_enable_nvmet_cnt;
+262 −0
Original line number Original line Diff line number Diff line
@@ -378,6 +378,126 @@ skipit:
	return len;
	return len;
}
}


/**
 * lpfc_debugfs_multixripools_data - Display multi-XRI pools information
 * @phba: The HBA to gather host buffer info from.
 * @buf: The buffer to dump log into.
 * @size: The maximum amount of data to process.
 *
 * Description:
 * This routine displays current multi-XRI pools information including XRI
 * count in public, private and txcmplq. It also displays current high and
 * low watermark.
 *
 * Return Value:
 * This routine returns the amount of bytes that were dumped into @buf and will
 * not exceed @size.
 **/
static int
lpfc_debugfs_multixripools_data(struct lpfc_hba *phba, char *buf, int size)
{
	u32 i;
	u32 hwq_count;
	struct lpfc_sli4_hdw_queue *qp;
	struct lpfc_multixri_pool *multixri_pool;
	struct lpfc_pvt_pool *pvt_pool;
	struct lpfc_pbl_pool *pbl_pool;
	u32 txcmplq_cnt;
	char tmp[LPFC_DEBUG_OUT_LINE_SZ] = {0};

	/*
	 * Pbl: Current number of free XRIs in public pool
	 * Pvt: Current number of free XRIs in private pool
	 * Busy: Current number of outstanding XRIs
	 * HWM: Current high watermark
	 * pvt_empty: Incremented by 1 when IO submission fails (no xri)
	 * pbl_empty: Incremented by 1 when all pbl_pool are empty during
	 *            IO submission
	 */
	scnprintf(tmp, sizeof(tmp),
		  "HWQ:  Pbl  Pvt Busy  HWM |  pvt_empty  pbl_empty ");
	if (strlcat(buf, tmp, size) >= size)
		return strnlen(buf, size);

#ifdef LPFC_MXP_STAT
	/*
	 * MAXH: Max high watermark seen so far
	 * above_lmt: Incremented by 1 if xri_owned > xri_limit during
	 *            IO submission
	 * below_lmt: Incremented by 1 if xri_owned <= xri_limit  during
	 *            IO submission
	 * locPbl_hit: Incremented by 1 if successfully get a batch of XRI from
	 *             local pbl_pool
	 * othPbl_hit: Incremented by 1 if successfully get a batch of XRI from
	 *             other pbl_pool
	 */
	scnprintf(tmp, sizeof(tmp),
		  "MAXH  above_lmt  below_lmt locPbl_hit othPbl_hit");
	if (strlcat(buf, tmp, size) >= size)
		return strnlen(buf, size);

	/*
	 * sPbl: snapshot of Pbl 15 sec after stat gets cleared
	 * sPvt: snapshot of Pvt 15 sec after stat gets cleared
	 * sBusy: snapshot of Busy 15 sec after stat gets cleared
	 */
	scnprintf(tmp, sizeof(tmp),
		  " | sPbl sPvt sBusy");
	if (strlcat(buf, tmp, size) >= size)
		return strnlen(buf, size);
#endif

	scnprintf(tmp, sizeof(tmp), "\n");
	if (strlcat(buf, tmp, size) >= size)
		return strnlen(buf, size);

	hwq_count = phba->cfg_hdw_queue;
	for (i = 0; i < hwq_count; i++) {
		qp = &phba->sli4_hba.hdwq[i];
		multixri_pool = qp->p_multixri_pool;
		if (!multixri_pool)
			continue;
		pbl_pool = &multixri_pool->pbl_pool;
		pvt_pool = &multixri_pool->pvt_pool;
		txcmplq_cnt = qp->fcp_wq->pring->txcmplq_cnt;
		if (qp->nvme_wq)
			txcmplq_cnt += qp->nvme_wq->pring->txcmplq_cnt;

		scnprintf(tmp, sizeof(tmp),
			  "%03d: %4d %4d %4d %4d | %10d %10d ",
			  i, pbl_pool->count, pvt_pool->count,
			  txcmplq_cnt, pvt_pool->high_watermark,
			  qp->empty_io_bufs, multixri_pool->pbl_empty_count);
		if (strlcat(buf, tmp, size) >= size)
			break;

#ifdef LPFC_MXP_STAT
		scnprintf(tmp, sizeof(tmp),
			  "%4d %10d %10d %10d %10d",
			  multixri_pool->stat_max_hwm,
			  multixri_pool->above_limit_count,
			  multixri_pool->below_limit_count,
			  multixri_pool->local_pbl_hit_count,
			  multixri_pool->other_pbl_hit_count);
		if (strlcat(buf, tmp, size) >= size)
			break;

		scnprintf(tmp, sizeof(tmp),
			  " | %4d %4d %5d",
			  multixri_pool->stat_pbl_count,
			  multixri_pool->stat_pvt_count,
			  multixri_pool->stat_busy_count);
		if (strlcat(buf, tmp, size) >= size)
			break;
#endif

		scnprintf(tmp, sizeof(tmp), "\n");
		if (strlcat(buf, tmp, size) >= size)
			break;
	}
	return strnlen(buf, size);
}

static int lpfc_debugfs_last_hdwq;
static int lpfc_debugfs_last_hdwq;


/**
/**
@@ -1751,6 +1871,53 @@ out:
	return rc;
	return rc;
}
}


/**
 * lpfc_debugfs_multixripools_open - Open the multixripool debugfs buffer
 * @inode: The inode pointer that contains a hba pointer.
 * @file: The file pointer to attach the log output.
 *
 * Description:
 * This routine is the entry point for the debugfs open file operation. It gets
 * the hba from the i_private field in @inode, allocates the necessary buffer
 * for the log, fills the buffer from the in-memory log for this hba, and then
 * returns a pointer to that log in the private_data field in @file.
 *
 * Returns:
 * This function returns zero if successful. On error it will return a negative
 * error value.
 **/
static int
lpfc_debugfs_multixripools_open(struct inode *inode, struct file *file)
{
	struct lpfc_hba *phba = inode->i_private;
	struct lpfc_debug *debug;
	int rc = -ENOMEM;

	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
	if (!debug)
		goto out;

	/* Round to page boundary */
	debug->buffer = kzalloc(LPFC_DUMP_MULTIXRIPOOL_SIZE, GFP_KERNEL);
	if (!debug->buffer) {
		kfree(debug);
		goto out;
	}

	if (phba->cfg_xri_rebalancing)
		debug->len = lpfc_debugfs_multixripools_data(
			phba, debug->buffer, LPFC_DUMP_MULTIXRIPOOL_SIZE);
	else
		debug->len = 0;

	debug->i_private = inode->i_private;
	file->private_data = debug;

	rc = 0;
out:
	return rc;
}

/**
/**
 * lpfc_debugfs_hdwqinfo_open - Open the hdwqinfo debugfs buffer
 * lpfc_debugfs_hdwqinfo_open - Open the hdwqinfo debugfs buffer
 * @inode: The inode pointer that contains a vport pointer.
 * @inode: The inode pointer that contains a vport pointer.
@@ -2182,6 +2349,75 @@ lpfc_debugfs_dumpDataDif_release(struct inode *inode, struct file *file)
	return 0;
	return 0;
}
}


/**
 * lpfc_debugfs_multixripools_write - Clear multi-XRI pools statistics
 * @file: The file pointer to read from.
 * @buf: The buffer to copy the user data from.
 * @nbytes: The number of bytes to get.
 * @ppos: The position in the file to start reading from.
 *
 * Description:
 * This routine clears multi-XRI pools statistics when buf contains "clear".
 *
 * Return Value:
 * It returns the @nbytges passing in from debugfs user space when successful.
 * In case of error conditions, it returns proper error code back to the user
 * space.
 **/
static ssize_t
lpfc_debugfs_multixripools_write(struct file *file, const char __user *buf,
				 size_t nbytes, loff_t *ppos)
{
	struct lpfc_debug *debug = file->private_data;
	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
	char mybuf[64];
	char *pbuf;
	u32 i;
	u32 hwq_count;
	struct lpfc_sli4_hdw_queue *qp;
	struct lpfc_multixri_pool *multixri_pool;

	if (nbytes > 64)
		nbytes = 64;

	/* Protect copy from user */
	if (!access_ok(buf, nbytes))
		return -EFAULT;

	memset(mybuf, 0, sizeof(mybuf));

	if (copy_from_user(mybuf, buf, nbytes))
		return -EFAULT;
	pbuf = &mybuf[0];

	if ((strncmp(pbuf, "clear", strlen("clear"))) == 0) {
		hwq_count = phba->cfg_hdw_queue;
		for (i = 0; i < hwq_count; i++) {
			qp = &phba->sli4_hba.hdwq[i];
			multixri_pool = qp->p_multixri_pool;
			if (!multixri_pool)
				continue;

			qp->empty_io_bufs = 0;
			multixri_pool->pbl_empty_count = 0;
#ifdef LPFC_MXP_STAT
			multixri_pool->above_limit_count = 0;
			multixri_pool->below_limit_count = 0;
			multixri_pool->stat_max_hwm = 0;
			multixri_pool->local_pbl_hit_count = 0;
			multixri_pool->other_pbl_hit_count = 0;

			multixri_pool->stat_pbl_count = 0;
			multixri_pool->stat_pvt_count = 0;
			multixri_pool->stat_busy_count = 0;
			multixri_pool->stat_snapshot_taken = 0;
#endif
		}
		return strlen(pbuf);
	}

	return -EINVAL;
}


static int
static int
lpfc_debugfs_nvmestat_open(struct inode *inode, struct file *file)
lpfc_debugfs_nvmestat_open(struct inode *inode, struct file *file)
@@ -5044,6 +5280,16 @@ static const struct file_operations lpfc_debugfs_op_nodelist = {
	.release =      lpfc_debugfs_release,
	.release =      lpfc_debugfs_release,
};
};


#undef lpfc_debugfs_op_multixripools
static const struct file_operations lpfc_debugfs_op_multixripools = {
	.owner =        THIS_MODULE,
	.open =         lpfc_debugfs_multixripools_open,
	.llseek =       lpfc_debugfs_lseek,
	.read =         lpfc_debugfs_read,
	.write =	lpfc_debugfs_multixripools_write,
	.release =      lpfc_debugfs_release,
};

#undef lpfc_debugfs_op_hbqinfo
#undef lpfc_debugfs_op_hbqinfo
static const struct file_operations lpfc_debugfs_op_hbqinfo = {
static const struct file_operations lpfc_debugfs_op_hbqinfo = {
	.owner =        THIS_MODULE,
	.owner =        THIS_MODULE,
@@ -5490,6 +5736,19 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
		atomic_inc(&lpfc_debugfs_hba_count);
		atomic_inc(&lpfc_debugfs_hba_count);
		atomic_set(&phba->debugfs_vport_count, 0);
		atomic_set(&phba->debugfs_vport_count, 0);


		/* Multi-XRI pools */
		snprintf(name, sizeof(name), "multixripools");
		phba->debug_multixri_pools =
			debugfs_create_file(name, S_IFREG | 0644,
					    phba->hba_debugfs_root,
					    phba,
					    &lpfc_debugfs_op_multixripools);
		if (!phba->debug_multixri_pools) {
			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
					 "0527 Cannot create debugfs multixripools\n");
			goto debug_failed;
		}

		/* Setup hbqinfo */
		/* Setup hbqinfo */
		snprintf(name, sizeof(name), "hbqinfo");
		snprintf(name, sizeof(name), "hbqinfo");
		phba->debug_hbqinfo =
		phba->debug_hbqinfo =
@@ -5906,6 +6165,9 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)


	if (atomic_read(&phba->debugfs_vport_count) == 0) {
	if (atomic_read(&phba->debugfs_vport_count) == 0) {


		debugfs_remove(phba->debug_multixri_pools); /* multixripools*/
		phba->debug_multixri_pools = NULL;

		debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
		debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
		phba->debug_hbqinfo = NULL;
		phba->debug_hbqinfo = NULL;


+3 −0
Original line number Original line Diff line number Diff line
@@ -287,6 +287,9 @@ struct lpfc_idiag {


#endif
#endif


/* multixripool output buffer size */
#define LPFC_DUMP_MULTIXRIPOOL_SIZE 8192

/* hdwqinfo output buffer size */
/* hdwqinfo output buffer size */
#define LPFC_HDWQINFO_SIZE 8192
#define LPFC_HDWQINFO_SIZE 8192


Loading