in prov/verbs/src/verbs_ep.c [961:1130]
int vrb_open_ep(struct fid_domain *domain, struct fi_info *info,
struct fid_ep **ep_fid, void *context)
{
struct vrb_domain *dom;
struct vrb_ep *ep;
struct vrb_connreq *connreq;
struct vrb_pep *pep;
struct fi_info *fi;
int ret;
if (info->src_addr)
ofi_straddr_dbg(&vrb_prov, FI_LOG_FABRIC,
"open_ep src addr", info->src_addr);
if (info->dest_addr)
ofi_straddr_dbg(&vrb_prov, FI_LOG_FABRIC,
"open_ep dest addr", info->dest_addr);
dom = container_of(domain, struct vrb_domain,
util_domain.domain_fid);
/* strncmp is used here, because the function is used
* to allocate DGRAM (has prefix <dev_name>-dgram) and MSG EPs */
if (strncmp(dom->verbs->device->name, info->domain_attr->name,
strlen(dom->verbs->device->name))) {
VERBS_INFO(FI_LOG_DOMAIN,
"Invalid info->domain_attr->name: %s and %s\n",
dom->verbs->device->name, info->domain_attr->name);
return -FI_EINVAL;
}
fi = dom->info;
if (info->ep_attr) {
ret = vrb_check_ep_attr(info, fi);
if (ret)
return ret;
}
if (info->tx_attr) {
ret = ofi_check_tx_attr(&vrb_prov, fi->tx_attr,
info->tx_attr, info->mode);
if (ret)
return ret;
}
if (info->rx_attr) {
ret = vrb_check_rx_attr(info->rx_attr, info, fi);
if (ret)
return ret;
}
ep = vrb_alloc_init_ep(info, dom, context);
if (!ep) {
VERBS_WARN(FI_LOG_EP_CTRL,
"Unable to allocate/init EP memory\n");
return -FI_ENOMEM;
}
ep->inject_limit = ep->info->tx_attr->inject_size;
ep->peer_rq_credits = UINT64_MAX;
ep->threshold = UINT64_MAX; /* disables RQ flow control */
switch (info->ep_attr->type) {
case FI_EP_MSG:
if (dom->flags & VRB_USE_XRC) {
if (dom->util_domain.threading == FI_THREAD_SAFE) {
*ep->util_ep.ep_fid.msg = vrb_msg_xrc_ep_msg_ops_ts;
ep->util_ep.ep_fid.rma = &vrb_msg_xrc_ep_rma_ops_ts;
} else {
*ep->util_ep.ep_fid.msg = vrb_msg_xrc_ep_msg_ops;
ep->util_ep.ep_fid.rma = &vrb_msg_xrc_ep_rma_ops;
}
ep->util_ep.ep_fid.cm = &vrb_msg_xrc_ep_cm_ops;
ep->util_ep.ep_fid.atomic = &vrb_msg_xrc_ep_atomic_ops;
} else {
if (dom->util_domain.threading == FI_THREAD_SAFE) {
*ep->util_ep.ep_fid.msg = vrb_msg_ep_msg_ops_ts;
ep->util_ep.ep_fid.rma = &vrb_msg_ep_rma_ops_ts;
} else {
*ep->util_ep.ep_fid.msg = vrb_msg_ep_msg_ops;
ep->util_ep.ep_fid.rma = &vrb_msg_ep_rma_ops;
}
ep->util_ep.ep_fid.cm = &vrb_msg_ep_cm_ops;
ep->util_ep.ep_fid.atomic = &vrb_msg_ep_atomic_ops;
}
if (!info->handle) {
/* Only RC, XRC active RDMA CM ID is created at connect */
if (!(dom->flags & VRB_USE_XRC)) {
ret = vrb_create_ep(info, RDMA_PS_TCP,
&ep->id);
if (ret)
goto err1;
ep->id->context = &ep->util_ep.ep_fid.fid;
}
} else if (info->handle->fclass == FI_CLASS_CONNREQ) {
connreq = container_of(info->handle,
struct vrb_connreq, handle);
if (dom->flags & VRB_USE_XRC) {
assert(connreq->is_xrc);
if (!connreq->xrc.is_reciprocal) {
ret = vrb_process_xrc_connreq(ep,
connreq);
if (ret)
goto err1;
}
} else {
ep->id = connreq->id;
ep->ibv_qp = ep->id->qp;
ep->id->context = &ep->util_ep.ep_fid.fid;
}
} else if (info->handle->fclass == FI_CLASS_PEP) {
pep = container_of(info->handle, struct vrb_pep, pep_fid.fid);
ep->id = pep->id;
ep->ibv_qp = ep->id->qp;
pep->id = NULL;
if (rdma_resolve_addr(ep->id, info->src_addr, info->dest_addr,
VERBS_RESOLVE_TIMEOUT)) {
ret = -errno;
VERBS_INFO(FI_LOG_DOMAIN, "Unable to rdma_resolve_addr\n");
goto err2;
}
ep->id->context = &ep->util_ep.ep_fid.fid;
} else {
ret = -FI_ENOSYS;
goto err1;
}
break;
case FI_EP_DGRAM:
ep->service = (info->src_addr) ?
(((struct ofi_ib_ud_ep_name *)info->src_addr)->service) :
(((getpid() & 0x7FFF) << 16) + ((uintptr_t)ep & 0xFFFF));
if (dom->util_domain.threading == FI_THREAD_SAFE) {
*ep->util_ep.ep_fid.msg = vrb_dgram_msg_ops_ts;
} else {
*ep->util_ep.ep_fid.msg = vrb_dgram_msg_ops;
}
ep->util_ep.ep_fid.rma = &vrb_dgram_rma_ops;
ep->util_ep.ep_fid.cm = &vrb_dgram_cm_ops;
break;
default:
VERBS_INFO(FI_LOG_DOMAIN, "Unknown EP type\n");
ret = -FI_EINVAL;
assert(0);
goto err1;
}
if (info->ep_attr->rx_ctx_cnt == 0 ||
info->ep_attr->rx_ctx_cnt == 1)
ep->rx_cq_size = info->rx_attr->size;
if (info->ep_attr->tx_ctx_cnt == 0 ||
info->ep_attr->tx_ctx_cnt == 1)
ep->sq_credits = info->tx_attr->size;
*ep_fid = &ep->util_ep.ep_fid;
ep->util_ep.ep_fid.fid.ops = &vrb_ep_ops;
ep->util_ep.ep_fid.ops = &vrb_ep_base_ops;
return FI_SUCCESS;
err2:
ep->ibv_qp = NULL;
if (ep->id)
rdma_destroy_ep(ep->id);
err1:
vrb_close_free_ep(ep);
return ret;
}