int vrb_open_ep()

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;
}