Commit 5debb18f authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'cxgb4-chtls-fix-issues-related-to-high-priority-region'



Shahjada Abul Husain says:

====================
cxgb4/chtls: fix issues related to high priority region

The high priority region introduced by:

commit c2193999 ("cxgb4: add support for high priority filters")

had caused regression in some code paths, leading to connection
failures for the ULDs.

This series of patches attempt to fix the regressions.

Patch 1 fixes some code paths that have been missed to consider
the high priority region.

Patch 2 fixes ULD connection failures due to wrong TID base that
had been shifted after the high priority region.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8ae67496 59437d78
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1273,7 +1273,7 @@ static int chtls_pass_accept_req(struct chtls_dev *cdev, struct sk_buff *skb)
	ctx = (struct listen_ctx *)data;
	lsk = ctx->lsk;

	if (unlikely(tid >= cdev->tids->ntids)) {
	if (unlikely(tid_out_of_range(cdev->tids, tid))) {
		pr_info("passive open TID %u too large\n", tid);
		return 1;
	}
+10 −12
Original line number Diff line number Diff line
@@ -3171,14 +3171,12 @@ static const struct file_operations mem_debugfs_fops = {

static int tid_info_show(struct seq_file *seq, void *v)
{
	unsigned int tid_start = 0;
	struct adapter *adap = seq->private;
	const struct tid_info *t = &adap->tids;
	enum chip_type chip = CHELSIO_CHIP_VERSION(adap->params.chip);

	if (chip > CHELSIO_T5)
		tid_start = t4_read_reg(adap, LE_DB_ACTIVE_TABLE_START_INDEX_A);
	const struct tid_info *t;
	enum chip_type chip;

	t = &adap->tids;
	chip = CHELSIO_CHIP_VERSION(adap->params.chip);
	if (t4_read_reg(adap, LE_DB_CONFIG_A) & HASHEN_F) {
		unsigned int sb;
		seq_printf(seq, "Connections in use: %u\n",
@@ -3190,9 +3188,9 @@ static int tid_info_show(struct seq_file *seq, void *v)
			sb = t4_read_reg(adap, LE_DB_SRVR_START_INDEX_A);

		if (sb) {
			seq_printf(seq, "TID range: %u..%u/%u..%u", tid_start,
			seq_printf(seq, "TID range: %u..%u/%u..%u", t->tid_base,
				   sb - 1, adap->tids.hash_base,
				   t->ntids - 1);
				   t->tid_base + t->ntids - 1);
			seq_printf(seq, ", in use: %u/%u\n",
				   atomic_read(&t->tids_in_use),
				   atomic_read(&t->hash_tids_in_use));
@@ -3201,14 +3199,14 @@ static int tid_info_show(struct seq_file *seq, void *v)
				   t->aftid_base,
				   t->aftid_end,
				   adap->tids.hash_base,
				   t->ntids - 1);
				   t->tid_base + t->ntids - 1);
			seq_printf(seq, ", in use: %u/%u\n",
				   atomic_read(&t->tids_in_use),
				   atomic_read(&t->hash_tids_in_use));
		} else {
			seq_printf(seq, "TID range: %u..%u",
				   adap->tids.hash_base,
				   t->ntids - 1);
				   t->tid_base + t->ntids - 1);
			seq_printf(seq, ", in use: %u\n",
				   atomic_read(&t->hash_tids_in_use));
		}
@@ -3216,8 +3214,8 @@ static int tid_info_show(struct seq_file *seq, void *v)
		seq_printf(seq, "Connections in use: %u\n",
			   atomic_read(&t->conns_in_use));

		seq_printf(seq, "TID range: %u..%u", tid_start,
			   tid_start + t->ntids - 1);
		seq_printf(seq, "TID range: %u..%u", t->tid_base,
			   t->tid_base + t->ntids - 1);
		seq_printf(seq, ", in use: %u\n",
			   atomic_read(&t->tids_in_use));
	}
+20 −13
Original line number Diff line number Diff line
@@ -361,20 +361,22 @@ static int get_filter_count(struct adapter *adapter, unsigned int fidx,

	tcb_base = t4_read_reg(adapter, TP_CMM_TCB_BASE_A);
	if (is_hashfilter(adapter) && hash) {
		if (fidx < adapter->tids.ntids) {
			f = adapter->tids.tid_tab[fidx];
		if (tid_out_of_range(&adapter->tids, fidx))
			return -E2BIG;
		f = adapter->tids.tid_tab[fidx - adapter->tids.tid_base];
		if (!f)
			return -EINVAL;
	} else {
			return -E2BIG;
		}
	} else {
		if ((fidx != (adapter->tids.nftids +
			      adapter->tids.nsftids - 1)) &&
		    fidx >= adapter->tids.nftids)
		if ((fidx != (adapter->tids.nftids + adapter->tids.nsftids +
			      adapter->tids.nhpftids - 1)) &&
		    fidx >= (adapter->tids.nftids + adapter->tids.nhpftids))
			return -E2BIG;

		f = &adapter->tids.ftid_tab[fidx];
		if (fidx < adapter->tids.nhpftids)
			f = &adapter->tids.hpftid_tab[fidx];
		else
			f = &adapter->tids.ftid_tab[fidx -
						    adapter->tids.nhpftids];
		if (!f->valid)
			return -EINVAL;
	}
@@ -480,6 +482,7 @@ int cxgb4_get_free_ftid(struct net_device *dev, int family)
		ftid -= n;
	}
	spin_unlock_bh(&t->ftid_lock);
	ftid += t->nhpftids;

	return found ? ftid : -ENOMEM;
}
@@ -815,10 +818,14 @@ int delete_filter(struct adapter *adapter, unsigned int fidx)
	struct filter_entry *f;
	int ret;

	if (fidx >= adapter->tids.nftids + adapter->tids.nsftids)
	if (fidx >= adapter->tids.nftids + adapter->tids.nsftids +
		    adapter->tids.nhpftids)
		return -EINVAL;

	f = &adapter->tids.ftid_tab[fidx];
	if (fidx < adapter->tids.nhpftids)
		f = &adapter->tids.hpftid_tab[fidx];
	else
		f = &adapter->tids.ftid_tab[fidx - adapter->tids.nhpftids];
	ret = writable_filter(f);
	if (ret)
		return ret;
@@ -1606,7 +1613,7 @@ static int cxgb4_del_hash_filter(struct net_device *dev, int filter_id,
	netdev_dbg(dev, "%s: filter_id = %d ; nftids = %d\n",
		   __func__, filter_id, adapter->tids.nftids);

	if (filter_id > adapter->tids.ntids)
	if (tid_out_of_range(t, filter_id))
		return -E2BIG;

	f = lookup_tid(t, filter_id);
+8 −5
Original line number Diff line number Diff line
@@ -1447,8 +1447,8 @@ static void mk_tid_release(struct sk_buff *skb, unsigned int chan,
static void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
				    unsigned int tid)
{
	void **p = &t->tid_tab[tid];
	struct adapter *adap = container_of(t, struct adapter, tids);
	void **p = &t->tid_tab[tid - t->tid_base];

	spin_lock_bh(&adap->tid_release_lock);
	*p = adap->tid_release_head;
@@ -1500,13 +1500,13 @@ static void process_tid_release_list(struct work_struct *work)
void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid,
		      unsigned short family)
{
	struct sk_buff *skb;
	struct adapter *adap = container_of(t, struct adapter, tids);
	struct sk_buff *skb;

	WARN_ON(tid >= t->ntids);
	WARN_ON(tid_out_of_range(&adap->tids, tid));

	if (t->tid_tab[tid]) {
		t->tid_tab[tid] = NULL;
	if (t->tid_tab[tid - adap->tids.tid_base]) {
		t->tid_tab[tid - adap->tids.tid_base] = NULL;
		atomic_dec(&t->conns_in_use);
		if (t->hash_base && (tid >= t->hash_base)) {
			if (family == AF_INET6)
@@ -4727,6 +4727,9 @@ static int adap_init0(struct adapter *adap, int vpd_skip)
			adap->rawf_start = val[0];
			adap->rawf_cnt = val[1] - val[0] + 1;
		}

		adap->tids.tid_base =
			t4_read_reg(adap, LE_DB_ACTIVE_TABLE_START_INDEX_A);
	}

	/* qids (ingress/egress) returned from firmware can be anywhere
+2 −1
Original line number Diff line number Diff line
@@ -672,7 +672,8 @@ int cxgb4_tc_flower_replace(struct net_device *dev,
		 * 0 to driver. However, the hardware TCAM index
		 * starts from 0. Hence, the -1 here.
		 */
		if (cls->common.prio <= adap->tids.nftids) {
		if (cls->common.prio <= (adap->tids.nftids +
					 adap->tids.nhpftids)) {
			fidx = cls->common.prio - 1;
			if (fidx < adap->tids.nhpftids)
				fs->prio = 1;
Loading