예제 #1
0
static void server_recv_connreq(struct util_wait *wait,
				struct tcpx_cm_context *cm_ctx)
{
	struct tcpx_conn_handle *handle;
	struct fi_eq_cm_entry *cm_entry;
	struct ofi_ctrl_hdr conn_req;
	int ret;

	assert(cm_ctx->fid->fclass == FI_CLASS_CONNREQ);

	handle  = container_of(cm_ctx->fid,
			       struct tcpx_conn_handle,
			       handle);

	ret = rx_cm_data(handle->conn_fd, &conn_req, ofi_ctrl_connreq, cm_ctx);
	if (ret)
		goto err1;

	cm_entry = calloc(1, sizeof(*cm_entry) + cm_ctx->cm_data_sz);
	if (!cm_entry)
		goto err1;

	cm_entry->fid = &handle->pep->util_pep.pep_fid.fid;
	cm_entry->info = fi_dupinfo(&handle->pep->info);
	if (!cm_entry->info)
		goto err2;

	cm_entry->info->handle = &handle->handle;
	memcpy(cm_entry->data, cm_ctx->cm_data, cm_ctx->cm_data_sz);

	ret = (int) fi_eq_write(&handle->pep->util_pep.eq->eq_fid, FI_CONNREQ, cm_entry,
				sizeof(*cm_entry) + cm_ctx->cm_data_sz, 0);
	if (ret < 0) {
		FI_WARN(&tcpx_prov, FI_LOG_EP_CTRL, "Error writing to EQ\n");
		goto err3;
	}
	ret = ofi_wait_fd_del(wait, handle->conn_fd);
	if (ret)
		FI_WARN(&tcpx_prov, FI_LOG_EP_CTRL,
			"fd deletion from ofi_wait failed\n");
	free(cm_entry);
	free(cm_ctx);
	return;
err3:
	fi_freeinfo(cm_entry->info);
err2:
	free(cm_entry);
err1:
	ofi_wait_fd_del(wait, handle->conn_fd);
	ofi_close_socket(handle->conn_fd);
	free(cm_ctx);
	free(handle);
}
예제 #2
0
static void client_send_connreq(struct util_wait *wait,
				struct tcpx_cm_context *cm_ctx)
{
	struct tcpx_ep *ep;
	struct fi_eq_err_entry err_entry;
	socklen_t len;
	int status, ret = FI_SUCCESS;

	FI_DBG(&tcpx_prov, FI_LOG_EP_CTRL, "client send connreq\n");
	assert(cm_ctx->fid->fclass == FI_CLASS_EP);

	ep = container_of(cm_ctx->fid, struct tcpx_ep, util_ep.ep_fid.fid);

	len = sizeof(status);
	ret = getsockopt(ep->conn_fd, SOL_SOCKET, SO_ERROR, (char *) &status, &len);
	if (ret < 0 || status) {
		FI_WARN(&tcpx_prov, FI_LOG_EP_CTRL, "connection failure\n");
		ret = (ret < 0)? -ofi_sockerr() : status;
		goto err;
	}

	ret = tx_cm_data(ep->conn_fd, ofi_ctrl_connreq, cm_ctx);
	if (ret)
		goto err;

	ret = ofi_wait_fd_del(wait, ep->conn_fd);
	if (ret)
		goto err;

	cm_ctx->type = CLIENT_RECV_CONNRESP;
	ret = ofi_wait_fd_add(wait, ep->conn_fd, FI_EPOLL_IN,
			      tcpx_eq_wait_try_func, NULL, cm_ctx);
	if (ret)
		goto err;

	wait->signal(wait);
	return;
err:
	memset(&err_entry, 0, sizeof err_entry);
	err_entry.fid = cm_ctx->fid;
	err_entry.context = cm_ctx->fid->context;
	err_entry.err = -ret;

	free(cm_ctx);
	fi_eq_write(&ep->util_ep.eq->eq_fid, FI_NOTIFY,
		    &err_entry, sizeof(err_entry), UTIL_FLAG_ERROR);
}
예제 #3
0
static void server_send_cm_accept(struct util_wait *wait,
				  struct tcpx_cm_context *cm_ctx)
{
	struct fi_eq_cm_entry cm_entry = {0};
	struct fi_eq_err_entry err_entry;
	struct tcpx_ep *ep;
	int ret;

	assert(cm_ctx->fid->fclass == FI_CLASS_EP);
	ep = container_of(cm_ctx->fid, struct tcpx_ep, util_ep.ep_fid.fid);

	ret = tx_cm_data(ep->conn_fd, ofi_ctrl_connresp, cm_ctx);
	if (ret)
		goto err;

	cm_entry.fid =  cm_ctx->fid;
	ret = (int) fi_eq_write(&ep->util_ep.eq->eq_fid, FI_CONNECTED,
				&cm_entry, sizeof(cm_entry), 0);
	if (ret < 0) {
		FI_WARN(&tcpx_prov, FI_LOG_EP_CTRL, "Error writing to EQ\n");
	}

	ret = ofi_wait_fd_del(wait, ep->conn_fd);
	if (ret) {
		FI_WARN(&tcpx_prov, FI_LOG_EP_CTRL,
			"Could not remove fd from wait\n");
		goto err;
	}

	ret = tcpx_ep_msg_xfer_enable(ep);
	if (ret)
		goto err;

	FI_DBG(&tcpx_prov, FI_LOG_EP_CTRL, "Connection Accept Successful\n");
	free(cm_ctx);
	return;
err:
	memset(&err_entry, 0, sizeof err_entry);
	err_entry.fid = cm_ctx->fid;
	err_entry.context = cm_ctx->fid->context;
	err_entry.err = -ret;

	free(cm_ctx);
	fi_eq_write(&ep->util_ep.eq->eq_fid, FI_NOTIFY,
		    &err_entry, sizeof(err_entry), UTIL_FLAG_ERROR);
}
예제 #4
0
static void client_recv_connresp(struct util_wait *wait,
				 struct tcpx_cm_context *cm_ctx)
{
	struct fi_eq_err_entry err_entry = { 0 };
	struct tcpx_ep *ep;
	ssize_t ret;

	assert(cm_ctx->fid->fclass == FI_CLASS_EP);
	ep = container_of(cm_ctx->fid, struct tcpx_ep, util_ep.ep_fid.fid);

	ret = ofi_wait_fd_del(wait, ep->conn_fd);
	if (ret) {
		FI_WARN(&tcpx_prov, FI_LOG_EP_CTRL,
			"Could not remove fd from wait\n");
		goto err;
	}

	ret = proc_conn_resp(cm_ctx, ep);
	if (ret)
		goto err;

	FI_DBG(&tcpx_prov, FI_LOG_EP_CTRL, "Received Accept from server\n");
	free(cm_ctx);
	return;
err:
	err_entry.fid = cm_ctx->fid;
	err_entry.context = cm_ctx->fid->context;
	err_entry.err = -ret;
	if (cm_ctx->cm_data_sz) {
		err_entry.err_data = calloc(1, cm_ctx->cm_data_sz);
		if (OFI_LIKELY(err_entry.err_data != NULL)) {
			memcpy(err_entry.err_data, cm_ctx->cm_data,
			       cm_ctx->cm_data_sz);
			err_entry.err_data_size = cm_ctx->cm_data_sz;
		}
	}
	FI_DBG(&tcpx_prov, FI_LOG_EP_CTRL,
	       "fi_eq_write the conn refused %"PRId64"\n", ret);
	free(cm_ctx);
	/* `err_entry.err_data` must live until it is passed to user */
	ret = fi_eq_write(&ep->util_ep.eq->eq_fid, FI_NOTIFY,
			  &err_entry, sizeof(err_entry), UTIL_FLAG_ERROR);
	if (OFI_UNLIKELY(ret < 0)) {
		free(err_entry.err_data);
	}
}
예제 #5
0
파일: tcpx_ep.c 프로젝트: ofiwg/libfabric
static int tcpx_ep_close(struct fid *fid)
{
	struct tcpx_ep *ep = container_of(fid, struct tcpx_ep,
					  util_ep.ep_fid.fid);

	tcpx_ep_tx_rx_queues_release(ep);
	tcpx_cq_wait_ep_del(ep);
	if (ep->util_ep.eq->wait)
		ofi_wait_fd_del(ep->util_ep.eq->wait, ep->conn_fd);

	ofi_eq_remove_fid_events(ep->util_ep.eq,
				  &ep->util_ep.ep_fid.fid);
	ofi_close_socket(ep->conn_fd);
	ofi_endpoint_close(&ep->util_ep);
	fastlock_destroy(&ep->lock);

	free(ep);
	return 0;
}