Lines Matching +full:mcast +full:- +full:groups
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
12 #include "mcast.h"
15 * rvt_driver_mcast_init - init resources for multicast
26 spin_lock_init(&rdi->n_mcast_grps_lock); in rvt_driver_mcast_init()
30 * rvt_mcast_qp_alloc - alloc a struct to link a QP to mcast GID struct
41 mqp->qp = qp; in rvt_mcast_qp_alloc()
50 struct rvt_qp *qp = mqp->qp; in rvt_mcast_qp_free()
59 * rvt_mcast_alloc - allocate the multicast GID structure
67 struct rvt_mcast *mcast; in rvt_mcast_alloc() local
69 mcast = kzalloc(sizeof(*mcast), GFP_KERNEL); in rvt_mcast_alloc()
70 if (!mcast) in rvt_mcast_alloc()
73 mcast->mcast_addr.mgid = *mgid; in rvt_mcast_alloc()
74 mcast->mcast_addr.lid = lid; in rvt_mcast_alloc()
76 INIT_LIST_HEAD(&mcast->qp_list); in rvt_mcast_alloc()
77 init_waitqueue_head(&mcast->wait); in rvt_mcast_alloc()
78 atomic_set(&mcast->refcount, 0); in rvt_mcast_alloc()
81 return mcast; in rvt_mcast_alloc()
84 static void rvt_mcast_free(struct rvt_mcast *mcast) in rvt_mcast_free() argument
88 list_for_each_entry_safe(p, tmp, &mcast->qp_list, list) in rvt_mcast_free()
91 kfree(mcast); in rvt_mcast_free()
95 * rvt_mcast_find - search the global table for the given multicast GID/LID
113 spin_lock_irqsave(&ibp->lock, flags); in rvt_mcast_find()
114 n = ibp->mcast_tree.rb_node; in rvt_mcast_find()
117 struct rvt_mcast *mcast; in rvt_mcast_find() local
119 mcast = rb_entry(n, struct rvt_mcast, rb_node); in rvt_mcast_find()
121 ret = memcmp(mgid->raw, mcast->mcast_addr.mgid.raw, in rvt_mcast_find()
124 n = n->rb_left; in rvt_mcast_find()
126 n = n->rb_right; in rvt_mcast_find()
129 if (mcast->mcast_addr.lid == lid) { in rvt_mcast_find()
130 atomic_inc(&mcast->refcount); in rvt_mcast_find()
131 found = mcast; in rvt_mcast_find()
136 spin_unlock_irqrestore(&ibp->lock, flags); in rvt_mcast_find()
142 * rvt_mcast_add - insert mcast GID into table and attach QP struct
143 * @mcast: the mcast GID table
152 struct rvt_mcast *mcast, struct rvt_mcast_qp *mqp) in rvt_mcast_add() argument
154 struct rb_node **n = &ibp->mcast_tree.rb_node; in rvt_mcast_add()
158 spin_lock_irq(&ibp->lock); in rvt_mcast_add()
167 ret = memcmp(mcast->mcast_addr.mgid.raw, in rvt_mcast_add()
168 tmcast->mcast_addr.mgid.raw, in rvt_mcast_add()
169 sizeof(mcast->mcast_addr.mgid)); in rvt_mcast_add()
171 n = &pn->rb_left; in rvt_mcast_add()
175 n = &pn->rb_right; in rvt_mcast_add()
179 if (tmcast->mcast_addr.lid != mcast->mcast_addr.lid) { in rvt_mcast_add()
185 list_for_each_entry_rcu(p, &tmcast->qp_list, list) { in rvt_mcast_add()
186 if (p->qp == mqp->qp) { in rvt_mcast_add()
191 if (tmcast->n_attached == in rvt_mcast_add()
192 rdi->dparms.props.max_mcast_qp_attach) { in rvt_mcast_add()
197 tmcast->n_attached++; in rvt_mcast_add()
199 list_add_tail_rcu(&mqp->list, &tmcast->qp_list); in rvt_mcast_add()
204 spin_lock(&rdi->n_mcast_grps_lock); in rvt_mcast_add()
205 if (rdi->n_mcast_grps_allocated == rdi->dparms.props.max_mcast_grp) { in rvt_mcast_add()
206 spin_unlock(&rdi->n_mcast_grps_lock); in rvt_mcast_add()
211 rdi->n_mcast_grps_allocated++; in rvt_mcast_add()
212 spin_unlock(&rdi->n_mcast_grps_lock); in rvt_mcast_add()
214 mcast->n_attached++; in rvt_mcast_add()
216 list_add_tail_rcu(&mqp->list, &mcast->qp_list); in rvt_mcast_add()
218 atomic_inc(&mcast->refcount); in rvt_mcast_add()
219 rb_link_node(&mcast->rb_node, pn, n); in rvt_mcast_add()
220 rb_insert_color(&mcast->rb_node, &ibp->mcast_tree); in rvt_mcast_add()
225 spin_unlock_irq(&ibp->lock); in rvt_mcast_add()
231 * rvt_attach_mcast - attach a qp to a multicast group
241 struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device); in rvt_attach_mcast()
242 struct rvt_ibport *ibp = rdi->ports[qp->port_num - 1]; in rvt_attach_mcast()
243 struct rvt_mcast *mcast; in rvt_attach_mcast() local
245 int ret = -ENOMEM; in rvt_attach_mcast()
247 if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET) in rvt_attach_mcast()
248 return -EINVAL; in rvt_attach_mcast()
254 mcast = rvt_mcast_alloc(gid, lid); in rvt_attach_mcast()
255 if (!mcast) in rvt_attach_mcast()
256 return -ENOMEM; in rvt_attach_mcast()
262 switch (rvt_mcast_add(rdi, ibp, mcast, mqp)) { in rvt_attach_mcast()
267 case EEXIST: /* The mcast wasn't used */ in rvt_attach_mcast()
271 /* Exceeded the maximum number of mcast groups. */ in rvt_attach_mcast()
272 ret = -ENOMEM; in rvt_attach_mcast()
276 ret = -EINVAL; in rvt_attach_mcast()
288 rvt_mcast_free(mcast); in rvt_attach_mcast()
294 * rvt_detach_mcast - remove a qp from a multicast group
304 struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device); in rvt_detach_mcast()
305 struct rvt_ibport *ibp = rdi->ports[qp->port_num - 1]; in rvt_detach_mcast()
306 struct rvt_mcast *mcast = NULL; in rvt_detach_mcast() local
312 if (ibqp->qp_num <= 1) in rvt_detach_mcast()
313 return -EINVAL; in rvt_detach_mcast()
315 spin_lock_irq(&ibp->lock); in rvt_detach_mcast()
317 /* Find the GID in the mcast table. */ in rvt_detach_mcast()
318 n = ibp->mcast_tree.rb_node; in rvt_detach_mcast()
321 spin_unlock_irq(&ibp->lock); in rvt_detach_mcast()
322 return -EINVAL; in rvt_detach_mcast()
325 mcast = rb_entry(n, struct rvt_mcast, rb_node); in rvt_detach_mcast()
326 ret = memcmp(gid->raw, mcast->mcast_addr.mgid.raw, in rvt_detach_mcast()
329 n = n->rb_left; in rvt_detach_mcast()
331 n = n->rb_right; in rvt_detach_mcast()
334 if (mcast->mcast_addr.lid != lid) { in rvt_detach_mcast()
335 spin_unlock_irq(&ibp->lock); in rvt_detach_mcast()
336 return -EINVAL; in rvt_detach_mcast()
343 list_for_each_entry_safe(p, tmp, &mcast->qp_list, list) { in rvt_detach_mcast()
344 if (p->qp != qp) in rvt_detach_mcast()
350 list_del_rcu(&p->list); in rvt_detach_mcast()
351 mcast->n_attached--; in rvt_detach_mcast()
355 if (list_empty(&mcast->qp_list)) { in rvt_detach_mcast()
356 rb_erase(&mcast->rb_node, &ibp->mcast_tree); in rvt_detach_mcast()
362 spin_unlock_irq(&ibp->lock); in rvt_detach_mcast()
365 return -EINVAL; in rvt_detach_mcast()
371 wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1); in rvt_detach_mcast()
375 atomic_dec(&mcast->refcount); in rvt_detach_mcast()
376 wait_event(mcast->wait, !atomic_read(&mcast->refcount)); in rvt_detach_mcast()
377 rvt_mcast_free(mcast); in rvt_detach_mcast()
378 spin_lock_irq(&rdi->n_mcast_grps_lock); in rvt_detach_mcast()
379 rdi->n_mcast_grps_allocated--; in rvt_detach_mcast()
380 spin_unlock_irq(&rdi->n_mcast_grps_lock); in rvt_detach_mcast()
387 * rvt_mcast_tree_empty - determine if any qps are attached to any mcast group
397 for (i = 0; i < rdi->dparms.nports; i++) in rvt_mcast_tree_empty()
398 if (rdi->ports[i]->mcast_tree.rb_node) in rvt_mcast_tree_empty()