RDMA/core: Use refcount_t instead of atomic_t on refcount of mcast_member
authorWeihang Li <liweihang@huawei.com>
Fri, 28 May 2021 09:37:35 +0000 (17:37 +0800)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 8 Jun 2021 17:43:56 +0000 (14:43 -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-5-git-send-email-liweihang@huawei.com
Signed-off-by: Weihang Li <liweihang@huawei.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/core/multicast.c

index a5dd4b7a74bc818d71ba46aafef8953067eb398d..de134a43b776db8dfca7be26d1787bae4e2ef062 100644 (file)
@@ -117,7 +117,7 @@ struct mcast_member {
        struct mcast_group      *group;
        struct list_head        list;
        enum mcast_state        state;
-       atomic_t                refcount;
+       refcount_t              refcount;
        struct completion       comp;
 };
 
@@ -199,7 +199,7 @@ static void release_group(struct mcast_group *group)
 
 static void deref_member(struct mcast_member *member)
 {
-       if (atomic_dec_and_test(&member->refcount))
+       if (refcount_dec_and_test(&member->refcount))
                complete(&member->comp);
 }
 
@@ -401,7 +401,7 @@ static void process_group_error(struct mcast_group *group)
        while (!list_empty(&group->active_list)) {
                member = list_entry(group->active_list.next,
                                    struct mcast_member, list);
-               atomic_inc(&member->refcount);
+               refcount_inc(&member->refcount);
                list_del_init(&member->list);
                adjust_membership(group, member->multicast.rec.join_state, -1);
                member->state = MCAST_ERROR;
@@ -445,7 +445,7 @@ retest:
                                    struct mcast_member, list);
                multicast = &member->multicast;
                join_state = multicast->rec.join_state;
-               atomic_inc(&member->refcount);
+               refcount_inc(&member->refcount);
 
                if (join_state == (group->rec.join_state & join_state)) {
                        status = cmp_rec(&group->rec, &multicast->rec,
@@ -497,7 +497,7 @@ static void process_join_error(struct mcast_group *group, int status)
        member = list_entry(group->pending_list.next,
                            struct mcast_member, list);
        if (group->last_join == member) {
-               atomic_inc(&member->refcount);
+               refcount_inc(&member->refcount);
                list_del_init(&member->list);
                spin_unlock_irq(&group->lock);
                ret = member->multicast.callback(status, &member->multicast);
@@ -632,7 +632,7 @@ ib_sa_join_multicast(struct ib_sa_client *client,
        member->multicast.callback = callback;
        member->multicast.context = context;
        init_completion(&member->comp);
-       atomic_set(&member->refcount, 1);
+       refcount_set(&member->refcount, 1);
        member->state = MCAST_JOINING;
 
        member->group = acquire_group(&dev->port[port_num - dev->start_port],