示例#1
0
static int client_setup(void)
{
	size_t opt_size;
	int ret;

	/* Get fabric info */
	ret = fi_getinfo(FT_FIVERSION, opts.dst_addr, opts.dst_port, 0, hints,
			&fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		return ret;
	}

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep();
	if (ret)
		return ret;

	/* Get the maximum cm_size for this domain + endpoint combination */
	opt_size = sizeof(opt_size);
	return fi_getopt(&ep->fid, FI_OPT_ENDPOINT, FI_OPT_CM_DATA_SIZE,
		&cm_data_size, &opt_size);
}
示例#2
0
int ft_server_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	ssize_t rd;
	int ret;

	rd = fi_eq_sread(eq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PROCESS_EQ_ERR(rd, eq, "fi_eq_sread", "listen");
		return (int) rd;
	}

	fi = entry.info;
	if (event != FI_CONNREQ) {
		fprintf(stderr, "Unexpected CM event %d\n", event);
		ret = -FI_EOTHER;
		goto err;
	}

	ret = fi_domain(fabric, fi, &domain, NULL);
	if (ret) {
		FT_PRINTERR("fi_domain", ret);
		goto err;
	}

	ret = ft_alloc_active_res(fi);
	if (ret)
		goto err;

	ret = ft_init_ep();
	if (ret)
		goto err;

	ret = fi_accept(ep, NULL, 0);
	if (ret) {
		FT_PRINTERR("fi_accept", ret);
		goto err;
	}

	rd = fi_eq_sread(eq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PROCESS_EQ_ERR(rd, eq, "fi_eq_sread", "accept");
		ret = (int) rd;
		goto err;
	}

	if (event != FI_CONNECTED || entry.fid != &ep->fid) {
		fprintf(stderr, "Unexpected CM event %d fid %p (ep %p)\n",
			event, entry.fid, ep);
		ret = -FI_EOTHER;
		goto err;
	}

	return 0;

err:
	fi_reject(pep, fi->handle, NULL, 0);
	return ret;
}
示例#3
0
int ft_init_fabric(void)
{
	int ret;

	ret = ft_getinfo(hints, &fi);
	if (ret)
		return ret;

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	if (hints->caps & FI_RMA) {
		ret = ft_set_rma_caps(fi, opts.rma_op);
		if (ret)
			return ret;
	}

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep();
	if (ret)
		return ret;

	ret = ft_init_av();
	if (ret)
		return ret;

	return 0;
}
示例#4
0
static int alloc_ep_res(struct fi_info *fi)
{
	struct fi_poll_attr poll_attr;
	int ret;

	ret = ft_alloc_bufs();
	if (ret)
		return ret;

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	memset(&poll_attr, 0, sizeof poll_attr);
	ret = fi_poll_open(domain, &poll_attr, &pollset);
	if (ret) {
		FT_PRINTERR("fi_poll_open", ret);
		return ret;
	}

	ret = fi_poll_add(pollset, &txcq->fid, 0);
	if (ret) {
		FT_PRINTERR("fi_poll_add", ret);
		return ret;
	}

	ret = fi_poll_add(pollset, &rxcq->fid, 0);
	if (ret) {
		FT_PRINTERR("fi_poll_add", ret);
		return ret;
	}

	return 0;
}
示例#5
0
static int alloc_ep_res(struct fi_info *fi)
{
	uint64_t access_mode;
	int ret;

	ret = ft_alloc_bufs();
	if (ret)
		return ret;

	switch (op_type) {
	case FT_RMA_READ:
		access_mode = FI_REMOTE_READ;
		break;
	case FT_RMA_WRITE:
	case FT_RMA_WRITEDATA:
		access_mode = FI_REMOTE_WRITE;
		break;
	default:
		/* Impossible to reach here */
		FT_PRINTERR("invalid op_type", ret);
		exit(1);
	}
	ret = fi_mr_reg(domain, buf, buf_size,
			access_mode, 0, 0, 0, &mr, NULL);
	if (ret) {
		FT_PRINTERR("fi_mr_reg", ret);
		return ret;
	}

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	return 0;
}
示例#6
0
static int init_fabric(void)
{
	uint64_t flags = 0;
	char *node, *service;
	int ret;

	ret = ft_read_addr_opts(&node, &service, hints, &flags, &opts);
	if (ret)
		return ret;

	ret = fi_getinfo(FT_FIVERSION, node, service, flags, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		return ret;
	}

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep();
	if (ret)
		return ret;

	return 0;
}
示例#7
0
static int alloc_ep_res(struct fid_ep *sep)
{
	int i, ret;

	/* Get number of bits needed to represent ctx_cnt */
	while (ctx_cnt >> ++rx_ctx_bits)
		;

	av_attr.rx_ctx_bits = rx_ctx_bits;

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;
	/* Closes non-scalable endpoint that was allocated in the common code */
	FT_CLOSE_FID(ep);

	txcq_array = calloc(ctx_cnt, sizeof *txcq_array);
	rxcq_array = calloc(ctx_cnt, sizeof *rxcq_array);
	tx_ep = calloc(ctx_cnt, sizeof *tx_ep);
	rx_ep = calloc(ctx_cnt, sizeof *rx_ep);
	remote_rx_addr = calloc(ctx_cnt, sizeof *remote_rx_addr);

	if (!buf || !txcq_array || !rxcq_array || !tx_ep || !rx_ep || !remote_rx_addr) {
		perror("malloc");
		return -1;
	}

	for (i = 0; i < ctx_cnt; i++) {
		ret = fi_tx_context(sep, i, NULL, &tx_ep[i], NULL);
		if (ret) {
			FT_PRINTERR("fi_tx_context", ret);
			return ret;
		}

		ret = fi_cq_open(domain, &cq_attr, &txcq_array[i], NULL);
		if (ret) {
			FT_PRINTERR("fi_cq_open", ret);
			return ret;
		}

		ret = fi_rx_context(sep, i, NULL, &rx_ep[i], NULL);
		if (ret) {
			FT_PRINTERR("fi_tx_context", ret);
			return ret;
		}

		ret = fi_cq_open(domain, &cq_attr, &rxcq_array[i], NULL);
		if (ret) {
			FT_PRINTERR("fi_cq_open", ret);
			return ret;
		}
	}

	return 0;
}
static int alloc_ep_res(struct fi_info *fi)
{
	struct fi_rx_attr rx_attr;
	struct fi_tx_attr tx_attr;
	int i, ret = 0;

	ret = ft_alloc_bufs();
	if (ret)
		return ret;

	remote_fi_addr = malloc(sizeof(*remote_fi_addr) * ep_cnt);
	if (!remote_fi_addr) {
		perror("malloc");
		return -FI_ENOMEM;
	}

	av_attr.count = ep_cnt;

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	/* TODO: avoid allocating EP when EP array is used. */
	FT_CLOSE_FID(ep);

	memset(&tx_attr, 0, sizeof tx_attr);
	memset(&rx_attr, 0, sizeof rx_attr);

	ret = fi_stx_context(domain, &tx_attr, &stx_ctx, NULL);
	if (ret) {
		FT_PRINTERR("fi_stx_context", ret);
		return ret;
	}

	ret = fi_srx_context(domain, &rx_attr, &srx_ctx, NULL);
	if (ret) {
		FT_PRINTERR("fi_srx_context", ret);
		return ret;
	}

	ep_array = calloc(ep_cnt, sizeof(*ep_array));
	if (!ep_array) {
		perror("malloc");
		return ret;
	}
	for (i = 0; i < ep_cnt; i++) {
		ret = fi_endpoint(domain, fi, &ep_array[i], NULL);
		if (ret) {
			FT_PRINTERR("fi_endpoint", ret);
			return ret;
		}
	}

	return 0;
}
示例#9
0
static int alloc_ep_res(struct fi_info *fi)
{
	int ret;

	ret = ft_alloc_bufs();
	if (ret)
		return ret;

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	return 0;
}
示例#10
0
static int alloc_ep_res(struct fi_info *fi)
{
	int ret;

	tx_size = MAX(FT_MAX_CTRL_MSG, opts.transfer_size);
	if (tx_size > fi->ep_attr->max_msg_size) {
		fprintf(stderr, "transfer size is larger than the maximum size "
				"of the data transfer supported by the provider\n");
		return -1;
	}

	tx_buf = malloc(tx_size);
	if (!tx_buf) {
		fprintf(stderr, "Cannot allocate tx_buf\n");
		return -1;
	}

	ret = fi_mr_reg(domain, tx_buf, tx_size, FI_SEND,
			0, FT_MR_KEY, 0, &mr, NULL);
	if (ret) {
		FT_PRINTERR("fi_mr_reg", ret);
		return ret;
	}

	// set the multi buffer size to be allocated
	rx_size = MAX(tx_size, DEFAULT_MULTI_BUF_SIZE) * MULTI_BUF_SIZE_FACTOR;
	rx_buf = malloc(rx_size);
	if (!rx_buf) {
		fprintf(stderr, "Cannot allocate rx_buf\n");
		return -1;
	}

	ret = fi_mr_reg(domain, rx_buf, rx_size, FI_RECV, 0, FT_MR_KEY + 1, 0,
			&mr_multi_recv, NULL);
	if (ret) {
		FT_PRINTERR("fi_mr_reg", ret);
		return ret;
	}

	/* Prevent memory registration by ft_alloc_active_res() -> ft_alloc_msgs() */
	ft_skip_mr = 1;

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	return 0;
}
示例#11
0
static int client_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	ssize_t rd;
	int ret;

	ret = fi_getinfo(FT_FIVERSION, opts.dst_addr, opts.dst_port, 0, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		return ret;
	}

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep();
	if (ret)
		return ret;

	ret = fi_connect(ep, fi->dest_addr, NULL, 0);
	if (ret) {
		FT_PRINTERR("fi_connect", ret);
		return ret;
	}

	rd = fi_eq_sread(eq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PROCESS_EQ_ERR(rd, eq, "fi_eq_sread", "connect");
		ret = (int) rd;
		return ret;
	}

	if (event != FI_CONNECTED || entry.fid != &ep->fid) {
		fprintf(stderr, "Unexpected CM event %d fid %p (ep %p)\n",
			event, entry.fid, ep);
		ret = -FI_EOTHER;
		return ret;
	}

	return 0;
}
示例#12
0
static int alloc_ep_res(struct fi_info *fi)
{
	int ret;

	ret = ft_alloc_bufs();
	if (ret)
		return ret;

	cq_attr.format = FI_CQ_FORMAT_DATA;
	cq_attr.wait_obj = FI_WAIT_UNSPEC;

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	return 0;
}
示例#13
0
static int alloc_ep_res(struct fi_info *fi)
{
	struct fi_wait_attr wait_attr;
	int ret;

	memset(&wait_attr, 0, sizeof wait_attr);
	wait_attr.wait_obj = FI_WAIT_UNSPEC;
	ret = fi_wait_open(fabric, &wait_attr, &waitset);
	if (ret) {
		FT_PRINTERR("fi_wait_open", ret);
		return ret;
	}

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	return 0;
}
static int alloc_ep_res(struct fi_info *fi)
{
	int ret;

	ret = ft_alloc_bufs();
	if (ret)
		return ret;

	/* TODO:
	 * Memory registration not required for send_buf since we use fi_inject.
	 * fi_inject copies the buffer of data that needs to be sent.
	 * Fix-up when separating send/receive buffer registration.
	 */

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	return 0;
}
示例#15
0
static int client_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	ssize_t rd;
	int ret;

	ret = fi_getinfo(FT_FIVERSION, opts.dst_addr, opts.dst_port, 0, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		return ret;
	}

	ret = fi_domain(fabric, fi, &domain, NULL);
	if (ret) {
		FT_PRINTERR("fi_domain", ret);
		return ret;
	}

	ret = check_address(&pep->fid, "fi_endpoint (pep)");
	if (ret)
		return ret;

	assert(fi->handle == &pep->fid);
	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	/* Close the passive endpoint that we "stole" the source address
	 * from */
	FT_CLOSE_FID(pep);

	ret = check_address(&ep->fid, "fi_endpoint (ep)");
	if (ret)
		return ret;

	ret = ft_init_ep();
	if (ret)
		return ret;

	/* Connect to server */
	ret = fi_connect(ep, fi->dest_addr, NULL, 0);
	if (ret) {
		FT_PRINTERR("fi_connect", ret);
		return ret;
	}

	/* Wait for the connection to be established */
	rd = fi_eq_sread(eq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PRINTERR("fi_eq_sread", rd);
		return (int) rd;
	}

	if (event != FI_CONNECTED || entry.fid != &ep->fid) {
		FT_ERR("Unexpected CM event %d fid %p (ep %p)\n", event, entry.fid, ep);
		return -FI_EOTHER;
	}

	ret = check_address(&ep->fid, "connect");
	if (ret) {
		return ret;
	}

	return 0;
}
示例#16
0
static int server_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	struct fi_info *info = NULL;
	ssize_t rd;
	int ret;

	/* Wait for connection request from client */
	rd = fi_eq_sread(eq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PRINTERR("fi_eq_sread", rd);
		return (int) rd;
	}

	info = entry.info;
	if (event != FI_CONNREQ) {
		FT_ERR("Unexpected CM event %d\n", event);
		ret = -FI_EOTHER;
		goto err;
	}

	ret = fi_domain(fabric, info, &domain, NULL);
	if (ret) {
		FT_PRINTERR("fi_domain", ret);
		goto err;
	}

	ret = ft_alloc_active_res(info);
	if (ret)
		 goto err;

	ret = ft_init_ep();
	if (ret)
		goto err;

	/* Accept the incoming connection. Also transitions endpoint to active state */
	ret = fi_accept(ep, NULL, 0);
	if (ret) {
		FT_PRINTERR("fi_accept", ret);
		goto err;
	}

	/* Wait for the connection to be established */
	rd = fi_eq_sread(eq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PRINTERR("fi_eq_sread", rd);
		goto err;
	}

	if (event != FI_CONNECTED || entry.fid != &ep->fid) {
		FT_ERR("Unexpected CM event %d fid %p (ep %p)\n", event, entry.fid, ep);
		ret = -FI_EOTHER;
		goto err;
	}

	ret = check_address(&ep->fid, "accept");
	if (ret) {
		goto err;
	}

	fi_freeinfo(info);
	return 0;

err:
	fi_reject(pep, info->handle, NULL, 0);
	fi_freeinfo(info);
	return ret;
}
示例#17
0
static int server_accept(size_t paramlen)
{
	uint32_t event;
	int ret;

	ret = server_listen(paramlen);
	if (ret)
		return ret;

	ret = fi_domain(fabric, fi, &domain, NULL);
	if (ret) {
		FT_PRINTERR("fi_domain", ret);
		goto err;
	}

	ret = ft_alloc_active_res(fi);
	if (ret) {
		FT_PRINTERR("alloc_active_res", ret);
		goto err;
	}

	ret = ft_init_ep();
	if (ret) {
		FT_PRINTERR("init_ep", ret);
		goto err;
	}
	/* Data will apppear on accept event on remote end. */
	ft_fill_buf(cm_data, paramlen);

	/* Accept the incoming connection. Also transitions endpoint to active
	 * state.
	 */
	ret = fi_accept(ep, cm_data, paramlen);
	if (ret) {
		FT_PRINTERR("fi_accept", ret);
		goto err;
	}

	/* Local FI_CONNECTED event does not have data associated. */
	memset(entry, 0, sizeof(*entry));
	ret = fi_eq_sread(eq, &event, entry, sizeof(*entry), -1, 0);
	if (ret != sizeof(*entry)) {
		FT_PROCESS_EQ_ERR(ret, eq, "fi_eq_sread", "accept");
		goto err;
	}

	if (event != FI_CONNECTED || entry->fid != &ep->fid) {
		FT_ERR("Unexpected CM event %d fid %p (ep %p)", event,
				entry->fid, ep);
		ret = -FI_EOTHER;
		goto err;
	}

	fi_shutdown(ep, 0);
	ret = read_shutdown_event();
	if (ret)
		goto err;

	FT_CLOSE_FID(ep);
	FT_CLOSE_FID(rxcq);
	FT_CLOSE_FID(txcq);
	FT_CLOSE_FID(rxcntr);
	FT_CLOSE_FID(txcntr);
	FT_CLOSE_FID(av);
	FT_CLOSE_FID(domain);

	return 0;

err:
	fi_reject(pep, fi->handle, NULL, 0);
	return ret;
}