in prov/gni/src/gnix_ep.c [2290:2465]
DIRECT_FN int gnix_ep_open(struct fid_domain *domain, struct fi_info *info,
struct fid_ep **ep, void *context)
{
int ret = FI_SUCCESS;
int err_ret;
struct gnix_fid_domain *domain_priv;
struct gnix_fid_ep *ep_priv;
struct gnix_auth_key *auth_key;
GNIX_TRACE(FI_LOG_EP_CTRL, "\n");
if ((domain == NULL) || (info == NULL) || (ep == NULL) ||
(info->ep_attr == NULL))
return -FI_EINVAL;
domain_priv = container_of(domain, struct gnix_fid_domain, domain_fid);
if (FI_VERSION_LT(domain_priv->fabric->fab_fid.api_version,
FI_VERSION(1, 5)) &&
(info->ep_attr->auth_key || info->ep_attr->auth_key_size))
return -FI_EINVAL;
if (info->ep_attr->auth_key_size) {
auth_key = GNIX_GET_AUTH_KEY(info->ep_attr->auth_key,
info->ep_attr->auth_key_size,
domain_priv->using_vmdh);
if (!auth_key)
return -FI_EINVAL;
} else {
auth_key = domain_priv->auth_key;
assert(auth_key);
}
ep_priv = calloc(1, sizeof *ep_priv);
if (!ep_priv)
return -FI_ENOMEM;
/* Set up libfabric fid data. */
ep_priv->ep_fid.fid.fclass = FI_CLASS_EP;
ep_priv->ep_fid.fid.context = context;
ep_priv->ep_fid.fid.ops = &gnix_ep_fi_ops;
ep_priv->ep_fid.ops = &gnix_ep_ops;
ep_priv->ep_fid.msg = &gnix_ep_msg_ops;
ep_priv->ep_fid.rma = &gnix_ep_rma_ops;
ep_priv->ep_fid.tagged = &gnix_ep_tagged_ops;
ep_priv->ep_fid.atomic = &gnix_ep_atomic_ops;
/* Init GNIX data. */
ep_priv->auth_key = auth_key;
ep_priv->type = info->ep_attr->type;
ep_priv->domain = domain_priv;
_gnix_ref_init(&ep_priv->ref_cnt, 1, __ep_destruct);
ep_priv->min_multi_recv = GNIX_OPT_MIN_MULTI_RECV_DEFAULT;
fastlock_init(&ep_priv->vc_lock);
ep_priv->progress_fn = NULL;
ep_priv->rx_progress_fn = NULL;
ep_priv->tx_enabled = false;
ep_priv->rx_enabled = false;
ep_priv->requires_lock = (domain_priv->thread_model !=
FI_THREAD_COMPLETION);
ep_priv->info = fi_dupinfo(info);
ep_priv->info->addr_format = info->addr_format;
GNIX_DEBUG(FI_LOG_DEBUG, "ep(%p) is using addr_format(%s)\n", ep_priv,
ep_priv->info->addr_format == FI_ADDR_STR ? "FI_ADDR_STR" :
"FI_ADDR_GNI");
if (info->src_addr) {
memcpy(&ep_priv->src_addr, info->src_addr,
sizeof(struct gnix_ep_name));
}
if (info->dest_addr) {
memcpy(&ep_priv->dest_addr, info->dest_addr,
sizeof(struct gnix_ep_name));
}
ret = __init_tag_storages(ep_priv, GNIX_TAG_LIST,
ep_priv->type == FI_EP_MSG ? 0 : 1);
if (ret)
goto err_tag_init;
ret = __fr_freelist_init(ep_priv);
if (ret != FI_SUCCESS) {
GNIX_WARN(FI_LOG_EP_CTRL,
"Error allocating gnix_fab_req freelist (%s)",
fi_strerror(-ret));
goto err_fl_init;
}
ep_priv->shared_tx = (info->ep_attr->tx_ctx_cnt == FI_SHARED_CONTEXT) ?
true : false;
/*
* try out XPMEM
*/
ret = _gnix_xpmem_handle_create(domain_priv,
&ep_priv->xpmem_hndl);
if (ret != FI_SUCCESS) {
GNIX_WARN(FI_LOG_EP_CTRL,
"_gnix_xpmem_handl_create returned %s\n",
fi_strerror(-ret));
}
/* Initialize caps, modes, permissions, behaviors. */
ep_priv->caps = info->caps & GNIX_EP_CAPS_FULL;
if (ep_priv->info->tx_attr)
ep_priv->op_flags = ep_priv->info->tx_attr->op_flags;
if (ep_priv->info->rx_attr)
ep_priv->op_flags |= ep_priv->info->rx_attr->op_flags;
ep_priv->op_flags &= GNIX_EP_OP_FLAGS;
gnix_ep_caps(ep_priv, ep_priv->caps);
ret = _gnix_ep_nic_init(domain_priv, ep_priv->info, ep_priv);
if (ret != FI_SUCCESS) {
GNIX_WARN(FI_LOG_EP_CTRL,
"_gnix_ep_nic_init returned %d\n",
ret);
goto err_nic_init;
}
/* Do EP type specific initialization. */
switch (ep_priv->type) {
case FI_EP_DGRAM:
case FI_EP_RDM:
ret = _gnix_ep_unconn_open(domain_priv, ep_priv->info, ep_priv);
if (ret != FI_SUCCESS) {
GNIX_INFO(FI_LOG_EP_CTRL,
"_gnix_ep_unconn_open() failed, err: %d\n",
ret);
goto err_type_init;
}
break;
case FI_EP_MSG:
ret = _gnix_ep_msg_open(domain_priv, ep_priv->info, ep_priv);
if (ret != FI_SUCCESS) {
GNIX_INFO(FI_LOG_EP_CTRL,
"_gnix_ep_msg_open() failed, err: %d\n",
ret);
goto err_type_init;
}
break;
default:
ret = -FI_EINVAL;
goto err_type_init;
}
_gnix_ref_get(ep_priv->domain);
*ep = &ep_priv->ep_fid;
return ret;
err_type_init:
if (ep_priv->nic)
_gnix_nic_free(ep_priv->nic);
_gnix_cm_nic_free(ep_priv->cm_nic);
err_nic_init:
if (ep_priv->xpmem_hndl) {
err_ret = _gnix_xpmem_handle_destroy(ep_priv->xpmem_hndl);
if (err_ret != FI_SUCCESS) {
GNIX_WARN(FI_LOG_EP_CTRL,
"_gnix_xpmem_handle_destroy returned %s\n",
fi_strerror(-err_ret));
}
}
__fr_freelist_destroy(ep_priv);
err_fl_init:
__destruct_tag_storages(ep_priv);
err_tag_init:
free(ep_priv);
return ret;
}