int main(int argc, char **argv) { struct sockaddr_in addr; struct rdma_cm_event *event = NULL; struct rdma_cm_id *listener = NULL; struct rdma_event_channel *ec = NULL; uint16_t port = 0; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; TEST_Z(ec = rdma_create_event_channel()); TEST_NZ(rdma_create_id(ec, &listener, NULL, RDMA_PS_TCP)); TEST_NZ(rdma_bind_addr(listener, (struct sockaddr *)&addr)); TEST_NZ(rdma_listen(listener, 10)); /* backlog=10 is arbitrary */ port = ntohs(rdma_get_src_port(listener)); printf("listening on port %d.\n", port); while (rdma_get_cm_event(ec, &event) == 0) { struct rdma_cm_event event_copy; memcpy(&event_copy, event, sizeof(*event)); rdma_ack_cm_event(event); if (on_event(&event_copy)) break; } rdma_destroy_id(listener); rdma_destroy_event_channel(ec); return 0; }
int ibrdma_transfer(struct transfer_info *tfi, int num_tfi) { struct addrinfo *addr; struct rdma_cm_id *cmid= NULL; struct rdma_event_channel *ec = NULL; struct rdma_conn_param cm_params; TEST_NZ(getaddrinfo(host, port, NULL, &addr)); TEST_Z(ec = rdma_create_event_channel()); TEST_NZ(rdma_create_id(ec, &cmid, NULL, RDMA_PS_TCP)); TEST_NZ(rdma_resolve_addr(cmid, NULL, addr->ai_addr, TIMEOUT_IN_MS)); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ADDR_RESOLVED)); freeaddrinfo(addr); build_connection(cmid); TEST_NZ(rdma_resolve_route(cmid, TIMEOUT_IN_MS)); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ROUTE_RESOLVED)); build_params(&cm_params); TEST_NZ(rdma_connect(cmid, &cm_params)); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ESTABLISHED)); on_connect(cmid->context); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_DISCONNECTED)); rdma_destroy_id(&cmid); rdma_destroy_event_channel(&ec); return 0; }
int xfer_rdma_finalize(struct xfer_data *data) { struct rdma_cm_event *event; int rc; if (data->servername) { rc = rdma_disconnect(data->cm_id); if (rc) { perror("rdma_disconnect"); fprintf(stderr, "%d:%s: rdma disconnect error\n", pid, __func__); return -1; } } rdma_get_cm_event(data->cm_channel, &event); if (event->event != RDMA_CM_EVENT_DISCONNECTED) fprintf(stderr, "%d:%s: unexpected event during disconnect %d\n", pid, __func__, event->event); rdma_ack_cm_event(event); rdma_destroy_id(data->cm_id); rdma_destroy_event_channel(data->cm_channel); return 0; }
void client_disconnect(void){ struct rdma_event_channel *ec = s_ctx->ec; struct rdma_cm_id *id = s_ctx->id; struct rdma_cm_event *event = NULL; struct timeval start, end, dt; gettimeofday(&start, NULL); printf("ready to disconnect\n"); rdma_disconnect(id); printf("send disconnect\n"); gettimeofday(&end, NULL); timersub(&end, &start, &dt); long usec = dt.tv_usec + 1000000 * dt.tv_sec; printf("[rdma_disconnect] takes %ld micro_secs.\n", usec); while(1){ if(rdma_get_cm_event(ec, &event) == 0) { struct rdma_cm_event event_copy; memcpy(&event_copy, event, sizeof(*event)); rdma_ack_cm_event(event); if (event_copy.event == RDMA_CM_EVENT_DISCONNECTED){ on_disconnect(event_copy.id); rdma_destroy_event_channel(ec); break; } } } return; }
static int fi_ibv_eq_close(fid_t fid) { struct fi_ibv_eq *eq; struct fi_ibv_eq_entry *entry; eq = container_of(fid, struct fi_ibv_eq, eq_fid.fid); /* TODO: use util code, if possible, and add ref counting */ if (eq->channel) rdma_destroy_event_channel(eq->channel); close(eq->epfd); while (!dlistfd_empty(&eq->list_head)) { entry = container_of(eq->list_head.list.next, struct fi_ibv_eq_entry, item); dlistfd_remove(eq->list_head.list.next, &eq->list_head); free(entry); } dlistfd_head_free(&eq->list_head); fastlock_destroy(&eq->lock); free(eq); return 0; }
//static int run(int argc, char **argv) int ibrdma_send(char* host, char* port, void* data, uint64_t size) { struct addrinfo *addr; struct rdma_cm_id *cmid= NULL; struct rdma_event_channel *ec = NULL; struct rdma_conn_param cm_params; TEST_NZ(getaddrinfo(host, port, NULL, &addr)); TEST_Z(ec = rdma_create_event_channel()); TEST_NZ(rdma_create_id(ec, &cmid, NULL, RDMA_PS_TCP)); TEST_NZ(rdma_resolve_addr(cmid, NULL, addr->ai_addr, TIMEOUT_IN_MS)); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ADDR_RESOLVED)); freeaddrinfo(addr); build_connection(cmid); TEST_NZ(rdma_resolve_route(cmid, TIMEOUT_IN_MS)); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ROUTE_RESOLVED)); build_params(&cm_params); TEST_NZ(rdma_connect(cmid, &cm_params)); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ESTABLISHED)); on_connect(cmid->context); /* Init MSG send to start RDMA*/ init_tfile(data, size); send_init(cmid->context); /*----------------------------*/ TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_DISCONNECTED)); rdma_destroy_id(cmid); rdma_destroy_event_channel(ec); return 0; }
static int migrate_channel(struct rdma_cm_id *listen_id) { struct rdma_event_channel *channel; int i, ret; printf("migrating to new event channel\n"); channel = rdma_create_event_channel(); if (!channel) { perror("cmatose: failed to create event channel"); return -1; } ret = 0; if (listen_id) ret = rdma_migrate_id(listen_id, channel); for (i = 0; i < connections && !ret; i++) ret = rdma_migrate_id(test.nodes[i].cma_id, channel); if (!ret) { rdma_destroy_event_channel(test.channel); test.channel = channel; } else perror("cmatose: failure migrating to channel"); return ret; }
int main(int argc, char **argv) { struct addrinfo *addr; struct rdma_cm_event *event = NULL; struct rdma_cm_id *conn= NULL; struct rdma_event_channel *ec = NULL; if (argc != 3) die("usage: client <server-address> <server-port>"); TEST_NZ(getaddrinfo(argv[1], argv[2], NULL, &addr)); TEST_Z(ec = rdma_create_event_channel()); TEST_NZ(rdma_create_id(ec, &conn, NULL, RDMA_PS_TCP)); TEST_NZ(rdma_resolve_addr(conn, NULL, addr->ai_addr, TIMEOUT_IN_MS)); freeaddrinfo(addr); while (rdma_get_cm_event(ec, &event) == 0) { struct rdma_cm_event event_copy; memcpy(&event_copy, event, sizeof(*event)); rdma_ack_cm_event(event); if (on_event(&event_copy)) break; } rdma_destroy_event_channel(ec); return 0; }
static int fi_ibv_eq_close(fid_t fid) { struct fi_ibv_eq *eq; struct fi_ibv_eq_entry *entry; eq = container_of(fid, struct fi_ibv_eq, eq_fid.fid); if (eq->channel) rdma_destroy_event_channel(eq->channel); close(eq->epfd); fastlock_acquire(&eq->lock); while(!dlistfd_empty(&eq->list_head)) { entry = container_of(eq->list_head.list.next, struct fi_ibv_eq_entry, item); dlistfd_remove(eq->list_head.list.next, &eq->list_head); free(entry); } dlistfd_head_free(&eq->list_head); fastlock_destroy(&eq->lock); free(eq); return 0; }
void client_disconnect(void){ struct rdma_event_channel *ec = s_ctx->ec; struct rdma_cm_id *id = s_ctx->id; struct rdma_cm_event *event = NULL; printf("ready to disconnect\n"); rdma_disconnect(id); printf("send disconnect\n"); while(1){ if(rdma_get_cm_event(ec, &event) == 0) { struct rdma_cm_event event_copy; memcpy(&event_copy, event, sizeof(*event)); rdma_ack_cm_event(event); if (event_copy.event == RDMA_CM_EVENT_DISCONNECTED){ on_disconnect(event_copy.id); rdma_destroy_event_channel(ec); break; } } } return; }
/// The IBConnectionGroup default destructor. virtual ~IBConnectionGroup() { for (auto& c : conn_) c = nullptr; if (listen_id_) { int err = rdma_destroy_id(listen_id_); if (err) { L_(error) << "rdma_destroy_id() failed"; } listen_id_ = nullptr; } if (cq_) { int err = ibv_destroy_cq(cq_); if (err) { L_(error) << "ibv_destroy_cq() failed"; } cq_ = nullptr; } if (pd_) { int err = ibv_dealloc_pd(pd_); if (err) { L_(error) << "ibv_dealloc_pd() failed"; } pd_ = nullptr; } rdma_destroy_event_channel(ec_); }
neigh_table_mgr::~neigh_table_mgr() { stop_garbage_collector(); if (m_neigh_cma_event_channel) { rdma_destroy_event_channel(m_neigh_cma_event_channel); } }
int RDMA_Active_Finalize(struct RDMA_communicator *comm) { TEST_NZ(wait_for_event(comm->ec, RDMA_CM_EVENT_DISCONNECTED)); rdma_destroy_id(comm->cm_id); rdma_destroy_event_channel(comm->ec); return 0; }
void network_release() { ibv_dereg_mr(mr_data); rdma_destroy_qp(cm_id); ibv_destroy_cq(cq); ibv_destroy_comp_channel(comp_chan); rdma_destroy_id(cm_id); rdma_destroy_event_channel(cm_channel); }
static int __fi_eq_cm_close(fid_t fid) { struct __fid_eq_cm *eq; eq = container_of(fid, struct __fid_eq_cm, eq_fid.fid); if (eq->channel) rdma_destroy_event_channel(eq->channel); free(eq); return 0; }
void cfio_rdma_client_final() { cfio_rdma_client_wait(NULL); // rdma_debug("final ..."); rdma_disconnect(rdma_conn->id); wait_rdma_event(); rdma_destroy_event_channel(ec); // rdma_debug("final successfully"); }
static int __fi_eq_open(struct fid_fabric *fabric, const struct fi_eq_attr *attr, struct fid_eq **eq, void *context) { struct __fid_eq_cm *_eq; long flags = 0; int ret; if (attr->format != FI_EQ_FORMAT_CM) return -FI_ENOSYS; _eq = calloc(1, sizeof *_eq); if (!_eq) return -FI_ENOMEM; _eq->fab = container_of(fabric, struct __fid_fabric, fabric_fid); switch (attr->wait_obj) { case FI_WAIT_FD: _eq->channel = rdma_create_event_channel(); if (!_eq->channel) { ret = -errno; goto err1; } fcntl(_eq->channel->fd, F_GETFL, &flags); ret = fcntl(_eq->channel->fd, F_SETFL, flags | O_NONBLOCK); if (ret) { ret = -errno; goto err2; } break; case FI_WAIT_NONE: break; default: return -FI_ENOSYS; } _eq->flags = attr->flags; _eq->eq_fid.fid.fclass = FID_CLASS_EQ; _eq->eq_fid.fid.context = context; _eq->eq_fid.fid.ops = &__fi_eq_cm_ops; _eq->eq_fid.ops = &__fi_eq_cm_data_ops; *eq = &_eq->eq_fid; return 0; err2: if (_eq->channel) rdma_destroy_event_channel(_eq->channel); err1: free(_eq); return ret; }
void diod_rdma_destroy (diod_rdma_t rdma) { if (rdma->listen_id) { rdma_destroy_id(rdma->listen_id); rdma->listen_id = NULL; } if (rdma->event_channel) { rdma_destroy_event_channel (rdma->event_channel); rdma->event_channel = NULL; } free (rdma); }
void kiro_server_stop (KiroServer *self) { g_return_if_fail (self != NULL); KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE (self); if (!priv->base) return; //Shut down event listening priv->close_signal = TRUE; g_debug ("Event handling stopped"); g_list_foreach (priv->clients, disconnect_client, NULL); g_list_free (priv->clients); // Stop the main loop and clear its memory g_main_loop_quit (priv->main_loop); g_main_loop_unref (priv->main_loop); priv->main_loop = NULL; // Ask the main thread to join (It probably already has, but we do it // anyways. Just in case!) g_thread_join (priv->main_thread); priv->main_thread = NULL; // We don't need the connection management IO channel container any more. // Unref and thus free it. g_io_channel_unref (priv->conn_ec); priv->conn_ec = NULL; priv->close_signal = FALSE; // kiro_destroy_connection would try to call rdma_disconnect on the given // connection. But the server never 'connects' to anywhere, so this would // cause a crash. We need to destroy the enpoint manually without disconnect struct kiro_connection_context *ctx = (struct kiro_connection_context *) (priv->base->context); kiro_destroy_connection_context (&ctx); rdma_destroy_ep (priv->base); priv->base = NULL; rdma_destroy_event_channel (priv->ec); priv->ec = NULL; g_message ("Server stopped successfully"); }
static int ibw_ctx_priv_destruct(struct ibw_ctx_priv *pctx) { DEBUG(DEBUG_DEBUG, ("ibw_ctx_priv_destruct(%p)\n", pctx)); /* * tevent_fd must be removed before the fd is closed */ TALLOC_FREE(pctx->cm_channel_event); /* destroy cm */ if (pctx->cm_channel) { rdma_destroy_event_channel(pctx->cm_channel); pctx->cm_channel = NULL; } if (pctx->cm_id) { rdma_destroy_id(pctx->cm_id); pctx->cm_id = NULL; } return 0; }
int main(int argc, char **argv) { struct addrinfo *addr; struct rdma_cm_event *event = NULL; struct rdma_cm_id *conn= NULL; struct rdma_event_channel *ec = NULL; if (argc != 4) usage(argv[0]); if (strcmp(argv[1], "write") == 0) set_mode(M_WRITE); else if (strcmp(argv[1], "read") == 0) set_mode(M_READ); else usage(argv[0]); TEST_NZ(getaddrinfo(argv[2], argv[3], NULL, &addr)); TEST_Z(ec = rdma_create_event_channel()); TEST_NZ(rdma_create_id(ec, &conn, NULL, RDMA_PS_TCP)); TEST_NZ(rdma_resolve_addr(conn, NULL, addr->ai_addr, TIMEOUT_IN_MS)); freeaddrinfo(addr); while (rdma_get_cm_event(ec, &event) == 0) { struct rdma_cm_event event_copy; memcpy(&event_copy, event, sizeof(*event)); rdma_ack_cm_event(event); if (on_event(&event_copy)) break; } rdma_destroy_event_channel(ec); return 0; }
int ibrdma_transfer(struct transfer_info tfi, int num_tfi) { struct addrinfo *addr; struct rdma_cm_id *cmid= NULL; struct rdma_event_channel *ec = NULL; struct rdma_conn_param cm_params; int i,j; /*Allocation buffer space for reading from local fs to memory*/ struct transfer_file *ffile = tfi.tfiles; int nf = tfi.tfiles; char* host = tfi.ib_host; char* port; sprintf(port,"%d",tfi.ib_port); for (i = 0; i < NUM_FILE_BUF_C; i++) { tfi.fbufs[i].fbuf = (char *)malloc(FILE_BUF_SIZE_C); tfi.fbufs[i].size = 0; } TEST_NZ(getaddrinfo(host, port, NULL, &addr)); TEST_Z(ec = rdma_create_event_channel()); TEST_NZ(rdma_create_id(ec, &cmid, NULL, RDMA_PS_TCP)); TEST_NZ(rdma_resolve_addr(cmid, NULL, addr->ai_addr, TIMEOUT_IN_MS)); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ADDR_RESOLVED)); freeaddrinfo(addr); build_connection(cmid); TEST_NZ(rdma_resolve_route(cmid, TIMEOUT_IN_MS)); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ROUTE_RESOLVED)); build_params(&cm_params); TEST_NZ(rdma_connect(cmid, &cm_params)); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ESTABLISHED)); on_connect(cmid->context); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_DISCONNECTED)); rdma_destroy_id(&cmid); rdma_destroy_event_channel(&ec); return 0; }
void close(boost::system::error_code &ec) { if(!event_channel_) { HPX_IBVERBS_RESET_EC(ec); return; } if(event_channel_) { rdma_destroy_event_channel(event_channel_); event_channel_ = 0; } else { HPX_IBVERBS_THROWS_IF(ec, boost::asio::error::not_connected); } if(listener_) { rdma_destroy_id(listener_); listener_ = 0; } HPX_IBVERBS_RESET_EC(ec); }
int main(int argc, char *argv[]) { struct rping_cb *cb; int op; int ret = 0; int persistent_server = 0; cb = malloc(sizeof(*cb)); if (!cb) return -ENOMEM; memset(cb, 0, sizeof(*cb)); cb->server = -1; cb->state = IDLE; cb->size = 64; cb->sin.ss_family = PF_INET; cb->port = htons(7174); sem_init(&cb->sem, 0, 0); opterr = 0; while ((op=getopt(argc, argv, "a:Pp:C:S:t:scvVd")) != -1) { switch (op) { case 'a': ret = get_addr(optarg, (struct sockaddr *) &cb->sin); break; case 'P': persistent_server = 1; break; case 'p': cb->port = htons(atoi(optarg)); DEBUG_LOG("port %d\n", (int) atoi(optarg)); break; case 's': cb->server = 1; DEBUG_LOG("server\n"); break; case 'c': cb->server = 0; DEBUG_LOG("client\n"); break; case 'S': cb->size = atoi(optarg); if ((cb->size < RPING_MIN_BUFSIZE) || (cb->size > (RPING_BUFSIZE - 1))) { fprintf(stderr, "Invalid size %d " "(valid range is %Zd to %d)\n", cb->size, RPING_MIN_BUFSIZE, RPING_BUFSIZE); ret = EINVAL; } else DEBUG_LOG("size %d\n", (int) atoi(optarg)); break; case 'C': cb->count = atoi(optarg); if (cb->count < 0) { fprintf(stderr, "Invalid count %d\n", cb->count); ret = EINVAL; } else DEBUG_LOG("count %d\n", (int) cb->count); break; case 'v': cb->verbose++; DEBUG_LOG("verbose\n"); break; case 'V': cb->validate++; DEBUG_LOG("validate data\n"); break; case 'd': debug++; break; default: usage("rping"); ret = EINVAL; goto out; } } if (ret) goto out; if (cb->server == -1) { usage("rping"); ret = EINVAL; goto out; } cb->cm_channel = rdma_create_event_channel(); if (!cb->cm_channel) { perror("rdma_create_event_channel"); ret = errno; goto out; } ret = rdma_create_id(cb->cm_channel, &cb->cm_id, cb, RDMA_PS_TCP); if (ret) { perror("rdma_create_id"); goto out2; } DEBUG_LOG("created cm_id %p\n", cb->cm_id); ret = pthread_create(&cb->cmthread, NULL, cm_thread, cb); if (ret) { perror("pthread_create"); goto out2; } if (cb->server) { if (persistent_server) ret = rping_run_persistent_server(cb); else ret = rping_run_server(cb); } else { ret = rping_run_client(cb); } DEBUG_LOG("destroy cm_id %p\n", cb->cm_id); rdma_destroy_id(cb->cm_id); out2: rdma_destroy_event_channel(cb->cm_channel); out: free(cb); return ret; }
int main(int argc, char **argv) { int op, ret; while ((op = getopt(argc, argv, "s:b:c:C:S:t:p:mT")) != -1) { switch (op) { case 's': dst_addr = optarg; break; case 'b': src_addr = optarg; break; case 'c': connections = atoi(optarg); break; case 'C': message_count = atoi(optarg); break; case 'S': message_size = atoi(optarg); break; case 't': set_tos = 1; tos = (uint8_t) strtoul(optarg, NULL, 0); break; case 'p': port = optarg; break; case 'm': migrate = 1; break; case 'T': set_ts = 1; break; default: printf("usage: %s\n", argv[0]); printf("\t[-s server_address]\n"); printf("\t[-b bind_address]\n"); printf("\t[-c connections]\n"); printf("\t[-C message_count]\n"); printf("\t[-S message_size]\n"); printf("\t[-t type_of_service]\n"); printf("\t[-p port_number]\n"); printf("\t[-m(igrate)]\n"); printf("\t[-T(imestamping)]\n"); exit(1); } } test.connects_left = connections; test.channel = rdma_create_event_channel(); if (!test.channel) { printf("failed to create event channel\n"); exit(1); } if (alloc_nodes()) exit(1); if (dst_addr) ret = run_client(); else ret = run_server(); printf("test complete\n"); destroy_nodes(); rdma_destroy_event_channel(test.channel); if (test.rai) rdma_freeaddrinfo(test.rai); printf("return status %d\n", ret); return ret; }
int main(int argc, char **argv) { int op, ret; while ((op = getopt(argc, argv, "m:M:sb:c:C:S:p:")) != -1) { switch (op) { case 'm': dst_addr = optarg; break; case 'M': unmapped_addr = 1; dst_addr = optarg; break; case 's': is_sender = 1; break; case 'b': src_addr = optarg; test.src_addr = (struct sockaddr *) &test.src_in; break; case 'c': connections = atoi(optarg); break; case 'C': message_count = atoi(optarg); break; case 'S': message_size = atoi(optarg); break; case 'p': port_space = strtol(optarg, NULL, 0); break; default: printf("usage: %s\n", argv[0]); printf("\t-m multicast_address\n"); printf("\t[-M unmapped_multicast_address]\n" "\t replaces -m and requires -b\n"); printf("\t[-s(ender)]\n"); printf("\t[-b bind_address]\n"); printf("\t[-c connections]\n"); printf("\t[-C message_count]\n"); printf("\t[-S message_size]\n"); printf("\t[-p port_space - %#x for UDP (default), " "%#x for IPOIB]\n", RDMA_PS_UDP, RDMA_PS_IPOIB); exit(1); } } if (unmapped_addr && !src_addr) { printf("unmapped multicast address requires binding " "to source address\n"); exit(1); } test.dst_addr = (struct sockaddr *) &test.dst_in; test.connects_left = connections; test.channel = rdma_create_event_channel(); if (!test.channel) { perror("failed to create event channel"); exit(1); } if (alloc_nodes()) exit(1); ret = run(); printf("test complete\n"); destroy_nodes(); rdma_destroy_event_channel(test.channel); printf("return status %d\n", ret); return ret; }
static int fi_ibv_mr_reg(struct fid *fid, const void *buf, size_t len, uint64_t access, uint64_t offset, uint64_t requested_key, uint64_t flags, struct fid_mr **mr, void *context) { struct fi_ibv_mem_desc *md; int fi_ibv_access = 0; struct fid_domain *domain; if (flags) return -FI_EBADFLAGS; if (fid->fclass != FI_CLASS_DOMAIN) { return -FI_EINVAL; } domain = container_of(fid, struct fid_domain, fid); md = calloc(1, sizeof *md); if (!md) return -FI_ENOMEM; md->domain = container_of(domain, struct fi_ibv_domain, domain_fid); md->mr_fid.fid.fclass = FI_CLASS_MR; md->mr_fid.fid.context = context; md->mr_fid.fid.ops = &fi_ibv_mr_ops; /* Enable local write access by default for FI_EP_RDM which hides local * registration requirements. This allows to avoid buffering or double * registration */ if (!(md->domain->info->caps & FI_LOCAL_MR)) fi_ibv_access |= IBV_ACCESS_LOCAL_WRITE; /* Local read access to an MR is enabled by default in verbs */ if (access & FI_RECV) fi_ibv_access |= IBV_ACCESS_LOCAL_WRITE; /* iWARP spec requires Remote Write access for an MR that is used * as a data sink for a Remote Read */ if (access & FI_READ) { fi_ibv_access |= IBV_ACCESS_LOCAL_WRITE; if (md->domain->verbs->device->transport_type == IBV_TRANSPORT_IWARP) fi_ibv_access |= IBV_ACCESS_REMOTE_WRITE; } if (access & FI_WRITE) fi_ibv_access |= IBV_ACCESS_LOCAL_WRITE; if (access & FI_REMOTE_READ) fi_ibv_access |= IBV_ACCESS_REMOTE_READ; /* Verbs requires Local Write access too for Remote Write access */ if (access & FI_REMOTE_WRITE) fi_ibv_access |= IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_REMOTE_ATOMIC; md->mr = ibv_reg_mr(md->domain->pd, (void *) buf, len, fi_ibv_access); if (!md->mr) goto err; md->mr_fid.mem_desc = (void *) (uintptr_t) md->mr->lkey; md->mr_fid.key = md->mr->rkey; *mr = &md->mr_fid; if(md->domain->eq && (md->domain->eq_flags & FI_REG_MR)) { struct fi_eq_entry entry = { .fid = &md->mr_fid.fid, .context = context }; fi_ibv_eq_write_event(md->domain->eq, FI_MR_COMPLETE, &entry, sizeof(entry)); } return 0; err: free(md); return -errno; } static int fi_ibv_mr_regv(struct fid *fid, const struct iovec * iov, size_t count, uint64_t access, uint64_t offset, uint64_t requested_key, uint64_t flags, struct fid_mr **mr, void *context) { if (count > VERBS_MR_IOV_LIMIT) { VERBS_WARN(FI_LOG_FABRIC, "iov count > %d not supported\n", VERBS_MR_IOV_LIMIT); return -FI_EINVAL; } return fi_ibv_mr_reg(fid, iov->iov_base, iov->iov_len, access, offset, requested_key, flags, mr, context); } static int fi_ibv_mr_regattr(struct fid *fid, const struct fi_mr_attr *attr, uint64_t flags, struct fid_mr **mr) { return fi_ibv_mr_regv(fid, attr->mr_iov, attr->iov_count, attr->access, 0, attr->requested_key, flags, mr, attr->context); } static int fi_ibv_domain_bind(struct fid *fid, struct fid *bfid, uint64_t flags) { struct fi_ibv_domain *domain; struct fi_ibv_eq *eq; domain = container_of(fid, struct fi_ibv_domain, domain_fid.fid); switch (bfid->fclass) { case FI_CLASS_EQ: eq = container_of(bfid, struct fi_ibv_eq, eq_fid); domain->eq = eq; domain->eq_flags = flags; break; default: return -EINVAL; } return 0; } static int fi_ibv_domain_close(fid_t fid) { struct fi_ibv_domain *domain; int ret; domain = container_of(fid, struct fi_ibv_domain, domain_fid.fid); if (domain->rdm) { rdma_destroy_ep(domain->rdm_cm->listener); free(domain->rdm_cm); } if (domain->pd) { ret = ibv_dealloc_pd(domain->pd); if (ret) return -ret; domain->pd = NULL; } fi_freeinfo(domain->info); free(domain); return 0; } static int fi_ibv_open_device_by_name(struct fi_ibv_domain *domain, const char *name) { struct ibv_context **dev_list; int i, ret = -FI_ENODEV; if (!name) return -FI_EINVAL; dev_list = rdma_get_devices(NULL); if (!dev_list) return -errno; for (i = 0; dev_list[i] && ret; i++) { if (domain->rdm) { ret = strncmp(name, ibv_get_device_name(dev_list[i]->device), strlen(name) - strlen(verbs_rdm_domain.suffix)); } else { ret = strcmp(name, ibv_get_device_name(dev_list[i]->device)); } if (!ret) domain->verbs = dev_list[i]; } rdma_free_devices(dev_list); return ret; } static struct fi_ops fi_ibv_fid_ops = { .size = sizeof(struct fi_ops), .close = fi_ibv_domain_close, .bind = fi_ibv_domain_bind, .control = fi_no_control, .ops_open = fi_no_ops_open, }; static struct fi_ops_mr fi_ibv_domain_mr_ops = { .size = sizeof(struct fi_ops_mr), .reg = fi_ibv_mr_reg, .regv = fi_ibv_mr_regv, .regattr = fi_ibv_mr_regattr, }; static struct fi_ops_domain fi_ibv_domain_ops = { .size = sizeof(struct fi_ops_domain), .av_open = fi_no_av_open, .cq_open = fi_ibv_cq_open, .endpoint = fi_ibv_open_ep, .scalable_ep = fi_no_scalable_ep, .cntr_open = fi_no_cntr_open, .poll_open = fi_no_poll_open, .stx_ctx = fi_no_stx_context, .srx_ctx = fi_ibv_srq_context, }; static struct fi_ops_domain fi_ibv_rdm_domain_ops = { .size = sizeof(struct fi_ops_domain), .av_open = fi_ibv_rdm_av_open, .cq_open = fi_ibv_rdm_cq_open, .endpoint = fi_ibv_rdm_open_ep, .scalable_ep = fi_no_scalable_ep, .cntr_open = fi_rbv_rdm_cntr_open, .poll_open = fi_no_poll_open, .stx_ctx = fi_no_stx_context, .srx_ctx = fi_no_srx_context, }; static int fi_ibv_domain(struct fid_fabric *fabric, struct fi_info *info, struct fid_domain **domain, void *context) { struct fi_ibv_domain *_domain; struct fi_ibv_fabric *fab; struct fi_info *fi; int ret; fi = fi_ibv_get_verbs_info(info->domain_attr->name); if (!fi) return -FI_EINVAL; fab = container_of(fabric, struct fi_ibv_fabric, util_fabric.fabric_fid); ret = ofi_check_domain_attr(&fi_ibv_prov, fabric->api_version, fi->domain_attr, info->domain_attr); if (ret) return ret; _domain = calloc(1, sizeof *_domain); if (!_domain) return -FI_ENOMEM; _domain->info = fi_dupinfo(info); if (!_domain->info) goto err1; _domain->rdm = FI_IBV_EP_TYPE_IS_RDM(info); if (_domain->rdm) { _domain->rdm_cm = calloc(1, sizeof(*_domain->rdm_cm)); if (!_domain->rdm_cm) { ret = -FI_ENOMEM; goto err2; } } ret = fi_ibv_open_device_by_name(_domain, info->domain_attr->name); if (ret) goto err2; _domain->pd = ibv_alloc_pd(_domain->verbs); if (!_domain->pd) { ret = -errno; goto err2; } _domain->domain_fid.fid.fclass = FI_CLASS_DOMAIN; _domain->domain_fid.fid.context = context; _domain->domain_fid.fid.ops = &fi_ibv_fid_ops; _domain->domain_fid.mr = &fi_ibv_domain_mr_ops; if (_domain->rdm) { _domain->domain_fid.ops = &fi_ibv_rdm_domain_ops; _domain->rdm_cm->ec = rdma_create_event_channel(); if (!_domain->rdm_cm->ec) { VERBS_INFO(FI_LOG_EP_CTRL, "Failed to create listener event channel: %s\n", strerror(errno)); ret = -FI_EOTHER; goto err2; } if (fi_fd_nonblock(_domain->rdm_cm->ec->fd) != 0) { VERBS_INFO_ERRNO(FI_LOG_EP_CTRL, "fcntl", errno); ret = -FI_EOTHER; goto err3; } if (rdma_create_id(_domain->rdm_cm->ec, &_domain->rdm_cm->listener, NULL, RDMA_PS_TCP)) { VERBS_INFO(FI_LOG_EP_CTRL, "Failed to create cm listener: %s\n", strerror(errno)); ret = -FI_EOTHER; goto err3; } _domain->rdm_cm->is_bound = 0; } else { _domain->domain_fid.ops = &fi_ibv_domain_ops; } _domain->fab = fab; *domain = &_domain->domain_fid; return 0; err3: if (_domain->rdm) rdma_destroy_event_channel(_domain->rdm_cm->ec); err2: if (_domain->rdm) free(_domain->rdm_cm); fi_freeinfo(_domain->info); err1: free(_domain); return ret; } static int fi_ibv_trywait(struct fid_fabric *fabric, struct fid **fids, int count) { struct fi_ibv_cq *cq; int ret, i; for (i = 0; i < count; i++) { switch (fids[i]->fclass) { case FI_CLASS_CQ: cq = container_of(fids[i], struct fi_ibv_cq, cq_fid.fid); ret = cq->trywait(fids[i]); if (ret) return ret; break; case FI_CLASS_EQ: /* We are always ready to wait on an EQ since * rdmacm EQ is based on an fd */ continue; case FI_CLASS_CNTR: case FI_CLASS_WAIT: return -FI_ENOSYS; default: return -FI_EINVAL; } } return FI_SUCCESS; } static int fi_ibv_fabric_close(fid_t fid) { struct fi_ibv_fabric *fab; int ret; fab = container_of(fid, struct fi_ibv_fabric, util_fabric.fabric_fid.fid); ret = ofi_fabric_close(&fab->util_fabric); if (ret) return ret; free(fab); return 0; } static struct fi_ops fi_ibv_fi_ops = { .size = sizeof(struct fi_ops), .close = fi_ibv_fabric_close, .bind = fi_no_bind, .control = fi_no_control, .ops_open = fi_no_ops_open, }; static struct fi_ops_fabric fi_ibv_ops_fabric = { .size = sizeof(struct fi_ops_fabric), .domain = fi_ibv_domain, .passive_ep = fi_ibv_passive_ep, .eq_open = fi_ibv_eq_open, .wait_open = fi_no_wait_open, .trywait = fi_ibv_trywait }; int fi_ibv_fabric(struct fi_fabric_attr *attr, struct fid_fabric **fabric, void *context) { struct fi_ibv_fabric *fab; struct fi_info *info; int ret; ret = fi_ibv_init_info(); if (ret) return ret; fab = calloc(1, sizeof(*fab)); if (!fab) return -FI_ENOMEM; for (info = verbs_info; info; info = info->next) { ret = ofi_fabric_init(&fi_ibv_prov, info->fabric_attr, attr, &fab->util_fabric, context); if (ret != -FI_ENODATA) break; } if (ret) { free(fab); return ret; } *fabric = &fab->util_fabric.fabric_fid; (*fabric)->fid.ops = &fi_ibv_fi_ops; (*fabric)->ops = &fi_ibv_ops_fabric; return 0; }
static int run(int argc, char **argv) { struct addrinfo *addr; //struct rdma_cm_event *event = NULL; struct rdma_cm_id *cmid= NULL; struct rdma_event_channel *ec = NULL; struct rdma_conn_param cm_params; if (argc != 4) usage(argv[0]); if (strcmp(argv[1], "write") == 0) set_mode(M_WRITE); else if (strcmp(argv[1], "read") == 0) set_mode(M_READ); else usage(argv[0]); TEST_NZ(getaddrinfo(argv[2], argv[3], NULL, &addr)); TEST_Z(ec = rdma_create_event_channel()); /*create rdma socket*/ TEST_NZ(rdma_create_id(ec, &cmid, NULL, RDMA_PS_TCP)); /* int rdma_resolve_addr (struct rdma_cm_id *id, struct sockaddr *src_addr, struct sockaddr dst_addr, int timeout_ms) id RDMA identifier src_addr Source address information. This parameter may be NULL. dst_addr Destination address information timeout_ms Time to wait for resolution to complete Description: Resolve destination and optional source addresses from IP addresses to an RDMA address. If suc- cessful, the specified rdma_cm_id will be bound to a local device. */ TEST_NZ(rdma_resolve_addr(cmid, NULL, addr->ai_addr, TIMEOUT_IN_MS)); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ADDR_RESOLVED)); freeaddrinfo(addr); build_connection(cmid); sprintf(get_local_message_region(cmid->context), "message from active/client side with pid %d", getpid()); /*--------------------*/ /* int rdma_resolve_route (struct rdma_cm_id *id, int timeout_ms); id RDMA identifier timeout_ms Time to wait for resolution to complete Description: Resolves an RDMA route to the destination address in order to establish a connection. The destination address must have already been resolved by calling rdma_resolve_addr. */ TEST_NZ(rdma_resolve_route(cmid, TIMEOUT_IN_MS)); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ROUTE_RESOLVED)); /* -------------------- */ print_path_rec(cmid); /* int rdma_connect (struct rdma_cm_id *id, struct rdma_conn_param *conn_param); id RDMA identifier conn_param connection parameters Description: For an rdma_cm_id of type RDMA_PS_TCP, this call initiates a connection request to a remote destination. For an rdma_cm_id of type RDMA_PS_UDP, it initiates a lookup of the remote QP providing the datagram service */ build_params(&cm_params); printf("Connecting ...\n"); TEST_NZ(rdma_connect(cmid, &cm_params)); TEST_NZ(wait_for_event(ec, RDMA_CM_EVENT_ESTABLISHED)); printf("Connected !\n"); /* --------------------- */ /*TODO: do something */ on_connect(cmid->context); send_mr(cmid->context); /*--------------------*/ rdma_disconnect(cmid); rdma_destroy_id(cmid); rdma_destroy_event_channel(ec); return 0; /*=================*/ /*=================*/ /* while (rdma_get_cm_event(ec, &event) == 0) { memcpy(&event_copy, event, sizeof(*event)); rdma_ack_cm_event(event); if (on_event(&event_copy)) break; } */ }
int fi_ibv_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr, struct fid_eq **eq, void *context) { struct fi_ibv_eq *_eq; struct epoll_event event; int ret; _eq = calloc(1, sizeof *_eq); if (!_eq) return -ENOMEM; _eq->fab = container_of(fabric, struct fi_ibv_fabric, fabric_fid); fastlock_init(&_eq->lock); ret = dlistfd_head_init(&_eq->list_head); if (ret) { FI_INFO(&fi_ibv_prov, FI_LOG_EQ, "Unable to initialize dlistfd\n"); goto err1; } _eq->epfd = epoll_create1(0); if (_eq->epfd < 0) { ret = -errno; goto err2; } memset(&event, 0, sizeof(event)); event.events = EPOLLIN; if (epoll_ctl(_eq->epfd, EPOLL_CTL_ADD, _eq->list_head.signal.fd[FI_READ_FD], &event)) { ret = -errno; goto err3; } switch (attr->wait_obj) { case FI_WAIT_NONE: case FI_WAIT_UNSPEC: case FI_WAIT_FD: _eq->channel = rdma_create_event_channel(); if (!_eq->channel) { ret = -errno; goto err3; } ret = fi_fd_nonblock(_eq->channel->fd); if (ret) goto err4; if (epoll_ctl(_eq->epfd, EPOLL_CTL_ADD, _eq->channel->fd, &event)) { ret = -errno; goto err4; } break; default: ret = -FI_ENOSYS; goto err1; } _eq->flags = attr->flags; _eq->eq_fid.fid.fclass = FI_CLASS_EQ; _eq->eq_fid.fid.context = context; _eq->eq_fid.fid.ops = &fi_ibv_eq_fi_ops; _eq->eq_fid.ops = &fi_ibv_eq_ops; *eq = &_eq->eq_fid; return 0; err4: if (_eq->channel) rdma_destroy_event_channel(_eq->channel); err3: close(_eq->epfd); err2: dlistfd_head_free(&_eq->list_head); err1: fastlock_destroy(&_eq->lock); free(_eq); return ret; }
int main(int argc, char **argv) { int op, ret; hints.ai_port_space = RDMA_PS_TCP; while ((op = getopt(argc, argv, "s:b:f:P:c:C:S:t:p:m")) != -1) { switch (op) { case 's': dst_addr = optarg; break; case 'b': src_addr = optarg; break; case 'f': if (!strncasecmp("ip", optarg, 2)) { hints.ai_flags = RAI_NUMERICHOST; } else if (!strncasecmp("gid", optarg, 3)) { hints.ai_flags = RAI_NUMERICHOST | RAI_FAMILY; hints.ai_family = AF_IB; } else if (strncasecmp("name", optarg, 4)) { fprintf(stderr, "Warning: unknown address format\n"); } break; case 'P': if (!strncasecmp("ib", optarg, 2)) { hints.ai_port_space = RDMA_PS_IB; } else if (strncasecmp("tcp", optarg, 3)) { fprintf(stderr, "Warning: unknown port space format\n"); } break; case 'c': connections = atoi(optarg); break; case 'C': message_count = atoi(optarg); break; case 'S': message_size = atoi(optarg); break; case 't': set_tos = 1; tos = (uint8_t) strtoul(optarg, NULL, 0); break; case 'p': port = optarg; break; case 'm': migrate = 1; break; default: printf("usage: %s\n", argv[0]); printf("\t[-s server_address]\n"); printf("\t[-b bind_address]\n"); printf("\t[-f address_format]\n"); printf("\t name, ip, ipv6, or gid\n"); printf("\t[-P port_space]\n"); printf("\t tcp or ib\n"); printf("\t[-c connections]\n"); printf("\t[-C message_count]\n"); printf("\t[-S message_size]\n"); printf("\t[-t type_of_service]\n"); printf("\t[-p port_number]\n"); printf("\t[-m(igrate)]\n"); exit(1); } } test.connects_left = connections; test.channel = create_first_event_channel(); if (!test.channel) { exit(1); } if (alloc_nodes()) exit(1); if (dst_addr) { ret = run_client(); } else { hints.ai_flags |= RAI_PASSIVE; ret = run_server(); } printf("test complete\n"); destroy_nodes(); rdma_destroy_event_channel(test.channel); if (test.rai) rdma_freeaddrinfo(test.rai); printf("return status %d\n", ret); return ret; }