On Fri, May 28, 2021 at 05:37:37PM +0800, Weihang Li wrote:
quoted hunk ↗ jump to hunk
@@ -565,8 +565,11 @@ static struct mcast_group *acquire_group(struct mcast_port *port,
if (!is_mgid0) {
spin_lock_irqsave(&port->lock, flags);
group = mcast_find(port, mgid);
- if (group)
+ if (group) {
+ refcount_inc(&group->refcount);
goto found;
+ }
+
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -590,8 +593,10 @@ static struct mcast_group *acquire_group(struct mcast_port *port,
group = cur_group;
} else
refcount_inc(&port->refcount);
+
+ refcount_set(&group->refcount, 1);
+
This isn't right, when mcast_insert() returns an existing group we
need to incr not set the refcount. Change it like this:
diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c
index 17abc212b87d05..cf99e17b81ce79 100644
--- a/drivers/infiniband/core/multicast.c
+++ b/drivers/infiniband/core/multicast.c
@@ -585,17 +585,17 @@ static struct mcast_group *acquire_group(struct mcast_port *port,
INIT_LIST_HEAD(&group->active_list);
INIT_WORK(&group->work, mcast_work_handler);
spin_lock_init(&group->lock);
+ refcount_set(&group->refcount, 1);
spin_lock_irqsave(&port->lock, flags);
cur_group = mcast_insert(port, group, is_mgid0);
if (cur_group) {
kfree(group);
group = cur_group;
+ refcount_inc(&group->refcount);
} else
refcount_inc(&port->refcount);
- refcount_set(&group->refcount, 1);
-
found:
spin_unlock_irqrestore(&port->lock, flags);
return group;