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; }
static int rping_bind_server(struct rping_cb *cb) { int ret; if (cb->sin.ss_family == AF_INET) ((struct sockaddr_in *) &cb->sin)->sin_port = cb->port; else ((struct sockaddr_in6 *) &cb->sin)->sin6_port = cb->port; ret = rdma_bind_addr(cb->cm_id, (struct sockaddr *) &cb->sin); if (ret) { perror("rdma_bind_addr"); return ret; } DEBUG_LOG("rdma_bind_addr successful\n"); DEBUG_LOG("rdma_listen\n"); ret = rdma_listen(cb->cm_id, 3); if (ret) { perror("rdma_listen"); return ret; } return 0; }
static int krping_bind_server(struct krping_cb *cb) { struct sockaddr_in sin; int ret; memset(&sin, 0, sizeof(sin)); sin.sin_len = sizeof sin; sin.sin_family = AF_INET; sin.sin_addr.s_addr = cb->addr.s_addr; sin.sin_port = cb->port; ret = rdma_bind_addr(cb->cm_id, (struct sockaddr *) &sin); if (ret) { log(LOG_ERR, "rdma_bind_addr error %d\n", ret); return ret; } DEBUG_LOG(PFX "rdma_bind_addr successful\n"); DEBUG_LOG(PFX "rdma_listen\n"); ret = rdma_listen(cb->cm_id, 3); if (ret) { log(LOG_ERR, "rdma_listen failed: %d\n", ret); return ret; } krping_wait(cb, CONNECT_REQUEST); if (cb->state != CONNECT_REQUEST) { log(LOG_ERR, "wait for CONNECT_REQUEST state %d\n", cb->state); return -1; } return 0; }
static int fi_ibv_pep_setname(fid_t pep_fid, void *addr, size_t addrlen) { struct fi_ibv_pep *pep; int ret; pep = container_of(pep_fid, struct fi_ibv_pep, pep_fid); if (pep->src_addrlen && (addrlen != pep->src_addrlen)) { FI_INFO(&fi_ibv_prov, FI_LOG_FABRIC, "addrlen expected: %d, got: %d.\n", pep->src_addrlen, addrlen); return -FI_EINVAL; } /* Re-create id if already bound */ if (pep->bound) { ret = rdma_destroy_id(pep->id); if (ret) { FI_INFO(&fi_ibv_prov, FI_LOG_FABRIC, "Unable to destroy previous rdma_cm_id\n"); return -errno; } ret = rdma_create_id(NULL, &pep->id, NULL, RDMA_PS_TCP); if (ret) { FI_INFO(&fi_ibv_prov, FI_LOG_FABRIC, "Unable to create rdma_cm_id\n"); return -errno; } } ret = rdma_bind_addr(pep->id, (struct sockaddr *)addr); if (ret) { FI_INFO(&fi_ibv_prov, FI_LOG_FABRIC, "Unable to bind addres to rdma_cm_id\n"); return -errno; } return 0; }
int isert_portal_listen(struct isert_portal *portal, struct sockaddr *sa, size_t addr_len) { int err; TRACE_ENTRY(); err = rdma_bind_addr(portal->cm_id, sa); if (err) { pr_warn("Failed to bind rdma addr, err:%d\n", err); goto out; } err = rdma_listen(portal->cm_id, ISER_LISTEN_BACKLOG); if (err) { pr_err("Failed rdma listen, err:%d\n", err); goto out; } memcpy(&portal->addr, sa, addr_len); switch (sa->sa_family) { case AF_INET: #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) pr_info("iser portal cm_id:%p listens on: " NIPQUAD_FMT ":%d\n", portal->cm_id, NIPQUAD(((struct sockaddr_in *)sa)->sin_addr.s_addr), (int)ntohs(((struct sockaddr_in *)sa)->sin_port)); #else pr_info("iser portal cm_id:%p listens on: " "%pI4:%d\n", portal->cm_id, &((struct sockaddr_in *)sa)->sin_addr.s_addr, (int)ntohs(((struct sockaddr_in *)sa)->sin_port)); #endif break; case AF_INET6: #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) pr_info("iser portal cm_id:%p listens on: " NIP6_FMT " %d\n", portal->cm_id, NIP6(((struct sockaddr_in6 *)sa)->sin6_addr), (int)ntohs(((struct sockaddr_in6 *)sa)->sin6_port)); #else pr_info("iser portal cm_id:%p listens on: " "%pI6 %d\n", portal->cm_id, &((struct sockaddr_in6 *)sa)->sin6_addr, (int)ntohs(((struct sockaddr_in6 *)sa)->sin6_port)); #endif break; default: pr_err("Unknown address family\n"); err = -EINVAL; goto out; } out: TRACE_EXIT_RES(err); return err; }
/* * Create a listening RDMA service endpoint. */ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, struct net *net, struct sockaddr *sa, int salen, int flags) { struct rdma_cm_id *listen_id; struct svcxprt_rdma *cma_xprt; struct svc_xprt *xprt; int ret; dprintk("svcrdma: Creating RDMA socket\n"); if (sa->sa_family != AF_INET) { dprintk("svcrdma: Address family %d is not supported.\n", sa->sa_family); return ERR_PTR(-EAFNOSUPPORT); } cma_xprt = rdma_create_xprt(serv, 1); if (!cma_xprt) return ERR_PTR(-ENOMEM); xprt = &cma_xprt->sc_xprt; listen_id = rdma_create_id(rdma_listen_handler, cma_xprt, RDMA_PS_TCP, IB_QPT_RC); if (IS_ERR(listen_id)) { ret = PTR_ERR(listen_id); dprintk("svcrdma: rdma_create_id failed = %d\n", ret); goto err0; } ret = rdma_bind_addr(listen_id, sa); if (ret) { dprintk("svcrdma: rdma_bind_addr failed = %d\n", ret); goto err1; } cma_xprt->sc_cm_id = listen_id; ret = rdma_listen(listen_id, RPCRDMA_LISTEN_BACKLOG); if (ret) { dprintk("svcrdma: rdma_listen failed = %d\n", ret); goto err1; } /* * We need to use the address from the cm_id in case the * caller specified 0 for the port number. */ sa = (struct sockaddr *)&cma_xprt->sc_cm_id->route.addr.src_addr; svc_xprt_set_local(&cma_xprt->sc_xprt, sa, salen); return &cma_xprt->sc_xprt; err1: rdma_destroy_id(listen_id); err0: kfree(cma_xprt); return ERR_PTR(ret); }
static int fi_ibv_rdm_cm_init(struct fi_ibv_rdm_cm* cm, const struct rdma_addrinfo* rai) { struct sockaddr_in* src_addr = (struct sockaddr_in*)rai->ai_src_addr; cm->ec = rdma_create_event_channel(); if (!cm->ec) { VERBS_INFO(FI_LOG_EP_CTRL, "Failed to create listener event channel: %s\n", strerror(errno)); return -FI_EOTHER; } if (fi_fd_nonblock(cm->ec->fd) != 0) { VERBS_INFO_ERRNO(FI_LOG_EP_CTRL, "fcntl", errno); return -FI_EOTHER; } if (rdma_create_id(cm->ec, &cm->listener, NULL, RDMA_PS_TCP)) { VERBS_INFO(FI_LOG_EP_CTRL, "Failed to create cm listener: %s\n", strerror(errno)); return -FI_EOTHER; } if (fi_ibv_rdm_find_ipoib_addr(src_addr, cm)) { VERBS_INFO(FI_LOG_EP_CTRL, "Failed to find correct IPoIB address\n"); return -FI_ENODEV; } cm->my_addr.sin_port = src_addr->sin_port; char my_ipoib_addr_str[INET6_ADDRSTRLEN]; inet_ntop(cm->my_addr.sin_family, &cm->my_addr.sin_addr.s_addr, my_ipoib_addr_str, INET_ADDRSTRLEN); VERBS_INFO(FI_LOG_EP_CTRL, "My IPoIB: %s\n", my_ipoib_addr_str); if (rdma_bind_addr(cm->listener, (struct sockaddr *)&cm->my_addr)) { VERBS_INFO(FI_LOG_EP_CTRL, "Failed to bind cm listener to my IPoIB addr %s: %s\n", my_ipoib_addr_str, strerror(errno)); return -FI_EOTHER; } if (!cm->my_addr.sin_port) { cm->my_addr.sin_port = rdma_get_src_port(cm->listener); } assert(cm->my_addr.sin_family == AF_INET); VERBS_INFO(FI_LOG_EP_CTRL, "My ep_addr: %s:%u\n", inet_ntoa(cm->my_addr.sin_addr), ntohs(cm->my_addr.sin_port)); return FI_SUCCESS; }
static int run_server(void) { struct rdma_cm_id *listen_id; int i, ret; printf("udaddy: starting server\n"); ret = rdma_create_id(test.channel, &listen_id, &test, port_space); if (ret) { perror("udaddy: listen request failed"); return ret; } if (src_addr) { ret = get_addr(src_addr, &test.src_in); if (ret) goto out; } else test.src_in.sin_family = PF_INET; test.src_in.sin_port = port; ret = rdma_bind_addr(listen_id, test.src_addr); if (ret) { perror("udaddy: bind address failed"); return ret; } ret = rdma_listen(listen_id, 0); if (ret) { perror("udaddy: failure trying to listen"); goto out; } connect_events(); if (message_count) { printf("receiving data transfers\n"); ret = poll_cqs(); if (ret) goto out; printf("sending replies\n"); for (i = 0; i < connections; i++) { ret = post_sends(&test.nodes[i], IBV_SEND_SIGNALED); if (ret) goto out; } ret = poll_cqs(); if (ret) goto out; printf("data transfers complete\n"); } out: rdma_destroy_id(listen_id); return ret; }
static int32_t af_inet_bind_to_port_lt_ceiling (struct rdma_cm_id *cm_id, struct sockaddr *sockaddr, socklen_t sockaddr_len, int ceiling) { int32_t ret = -1; uint16_t port = ceiling - 1; // by default assume none of the ports are blocked and all are available gf_boolean_t ports[1024] = {_gf_false,}; int i = 0; ret = gf_process_reserved_ports (ports); if (ret != 0) { for (i = 0; i < 1024; i++) ports[i] = _gf_false; } while (port) { switch (sockaddr->sa_family) { case AF_INET6: ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons (port); break; case AF_INET_SDP: case AF_INET: ((struct sockaddr_in *)sockaddr)->sin_port = htons (port); break; } // ignore the reserved ports if (ports[port] == _gf_true) { port--; continue; } ret = rdma_bind_addr (cm_id, sockaddr); if (ret == 0) break; if (ret == -1 && errno == EACCES) break; port--; } return ret; }
static int fio_rdmaio_setup_listen(struct thread_data *td, short port) { struct rdmaio_data *rd = td->io_ops->data; struct ibv_recv_wr *bad_wr; int state = td->runstate; td_set_runstate(td, TD_SETTING_UP); rd->addr.sin_family = AF_INET; rd->addr.sin_addr.s_addr = htonl(INADDR_ANY); rd->addr.sin_port = htons(port); /* rdma_listen */ if (rdma_bind_addr(rd->cm_id, (struct sockaddr *)&rd->addr) != 0) { log_err("fio: rdma_bind_addr fail\n"); return 1; } if (rdma_listen(rd->cm_id, 3) != 0) { log_err("fio: rdma_listen fail\n"); return 1; } log_info("fio: waiting for connection\n"); /* wait for CONNECT_REQUEST */ if (get_next_channel_event (td, rd->cm_channel, RDMA_CM_EVENT_CONNECT_REQUEST) != 0) { log_err("fio: wait for RDMA_CM_EVENT_CONNECT_REQUEST\n"); return 1; } if (fio_rdmaio_setup_qp(td) != 0) return 1; if (fio_rdmaio_setup_control_msg_buffers(td) != 0) return 1; /* post recv buf */ if (ibv_post_recv(rd->qp, &rd->rq_wr, &bad_wr) != 0) { log_err("fio: ibv_post_recv fail\n"); return 1; } td_set_runstate(td, state); return 0; }
static int rds_rdma_listen_init(void) { struct sockaddr_in sin; struct rdma_cm_id *cm_id; int ret; cm_id = rdma_create_id(&init_net, rds_rdma_cm_event_handler, NULL, RDMA_PS_TCP, IB_QPT_RC); if (IS_ERR(cm_id)) { ret = PTR_ERR(cm_id); printk(KERN_ERR "RDS/RDMA: failed to setup listener, " "rdma_create_id() returned %d\n", ret); return ret; } sin.sin_family = AF_INET; sin.sin_addr.s_addr = (__force u32)htonl(INADDR_ANY); sin.sin_port = (__force u16)htons(RDS_PORT); /* * XXX I bet this binds the cm_id to a device. If we want to support * fail-over we'll have to take this into consideration. */ ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin); if (ret) { printk(KERN_ERR "RDS/RDMA: failed to setup listener, " "rdma_bind_addr() returned %d\n", ret); goto out; } ret = rdma_listen(cm_id, 128); if (ret) { printk(KERN_ERR "RDS/RDMA: failed to setup listener, " "rdma_listen() returned %d\n", ret); goto out; } rdsdebug("cm %p listening on port %u\n", cm_id, RDS_PORT); rds_rdma_listen_id = cm_id; cm_id = NULL; out: if (cm_id) rdma_destroy_id(cm_id); return ret; }
int ibw_bind(struct ibw_ctx *ctx, struct sockaddr_in *my_addr) { struct ibw_ctx_priv *pctx = (struct ibw_ctx_priv *)ctx->internal; int rc; DEBUG(DEBUG_DEBUG, ("ibw_bind: addr=%s, port=%u\n", inet_ntoa(my_addr->sin_addr), ntohs(my_addr->sin_port))); rc = rdma_bind_addr(pctx->cm_id, (struct sockaddr *) my_addr); if (rc) { sprintf(ibw_lasterr, "rdma_bind_addr error %d\n", rc); DEBUG(DEBUG_ERR, (ibw_lasterr)); return rc; } DEBUG(DEBUG_DEBUG, ("rdma_bind_addr successful\n")); return 0; }
int diod_rdma_listen (diod_rdma_t rdma) { int n; rdma->addr.sin_family = AF_INET; rdma->addr.sin_port = htons(rdma_port); rdma->addr.sin_addr.s_addr = htonl(INADDR_ANY); n = rdma_bind_addr(rdma->listen_id, (struct sockaddr *)&rdma->addr); if (n) errn_exit (n, "rdma_bind_addr"); n = rdma_listen(rdma->listen_id, 1); if (n) errn (n, "rdma_listen"); return 0; }
int fi_ibv_rdm_cm_bind_ep(struct fi_ibv_rdm_cm *cm, struct fi_ibv_rdm_ep *ep) { char my_ipoib_addr_str[INET6_ADDRSTRLEN]; assert(cm->ec && cm->listener); if (ep->info->src_addr) { memcpy(&ep->my_addr, ep->info->src_addr, sizeof(ep->my_addr)); inet_ntop(ep->my_addr.sin_family, &ep->my_addr.sin_addr.s_addr, my_ipoib_addr_str, INET_ADDRSTRLEN); } else { strcpy(my_ipoib_addr_str, "undefined"); } VERBS_INFO(FI_LOG_EP_CTRL, "My IPoIB: %s\n", my_ipoib_addr_str); if (!cm->is_bound) { errno = 0; if (rdma_bind_addr(cm->listener, (struct sockaddr *)&ep->my_addr)) { VERBS_INFO(FI_LOG_EP_CTRL, "Failed to bind cm listener to my IPoIB addr %s: %s\n", my_ipoib_addr_str, strerror(errno)); return -FI_EOTHER; } if (rdma_listen(cm->listener, 1024)) { VERBS_INFO(FI_LOG_EP_CTRL, "rdma_listen failed: %s\n", strerror(errno)); return -FI_EOTHER; } cm->is_bound = 1; } if (!ep->my_addr.sin_port) { ep->my_addr.sin_port = rdma_get_src_port(cm->listener); } assert(ep->my_addr.sin_family == AF_INET); VERBS_INFO(FI_LOG_EP_CTRL, "My ep_addr: %s:%u\n", inet_ntoa(ep->my_addr.sin_addr), ntohs(ep->my_addr.sin_port)); return FI_SUCCESS; }
void accept(unsigned short port, unsigned int count) { conn_.resize(count); L_(debug) << "Setting up RDMA CM structures"; // Create rdma id (for listening) int err = rdma_create_id(ec_, &listen_id_, nullptr, RDMA_PS_TCP); if (err) { L_(error) << "rdma_create_id() failed"; throw InfinibandException("id creation failed"); } // Bind rdma id (for listening) to socket address (local port) struct sockaddr_in sin; memset(&sin, 0, sizeof sin); sin.sin_family = AF_INET; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" sin.sin_port = htons(port); sin.sin_addr.s_addr = INADDR_ANY; #pragma GCC diagnostic pop err = rdma_bind_addr(listen_id_, reinterpret_cast<struct sockaddr*>(&sin)); if (err) { L_(error) << "rdma_bind_addr(port=" << port << ") failed: " << strerror(errno); throw InfinibandException("RDMA bind_addr failed"); } // Listen for connection request on rdma id err = rdma_listen(listen_id_, count); if (err) { L_(error) << "rdma_listen() failed"; throw InfinibandException("RDMA listen failed"); } L_(debug) << "waiting for " << count << " connections"; }
void bind( boost::asio::ip::tcp::endpoint const & ep , boost::system::error_code &ec) { if(event_channel_) { HPX_IBVERBS_THROWS_IF(ec, boost::asio::error::already_connected); } else { event_channel_ = rdma_create_event_channel(); if(!event_channel_) { int verrno = errno; close(ec); boost::system::error_code err(verrno, boost::system::system_category()); HPX_IBVERBS_THROWS_IF( ec , err ); return; } set_nonblocking(event_channel_->fd, ec); if(ec) { close(ec); return; } int ret = 0; ret = rdma_create_id(event_channel_, &listener_, NULL, RDMA_PS_TCP); if(ret) { int verrno = errno; close(ec); boost::system::error_code err(verrno, boost::system::system_category()); HPX_IBVERBS_THROWS_IF( ec , err ); return; } std::string host = ep.address().to_string(); std::string port = boost::lexical_cast<std::string>(ep.port()); addrinfo *addr; getaddrinfo(host.c_str(), port.c_str(), NULL, &addr); ret = rdma_bind_addr(listener_, addr->ai_addr); freeaddrinfo(addr); if(ret) { int verrno = errno; close(ec); boost::system::error_code err(verrno, boost::system::system_category()); HPX_IBVERBS_THROWS_IF( ec , err ); return; } ret = rdma_listen(listener_, 10); /* backlog = 10 is arbitrary */ if(ret) { int verrno = errno; close(ec); boost::system::error_code err(verrno, boost::system::system_category()); HPX_IBVERBS_THROWS_IF( ec , err ); return; } HPX_IBVERBS_RESET_EC(ec); } }
static int p9_rdma_bind_privport(struct p9_trans_rdma *rdma) { struct sockaddr_in cl = { .sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_ANY), }; int port, err = -EINVAL; for (port = P9_DEF_MAX_RESVPORT; port >= P9_DEF_MIN_RESVPORT; port--) { cl.sin_port = htons((ushort)port); err = rdma_bind_addr(rdma->cm_id, (struct sockaddr *)&cl); if (err != -EADDRINUSE) break; } return err; } /** * trans_create_rdma - Transport method for creating atransport instance * @client: client instance * @addr: IP address string * @args: Mount options string */ static int rdma_create_trans(struct p9_client *client, const char *addr, char *args) { int err; struct p9_rdma_opts opts; struct p9_trans_rdma *rdma; struct rdma_conn_param conn_param; struct ib_qp_init_attr qp_attr; struct ib_device_attr devattr; struct ib_cq_init_attr cq_attr = {}; /* Parse the transport specific mount options */ err = parse_opts(args, &opts); if (err < 0) return err; /* Create and initialize the RDMA transport structure */ rdma = alloc_rdma(&opts); if (!rdma) return -ENOMEM; /* Create the RDMA CM ID */ rdma->cm_id = rdma_create_id(p9_cm_event_handler, client, RDMA_PS_TCP, IB_QPT_RC); if (IS_ERR(rdma->cm_id)) goto error; /* Associate the client with the transport */ client->trans = rdma; /* Bind to a privileged port if we need to */ if (opts.privport) { err = p9_rdma_bind_privport(rdma); if (err < 0) { pr_err("%s (%d): problem binding to privport: %d\n", __func__, task_pid_nr(current), -err); goto error; } } /* Resolve the server's address */ rdma->addr.sin_family = AF_INET; rdma->addr.sin_addr.s_addr = in_aton(addr); rdma->addr.sin_port = htons(opts.port); err = rdma_resolve_addr(rdma->cm_id, NULL, (struct sockaddr *)&rdma->addr, rdma->timeout); if (err) goto error; err = wait_for_completion_interruptible(&rdma->cm_done); if (err || (rdma->state != P9_RDMA_ADDR_RESOLVED)) goto error; /* Resolve the route to the server */ err = rdma_resolve_route(rdma->cm_id, rdma->timeout); if (err) goto error; err = wait_for_completion_interruptible(&rdma->cm_done); if (err || (rdma->state != P9_RDMA_ROUTE_RESOLVED)) goto error; /* Query the device attributes */ err = ib_query_device(rdma->cm_id->device, &devattr); if (err) goto error; /* Create the Completion Queue */ cq_attr.cqe = opts.sq_depth + opts.rq_depth + 1; rdma->cq = ib_create_cq(rdma->cm_id->device, cq_comp_handler, cq_event_handler, client, &cq_attr); if (IS_ERR(rdma->cq)) goto error; ib_req_notify_cq(rdma->cq, IB_CQ_NEXT_COMP); /* Create the Protection Domain */ rdma->pd = ib_alloc_pd(rdma->cm_id->device); if (IS_ERR(rdma->pd)) goto error; /* Cache the DMA lkey in the transport */ rdma->dma_mr = NULL; if (devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY) rdma->lkey = rdma->cm_id->device->local_dma_lkey; else { rdma->dma_mr = ib_get_dma_mr(rdma->pd, IB_ACCESS_LOCAL_WRITE); if (IS_ERR(rdma->dma_mr)) goto error; rdma->lkey = rdma->dma_mr->lkey; } /* Create the Queue Pair */ memset(&qp_attr, 0, sizeof qp_attr); qp_attr.event_handler = qp_event_handler; qp_attr.qp_context = client; qp_attr.cap.max_send_wr = opts.sq_depth; qp_attr.cap.max_recv_wr = opts.rq_depth; qp_attr.cap.max_send_sge = P9_RDMA_SEND_SGE; qp_attr.cap.max_recv_sge = P9_RDMA_RECV_SGE; qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR; qp_attr.qp_type = IB_QPT_RC; qp_attr.send_cq = rdma->cq; qp_attr.recv_cq = rdma->cq; err = rdma_create_qp(rdma->cm_id, rdma->pd, &qp_attr); if (err) goto error; rdma->qp = rdma->cm_id->qp; /* Request a connection */ memset(&conn_param, 0, sizeof(conn_param)); conn_param.private_data = NULL; conn_param.private_data_len = 0; conn_param.responder_resources = P9_RDMA_IRD; conn_param.initiator_depth = P9_RDMA_ORD; err = rdma_connect(rdma->cm_id, &conn_param); if (err) goto error; err = wait_for_completion_interruptible(&rdma->cm_done); if (err || (rdma->state != P9_RDMA_CONNECTED)) goto error; client->status = Connected; return 0; error: rdma_destroy_trans(rdma); return -ENOTCONN; }
struct xfer_context *xfer_rdma_server_connect(struct xfer_data *data) { struct addrinfo *res; struct addrinfo hints = { .ai_flags = AI_PASSIVE, .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM }; char *service; int n; struct rdma_cm_event *event; struct sockaddr_in sin; struct xfer_context *ctx = NULL; struct rdma_cm_id *child_cm_id; struct rdma_conn_param conn_param; if (asprintf(&service, "%d", data->port) < 0) goto err5; if ( (n = getaddrinfo(NULL, service, &hints, &res)) < 0 ) { fprintf(stderr, "%d:%s: %s for port %d\n", pid, __func__, gai_strerror(n), data->port); goto err5; } if (data->use_cma) { sin.sin_addr.s_addr = 0; sin.sin_family = AF_INET; sin.sin_port = htons(data->port); if (rdma_bind_addr(data->cm_id, (struct sockaddr *)&sin)) { fprintf(stderr, "%d:%s: rdma_bind_addr failed\n", pid, __func__); goto err3; } if (rdma_listen(data->cm_id, 0)) { fprintf(stderr, "%d:%s: rdma_listen failed\n", pid, __func__); goto err3; } if (rdma_get_cm_event(data->cm_channel, &event)) goto err3; if (event->event != RDMA_CM_EVENT_CONNECT_REQUEST) { fprintf(stderr, "%d:%s: bad event waiting for connect request %d\n", pid, __func__, event->event); goto err2; } if (event->param.conn.private_data && (event->param.conn.private_data_len > 0)) { data->remote_priv = malloc(event->param.conn.private_data_len); if (!data->remote_priv) goto err1; memcpy(data->remote_priv, event->param.conn.private_data, event->param.conn.private_data_len); } child_cm_id = (struct rdma_cm_id *)event->id; ctx = xfer_rdma_init_ctx(child_cm_id, data); if (!ctx) { goto err2; } memset(&conn_param, 0, sizeof conn_param); conn_param.responder_resources = 16; conn_param.initiator_depth = 16; conn_param.private_data = data->local_priv; conn_param.private_data_len = data->local_priv_size; if (rdma_accept(child_cm_id, &conn_param)) { fprintf(stderr, "%d:%s: rdma_accept failed\n", pid, __func__); goto err1; } rdma_ack_cm_event(event); if (rdma_get_cm_event(data->cm_channel, &event)) { fprintf(stderr, "%d:%s: rdma_get_cm_event error\n", pid, __func__); rdma_destroy_id(child_cm_id); goto err3; } if (event->event != RDMA_CM_EVENT_ESTABLISHED) { fprintf(stderr, "%d:%s: bad event waiting for established %d\n", pid, __func__, event->event); goto err1; } rdma_ack_cm_event(event); } else { // use an alternative to CMA here } freeaddrinfo(res); return ctx; err1: rdma_destroy_id(child_cm_id); err2: rdma_ack_cm_event(event); err3: rdma_destroy_id(data->cm_id); rdma_destroy_event_channel(data->cm_channel); err5: return NULL; }
int main(int argc, char *argv[]) { struct pdata rep_pdata; struct rdma_event_channel *cm_channel; struct rdma_cm_id *listen_id; struct rdma_cm_id *cm_id; struct rdma_cm_event *event; struct rdma_conn_param conn_param = { }; struct ibv_pd *pd; struct ibv_comp_channel *comp_chan; struct ibv_cq *cq; struct ibv_cq *evt_cq; struct ibv_mr *mr; struct ibv_qp_init_attr qp_attr = { }; struct ibv_sge sge; struct ibv_send_wr send_wr = { }; struct ibv_send_wr *bad_send_wr; struct ibv_recv_wr recv_wr = { }; struct ibv_recv_wr *bad_recv_wr; struct ibv_wc wc; void *cq_context; struct sockaddr_in sin; uint32_t *buf; int err; /* Set up RDMA CM structures */ cm_channel = rdma_create_event_channel(); if (!cm_channel) return 1; err = rdma_create_id(cm_channel, &listen_id, NULL, RDMA_PS_TCP); if (err) return err; sin.sin_family = AF_INET; sin.sin_port = htons(20079); sin.sin_addr.s_addr = INADDR_ANY; /* Bind to local port and listen for connection request */ err = rdma_bind_addr(listen_id, (struct sockaddr *) &sin); if (err) return 1; err = rdma_listen(listen_id, 1); if (err) return 1; err = rdma_get_cm_event(cm_channel, &event); if (err) return err; printf("after get_cm_event\n"); if (event->event != RDMA_CM_EVENT_CONNECT_REQUEST) return 1; cm_id = event->id; rdma_ack_cm_event(event); /* Create verbs objects now that we know which device to use */ pd = ibv_alloc_pd(cm_id->verbs); if (!pd) return 1; comp_chan = ibv_create_comp_channel(cm_id->verbs); if (!comp_chan) return 1; cq = ibv_create_cq(cm_id->verbs, 2, NULL, comp_chan, 0); if (!cq) return 1; if (ibv_req_notify_cq(cq, 0)) return 1; buf = calloc(2, sizeof(uint32_t)); if (!buf) return 1; mr = ibv_reg_mr(pd, buf, 2 * sizeof(uint32_t), IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ | IBV_ACCESS_REMOTE_WRITE); if (!mr) return 1; qp_attr.cap.max_send_wr = 1; qp_attr.cap.max_send_sge = 1; qp_attr.cap.max_recv_wr = 1; qp_attr.cap.max_recv_sge = 1; qp_attr.send_cq = cq; qp_attr.recv_cq = cq; qp_attr.qp_type = IBV_QPT_RC; err = rdma_create_qp(cm_id, pd, &qp_attr); if (err) return err; /* Post receive before accepting connection */ sge.addr = (uintptr_t) buf + sizeof(uint32_t); sge.length = sizeof(uint32_t); sge.lkey = mr->lkey; recv_wr.sg_list = &sge; recv_wr.num_sge = 1; if (ibv_post_recv(cm_id->qp, &recv_wr, &bad_recv_wr)) return 1; rep_pdata.buf_va = htonll((uintptr_t) buf); rep_pdata.buf_rkey = htonl(mr->rkey); conn_param.responder_resources = 1; conn_param.private_data = &rep_pdata; conn_param.private_data_len = sizeof rep_pdata; /* Accept connection */ printf("before accept\n"); err = rdma_accept(cm_id, &conn_param); if (err) return 1; printf("after accept\n"); err = rdma_get_cm_event(cm_channel, &event); if (err) return err; if (event->event != RDMA_CM_EVENT_ESTABLISHED) return 1; rdma_ack_cm_event(event); /* Wait for receive completion */ if (ibv_get_cq_event(comp_chan, &evt_cq, &cq_context)) return 1; if (ibv_req_notify_cq(cq, 0)) return 1; if (ibv_poll_cq(cq, 1, &wc) < 1) return 1; if (wc.status != IBV_WC_SUCCESS) return 1; /* Add two integers and send reply back */ buf[0] = htonl(ntohl(buf[0]) + ntohl(buf[1])); sge.addr = (uintptr_t) buf; sge.length = sizeof(uint32_t); sge.lkey = mr->lkey; send_wr.opcode = IBV_WR_SEND; send_wr.send_flags = IBV_SEND_SIGNALED; send_wr.sg_list = &sge; send_wr.num_sge = 1; if (ibv_post_send(cm_id->qp, &send_wr, &bad_send_wr)) return 1; /* Wait for send completion */ if (ibv_get_cq_event(comp_chan, &evt_cq, &cq_context)) return 1; if (ibv_poll_cq(cq, 1, &wc) < 1) return 1; if (wc.status != IBV_WC_SUCCESS) return 1; printf("before ack cq 2\n"); ibv_ack_cq_events(cq, 2); return 0; }
static int run_server(void) { struct rdma_cm_id *listen_id; int i, ret; printf("cmatose: starting server\n"); ret = rdma_create_id(test.channel, &listen_id, &test, hints.ai_port_space); if (ret) { perror("cmatose: listen request failed"); return ret; } ret = get_rdma_addr(src_addr, dst_addr, port, &hints, &test.rai); if (ret) { printf("cmatose: getrdmaaddr error: %s\n", gai_strerror(ret)); goto out; } ret = rdma_bind_addr(listen_id, test.rai->ai_src_addr); if (ret) { perror("cmatose: bind address failed"); goto out; } ret = rdma_listen(listen_id, 0); if (ret) { perror("cmatose: failure trying to listen"); goto out; } ret = connect_events(); if (ret) goto out; if (message_count) { printf("initiating data transfers\n"); for (i = 0; i < connections; i++) { ret = post_sends(&test.nodes[i]); if (ret) goto out; } printf("completing sends\n"); ret = poll_cqs(SEND_CQ_INDEX); if (ret) goto out; printf("receiving data transfers\n"); ret = poll_cqs(RECV_CQ_INDEX); if (ret) goto out; printf("data transfers complete\n"); } if (migrate) { ret = migrate_channel(listen_id); if (ret) goto out; } printf("cmatose: disconnecting\n"); for (i = 0; i < connections; i++) { if (!test.nodes[i].connected) continue; test.nodes[i].connected = 0; rdma_disconnect(test.nodes[i].cma_id); } ret = disconnect_events(); printf("disconnected\n"); out: rdma_destroy_id(listen_id); return ret; }
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; if (argc != 2) 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]); 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 (1) { // pthread_t thread_id; // pthread_attr_t thread_attr; // simple_context_t *context = NULL; // struct rdma_cm_id *id = NULL; int rc =0; fprintf(stderr, "Waiting for cm_event... "); if ((rc = rdma_get_cm_event(ec, &event))){ fprintf(stderr, "get event failed : %d\n", rc); break; } fprintf(stderr, "\"%s\"\n", event_type_str(event->event)); switch (event->event){ case RDMA_CM_EVENT_CONNECT_REQUEST: accept_connection(event->id); break; case RDMA_CM_EVENT_ESTABLISHED: on_connect(event->id->context); // pthread_attr_init(&thread_attr); // pthread_create(&thread_id, // &thread_attr, // handle_server_cq, // (void *)(event->id->context)); break; case RDMA_CM_EVENT_DISCONNECTED: fprintf(stderr, "Disconnect from id : %p \n", event->id); // fprintf(stderr, "Disconnect from id : %p (total connections %d)\n", // event->id, connections); // context = (simple_context_t *)(event->id->context); // id = event->id; break; default: break; } rdma_ack_cm_event(event); // if (context){ // context->quit_cq_thread = 1; // pthread_join(thread_id, NULL); // rdma_destroy_id(id); // free_connection(context); // context = NULL; // } } rdma_destroy_id(listener); rdma_destroy_event_channel(ec); return 0; /* 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; */ }
static int run(void) { int i, ret; printf("mckey: starting %s\n", is_sender ? "client" : "server"); if (src_addr) { ret = get_addr(src_addr, (struct sockaddr *) &test.src_in); if (ret) return ret; } ret = get_addr(dst_addr, (struct sockaddr *) &test.dst_in); if (ret) return ret; printf("mckey: joining\n"); for (i = 0; i < connections; i++) { if (src_addr) { ret = rdma_bind_addr(test.nodes[i].cma_id, test.src_addr); if (ret) { perror("mckey: addr bind failure"); connect_error(); return ret; } } if (unmapped_addr) ret = addr_handler(&test.nodes[i]); else ret = rdma_resolve_addr(test.nodes[i].cma_id, test.src_addr, test.dst_addr, 2000); if (ret) { perror("mckey: resolve addr failure"); connect_error(); return ret; } } ret = connect_events(); if (ret) goto out; pthread_create(&test.cmathread, NULL, cma_thread, NULL); /* * Pause to give SM chance to configure switches. We don't want to * handle reliability issue in this simple test program. */ sleep(3); if (message_count) { if (is_sender) { printf("initiating data transfers\n"); for (i = 0; i < connections; i++) { ret = post_sends(&test.nodes[i], 0); if (ret) goto out; } } else { printf("receiving data transfers\n"); ret = poll_cqs(); if (ret) goto out; } printf("data transfers complete\n"); } out: for (i = 0; i < connections; i++) { ret = rdma_leave_multicast(test.nodes[i].cma_id, test.dst_addr); if (ret) perror("mckey: failure leaving"); } return ret; }
/* * Create a listening RDMA service endpoint. */ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, struct net *net, struct sockaddr *sa, int salen, int flags) { struct rdma_cm_id *listen_id; struct svcxprt_rdma *cma_xprt; int ret; dprintk("svcrdma: Creating RDMA listener\n"); if ((sa->sa_family != AF_INET) && (sa->sa_family != AF_INET6)) { dprintk("svcrdma: Address family %d is not supported.\n", sa->sa_family); return ERR_PTR(-EAFNOSUPPORT); } cma_xprt = svc_rdma_create_xprt(serv, net); if (!cma_xprt) return ERR_PTR(-ENOMEM); set_bit(XPT_LISTENER, &cma_xprt->sc_xprt.xpt_flags); strcpy(cma_xprt->sc_xprt.xpt_remotebuf, "listener"); listen_id = rdma_create_id(net, rdma_listen_handler, cma_xprt, RDMA_PS_TCP, IB_QPT_RC); if (IS_ERR(listen_id)) { ret = PTR_ERR(listen_id); dprintk("svcrdma: rdma_create_id failed = %d\n", ret); goto err0; } /* Allow both IPv4 and IPv6 sockets to bind a single port * at the same time. */ #if IS_ENABLED(CONFIG_IPV6) ret = rdma_set_afonly(listen_id, 1); if (ret) { dprintk("svcrdma: rdma_set_afonly failed = %d\n", ret); goto err1; } #endif ret = rdma_bind_addr(listen_id, sa); if (ret) { dprintk("svcrdma: rdma_bind_addr failed = %d\n", ret); goto err1; } cma_xprt->sc_cm_id = listen_id; ret = rdma_listen(listen_id, RPCRDMA_LISTEN_BACKLOG); if (ret) { dprintk("svcrdma: rdma_listen failed = %d\n", ret); goto err1; } /* * We need to use the address from the cm_id in case the * caller specified 0 for the port number. */ sa = (struct sockaddr *)&cma_xprt->sc_cm_id->route.addr.src_addr; svc_xprt_set_local(&cma_xprt->sc_xprt, sa, salen); return &cma_xprt->sc_xprt; err1: rdma_destroy_id(listen_id); err0: kfree(cma_xprt); return ERR_PTR(ret); }
/****************************************************************************** + * + ******************************************************************************/ int rdma_server_connect(struct pingpong_context *ctx, struct perftest_parameters *user_param) { int temp; struct addrinfo *res; struct rdma_cm_event *event; struct rdma_conn_param conn_param; struct addrinfo hints; char *service; struct sockaddr_in sin; memset(&hints, 0, sizeof hints); hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if (check_add_port(&service,user_param->port,user_param->servername,&hints,&res)) { fprintf(stderr, "Problem in resolving basic adress and port\n"); return FAILURE; } sin.sin_addr.s_addr = 0; sin.sin_family = PF_INET; sin.sin_port = htons((unsigned short)user_param->port); if (rdma_bind_addr(ctx->cm_id_control,(struct sockaddr *)&sin)) { fprintf(stderr," rdma_bind_addr failed\n"); return 1; } if (rdma_listen(ctx->cm_id_control,0)) { fprintf(stderr, "rdma_listen failed\n"); return 1; } if (rdma_get_cm_event(ctx->cm_channel,&event)) { fprintf(stderr, "rdma_get_cm_events failed\n"); return 1; } if (event->event != RDMA_CM_EVENT_CONNECT_REQUEST) { fprintf(stderr, "bad event waiting for connect request %d\n",event->event); return 1; } ctx->cm_id = (struct rdma_cm_id*)event->id; ctx->context = ctx->cm_id->verbs; if (user_param->work_rdma_cm == ON) alloc_ctx(ctx,user_param); temp = user_param->work_rdma_cm; user_param->work_rdma_cm = ON; if (ctx_init(ctx,user_param)) { fprintf(stderr," Unable to create the resources needed by comm struct\n"); return FAILURE; } memset(&conn_param, 0, sizeof conn_param); if (user_param->verb == READ || user_param->verb == ATOMIC) { conn_param.responder_resources = user_param->out_reads; conn_param.initiator_depth = user_param->out_reads; } if (user_param->connection_type == UD) conn_param.qp_num = ctx->qp[0]->qp_num; conn_param.retry_count = user_param->retry_count; conn_param.rnr_retry_count = 7; user_param->work_rdma_cm = temp; if (user_param->work_rdma_cm == OFF) { if (post_one_recv_wqe(ctx)) { fprintf(stderr, "Couldn't post send \n"); return 1; } } else if (user_param->connection_type == UD) { if (user_param->tst == LAT || (user_param->tst == BW && user_param->duplex)) { if (post_recv_to_get_ah(ctx)) { fprintf(stderr, "Couldn't post send \n"); return 1; } } } if (rdma_accept(ctx->cm_id, &conn_param)) { fprintf(stderr, "Function rdma_accept failed\n"); return 1; } if (user_param->work_rdma_cm && user_param->connection_type == UD) { if (user_param->tst == LAT || (user_param->tst == BW && user_param->duplex)) { if (create_ah_from_wc_recv(ctx,user_param)) { fprintf(stderr, "Unable to create AH from WC\n"); return 1; } } } rdma_ack_cm_event(event); rdma_destroy_id(ctx->cm_id_control); freeaddrinfo(res); return 0; }