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; }
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; }
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; }
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; }
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; } }
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; }
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"); } }
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 }
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; }
/* * 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); }