Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.com
Signed-off-by: Weihang Li <liweihang@huawei.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

authored by

Weihang Li and committed by
Jason Gunthorpe
a5e27fb6 7183451f

+6 -6
+2 -2
drivers/infiniband/ulp/ipoib/ipoib.h
··· 454 454 struct list_head list; 455 455 struct ipoib_neigh __rcu *hnext; 456 456 struct rcu_head rcu; 457 - atomic_t refcnt; 457 + refcount_t refcnt; 458 458 unsigned long alive; 459 459 }; 460 460 ··· 464 464 void ipoib_neigh_dtor(struct ipoib_neigh *neigh); 465 465 static inline void ipoib_neigh_put(struct ipoib_neigh *neigh) 466 466 { 467 - if (atomic_dec_and_test(&neigh->refcnt)) 467 + if (refcount_dec_and_test(&neigh->refcnt)) 468 468 ipoib_neigh_dtor(neigh); 469 469 } 470 470 struct ipoib_neigh *ipoib_neigh_get(struct net_device *dev, u8 *daddr);
+4 -4
drivers/infiniband/ulp/ipoib/ipoib_main.c
··· 1287 1287 neigh = rcu_dereference_bh(neigh->hnext)) { 1288 1288 if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) { 1289 1289 /* found, take one ref on behalf of the caller */ 1290 - if (!atomic_inc_not_zero(&neigh->refcnt)) { 1290 + if (!refcount_inc_not_zero(&neigh->refcnt)) { 1291 1291 /* deleted */ 1292 1292 neigh = NULL; 1293 1293 goto out_unlock; ··· 1382 1382 INIT_LIST_HEAD(&neigh->list); 1383 1383 ipoib_cm_set(neigh, NULL); 1384 1384 /* one ref on behalf of the caller */ 1385 - atomic_set(&neigh->refcnt, 1); 1385 + refcount_set(&neigh->refcnt, 1); 1386 1386 1387 1387 return neigh; 1388 1388 } ··· 1414 1414 lockdep_is_held(&priv->lock))) { 1415 1415 if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) { 1416 1416 /* found, take one ref on behalf of the caller */ 1417 - if (!atomic_inc_not_zero(&neigh->refcnt)) { 1417 + if (!refcount_inc_not_zero(&neigh->refcnt)) { 1418 1418 /* deleted */ 1419 1419 neigh = NULL; 1420 1420 break; ··· 1429 1429 goto out_unlock; 1430 1430 1431 1431 /* one ref on behalf of the hash table */ 1432 - atomic_inc(&neigh->refcnt); 1432 + refcount_inc(&neigh->refcnt); 1433 1433 neigh->alive = jiffies; 1434 1434 /* put in hash */ 1435 1435 rcu_assign_pointer(neigh->hnext,