提交 5debb18f 编写于 作者: D David S. Miller

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: NDavid S. Miller <davem@davemloft.net>
...@@ -1273,7 +1273,7 @@ static int chtls_pass_accept_req(struct chtls_dev *cdev, struct sk_buff *skb) ...@@ -1273,7 +1273,7 @@ static int chtls_pass_accept_req(struct chtls_dev *cdev, struct sk_buff *skb)
ctx = (struct listen_ctx *)data; ctx = (struct listen_ctx *)data;
lsk = ctx->lsk; 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); pr_info("passive open TID %u too large\n", tid);
return 1; return 1;
} }
......
...@@ -3171,14 +3171,12 @@ static const struct file_operations mem_debugfs_fops = { ...@@ -3171,14 +3171,12 @@ static const struct file_operations mem_debugfs_fops = {
static int tid_info_show(struct seq_file *seq, void *v) static int tid_info_show(struct seq_file *seq, void *v)
{ {
unsigned int tid_start = 0;
struct adapter *adap = seq->private; struct adapter *adap = seq->private;
const struct tid_info *t = &adap->tids; const struct tid_info *t;
enum chip_type chip = CHELSIO_CHIP_VERSION(adap->params.chip); enum chip_type chip;
if (chip > CHELSIO_T5)
tid_start = t4_read_reg(adap, LE_DB_ACTIVE_TABLE_START_INDEX_A);
t = &adap->tids;
chip = CHELSIO_CHIP_VERSION(adap->params.chip);
if (t4_read_reg(adap, LE_DB_CONFIG_A) & HASHEN_F) { if (t4_read_reg(adap, LE_DB_CONFIG_A) & HASHEN_F) {
unsigned int sb; unsigned int sb;
seq_printf(seq, "Connections in use: %u\n", seq_printf(seq, "Connections in use: %u\n",
...@@ -3190,9 +3188,9 @@ static int tid_info_show(struct seq_file *seq, void *v) ...@@ -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); sb = t4_read_reg(adap, LE_DB_SRVR_START_INDEX_A);
if (sb) { 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, sb - 1, adap->tids.hash_base,
t->ntids - 1); t->tid_base + t->ntids - 1);
seq_printf(seq, ", in use: %u/%u\n", seq_printf(seq, ", in use: %u/%u\n",
atomic_read(&t->tids_in_use), atomic_read(&t->tids_in_use),
atomic_read(&t->hash_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) ...@@ -3201,14 +3199,14 @@ static int tid_info_show(struct seq_file *seq, void *v)
t->aftid_base, t->aftid_base,
t->aftid_end, t->aftid_end,
adap->tids.hash_base, adap->tids.hash_base,
t->ntids - 1); t->tid_base + t->ntids - 1);
seq_printf(seq, ", in use: %u/%u\n", seq_printf(seq, ", in use: %u/%u\n",
atomic_read(&t->tids_in_use), atomic_read(&t->tids_in_use),
atomic_read(&t->hash_tids_in_use)); atomic_read(&t->hash_tids_in_use));
} else { } else {
seq_printf(seq, "TID range: %u..%u", seq_printf(seq, "TID range: %u..%u",
adap->tids.hash_base, adap->tids.hash_base,
t->ntids - 1); t->tid_base + t->ntids - 1);
seq_printf(seq, ", in use: %u\n", seq_printf(seq, ", in use: %u\n",
atomic_read(&t->hash_tids_in_use)); atomic_read(&t->hash_tids_in_use));
} }
...@@ -3216,8 +3214,8 @@ static int tid_info_show(struct seq_file *seq, void *v) ...@@ -3216,8 +3214,8 @@ static int tid_info_show(struct seq_file *seq, void *v)
seq_printf(seq, "Connections in use: %u\n", seq_printf(seq, "Connections in use: %u\n",
atomic_read(&t->conns_in_use)); atomic_read(&t->conns_in_use));
seq_printf(seq, "TID range: %u..%u", tid_start, seq_printf(seq, "TID range: %u..%u", t->tid_base,
tid_start + t->ntids - 1); t->tid_base + t->ntids - 1);
seq_printf(seq, ", in use: %u\n", seq_printf(seq, ", in use: %u\n",
atomic_read(&t->tids_in_use)); atomic_read(&t->tids_in_use));
} }
......
...@@ -361,20 +361,22 @@ static int get_filter_count(struct adapter *adapter, unsigned int fidx, ...@@ -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); tcb_base = t4_read_reg(adapter, TP_CMM_TCB_BASE_A);
if (is_hashfilter(adapter) && hash) { if (is_hashfilter(adapter) && hash) {
if (fidx < adapter->tids.ntids) { if (tid_out_of_range(&adapter->tids, fidx))
f = adapter->tids.tid_tab[fidx];
if (!f)
return -EINVAL;
} else {
return -E2BIG; return -E2BIG;
} f = adapter->tids.tid_tab[fidx - adapter->tids.tid_base];
if (!f)
return -EINVAL;
} else { } else {
if ((fidx != (adapter->tids.nftids + if ((fidx != (adapter->tids.nftids + adapter->tids.nsftids +
adapter->tids.nsftids - 1)) && adapter->tids.nhpftids - 1)) &&
fidx >= adapter->tids.nftids) fidx >= (adapter->tids.nftids + adapter->tids.nhpftids))
return -E2BIG; 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) if (!f->valid)
return -EINVAL; return -EINVAL;
} }
...@@ -480,6 +482,7 @@ int cxgb4_get_free_ftid(struct net_device *dev, int family) ...@@ -480,6 +482,7 @@ int cxgb4_get_free_ftid(struct net_device *dev, int family)
ftid -= n; ftid -= n;
} }
spin_unlock_bh(&t->ftid_lock); spin_unlock_bh(&t->ftid_lock);
ftid += t->nhpftids;
return found ? ftid : -ENOMEM; return found ? ftid : -ENOMEM;
} }
...@@ -815,10 +818,14 @@ int delete_filter(struct adapter *adapter, unsigned int fidx) ...@@ -815,10 +818,14 @@ int delete_filter(struct adapter *adapter, unsigned int fidx)
struct filter_entry *f; struct filter_entry *f;
int ret; int ret;
if (fidx >= adapter->tids.nftids + adapter->tids.nsftids) if (fidx >= adapter->tids.nftids + adapter->tids.nsftids +
adapter->tids.nhpftids)
return -EINVAL; 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); ret = writable_filter(f);
if (ret) if (ret)
return ret; return ret;
...@@ -1606,7 +1613,7 @@ static int cxgb4_del_hash_filter(struct net_device *dev, int filter_id, ...@@ -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", netdev_dbg(dev, "%s: filter_id = %d ; nftids = %d\n",
__func__, filter_id, adapter->tids.nftids); __func__, filter_id, adapter->tids.nftids);
if (filter_id > adapter->tids.ntids) if (tid_out_of_range(t, filter_id))
return -E2BIG; return -E2BIG;
f = lookup_tid(t, filter_id); f = lookup_tid(t, filter_id);
......
...@@ -1447,8 +1447,8 @@ static void mk_tid_release(struct sk_buff *skb, unsigned int chan, ...@@ -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, static void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
unsigned int tid) unsigned int tid)
{ {
void **p = &t->tid_tab[tid];
struct adapter *adap = container_of(t, struct adapter, tids); 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); spin_lock_bh(&adap->tid_release_lock);
*p = adap->tid_release_head; *p = adap->tid_release_head;
...@@ -1500,13 +1500,13 @@ static void process_tid_release_list(struct work_struct *work) ...@@ -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, void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid,
unsigned short family) unsigned short family)
{ {
struct sk_buff *skb;
struct adapter *adap = container_of(t, struct adapter, tids); 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]) { if (t->tid_tab[tid - adap->tids.tid_base]) {
t->tid_tab[tid] = NULL; t->tid_tab[tid - adap->tids.tid_base] = NULL;
atomic_dec(&t->conns_in_use); atomic_dec(&t->conns_in_use);
if (t->hash_base && (tid >= t->hash_base)) { if (t->hash_base && (tid >= t->hash_base)) {
if (family == AF_INET6) if (family == AF_INET6)
...@@ -4727,6 +4727,9 @@ static int adap_init0(struct adapter *adap, int vpd_skip) ...@@ -4727,6 +4727,9 @@ static int adap_init0(struct adapter *adap, int vpd_skip)
adap->rawf_start = val[0]; adap->rawf_start = val[0];
adap->rawf_cnt = val[1] - val[0] + 1; 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 /* qids (ingress/egress) returned from firmware can be anywhere
......
...@@ -672,7 +672,8 @@ int cxgb4_tc_flower_replace(struct net_device *dev, ...@@ -672,7 +672,8 @@ int cxgb4_tc_flower_replace(struct net_device *dev,
* 0 to driver. However, the hardware TCAM index * 0 to driver. However, the hardware TCAM index
* starts from 0. Hence, the -1 here. * 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; fidx = cls->common.prio - 1;
if (fidx < adap->tids.nhpftids) if (fidx < adap->tids.nhpftids)
fs->prio = 1; fs->prio = 1;
......
...@@ -137,7 +137,7 @@ static int cxgb4_matchall_alloc_filter(struct net_device *dev, ...@@ -137,7 +137,7 @@ static int cxgb4_matchall_alloc_filter(struct net_device *dev,
* -1 here. 1 slot is enough to create a wildcard matchall * -1 here. 1 slot is enough to create a wildcard matchall
* VIID rule. * VIID rule.
*/ */
if (cls->common.prio <= adap->tids.nftids) if (cls->common.prio <= (adap->tids.nftids + adap->tids.nhpftids))
fidx = cls->common.prio - 1; fidx = cls->common.prio - 1;
else else
fidx = cxgb4_get_free_ftid(dev, PF_INET); fidx = cxgb4_get_free_ftid(dev, PF_INET);
......
...@@ -99,6 +99,7 @@ struct eotid_entry { ...@@ -99,6 +99,7 @@ struct eotid_entry {
*/ */
struct tid_info { struct tid_info {
void **tid_tab; void **tid_tab;
unsigned int tid_base;
unsigned int ntids; unsigned int ntids;
struct serv_entry *stid_tab; struct serv_entry *stid_tab;
...@@ -152,9 +153,15 @@ struct tid_info { ...@@ -152,9 +153,15 @@ struct tid_info {
static inline void *lookup_tid(const struct tid_info *t, unsigned int tid) static inline void *lookup_tid(const struct tid_info *t, unsigned int tid)
{ {
tid -= t->tid_base;
return tid < t->ntids ? t->tid_tab[tid] : NULL; return tid < t->ntids ? t->tid_tab[tid] : NULL;
} }
static inline bool tid_out_of_range(const struct tid_info *t, unsigned int tid)
{
return ((tid - t->tid_base) >= t->ntids);
}
static inline void *lookup_atid(const struct tid_info *t, unsigned int atid) static inline void *lookup_atid(const struct tid_info *t, unsigned int atid)
{ {
return atid < t->natids ? t->atid_tab[atid].data : NULL; return atid < t->natids ? t->atid_tab[atid].data : NULL;
...@@ -176,7 +183,7 @@ static inline void *lookup_stid(const struct tid_info *t, unsigned int stid) ...@@ -176,7 +183,7 @@ static inline void *lookup_stid(const struct tid_info *t, unsigned int stid)
static inline void cxgb4_insert_tid(struct tid_info *t, void *data, static inline void cxgb4_insert_tid(struct tid_info *t, void *data,
unsigned int tid, unsigned short family) unsigned int tid, unsigned short family)
{ {
t->tid_tab[tid] = data; t->tid_tab[tid - t->tid_base] = data;
if (t->hash_base && (tid >= t->hash_base)) { if (t->hash_base && (tid >= t->hash_base)) {
if (family == AF_INET6) if (family == AF_INET6)
atomic_add(2, &t->hash_tids_in_use); atomic_add(2, &t->hash_tids_in_use);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册