Commit a5e27fb6 authored by Weihang Li's avatar Weihang Li Committed by Jason Gunthorpe

RDMA/ipoib: Use refcount_t instead of atomic_t for reference counting

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.comSigned-off-by: default avatarWeihang Li <liweihang@huawei.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 7183451f
...@@ -454,7 +454,7 @@ struct ipoib_neigh { ...@@ -454,7 +454,7 @@ struct ipoib_neigh {
struct list_head list; struct list_head list;
struct ipoib_neigh __rcu *hnext; struct ipoib_neigh __rcu *hnext;
struct rcu_head rcu; struct rcu_head rcu;
atomic_t refcnt; refcount_t refcnt;
unsigned long alive; unsigned long alive;
}; };
...@@ -464,7 +464,7 @@ struct ipoib_neigh { ...@@ -464,7 +464,7 @@ struct ipoib_neigh {
void ipoib_neigh_dtor(struct ipoib_neigh *neigh); void ipoib_neigh_dtor(struct ipoib_neigh *neigh);
static inline void ipoib_neigh_put(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); ipoib_neigh_dtor(neigh);
} }
struct ipoib_neigh *ipoib_neigh_get(struct net_device *dev, u8 *daddr); struct ipoib_neigh *ipoib_neigh_get(struct net_device *dev, u8 *daddr);
......
...@@ -1287,7 +1287,7 @@ struct ipoib_neigh *ipoib_neigh_get(struct net_device *dev, u8 *daddr) ...@@ -1287,7 +1287,7 @@ struct ipoib_neigh *ipoib_neigh_get(struct net_device *dev, u8 *daddr)
neigh = rcu_dereference_bh(neigh->hnext)) { neigh = rcu_dereference_bh(neigh->hnext)) {
if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) { if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) {
/* found, take one ref on behalf of the caller */ /* found, take one ref on behalf of the caller */
if (!atomic_inc_not_zero(&neigh->refcnt)) { if (!refcount_inc_not_zero(&neigh->refcnt)) {
/* deleted */ /* deleted */
neigh = NULL; neigh = NULL;
goto out_unlock; goto out_unlock;
...@@ -1382,7 +1382,7 @@ static struct ipoib_neigh *ipoib_neigh_ctor(u8 *daddr, ...@@ -1382,7 +1382,7 @@ static struct ipoib_neigh *ipoib_neigh_ctor(u8 *daddr,
INIT_LIST_HEAD(&neigh->list); INIT_LIST_HEAD(&neigh->list);
ipoib_cm_set(neigh, NULL); ipoib_cm_set(neigh, NULL);
/* one ref on behalf of the caller */ /* one ref on behalf of the caller */
atomic_set(&neigh->refcnt, 1); refcount_set(&neigh->refcnt, 1);
return neigh; return neigh;
} }
...@@ -1414,7 +1414,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr, ...@@ -1414,7 +1414,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr,
lockdep_is_held(&priv->lock))) { lockdep_is_held(&priv->lock))) {
if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) { if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) {
/* found, take one ref on behalf of the caller */ /* found, take one ref on behalf of the caller */
if (!atomic_inc_not_zero(&neigh->refcnt)) { if (!refcount_inc_not_zero(&neigh->refcnt)) {
/* deleted */ /* deleted */
neigh = NULL; neigh = NULL;
break; break;
...@@ -1429,7 +1429,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr, ...@@ -1429,7 +1429,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr,
goto out_unlock; goto out_unlock;
/* one ref on behalf of the hash table */ /* one ref on behalf of the hash table */
atomic_inc(&neigh->refcnt); refcount_inc(&neigh->refcnt);
neigh->alive = jiffies; neigh->alive = jiffies;
/* put in hash */ /* put in hash */
rcu_assign_pointer(neigh->hnext, rcu_assign_pointer(neigh->hnext,
......
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