Lines Matching +full:mcast +full:- +full:groups
24 * - Redistributions of source code must retain the above copyright
26 * - Redistributions in binary form must reproduce the above copyright
30 * - Neither the name of Intel Corporation nor the names of its
54 #include "mcast.h"
57 * rvt_driver_mcast - init resources for multicast
68 spin_lock_init(&rdi->n_mcast_grps_lock); in rvt_driver_mcast_init()
72 * mcast_qp_alloc - alloc a struct to link a QP to mcast GID struct
83 mqp->qp = qp; in rvt_mcast_qp_alloc()
92 struct rvt_qp *qp = mqp->qp; in rvt_mcast_qp_free()
101 * mcast_alloc - allocate the multicast GID structure
109 struct rvt_mcast *mcast; in rvt_mcast_alloc() local
111 mcast = kzalloc(sizeof(*mcast), GFP_KERNEL); in rvt_mcast_alloc()
112 if (!mcast) in rvt_mcast_alloc()
115 mcast->mcast_addr.mgid = *mgid; in rvt_mcast_alloc()
116 mcast->mcast_addr.lid = lid; in rvt_mcast_alloc()
118 INIT_LIST_HEAD(&mcast->qp_list); in rvt_mcast_alloc()
119 init_waitqueue_head(&mcast->wait); in rvt_mcast_alloc()
120 atomic_set(&mcast->refcount, 0); in rvt_mcast_alloc()
123 return mcast; in rvt_mcast_alloc()
126 static void rvt_mcast_free(struct rvt_mcast *mcast) in rvt_mcast_free() argument
130 list_for_each_entry_safe(p, tmp, &mcast->qp_list, list) in rvt_mcast_free()
133 kfree(mcast); in rvt_mcast_free()
137 * rvt_mcast_find - search the global table for the given multicast GID/LID
155 spin_lock_irqsave(&ibp->lock, flags); in rvt_mcast_find()
156 n = ibp->mcast_tree.rb_node; in rvt_mcast_find()
159 struct rvt_mcast *mcast; in rvt_mcast_find() local
161 mcast = rb_entry(n, struct rvt_mcast, rb_node); in rvt_mcast_find()
163 ret = memcmp(mgid->raw, mcast->mcast_addr.mgid.raw, in rvt_mcast_find()
166 n = n->rb_left; in rvt_mcast_find()
168 n = n->rb_right; in rvt_mcast_find()
171 if (mcast->mcast_addr.lid == lid) { in rvt_mcast_find()
172 atomic_inc(&mcast->refcount); in rvt_mcast_find()
173 found = mcast; in rvt_mcast_find()
178 spin_unlock_irqrestore(&ibp->lock, flags); in rvt_mcast_find()
184 * mcast_add - insert mcast GID into table and attach QP struct
185 * @mcast: the mcast GID table
194 struct rvt_mcast *mcast, struct rvt_mcast_qp *mqp) in rvt_mcast_add() argument
196 struct rb_node **n = &ibp->mcast_tree.rb_node; in rvt_mcast_add()
200 spin_lock_irq(&ibp->lock); in rvt_mcast_add()
209 ret = memcmp(mcast->mcast_addr.mgid.raw, in rvt_mcast_add()
210 tmcast->mcast_addr.mgid.raw, in rvt_mcast_add()
211 sizeof(mcast->mcast_addr.mgid)); in rvt_mcast_add()
213 n = &pn->rb_left; in rvt_mcast_add()
217 n = &pn->rb_right; in rvt_mcast_add()
221 if (tmcast->mcast_addr.lid != mcast->mcast_addr.lid) { in rvt_mcast_add()
227 list_for_each_entry_rcu(p, &tmcast->qp_list, list) { in rvt_mcast_add()
228 if (p->qp == mqp->qp) { in rvt_mcast_add()
233 if (tmcast->n_attached == in rvt_mcast_add()
234 rdi->dparms.props.max_mcast_qp_attach) { in rvt_mcast_add()
239 tmcast->n_attached++; in rvt_mcast_add()
241 list_add_tail_rcu(&mqp->list, &tmcast->qp_list); in rvt_mcast_add()
246 spin_lock(&rdi->n_mcast_grps_lock); in rvt_mcast_add()
247 if (rdi->n_mcast_grps_allocated == rdi->dparms.props.max_mcast_grp) { in rvt_mcast_add()
248 spin_unlock(&rdi->n_mcast_grps_lock); in rvt_mcast_add()
253 rdi->n_mcast_grps_allocated++; in rvt_mcast_add()
254 spin_unlock(&rdi->n_mcast_grps_lock); in rvt_mcast_add()
256 mcast->n_attached++; in rvt_mcast_add()
258 list_add_tail_rcu(&mqp->list, &mcast->qp_list); in rvt_mcast_add()
260 atomic_inc(&mcast->refcount); in rvt_mcast_add()
261 rb_link_node(&mcast->rb_node, pn, n); in rvt_mcast_add()
262 rb_insert_color(&mcast->rb_node, &ibp->mcast_tree); in rvt_mcast_add()
267 spin_unlock_irq(&ibp->lock); in rvt_mcast_add()
273 * rvt_attach_mcast - attach a qp to a multicast group
283 struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device); in rvt_attach_mcast()
284 struct rvt_ibport *ibp = rdi->ports[qp->port_num - 1]; in rvt_attach_mcast()
285 struct rvt_mcast *mcast; in rvt_attach_mcast() local
287 int ret = -ENOMEM; in rvt_attach_mcast()
289 if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET) in rvt_attach_mcast()
290 return -EINVAL; in rvt_attach_mcast()
296 mcast = rvt_mcast_alloc(gid, lid); in rvt_attach_mcast()
297 if (!mcast) in rvt_attach_mcast()
298 return -ENOMEM; in rvt_attach_mcast()
304 switch (rvt_mcast_add(rdi, ibp, mcast, mqp)) { in rvt_attach_mcast()
309 case EEXIST: /* The mcast wasn't used */ in rvt_attach_mcast()
313 /* Exceeded the maximum number of mcast groups. */ in rvt_attach_mcast()
314 ret = -ENOMEM; in rvt_attach_mcast()
318 ret = -EINVAL; in rvt_attach_mcast()
330 rvt_mcast_free(mcast); in rvt_attach_mcast()
336 * rvt_detach_mcast - remove a qp from a multicast group
346 struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device); in rvt_detach_mcast()
347 struct rvt_ibport *ibp = rdi->ports[qp->port_num - 1]; in rvt_detach_mcast()
348 struct rvt_mcast *mcast = NULL; in rvt_detach_mcast() local
354 if (ibqp->qp_num <= 1) in rvt_detach_mcast()
355 return -EINVAL; in rvt_detach_mcast()
357 spin_lock_irq(&ibp->lock); in rvt_detach_mcast()
359 /* Find the GID in the mcast table. */ in rvt_detach_mcast()
360 n = ibp->mcast_tree.rb_node; in rvt_detach_mcast()
363 spin_unlock_irq(&ibp->lock); in rvt_detach_mcast()
364 return -EINVAL; in rvt_detach_mcast()
367 mcast = rb_entry(n, struct rvt_mcast, rb_node); in rvt_detach_mcast()
368 ret = memcmp(gid->raw, mcast->mcast_addr.mgid.raw, in rvt_detach_mcast()
371 n = n->rb_left; in rvt_detach_mcast()
373 n = n->rb_right; in rvt_detach_mcast()
376 if (mcast->mcast_addr.lid != lid) { in rvt_detach_mcast()
377 spin_unlock_irq(&ibp->lock); in rvt_detach_mcast()
378 return -EINVAL; in rvt_detach_mcast()
385 list_for_each_entry_safe(p, tmp, &mcast->qp_list, list) { in rvt_detach_mcast()
386 if (p->qp != qp) in rvt_detach_mcast()
392 list_del_rcu(&p->list); in rvt_detach_mcast()
393 mcast->n_attached--; in rvt_detach_mcast()
397 if (list_empty(&mcast->qp_list)) { in rvt_detach_mcast()
398 rb_erase(&mcast->rb_node, &ibp->mcast_tree); in rvt_detach_mcast()
404 spin_unlock_irq(&ibp->lock); in rvt_detach_mcast()
407 return -EINVAL; in rvt_detach_mcast()
413 wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1); in rvt_detach_mcast()
417 atomic_dec(&mcast->refcount); in rvt_detach_mcast()
418 wait_event(mcast->wait, !atomic_read(&mcast->refcount)); in rvt_detach_mcast()
419 rvt_mcast_free(mcast); in rvt_detach_mcast()
420 spin_lock_irq(&rdi->n_mcast_grps_lock); in rvt_detach_mcast()
421 rdi->n_mcast_grps_allocated--; in rvt_detach_mcast()
422 spin_unlock_irq(&rdi->n_mcast_grps_lock); in rvt_detach_mcast()
429 *rvt_mast_tree_empty - determine if any qps are attached to any mcast group
439 for (i = 0; i < rdi->dparms.nports; i++) in rvt_mcast_tree_empty()
440 if (rdi->ports[i]->mcast_tree.rb_node) in rvt_mcast_tree_empty()