Commit 1dec4cec authored by Ganesh Goudar's avatar Ganesh Goudar Committed by David S. Miller

cxgb4: Fix tids count for ipv6 offload connection

the adapter consumes two tids for every ipv6 offload
connection be it active or passive, calculate tid usage
count accordingly.

Also change the signatures of relevant functions to get
the address family.
Signed-off-by: default avatarRizwan Ansari <rizwana@chelsio.com>
Signed-off-by: default avatarVarun Prakash <varun@chelsio.com>
Signed-off-by: default avatarGanesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e5c5180a
...@@ -398,7 +398,8 @@ void _c4iw_free_ep(struct kref *kref) ...@@ -398,7 +398,8 @@ void _c4iw_free_ep(struct kref *kref)
(const u32 *)&sin6->sin6_addr.s6_addr, (const u32 *)&sin6->sin6_addr.s6_addr,
1); 1);
} }
cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid); cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid,
ep->com.local_addr.ss_family);
dst_release(ep->dst); dst_release(ep->dst);
cxgb4_l2t_release(ep->l2t); cxgb4_l2t_release(ep->l2t);
if (ep->mpa_skb) if (ep->mpa_skb)
...@@ -1199,7 +1200,7 @@ static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb) ...@@ -1199,7 +1200,7 @@ static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb)
/* setup the hwtid for this connection */ /* setup the hwtid for this connection */
ep->hwtid = tid; ep->hwtid = tid;
cxgb4_insert_tid(t, ep, tid); cxgb4_insert_tid(t, ep, tid, ep->com.local_addr.ss_family);
insert_ep_tid(ep); insert_ep_tid(ep);
ep->snd_seq = be32_to_cpu(req->snd_isn); ep->snd_seq = be32_to_cpu(req->snd_isn);
...@@ -2304,7 +2305,8 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) ...@@ -2304,7 +2305,8 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
(const u32 *)&sin6->sin6_addr.s6_addr, 1); (const u32 *)&sin6->sin6_addr.s6_addr, 1);
} }
if (status && act_open_has_tid(status)) if (status && act_open_has_tid(status))
cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, GET_TID(rpl)); cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, GET_TID(rpl),
ep->com.local_addr.ss_family);
remove_handle(ep->com.dev, &ep->com.dev->atid_idr, atid); remove_handle(ep->com.dev, &ep->com.dev->atid_idr, atid);
cxgb4_free_atid(t, atid); cxgb4_free_atid(t, atid);
...@@ -2581,7 +2583,8 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) ...@@ -2581,7 +2583,8 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
child_ep->tx_chan, child_ep->smac_idx, child_ep->rss_qid); child_ep->tx_chan, child_ep->smac_idx, child_ep->rss_qid);
init_timer(&child_ep->timer); init_timer(&child_ep->timer);
cxgb4_insert_tid(t, child_ep, hwtid); cxgb4_insert_tid(t, child_ep, hwtid,
child_ep->com.local_addr.ss_family);
insert_ep_tid(child_ep); insert_ep_tid(child_ep);
if (accept_cr(child_ep, skb, req)) { if (accept_cr(child_ep, skb, req)) {
c4iw_put_ep(&parent_ep->com); c4iw_put_ep(&parent_ep->com);
...@@ -2849,7 +2852,8 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) ...@@ -2849,7 +2852,8 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb)
1); 1);
} }
remove_handle(ep->com.dev, &ep->com.dev->hwtid_idr, ep->hwtid); remove_handle(ep->com.dev, &ep->com.dev->hwtid_idr, ep->hwtid);
cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid); cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid,
ep->com.local_addr.ss_family);
dst_release(ep->dst); dst_release(ep->dst);
cxgb4_l2t_release(ep->l2t); cxgb4_l2t_release(ep->l2t);
c4iw_reconnect(ep); c4iw_reconnect(ep);
......
...@@ -2669,6 +2669,8 @@ static int tid_info_show(struct seq_file *seq, void *v) ...@@ -2669,6 +2669,8 @@ static int tid_info_show(struct seq_file *seq, void *v)
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",
atomic_read(&t->conns_in_use));
if (chip <= CHELSIO_T5) if (chip <= CHELSIO_T5)
sb = t4_read_reg(adap, LE_DB_SERVER_INDEX_A) / 4; sb = t4_read_reg(adap, LE_DB_SERVER_INDEX_A) / 4;
...@@ -2699,17 +2701,23 @@ static int tid_info_show(struct seq_file *seq, void *v) ...@@ -2699,17 +2701,23 @@ static int tid_info_show(struct seq_file *seq, void *v)
atomic_read(&t->hash_tids_in_use)); atomic_read(&t->hash_tids_in_use));
} }
} else if (t->ntids) { } else if (t->ntids) {
seq_printf(seq, "Connections in use: %u\n",
atomic_read(&t->conns_in_use));
seq_printf(seq, "TID range: 0..%u", t->ntids - 1); seq_printf(seq, "TID range: 0..%u", 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));
} }
if (t->nstids) if (t->nstids)
seq_printf(seq, "STID range: %u..%u, in use: %u\n", seq_printf(seq, "STID range: %u..%u, in use-IPv4/IPv6: %u/%u\n",
(!t->stid_base && (!t->stid_base &&
(chip <= CHELSIO_T5)) ? (chip <= CHELSIO_T5)) ?
t->stid_base + 1 : t->stid_base, t->stid_base + 1 : t->stid_base,
t->stid_base + t->nstids - 1, t->stids_in_use); t->stid_base + t->nstids - 1,
t->stids_in_use - t->v6_stids_in_use,
t->v6_stids_in_use);
if (t->natids) if (t->natids)
seq_printf(seq, "ATID range: 0..%u, in use: %u\n", seq_printf(seq, "ATID range: 0..%u, in use: %u\n",
t->natids - 1, t->atids_in_use); t->natids - 1, t->atids_in_use);
......
...@@ -1093,10 +1093,12 @@ int cxgb4_alloc_stid(struct tid_info *t, int family, void *data) ...@@ -1093,10 +1093,12 @@ int cxgb4_alloc_stid(struct tid_info *t, int family, void *data)
* This is equivalent to 4 TIDs. With CLIP enabled it * This is equivalent to 4 TIDs. With CLIP enabled it
* needs 2 TIDs. * needs 2 TIDs.
*/ */
if (family == PF_INET) if (family == PF_INET6) {
t->stids_in_use++;
else
t->stids_in_use += 2; t->stids_in_use += 2;
t->v6_stids_in_use += 2;
} else {
t->stids_in_use++;
}
} }
spin_unlock_bh(&t->stid_lock); spin_unlock_bh(&t->stid_lock);
return stid; return stid;
...@@ -1150,13 +1152,16 @@ void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family) ...@@ -1150,13 +1152,16 @@ void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family)
bitmap_release_region(t->stid_bmap, stid, 1); bitmap_release_region(t->stid_bmap, stid, 1);
t->stid_tab[stid].data = NULL; t->stid_tab[stid].data = NULL;
if (stid < t->nstids) { if (stid < t->nstids) {
if (family == PF_INET) if (family == PF_INET6) {
t->stids_in_use--;
else
t->stids_in_use -= 2; t->stids_in_use -= 2;
t->v6_stids_in_use -= 2;
} else {
t->stids_in_use--;
}
} else { } else {
t->sftids_in_use--; t->sftids_in_use--;
} }
spin_unlock_bh(&t->stid_lock); spin_unlock_bh(&t->stid_lock);
} }
EXPORT_SYMBOL(cxgb4_free_stid); EXPORT_SYMBOL(cxgb4_free_stid);
...@@ -1232,7 +1237,8 @@ static void process_tid_release_list(struct work_struct *work) ...@@ -1232,7 +1237,8 @@ static void process_tid_release_list(struct work_struct *work)
* Release a TID and inform HW. If we are unable to allocate the release * Release a TID and inform HW. If we are unable to allocate the release
* message we defer to a work queue. * message we defer to a work queue.
*/ */
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)
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct adapter *adap = container_of(t, struct adapter, tids); struct adapter *adap = container_of(t, struct adapter, tids);
...@@ -1241,10 +1247,18 @@ void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid) ...@@ -1241,10 +1247,18 @@ void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid)
if (t->tid_tab[tid]) { if (t->tid_tab[tid]) {
t->tid_tab[tid] = NULL; t->tid_tab[tid] = NULL;
if (t->hash_base && (tid >= t->hash_base)) atomic_dec(&t->conns_in_use);
atomic_dec(&t->hash_tids_in_use); if (t->hash_base && (tid >= t->hash_base)) {
else if (family == AF_INET6)
atomic_dec(&t->tids_in_use); atomic_sub(2, &t->hash_tids_in_use);
else
atomic_dec(&t->hash_tids_in_use);
} else {
if (family == AF_INET6)
atomic_sub(2, &t->tids_in_use);
else
atomic_dec(&t->tids_in_use);
}
} }
skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_ATOMIC); skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_ATOMIC);
...@@ -1292,10 +1306,12 @@ static int tid_init(struct tid_info *t) ...@@ -1292,10 +1306,12 @@ static int tid_init(struct tid_info *t)
spin_lock_init(&t->ftid_lock); spin_lock_init(&t->ftid_lock);
t->stids_in_use = 0; t->stids_in_use = 0;
t->v6_stids_in_use = 0;
t->sftids_in_use = 0; t->sftids_in_use = 0;
t->afree = NULL; t->afree = NULL;
t->atids_in_use = 0; t->atids_in_use = 0;
atomic_set(&t->tids_in_use, 0); atomic_set(&t->tids_in_use, 0);
atomic_set(&t->conns_in_use, 0);
atomic_set(&t->hash_tids_in_use, 0); atomic_set(&t->hash_tids_in_use, 0);
/* Setup the free list for atid_tab and clear the stid bitmap. */ /* Setup the free list for atid_tab and clear the stid bitmap. */
......
...@@ -123,12 +123,14 @@ struct tid_info { ...@@ -123,12 +123,14 @@ struct tid_info {
spinlock_t stid_lock; spinlock_t stid_lock;
unsigned int stids_in_use; unsigned int stids_in_use;
unsigned int v6_stids_in_use;
unsigned int sftids_in_use; unsigned int sftids_in_use;
/* TIDs in the TCAM */ /* TIDs in the TCAM */
atomic_t tids_in_use; atomic_t tids_in_use;
/* TIDs in the HASH */ /* TIDs in the HASH */
atomic_t hash_tids_in_use; atomic_t hash_tids_in_use;
atomic_t conns_in_use;
/* lock for setting/clearing filter bitmap */ /* lock for setting/clearing filter bitmap */
spinlock_t ftid_lock; spinlock_t ftid_lock;
}; };
...@@ -157,13 +159,21 @@ static inline void *lookup_stid(const struct tid_info *t, unsigned int stid) ...@@ -157,13 +159,21 @@ 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 int tid, unsigned short family)
{ {
t->tid_tab[tid] = data; t->tid_tab[tid] = data;
if (t->hash_base && (tid >= t->hash_base)) if (t->hash_base && (tid >= t->hash_base)) {
atomic_inc(&t->hash_tids_in_use); if (family == AF_INET6)
else atomic_add(2, &t->hash_tids_in_use);
atomic_inc(&t->tids_in_use); else
atomic_inc(&t->hash_tids_in_use);
} else {
if (family == AF_INET6)
atomic_add(2, &t->tids_in_use);
else
atomic_inc(&t->tids_in_use);
}
atomic_inc(&t->conns_in_use);
} }
int cxgb4_alloc_atid(struct tid_info *t, void *data); int cxgb4_alloc_atid(struct tid_info *t, void *data);
...@@ -171,8 +181,8 @@ int cxgb4_alloc_stid(struct tid_info *t, int family, void *data); ...@@ -171,8 +181,8 @@ int cxgb4_alloc_stid(struct tid_info *t, int family, void *data);
int cxgb4_alloc_sftid(struct tid_info *t, int family, void *data); int cxgb4_alloc_sftid(struct tid_info *t, int family, void *data);
void cxgb4_free_atid(struct tid_info *t, unsigned int atid); void cxgb4_free_atid(struct tid_info *t, unsigned int atid);
void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family); void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family);
void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid); void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid,
unsigned short family);
struct in6_addr; struct in6_addr;
int cxgb4_create_server(const struct net_device *dev, unsigned int stid, int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
......
...@@ -806,7 +806,7 @@ static void do_act_establish(struct cxgbi_device *cdev, struct sk_buff *skb) ...@@ -806,7 +806,7 @@ static void do_act_establish(struct cxgbi_device *cdev, struct sk_buff *skb)
cxgbi_sock_get(csk); cxgbi_sock_get(csk);
csk->tid = tid; csk->tid = tid;
cxgb4_insert_tid(lldi->tids, csk, tid); cxgb4_insert_tid(lldi->tids, csk, tid, csk->csk_family);
cxgbi_sock_set_flag(csk, CTPF_HAS_TID); cxgbi_sock_set_flag(csk, CTPF_HAS_TID);
free_atid(csk); free_atid(csk);
...@@ -956,7 +956,8 @@ static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb) ...@@ -956,7 +956,8 @@ static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
if (status && status != CPL_ERR_TCAM_FULL && if (status && status != CPL_ERR_TCAM_FULL &&
status != CPL_ERR_CONN_EXIST && status != CPL_ERR_CONN_EXIST &&
status != CPL_ERR_ARP_MISS) status != CPL_ERR_ARP_MISS)
cxgb4_remove_tid(lldi->tids, csk->port_id, GET_TID(rpl)); cxgb4_remove_tid(lldi->tids, csk->port_id, GET_TID(rpl),
csk->csk_family);
cxgbi_sock_get(csk); cxgbi_sock_get(csk);
spin_lock_bh(&csk->lock); spin_lock_bh(&csk->lock);
...@@ -1590,7 +1591,8 @@ static void release_offload_resources(struct cxgbi_sock *csk) ...@@ -1590,7 +1591,8 @@ static void release_offload_resources(struct cxgbi_sock *csk)
free_atid(csk); free_atid(csk);
else if (cxgbi_sock_flag(csk, CTPF_HAS_TID)) { else if (cxgbi_sock_flag(csk, CTPF_HAS_TID)) {
lldi = cxgbi_cdev_priv(csk->cdev); lldi = cxgbi_cdev_priv(csk->cdev);
cxgb4_remove_tid(lldi->tids, 0, csk->tid); cxgb4_remove_tid(lldi->tids, 0, csk->tid,
csk->csk_family);
cxgbi_sock_clear_flag(csk, CTPF_HAS_TID); cxgbi_sock_clear_flag(csk, CTPF_HAS_TID);
cxgbi_sock_put(csk); cxgbi_sock_put(csk);
} }
......
...@@ -752,7 +752,8 @@ void _cxgbit_free_csk(struct kref *kref) ...@@ -752,7 +752,8 @@ void _cxgbit_free_csk(struct kref *kref)
&sin6->sin6_addr.s6_addr, 1); &sin6->sin6_addr.s6_addr, 1);
} }
cxgb4_remove_tid(csk->com.cdev->lldi.tids, 0, csk->tid); cxgb4_remove_tid(csk->com.cdev->lldi.tids, 0, csk->tid,
csk->com.local_addr.ss_family);
dst_release(csk->dst); dst_release(csk->dst);
cxgb4_l2t_release(csk->l2t); cxgb4_l2t_release(csk->l2t);
...@@ -1313,8 +1314,7 @@ cxgbit_pass_accept_req(struct cxgbit_device *cdev, struct sk_buff *skb) ...@@ -1313,8 +1314,7 @@ cxgbit_pass_accept_req(struct cxgbit_device *cdev, struct sk_buff *skb)
spin_lock(&cdev->cskq.lock); spin_lock(&cdev->cskq.lock);
list_add_tail(&csk->list, &cdev->cskq.list); list_add_tail(&csk->list, &cdev->cskq.list);
spin_unlock(&cdev->cskq.lock); spin_unlock(&cdev->cskq.lock);
cxgb4_insert_tid(t, csk, tid, csk->com.local_addr.ss_family);
cxgb4_insert_tid(t, csk, tid);
cxgbit_pass_accept_rpl(csk, req); cxgbit_pass_accept_rpl(csk, req);
goto rel_skb; goto rel_skb;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment