ret = memcmp(mcast->mcast_addr.mgid.raw,
tmcast->mcast_addr.mgid.raw, sizeof(mcast->mcast_addr.mgid)); if (ret < 0) {
n = &pn->rb_left; continue;
} if (ret > 0) {
n = &pn->rb_right; continue;
}
if (tmcast->mcast_addr.lid != mcast->mcast_addr.lid) {
ret = EINVAL; goto bail;
}
/* Search the QP list to see if this is already there. */
list_for_each_entry_rcu(p, &tmcast->qp_list, list) { if (p->qp == mqp->qp) {
ret = ESRCH; goto bail;
}
} if (tmcast->n_attached ==
rdi->dparms.props.max_mcast_qp_attach) {
ret = ENOMEM; goto bail;
}
tmcast->n_attached++;
list_add_tail_rcu(&mqp->list, &tmcast->qp_list);
ret = EEXIST; goto bail;
}
spin_lock(&rdi->n_mcast_grps_lock); if (rdi->n_mcast_grps_allocated == rdi->dparms.props.max_mcast_grp) {
spin_unlock(&rdi->n_mcast_grps_lock);
ret = ENOMEM; goto bail;
}
mqp = rvt_mcast_qp_alloc(qp); if (!mqp) goto bail_mcast;
switch (rvt_mcast_add(rdi, ibp, mcast, mqp)) { case ESRCH: /* Neither was used: OK to attach the same QP twice. */
ret = 0; goto bail_mqp; case EEXIST: /* The mcast wasn't used */
ret = 0; goto bail_mcast; case ENOMEM: /* Exceeded the maximum number of mcast groups. */
ret = -ENOMEM; goto bail_mqp; case EINVAL: /* Invalid MGID/MLID pair */
ret = -EINVAL; goto bail_mqp; default: break;
}
return0;
bail_mqp:
rvt_mcast_qp_free(mqp);
bail_mcast:
rvt_mcast_free(mcast);
return ret;
}
/** *rvt_detach_mcast-removeaqpfromamulticastgroup *@ibqp:Infinibandqp *@gid:multicastguid *@lid:multicastlid * *Return:0onsuccess
*/ int rvt_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
{ struct rvt_qp *qp = ibqp_to_rvtqp(ibqp); struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device); struct rvt_ibport *ibp = rdi->ports[qp->port_num - 1]; struct rvt_mcast *mcast = NULL; struct rvt_mcast_qp *p, *tmp, *delp = NULL; struct rb_node *n; int last = 0; int ret = 0;
if (ibqp->qp_num <= 1) return -EINVAL;
spin_lock_irq(&ibp->lock);
/* Find the GID in the mcast table. */
n = ibp->mcast_tree.rb_node; while (1) { if (!n) {
spin_unlock_irq(&ibp->lock); return -EINVAL;
}
mcast = rb_entry(n, struct rvt_mcast, rb_node);
ret = memcmp(gid->raw, mcast->mcast_addr.mgid.raw, sizeof(*gid)); if (ret < 0) {
n = n->rb_left;
} elseif (ret > 0) {
n = n->rb_right;
} else { /* MGID/MLID must match */ if (mcast->mcast_addr.lid != lid) {
spin_unlock_irq(&ibp->lock); return -EINVAL;
} break;
}
}
/* If this was the last attached QP, remove the GID too. */ if (list_empty(&mcast->qp_list)) {
rb_erase(&mcast->rb_node, &ibp->mcast_tree);
last = 1;
} break;
}
spin_unlock_irq(&ibp->lock); /* QP not attached */ if (!delp) return -EINVAL;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.