|
@@ -286,15 +286,13 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
|
|
struct qib_ibdev *dev = to_idev(ibqp->device);
|
|
|
struct qib_ibport *ibp = to_iport(ibqp->device, qp->port_num);
|
|
|
struct qib_mcast *mcast = NULL;
|
|
|
- struct qib_mcast_qp *p, *tmp;
|
|
|
+ struct qib_mcast_qp *p, *tmp, *delp = NULL;
|
|
|
struct rb_node *n;
|
|
|
int last = 0;
|
|
|
int ret;
|
|
|
|
|
|
- if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET) {
|
|
|
- ret = -EINVAL;
|
|
|
- goto bail;
|
|
|
- }
|
|
|
+ if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET)
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
spin_lock_irq(&ibp->lock);
|
|
|
|
|
@@ -303,8 +301,7 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
|
|
while (1) {
|
|
|
if (n == NULL) {
|
|
|
spin_unlock_irq(&ibp->lock);
|
|
|
- ret = -EINVAL;
|
|
|
- goto bail;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
mcast = rb_entry(n, struct qib_mcast, rb_node);
|
|
@@ -328,6 +325,7 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
|
|
*/
|
|
|
list_del_rcu(&p->list);
|
|
|
mcast->n_attached--;
|
|
|
+ delp = p;
|
|
|
|
|
|
/* If this was the last attached QP, remove the GID too. */
|
|
|
if (list_empty(&mcast->qp_list)) {
|
|
@@ -338,15 +336,16 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
|
|
}
|
|
|
|
|
|
spin_unlock_irq(&ibp->lock);
|
|
|
+ /* QP not attached */
|
|
|
+ if (!delp)
|
|
|
+ return -EINVAL;
|
|
|
+ /*
|
|
|
+ * Wait for any list walkers to finish before freeing the
|
|
|
+ * list element.
|
|
|
+ */
|
|
|
+ wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1);
|
|
|
+ qib_mcast_qp_free(delp);
|
|
|
|
|
|
- if (p) {
|
|
|
- /*
|
|
|
- * Wait for any list walkers to finish before freeing the
|
|
|
- * list element.
|
|
|
- */
|
|
|
- wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1);
|
|
|
- qib_mcast_qp_free(p);
|
|
|
- }
|
|
|
if (last) {
|
|
|
atomic_dec(&mcast->refcount);
|
|
|
wait_event(mcast->wait, !atomic_read(&mcast->refcount));
|
|
@@ -355,11 +354,7 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
|
|
dev->n_mcast_grps_allocated--;
|
|
|
spin_unlock_irq(&dev->n_mcast_grps_lock);
|
|
|
}
|
|
|
-
|
|
|
- ret = 0;
|
|
|
-
|
|
|
-bail:
|
|
|
- return ret;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
int qib_mcast_tree_empty(struct qib_ibport *ibp)
|