1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
3 * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
4 * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.
10 int rxe_mcast_get_grp(struct rxe_dev
*rxe
, union ib_gid
*mgid
,
11 struct rxe_mc_grp
**grp_p
)
14 struct rxe_mc_grp
*grp
;
16 if (rxe
->attr
.max_mcast_qp_attach
== 0) {
21 grp
= rxe_pool_get_key(&rxe
->mc_grp_pool
, mgid
);
25 grp
= rxe_alloc(&rxe
->mc_grp_pool
);
31 INIT_LIST_HEAD(&grp
->qp_list
);
32 spin_lock_init(&grp
->mcg_lock
);
35 rxe_add_key(grp
, mgid
);
37 err
= rxe_mcast_add(rxe
, mgid
);
51 int rxe_mcast_add_grp_elem(struct rxe_dev
*rxe
, struct rxe_qp
*qp
,
52 struct rxe_mc_grp
*grp
)
55 struct rxe_mc_elem
*elem
;
57 /* check to see of the qp is already a member of the group */
58 spin_lock_bh(&qp
->grp_lock
);
59 spin_lock_bh(&grp
->mcg_lock
);
60 list_for_each_entry(elem
, &grp
->qp_list
, qp_list
) {
67 if (grp
->num_qp
>= rxe
->attr
.max_mcast_qp_attach
) {
72 elem
= rxe_alloc(&rxe
->mc_elem_pool
);
78 /* each qp holds a ref on the grp */
85 list_add(&elem
->qp_list
, &grp
->qp_list
);
86 list_add(&elem
->grp_list
, &qp
->grp_list
);
90 spin_unlock_bh(&grp
->mcg_lock
);
91 spin_unlock_bh(&qp
->grp_lock
);
95 int rxe_mcast_drop_grp_elem(struct rxe_dev
*rxe
, struct rxe_qp
*qp
,
98 struct rxe_mc_grp
*grp
;
99 struct rxe_mc_elem
*elem
, *tmp
;
101 grp
= rxe_pool_get_key(&rxe
->mc_grp_pool
, mgid
);
105 spin_lock_bh(&qp
->grp_lock
);
106 spin_lock_bh(&grp
->mcg_lock
);
108 list_for_each_entry_safe(elem
, tmp
, &grp
->qp_list
, qp_list
) {
109 if (elem
->qp
== qp
) {
110 list_del(&elem
->qp_list
);
111 list_del(&elem
->grp_list
);
114 spin_unlock_bh(&grp
->mcg_lock
);
115 spin_unlock_bh(&qp
->grp_lock
);
117 rxe_drop_ref(grp
); /* ref held by QP */
118 rxe_drop_ref(grp
); /* ref from get_key */
123 spin_unlock_bh(&grp
->mcg_lock
);
124 spin_unlock_bh(&qp
->grp_lock
);
125 rxe_drop_ref(grp
); /* ref from get_key */
130 void rxe_drop_all_mcast_groups(struct rxe_qp
*qp
)
132 struct rxe_mc_grp
*grp
;
133 struct rxe_mc_elem
*elem
;
136 spin_lock_bh(&qp
->grp_lock
);
137 if (list_empty(&qp
->grp_list
)) {
138 spin_unlock_bh(&qp
->grp_lock
);
141 elem
= list_first_entry(&qp
->grp_list
, struct rxe_mc_elem
,
143 list_del(&elem
->grp_list
);
144 spin_unlock_bh(&qp
->grp_lock
);
147 spin_lock_bh(&grp
->mcg_lock
);
148 list_del(&elem
->qp_list
);
150 spin_unlock_bh(&grp
->mcg_lock
);
156 void rxe_mc_cleanup(struct rxe_pool_entry
*arg
)
158 struct rxe_mc_grp
*grp
= container_of(arg
, typeof(*grp
), pelem
);
159 struct rxe_dev
*rxe
= grp
->rxe
;
162 rxe_mcast_delete(rxe
, &grp
->mgid
);