Пример #1
0
static int psmx_cntr_control(fid_t fid, int command, void *arg)
{
	struct psmx_fid_cntr *cntr;
	int ret = 0;

	cntr = container_of(fid, struct psmx_fid_cntr, cntr.fid);

	switch (command) {
	case FI_SETOPSFLAG:
		cntr->flags = *(uint64_t *)arg;
		break;

	case FI_GETOPSFLAG:
		if (!arg)
			return -FI_EINVAL;
		*(uint64_t *)arg = cntr->flags;
		break;

	case FI_GETWAIT:
		if (cntr->wait)
			ret = fi_control(&cntr->wait->wait_fid.fid, FI_GETWAIT, arg);
		else
			return -FI_EINVAL;
		break;

	default:
		return -FI_ENOSYS;
	}

	return ret;
}
Пример #2
0
static int rxd_dg_cq_open(struct rxd_ep *rxd_ep, enum fi_wait_obj wait_obj)
{
	struct rxd_domain *rxd_domain;
	struct fi_cq_attr cq_attr = {0};
	int ret;

	assert((wait_obj == FI_WAIT_NONE) || (wait_obj == FI_WAIT_FD));

	cq_attr.size = rxd_ep->tx_size + rxd_ep->rx_size;
	cq_attr.format = FI_CQ_FORMAT_MSG;
	cq_attr.wait_obj = wait_obj;

	rxd_domain = container_of(rxd_ep->util_ep.domain, struct rxd_domain,
				  util_domain);

	ret = fi_cq_open(rxd_domain->dg_domain, &cq_attr, &rxd_ep->dg_cq, rxd_ep);
	if (ret)
		return ret;

	if (wait_obj == FI_WAIT_FD && (!rxd_ep->dg_cq_fd)) {
		ret = fi_control(&rxd_ep->dg_cq->fid, FI_GETWAIT,
				 &rxd_ep->dg_cq_fd);
		if (ret) {
			FI_WARN(&rxd_prov, FI_LOG_EP_CTRL,
				"Unable to get dg CQ fd\n");
			goto err;
		}
	}

	return 0;
err:
	fi_close(&rxd_ep->dg_cq->fid);
	rxd_ep->dg_cq = NULL;
	return ret;
}
Пример #3
0
int ft_get_cq_fd(struct fid_cq *cq, int *fd)
{
	int ret = FI_SUCCESS;

	if (cq && opts.comp_method == FT_COMP_WAIT_FD) {
		ret = fi_control(&cq->fid, FI_GETWAIT, fd);
		if (ret)
			FT_PRINTERR("fi_control(FI_GETWAIT)", ret);
	}

	return ret;
}
Пример #4
0
static int util_eq_control(struct fid *fid, int command, void *arg)
{
	struct util_eq *eq;
	int ret;

	eq = container_of(fid, struct util_eq, eq_fid.fid);

	switch (command) {
	case FI_GETWAIT:
		ret = fi_control(&eq->wait->wait_fid.fid, command, arg);
		break;
	default:
		ret = -FI_ENOSYS;
		break;
	}

	return ret;
}
Пример #5
0
static int tcpx_cq_control(struct fid *fid, int command, void *arg)
{
	struct util_cq *cq;
	int ret;

	cq = container_of(fid, struct util_cq, cq_fid.fid);

	switch(command) {
	case FI_GETWAIT:
		if (!cq->wait)
			return -FI_ENOSYS;

		ret = fi_control(&cq->wait->wait_fid.fid,
				 command, arg);
		if (ret)
			return ret;

		return FI_SUCCESS;
	default:
		return -FI_ENOSYS;
	}
}
Пример #6
0
static int alloc_ep_res(struct fi_info *fi)
{
	struct fi_cq_attr cq_attr;
	struct epoll_event event;
	int ret, fd;

	buf = malloc(buffer_size);
	if (!buf) {
		perror("malloc");
		return -1;
	}

	memset(&cq_attr, 0, sizeof cq_attr);
	cq_attr.format = FI_CQ_FORMAT_CONTEXT;
	cq_attr.wait_obj = FI_WAIT_FD;
	cq_attr.size = rx_depth;

	/* Open completion queue for send completions */
	ret = fi_cq_open(dom, &cq_attr, &scq, NULL);
	if (ret) {
		FT_PRINTERR("fi_cq_open", ret);
		goto err1;
	}

	/* Open completion queue for recv completions */
	ret = fi_cq_open(dom, &cq_attr, &rcq, NULL);
	if (ret) {
		FT_PRINTERR("fi_cq_open", ret);
		goto err2;
	}

	/* Create epoll set */
	epfd = epoll_create1(0);
	if (epfd < 0) {
		ret = -errno;
		FT_PRINTERR("epoll_create1", ret);
		goto err3;
	}

	/* Retrieve receive queue wait object */
	ret = fi_control (&rcq->fid, FI_GETWAIT, (void *) &fd);
	if (ret) {
		FT_PRINTERR("fi_control(FI_GETWAIT)", ret);
		goto err4;
	}

	/* Add receive queue wait object to epoll set */
	memset((void *)&event, 0, sizeof event);
	event.events = EPOLLIN;
	event.data.ptr = (void *)&rcq->fid;
	ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
	if (ret) {
		ret = -errno;
		FT_PRINTERR("epoll_ctl", ret);
		goto err4;
	}

	/* Retrieve send queue wait object */
	ret = fi_control (&scq->fid, FI_GETWAIT, (void *) &fd);
	if (ret) {
		FT_PRINTERR("fi_control(FI_GETWAIT)", ret);
		goto err4;
	}

	/* Add send queue wait object to epoll set */
	memset((void *)&event, 0, sizeof event);
	event.events = EPOLLIN;
	event.data.ptr = (void *)&scq->fid;
	ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
	if (ret) {
		ret = -errno;
		FT_PRINTERR("epoll_ctl", ret);
		goto err4;
	}

	/* Register memory */
	ret = fi_mr_reg(dom, buf, buffer_size, 0, 0, 0, 0, &mr, NULL);
	if (ret) {
		FT_PRINTERR("fi_mr_reg", ret);
		goto err4;
	}

	ret = fi_endpoint(dom, fi, &ep, NULL);
	if (ret) {
		FT_PRINTERR("fi_endpoint", ret);
		goto err5;
	}

	return 0;

err5:
	fi_close(&mr->fid);
err4:
	close(epfd);
err3:
	fi_close(&rcq->fid);
err2:
	fi_close(&scq->fid);
err1:
	free(buf);
	return ret;
}
Пример #7
0
static void setup_ofi_active(struct fi_info *info,
                             struct fid_ep **ep)
{
    // Make an EQ
    int ret;
    ret = fi_endpoint(fidev.domain, info, ep, NULL);
    if (0 != ret) {
        error("fi_endpoint failed");
    }

#if WANT_FDS
    // Add the EQ FD to the epoll fd
    static struct epoll_event edt;
    memset(&edt, 0, sizeof(edt));
    edt.events = EPOLLIN;
    edt.data.u32 = 2222;
    ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fidev.eq_fd, &edt);
    if (ret < 0) {
        error("epoll_ctl failed");
    }
#endif

    // Bind the EP to the EQ
    ret = fi_ep_bind(*ep, &fidev.eq->fid, 0);
    if (0 != ret) {
        error("fi_ep_bind(eq) failed");
    }

    // Make a CQ
    struct fi_cq_attr cq_attr;
    memset(&cq_attr, 0, sizeof(cq_attr));
    cq_attr.format = FI_CQ_FORMAT_CONTEXT;
    cq_attr.wait_obj = FI_WAIT_FD;
    cq_attr.size = 32; // JMS POC
    ret = fi_cq_open(fidev.domain, &cq_attr, &ficonn.cq, NULL);
    if (ret != 0) {
        error("fi_cq_open failed");
    }

    // Bind the CQ TX and RX queues to the EQ
    ret = fi_ep_bind(*ep, &ficonn.cq->fid, FI_TRANSMIT);
    if (0 != ret) {
        error("fi_ep_bind(cq tx) failed");
    }
    ret = fi_ep_bind(*ep, &ficonn.cq->fid, FI_RECV);
    if (0 != ret) {
        error("fi_ep_bind(cq rx) failed");
    }

#if WANT_FDS
    // Get the fd associated with this CQ
    ret = fi_control(&(ficonn.cq->fid), FI_GETWAIT, &ficonn.cq_fd);
    if (ret != 0) {
        error("fi_control to get cq fq failed");
    }
#endif

    // Enable the EP!
    ret = fi_enable(*ep);
    if (0 != ret) {
        error("fi_enable failed");
    }

    // Register the buffers (must use different keys for each)
    ret = fi_mr_reg(fidev.domain, send_buffer, sizeof(send_buffer),
                    FI_SEND, 0, (uintptr_t) send_buffer,
                    0, &ficonn.send_mr, NULL);
    if (ret != 0) {
        error("fi_mr_reg(send) failed\n");
    }
    ret = fi_mr_reg(fidev.domain, recv_buffer, sizeof(recv_buffer),
                    FI_RECV, 0, (uintptr_t) recv_buffer,
                    0, &ficonn.recv_mr, NULL);
    if (ret != 0) {
        printf("ERROR: ret=%d, %s\n", ret, fi_strerror(-ret));
        error("fi_mr_reg(recv) failed\n");
    }

}
Пример #8
0
static void setup_ofi(const char *node, const char *service,
                      uint64_t flags)
{
    struct fi_fabric_attr fabric_attr;
    memset(&fabric_attr, 0, sizeof(fabric_attr));
    fabric_attr.prov_name = (char*) "sockets";
    //fabric_attr.prov_name = (char*) "usnic";
    struct fi_ep_attr ep_attr;
    memset(&ep_attr, 0, sizeof(ep_attr));
    ep_attr.type = FI_EP_MSG;

    struct fi_info hints;
    memset(&hints, 0, sizeof(hints));
    hints.caps = FI_MSG;
    hints.mode = FI_LOCAL_MR;
    hints.addr_format = FI_SOCKADDR_IN;
    hints.ep_attr = &ep_attr;
    hints.fabric_attr = &fabric_attr;

    /* Get a minimum of libfabric v1.3.0.  There were bugs in prior
       versions; might as well start with the current libfabric
       version. */
    uint32_t libfabric_api;
    libfabric_api = FI_VERSION(1, 3);
    int ret;
    ret = fi_getinfo(libfabric_api, node, service, flags,
                     &hints, &fidev.info);
    if (0 != ret) {
        error("cannot fi_getinfo");
    }

    int num_devs = 0;
    for (struct fi_info *info = fidev.info;
         NULL != info; info = info->next) {
        ++num_devs;
    }
    if (0 == num_devs) {
        error("no fi devices available");
    }

    printf("INFO: %s\n", fi_tostr(fidev.info, FI_TYPE_INFO));

    // Just use the first info returned
    ret = fi_fabric(fidev.info->fabric_attr, &fidev.fabric, NULL);
    if (0 != ret) {
        error("fi_fabric failed");
    }

    // Make an EQ
    struct fi_eq_attr eq_attr;
    memset(&eq_attr, 0, sizeof(eq_attr));
#if WANT_FDS
    eq_attr.wait_obj = FI_WAIT_FD;
#else
    eq_attr.wait_obj = FI_WAIT_UNSPEC;
#endif
    ret = fi_eq_open(fidev.fabric, &eq_attr, &fidev.eq, NULL);
    if (0 != ret) {
        error("fi_eq failed");
    }

#if WANT_FDS
    // Get the fd associated with this EQ
    ret = fi_control(&(fidev.eq->fid), FI_GETWAIT, &fidev.eq_fd);
    if (ret < 0) {
        error("fi_control to get eq fq failed");
    }
#endif

    ret = fi_domain(fidev.fabric, fidev.info, &fidev.domain, NULL);
    if (0 != ret) {
        error("fi_domain failed");
    }

#if WANT_FDS
    // Make an epoll fd to listen on
    epoll_fd = epoll_create(4096);
    if (epoll_fd < 0) {
        error("epoll_create failed");
    }
#endif
}
Пример #9
0
int ft_alloc_active_res(struct fi_info *fi)
{
	int ret;

	ret = ft_alloc_msgs();
	if (ret)
		return ret;

	if (cq_attr.format == FI_CQ_FORMAT_UNSPEC) {
		if (fi->caps & FI_TAGGED)
			cq_attr.format = FI_CQ_FORMAT_TAGGED;
		else
			cq_attr.format = FI_CQ_FORMAT_CONTEXT;
	}

	if (opts.options & FT_OPT_TX_CQ) {
		ft_cq_set_wait_attr();
		cq_attr.size = fi->tx_attr->size;
		ret = fi_cq_open(domain, &cq_attr, &txcq, &txcq);
		if (ret) {
			FT_PRINTERR("fi_cq_open", ret);
			return ret;
		}

		if (opts.comp_method == FT_COMP_WAIT_FD) {
			ret = fi_control(&txcq->fid, FI_GETWAIT, (void *) &tx_fd);
			if (ret) {
				FT_PRINTERR("fi_control(FI_GETWAIT)", ret);
				return ret;
			}
		}
	}

	if (opts.options & FT_OPT_TX_CNTR) {
		ft_cntr_set_wait_attr();
		ret = fi_cntr_open(domain, &cntr_attr, &txcntr, &txcntr);
		if (ret) {
			FT_PRINTERR("fi_cntr_open", ret);
			return ret;
		}
	}

	if (opts.options & FT_OPT_RX_CQ) {
		ft_cq_set_wait_attr();
		cq_attr.size = fi->rx_attr->size;
		ret = fi_cq_open(domain, &cq_attr, &rxcq, &rxcq);
		if (ret) {
			FT_PRINTERR("fi_cq_open", ret);
			return ret;
		}

		if (opts.comp_method == FT_COMP_WAIT_FD) {
			ret = fi_control(&rxcq->fid, FI_GETWAIT, (void *) &rx_fd);
			if (ret) {
				FT_PRINTERR("fi_control(FI_GETWAIT)", ret);
				return ret;
			}
		}
	}

	if (opts.options & FT_OPT_RX_CNTR) {
		ft_cntr_set_wait_attr();
		ret = fi_cntr_open(domain, &cntr_attr, &rxcntr, &rxcntr);
		if (ret) {
			FT_PRINTERR("fi_cntr_open", ret);
			return ret;
		}
	}

	if (fi->ep_attr->type == FI_EP_RDM || fi->ep_attr->type == FI_EP_DGRAM) {
		if (fi->domain_attr->av_type != FI_AV_UNSPEC)
			av_attr.type = fi->domain_attr->av_type;

		if (opts.av_name) {
			av_attr.name = opts.av_name;
		}
		ret = fi_av_open(domain, &av_attr, &av, NULL);
		if (ret) {
			FT_PRINTERR("fi_av_open", ret);
			return ret;
		}
	}

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

	return 0;
}
Пример #10
0
/*
 * Tests:
 * - extracting FD from EQ with FI_WAIT_FD
 * - wait on fd with nothing pending
 * - wait on fd with event pending
 */
static int
eq_wait_fd_poll()
{
	int fd;
	struct fi_eq_entry entry;
	struct pollfd pfd;
	struct fid *fids[1];
	int testret;
	int ret;

	testret = FAIL;

	ret = create_eq(32, FI_WRITE, FI_WAIT_FD);
	if (ret != 0) {
		sprintf(err_buf, "fi_eq_open ret=%d, %s", ret, fi_strerror(-ret));
		goto fail;
	}

	ret = fi_control(&eq->fid, FI_GETWAIT, &fd);
	if (ret != 0) {
		sprintf(err_buf, "fi_control ret=%d, %s", ret, fi_strerror(-ret));
		goto fail;
	}

	fids[0] = &eq->fid;
	if (fi_trywait(fabric, fids, 1) != FI_SUCCESS) {
		sprintf(err_buf, "fi_trywait ret=%d, %s", ret, fi_strerror(-ret));
		goto fail;
	}

	pfd.fd = fd;
	pfd.events = POLLIN;
	ret = poll(&pfd, 1, 0);
	if (ret < 0) {
		sprintf(err_buf, "poll errno=%d, %s", errno, fi_strerror(-errno));
		goto fail;
	}
	if (ret > 0) {
		sprintf(err_buf, "poll returned %d, should be 0", ret);
		goto fail;
	}

	/* write an event */
	entry.fid = &eq->fid;
	entry.context = eq;
	ret = fi_eq_write(eq, FI_NOTIFY, &entry, sizeof(entry), 0);
	if (ret != sizeof(entry)) {
		sprintf(err_buf, "fi_eq_write ret=%d, %s", ret, fi_strerror(-ret));
		goto fail;
	}

	pfd.fd = fd;
	pfd.events = POLLIN;
	ret = poll(&pfd, 1, 0);
	if (ret < 0) {
		sprintf(err_buf, "poll errno=%d, %s", errno, fi_strerror(-errno));
		goto fail;
	}
	if (ret != 1) {
		sprintf(err_buf, "poll returned %d, should be 1", ret);
		goto fail;
	}

	testret = PASS;
fail:
	FT_CLOSE_FID(eq);
	return TEST_RET_VAL(ret, testret);
}