RDMA/ipoib: Use refcount_t instead of atomic_t for reference counting
authorWeihang Li <liweihang@huawei.com>
Fri, 28 May 2021 09:37:43 +0000 (17:37 +0800)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 8 Jun 2021 18:00:04 +0000 (15:00 -0300)
The refcount_t API will WARN on underflow and overflow of a reference
counter, and avoid use-after-free risks.

Link: https://lore.kernel.org/r/1622194663-2383-13-git-send-email-liweihang@huawei.com
Signed-off-by: Weihang Li <liweihang@huawei.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_main.c

index 75cd44789661b4c113e3bd2e411fa5953b2be4ce..44d8d151ff9041e4863f69ce7dbf1245305cbae9 100644 (file)
@@ -454,7 +454,7 @@ struct ipoib_neigh {
        struct list_head    list;
        struct ipoib_neigh __rcu *hnext;
        struct rcu_head     rcu;
-       atomic_t            refcnt;
+       refcount_t          refcnt;
        unsigned long       alive;
 };
 
@@ -464,7 +464,7 @@ struct ipoib_neigh {
 void ipoib_neigh_dtor(struct ipoib_neigh *neigh);
 static inline void ipoib_neigh_put(struct ipoib_neigh *neigh)
 {
-       if (atomic_dec_and_test(&neigh->refcnt))
+       if (refcount_dec_and_test(&neigh->refcnt))
                ipoib_neigh_dtor(neigh);
 }
 struct ipoib_neigh *ipoib_neigh_get(struct net_device *dev, u8 *daddr);
index a4f9220161add2c11012c27947ad5c19885e13f5..7bd110ac4fe682cf3269297975ec91de90b5854b 100644 (file)
@@ -1287,7 +1287,7 @@ struct ipoib_neigh *ipoib_neigh_get(struct net_device *dev, u8 *daddr)
             neigh = rcu_dereference_bh(neigh->hnext)) {
                if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) {
                        /* found, take one ref on behalf of the caller */
-                       if (!atomic_inc_not_zero(&neigh->refcnt)) {
+                       if (!refcount_inc_not_zero(&neigh->refcnt)) {
                                /* deleted */
                                neigh = NULL;
                                goto out_unlock;
@@ -1382,7 +1382,7 @@ static struct ipoib_neigh *ipoib_neigh_ctor(u8 *daddr,
        INIT_LIST_HEAD(&neigh->list);
        ipoib_cm_set(neigh, NULL);
        /* one ref on behalf of the caller */
-       atomic_set(&neigh->refcnt, 1);
+       refcount_set(&neigh->refcnt, 1);
 
        return neigh;
 }
@@ -1414,7 +1414,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr,
                                               lockdep_is_held(&priv->lock))) {
                if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) {
                        /* found, take one ref on behalf of the caller */
-                       if (!atomic_inc_not_zero(&neigh->refcnt)) {
+                       if (!refcount_inc_not_zero(&neigh->refcnt)) {
                                /* deleted */
                                neigh = NULL;
                                break;
@@ -1429,7 +1429,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr,
                goto out_unlock;
 
        /* one ref on behalf of the hash table */
-       atomic_inc(&neigh->refcnt);
+       refcount_inc(&neigh->refcnt);
        neigh->alive = jiffies;
        /* put in hash */
        rcu_assign_pointer(neigh->hnext,