Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b377d11 authored by Hariprasad Shenai's avatar Hariprasad Shenai Committed by David S. Miller
Browse files

cxgb4: Add debugfs facility to inject FL starvation



Add debugfs entry to inject Freelist starvation, used only for debugging
purpose.

Signed-off-by: default avatarHariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c6bfda8d
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -650,6 +650,7 @@ struct sge {
	struct sge_rspq **ingr_map; /* qid->queue ingress queue map */
	struct sge_rspq **ingr_map; /* qid->queue ingress queue map */
	unsigned long *starving_fl;
	unsigned long *starving_fl;
	unsigned long *txq_maperr;
	unsigned long *txq_maperr;
	unsigned long *blocked_fl;
	struct timer_list rx_timer; /* refills starving FLs */
	struct timer_list rx_timer; /* refills starving FLs */
	struct timer_list tx_timer; /* checks Tx queues */
	struct timer_list tx_timer; /* checks Tx queues */
};
};
+56 −0
Original line number Original line Diff line number Diff line
@@ -1959,6 +1959,61 @@ static void add_debugfs_mem(struct adapter *adap, const char *name,
				 size_mb << 20);
				 size_mb << 20);
}
}


static int blocked_fl_open(struct inode *inode, struct file *file)
{
	file->private_data = inode->i_private;
	return 0;
}

static ssize_t blocked_fl_read(struct file *filp, char __user *ubuf,
			       size_t count, loff_t *ppos)
{
	int len;
	const struct adapter *adap = filp->private_data;
	char *buf;
	ssize_t size = (adap->sge.egr_sz + 3) / 4 +
			adap->sge.egr_sz / 32 + 2; /* includes ,/\n/\0 */

	buf = kzalloc(size, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	len = snprintf(buf, size - 1, "%*pb\n",
		       adap->sge.egr_sz, adap->sge.blocked_fl);
	len += sprintf(buf + len, "\n");
	size = simple_read_from_buffer(ubuf, count, ppos, buf, len);
	t4_free_mem(buf);
	return size;
}

static ssize_t blocked_fl_write(struct file *filp, const char __user *ubuf,
				size_t count, loff_t *ppos)
{
	int err;
	unsigned long *t;
	struct adapter *adap = filp->private_data;

	t = kcalloc(BITS_TO_LONGS(adap->sge.egr_sz), sizeof(long), GFP_KERNEL);
	if (!t)
		return -ENOMEM;

	err = bitmap_parse_user(ubuf, count, t, adap->sge.egr_sz);
	if (err)
		return err;

	bitmap_copy(adap->sge.blocked_fl, t, adap->sge.egr_sz);
	t4_free_mem(t);
	return count;
}

static const struct file_operations blocked_fl_fops = {
	.owner   = THIS_MODULE,
	.open    = blocked_fl_open,
	.read    = blocked_fl_read,
	.write   = blocked_fl_write,
	.llseek  = generic_file_llseek,
};

/* Add an array of Debug FS files.
/* Add an array of Debug FS files.
 */
 */
void add_debugfs_files(struct adapter *adap,
void add_debugfs_files(struct adapter *adap,
@@ -2022,6 +2077,7 @@ int t4_setup_debugfs(struct adapter *adap)
#if IS_ENABLED(CONFIG_IPV6)
#if IS_ENABLED(CONFIG_IPV6)
		{ "clip_tbl", &clip_tbl_debugfs_fops, S_IRUSR, 0 },
		{ "clip_tbl", &clip_tbl_debugfs_fops, S_IRUSR, 0 },
#endif
#endif
		{ "blocked_fl", &blocked_fl_fops, S_IRUSR | S_IWUSR, 0 },
	};
	};


	/* Debug FS nodes common to all T5 and later adapters.
	/* Debug FS nodes common to all T5 and later adapters.
+19 −1
Original line number Original line Diff line number Diff line
@@ -3844,7 +3844,7 @@ static int adap_init0(struct adapter *adap)
	}
	}


	/* Allocate the memory for the vaious egress queue bitmaps
	/* Allocate the memory for the vaious egress queue bitmaps
	 * ie starving_fl and txq_maperr.
	 * ie starving_fl, txq_maperr and blocked_fl.
	 */
	 */
	adap->sge.starving_fl =	kcalloc(BITS_TO_LONGS(adap->sge.egr_sz),
	adap->sge.starving_fl =	kcalloc(BITS_TO_LONGS(adap->sge.egr_sz),
					sizeof(long), GFP_KERNEL);
					sizeof(long), GFP_KERNEL);
@@ -3860,6 +3860,15 @@ static int adap_init0(struct adapter *adap)
		goto bye;
		goto bye;
	}
	}


#ifdef CONFIG_DEBUG_FS
	adap->sge.blocked_fl = kcalloc(BITS_TO_LONGS(adap->sge.egr_sz),
				       sizeof(long), GFP_KERNEL);
	if (!adap->sge.blocked_fl) {
		ret = -ENOMEM;
		goto bye;
	}
#endif

	params[0] = FW_PARAM_PFVF(CLIP_START);
	params[0] = FW_PARAM_PFVF(CLIP_START);
	params[1] = FW_PARAM_PFVF(CLIP_END);
	params[1] = FW_PARAM_PFVF(CLIP_END);
	ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, params, val);
	ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, params, val);
@@ -4072,6 +4081,9 @@ static int adap_init0(struct adapter *adap)
	kfree(adap->sge.ingr_map);
	kfree(adap->sge.ingr_map);
	kfree(adap->sge.starving_fl);
	kfree(adap->sge.starving_fl);
	kfree(adap->sge.txq_maperr);
	kfree(adap->sge.txq_maperr);
#ifdef CONFIG_DEBUG_FS
	kfree(adap->sge.blocked_fl);
#endif
	if (ret != -ETIMEDOUT && ret != -EIO)
	if (ret != -ETIMEDOUT && ret != -EIO)
		t4_fw_bye(adap, adap->mbox);
		t4_fw_bye(adap, adap->mbox);
	return ret;
	return ret;
@@ -4515,6 +4527,9 @@ static void free_some_resources(struct adapter *adapter)
	kfree(adapter->sge.ingr_map);
	kfree(adapter->sge.ingr_map);
	kfree(adapter->sge.starving_fl);
	kfree(adapter->sge.starving_fl);
	kfree(adapter->sge.txq_maperr);
	kfree(adapter->sge.txq_maperr);
#ifdef CONFIG_DEBUG_FS
	kfree(adapter->sge.blocked_fl);
#endif
	disable_msi(adapter);
	disable_msi(adapter);


	for_each_port(adapter, i)
	for_each_port(adapter, i)
@@ -4661,6 +4676,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)


	setup_memwin(adapter);
	setup_memwin(adapter);
	err = adap_init0(adapter);
	err = adap_init0(adapter);
#ifdef CONFIG_DEBUG_FS
	bitmap_zero(adapter->sge.blocked_fl, adapter->sge.egr_sz);
#endif
	setup_memwin_rdma(adapter);
	setup_memwin_rdma(adapter);
	if (err)
	if (err)
		goto out_unmap_bar;
		goto out_unmap_bar;
+5 −0
Original line number Original line Diff line number Diff line
@@ -588,6 +588,11 @@ static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n,
	struct rx_sw_desc *sd = &q->sdesc[q->pidx];
	struct rx_sw_desc *sd = &q->sdesc[q->pidx];
	int node;
	int node;


#ifdef CONFIG_DEBUG_FS
	if (test_bit(q->cntxt_id - adap->sge.egr_start, adap->sge.blocked_fl))
		goto out;
#endif

	gfp |= __GFP_NOWARN;
	gfp |= __GFP_NOWARN;
	node = dev_to_node(adap->pdev_dev);
	node = dev_to_node(adap->pdev_dev);