DIRECT_FN int gnix_ep_open()

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