cxgb4: Fix tids count for ipv6 offload connection
authorGanesh Goudar <ganeshgr@chelsio.com>
Wed, 7 Jun 2017 09:34:51 +0000 (15:04 +0530)
committerDavid S. Miller <davem@davemloft.net>
Wed, 7 Jun 2017 19:14:34 +0000 (15:14 -0400)
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: Rizwan Ansari <rizwana@chelsio.com>
Signed-off-by: Varun Prakash <varun@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/infiniband/hw/cxgb4/cm.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
drivers/target/iscsi/cxgbit/cxgbit_cm.c

index 0910faf3587b547e873bc4e5572e7defd93623b3..b0ae4f0c8aa7f143bed5967b97c7006ad61db4a1 100644 (file)
@@ -398,7 +398,8 @@ void _c4iw_free_ep(struct kref *kref)
                                        (const u32 *)&sin6->sin6_addr.s6_addr,
                                        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);
                cxgb4_l2t_release(ep->l2t);
                if (ep->mpa_skb)
@@ -1199,7 +1200,7 @@ static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb)
 
        /* setup the hwtid for this connection */
        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);
 
        ep->snd_seq = be32_to_cpu(req->snd_isn);
@@ -2304,7 +2305,8 @@ fail:
                                   (const u32 *)&sin6->sin6_addr.s6_addr, 1);
        }
        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);
        cxgb4_free_atid(t, atid);
@@ -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);
 
        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);
        if (accept_cr(child_ep, skb, req)) {
                c4iw_put_ep(&parent_ep->com);
@@ -2849,7 +2852,8 @@ out:
                                        1);
                }
                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);
                cxgb4_l2t_release(ep->l2t);
                c4iw_reconnect(ep);
index 1fa34b009891ba93269c27da4c48a55f4b150b68..00044d75013934b4179b369ecf7af244a0bffdc3 100644 (file)
@@ -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) {
                unsigned int sb;
+               seq_printf(seq, "Connections in use: %u\n",
+                          atomic_read(&t->conns_in_use));
 
                if (chip <= CHELSIO_T5)
                        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)
                                   atomic_read(&t->hash_tids_in_use));
                }
        } 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, ", in use: %u\n",
                           atomic_read(&t->tids_in_use));
        }
 
        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 &&
                           (chip <= CHELSIO_T5)) ?
                           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)
                seq_printf(seq, "ATID range: 0..%u, in use: %u\n",
                           t->natids - 1, t->atids_in_use);
index 6c463703e072d853b829f60863fb8d57e56538d9..91685bf21878c62d72e8ab9e3d37e80ead2dc7d9 100644 (file)
@@ -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
                 * needs 2 TIDs.
                 */
-               if (family == PF_INET)
-                       t->stids_in_use++;
-               else
+               if (family == PF_INET6) {
                        t->stids_in_use += 2;
+                       t->v6_stids_in_use += 2;
+               } else {
+                       t->stids_in_use++;
+               }
        }
        spin_unlock_bh(&t->stid_lock);
        return stid;
@@ -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);
        t->stid_tab[stid].data = NULL;
        if (stid < t->nstids) {
-               if (family == PF_INET)
-                       t->stids_in_use--;
-               else
+               if (family == PF_INET6) {
                        t->stids_in_use -= 2;
+                       t->v6_stids_in_use -= 2;
+               } else {
+                       t->stids_in_use--;
+               }
        } else {
                t->sftids_in_use--;
        }
+
        spin_unlock_bh(&t->stid_lock);
 }
 EXPORT_SYMBOL(cxgb4_free_stid);
@@ -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
  * 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 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)
 
        if (t->tid_tab[tid]) {
                t->tid_tab[tid] = NULL;
-               if (t->hash_base && (tid >= t->hash_base))
-                       atomic_dec(&t->hash_tids_in_use);
-               else
-                       atomic_dec(&t->tids_in_use);
+               atomic_dec(&t->conns_in_use);
+               if (t->hash_base && (tid >= t->hash_base)) {
+                       if (family == AF_INET6)
+                               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);
@@ -1292,10 +1306,12 @@ static int tid_init(struct tid_info *t)
        spin_lock_init(&t->ftid_lock);
 
        t->stids_in_use = 0;
+       t->v6_stids_in_use = 0;
        t->sftids_in_use = 0;
        t->afree = NULL;
        t->atids_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);
 
        /* Setup the free list for atid_tab and clear the stid bitmap. */
index 6e74040af49af41fb9aa4065cc2152983f9c7ae5..ce0d9fbf0648e7b8b3265f47489a16e8fe084356 100644 (file)
@@ -123,12 +123,14 @@ struct tid_info {
 
        spinlock_t stid_lock;
        unsigned int stids_in_use;
+       unsigned int v6_stids_in_use;
        unsigned int sftids_in_use;
 
        /* TIDs in the TCAM */
        atomic_t tids_in_use;
        /* TIDs in the HASH */
        atomic_t hash_tids_in_use;
+       atomic_t conns_in_use;
        /* lock for setting/clearing filter bitmap */
        spinlock_t ftid_lock;
 };
@@ -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,
-                                   unsigned int tid)
+                                   unsigned int tid, unsigned short family)
 {
        t->tid_tab[tid] = data;
-       if (t->hash_base && (tid >= t->hash_base))
-               atomic_inc(&t->hash_tids_in_use);
-       else
-               atomic_inc(&t->tids_in_use);
+       if (t->hash_base && (tid >= t->hash_base)) {
+               if (family == AF_INET6)
+                       atomic_add(2, &t->hash_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);
@@ -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);
 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_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;
 
 int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
index 1076c157832291b4794f2d4eaf0ea49489fb1abb..9a92b515021882a2e10b4eeedcc4b8cb08633185 100644 (file)
@@ -806,7 +806,7 @@ static void do_act_establish(struct cxgbi_device *cdev, struct sk_buff *skb)
 
        cxgbi_sock_get(csk);
        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);
 
        free_atid(csk);
@@ -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 &&
            status != CPL_ERR_CONN_EXIST &&
            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);
        spin_lock_bh(&csk->lock);
@@ -1590,7 +1591,8 @@ static void release_offload_resources(struct cxgbi_sock *csk)
                free_atid(csk);
        else if (cxgbi_sock_flag(csk, CTPF_HAS_TID)) {
                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_put(csk);
        }
index 37a05185dcbe0e1d21fec4bac454c5a316ea3ebb..939c6ec51e4d1eb0bfd357c99317374b83ab444b 100644 (file)
@@ -752,7 +752,8 @@ void _cxgbit_free_csk(struct kref *kref)
                                   &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);
        cxgb4_l2t_release(csk->l2t);
 
@@ -1313,8 +1314,7 @@ cxgbit_pass_accept_req(struct cxgbit_device *cdev, struct sk_buff *skb)
        spin_lock(&cdev->cskq.lock);
        list_add_tail(&csk->list, &cdev->cskq.list);
        spin_unlock(&cdev->cskq.lock);
-
-       cxgb4_insert_tid(t, csk, tid);
+       cxgb4_insert_tid(t, csk, tid, csk->com.local_addr.ss_family);
        cxgbit_pass_accept_rpl(csk, req);
        goto rel_skb;