static struct fi_info * fi_ibv_eq_cm_getinfo(struct fi_ibv_fabric *fab, struct rdma_cm_event *event, struct fi_info *pep_info) { struct fi_info *info, *fi; struct fi_ibv_connreq *connreq; const char *devname = ibv_get_device_name(event->id->verbs->device); if (strcmp(devname, fab->info->domain_attr->name)) { fi = fi_ibv_get_verbs_info(fab->all_infos, devname); if (!fi) return NULL; } else { fi = fab->info; } info = fi_dupinfo(fi); if (!info) return NULL; info->fabric_attr->fabric = &fab->util_fabric.fabric_fid; if (!(info->fabric_attr->prov_name = strdup(VERBS_PROV_NAME))) goto err; ofi_alter_info(info, pep_info, fab->util_fabric.fabric_fid.api_version); info->src_addrlen = fi_ibv_sockaddr_len(rdma_get_local_addr(event->id)); if (!(info->src_addr = malloc(info->src_addrlen))) goto err; memcpy(info->src_addr, rdma_get_local_addr(event->id), info->src_addrlen); info->dest_addrlen = fi_ibv_sockaddr_len(rdma_get_peer_addr(event->id)); if (!(info->dest_addr = malloc(info->dest_addrlen))) goto err; memcpy(info->dest_addr, rdma_get_peer_addr(event->id), info->dest_addrlen); VERBS_INFO(FI_LOG_CORE, "src_addr: %s:%d\n", inet_ntoa(((struct sockaddr_in *)info->src_addr)->sin_addr), ntohs(((struct sockaddr_in *)info->src_addr)->sin_port)); VERBS_INFO(FI_LOG_CORE, "dst_addr: %s:%d\n", inet_ntoa(((struct sockaddr_in *)info->dest_addr)->sin_addr), ntohs(((struct sockaddr_in *)info->dest_addr)->sin_port)); connreq = calloc(1, sizeof *connreq); if (!connreq) goto err; connreq->handle.fclass = FI_CLASS_CONNREQ; connreq->id = event->id; info->handle = &connreq->handle; return info; err: fi_freeinfo(info); return NULL; }
/* TODO: This should copy the listening fi_info as the base */ static struct fi_info * fi_ibv_eq_cm_getinfo(struct fi_ibv_fabric *fab, struct rdma_cm_event *event) { struct fi_info *info, *fi; struct fi_ibv_connreq *connreq; fi = fi_ibv_get_verbs_info(ibv_get_device_name(event->id->verbs->device)); if (!fi) return NULL; info = fi_dupinfo(fi); if (!info) return NULL; info->fabric_attr->fabric = &fab->fabric_fid; if (!(info->fabric_attr->prov_name = strdup(VERBS_PROV_NAME))) goto err; fi_ibv_update_info(NULL, info); info->src_addrlen = fi_ibv_sockaddr_len(rdma_get_local_addr(event->id)); if (!(info->src_addr = malloc(info->src_addrlen))) goto err; memcpy(info->src_addr, rdma_get_local_addr(event->id), info->src_addrlen); info->dest_addrlen = fi_ibv_sockaddr_len(rdma_get_peer_addr(event->id)); if (!(info->dest_addr = malloc(info->dest_addrlen))) goto err; memcpy(info->dest_addr, rdma_get_peer_addr(event->id), info->dest_addrlen); FI_INFO(&fi_ibv_prov, FI_LOG_CORE, "src_addr: %s:%d\n", inet_ntoa(((struct sockaddr_in *)info->src_addr)->sin_addr), ntohs(((struct sockaddr_in *)info->src_addr)->sin_port)); FI_INFO(&fi_ibv_prov, FI_LOG_CORE, "dst_addr: %s:%d\n", inet_ntoa(((struct sockaddr_in *)info->dest_addr)->sin_addr), ntohs(((struct sockaddr_in *)info->dest_addr)->sin_port)); connreq = calloc(1, sizeof *connreq); if (!connreq) goto err; connreq->handle.fclass = FI_CLASS_CONNREQ; connreq->id = event->id; info->handle = &connreq->handle; return info; err: fi_freeinfo(info); return NULL; }
int fi_ibv_accept_xrc(struct fi_ibv_xrc_ep *ep, int reciprocal, void *param, size_t paramlen) { struct sockaddr *addr; struct fi_ibv_connreq *connreq; struct rdma_conn_param conn_param = { 0 }; struct fi_ibv_xrc_cm_data *cm_data = param; int ret; addr = rdma_get_local_addr(ep->tgt_id); if (addr) ofi_straddr_dbg(&fi_ibv_prov, FI_LOG_CORE, "src_addr", addr); addr = rdma_get_peer_addr(ep->tgt_id); if (addr) ofi_straddr_dbg(&fi_ibv_prov, FI_LOG_CORE, "dest_addr", addr); connreq = container_of(ep->base_ep.info->handle, struct fi_ibv_connreq, handle); ret = fi_ibv_ep_create_tgt_qp(ep, connreq->xrc.conn_data); if (ret) return ret; fi_ibv_set_xrc_cm_data(cm_data, connreq->xrc.is_reciprocal, connreq->xrc.conn_tag, connreq->xrc.port, ep->srqn); conn_param.private_data = cm_data; conn_param.private_data_len = paramlen; conn_param.responder_resources = RDMA_MAX_RESP_RES; conn_param.initiator_depth = RDMA_MAX_INIT_DEPTH; conn_param.flow_control = 1; conn_param.rnr_retry_count = 7; if (ep->base_ep.srq_ep) conn_param.srq = 1; /* Shared INI/TGT QP connection use a temporarily reserved QP number * avoid the appearance of being a stale/duplicate IB CM message */ if (!ep->tgt_id->qp) conn_param.qp_num = ep->conn_setup->rsvd_tgt_qpn->qp_num; if (connreq->xrc.is_reciprocal) fi_ibv_eq_clear_xrc_conn_tag(ep); else ep->conn_setup->conn_tag = connreq->xrc.conn_tag; assert(ep->conn_state == FI_IBV_XRC_UNCONNECTED || ep->conn_state == FI_IBV_XRC_ORIG_CONNECTED); fi_ibv_next_xrc_conn_state(ep); ret = rdma_accept(ep->tgt_id, &conn_param); if (ret) { ret = -errno; VERBS_INFO_ERRNO(FI_LOG_EP_CTRL, "XRC TGT, ibv_open_qp", errno); fi_ibv_prev_xrc_conn_state(ep); } free(connreq); return ret; }
static int fi_ibv_msg_ep_getname(fid_t ep, void *addr, size_t *addrlen) { struct fi_ibv_msg_ep *_ep; struct sockaddr *sa; _ep = container_of(ep, struct fi_ibv_msg_ep, ep_fid); sa = rdma_get_local_addr(_ep->id); return fi_ibv_copy_addr(addr, addrlen, sa); }
static struct fi_info * __fi_eq_cm_getinfo(struct __fid_fabric *fab, struct rdma_cm_event *event) { struct fi_info *fi; fi = calloc(1, sizeof *fi); if (!fi) return NULL; fi->type = FID_MSG; if (event->id->verbs->device->transport_type == IBV_TRANSPORT_IWARP) { fi->protocol = FI_PROTO_IWARP; } else { fi->protocol = FI_PROTO_IB_RC; } fi->ep_cap = FI_MSG | FI_RMA; fi->src_addrlen = fi_sockaddr_len(rdma_get_local_addr(event->id)); if (!(fi->src_addr = malloc(fi->src_addrlen))) goto err; memcpy(fi->src_addr, rdma_get_local_addr(event->id), fi->src_addrlen); fi->dest_addrlen = fi_sockaddr_len(rdma_get_peer_addr(event->id)); if (!(fi->dest_addr = malloc(fi->dest_addrlen))) goto err; memcpy(fi->dest_addr, rdma_get_peer_addr(event->id), fi->dest_addrlen); if (!(fi->fabric_name = strdup(fab->name))) goto err; if (!(fi->domain_name = strdup(event->id->verbs->device->name))) goto err; fi->datalen = sizeof event->id; fi->data = event->id; return fi; err: fi_freeinfo(fi); return NULL; }
/* * svc_rdma_ncreate: waits for connection request and returns transport */ SVCXPRT * svc_rdma_ncreate(void *arg, const u_int sendsize, const u_int recvsize, const u_int flags) { struct svc_rdma_xdr *sm; struct sockaddr_storage *ss; RDMAXPRT *l_xprt = arg; RDMAXPRT *xprt = rpc_rdma_accept_wait(l_xprt, l_xprt->xa->timeout); if (!xprt) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s:%u ERROR (return)", __func__, __LINE__); return (NULL); } sm = mem_zalloc(sizeof (*sm)); sm->sm_xdrs.x_lib[1] = xprt; xprt->xprt.xp_p2 = sm; xprt->xprt.xp_flags = flags; /* fixme: put something here, but make it not work on fd operations. */ xprt->xprt.xp_fd = -1; ss = (struct sockaddr_storage *)rdma_get_local_addr(xprt->cm_id); __rpc_set_address(&xprt->xprt.xp_local, ss, 0); ss = (struct sockaddr_storage *)rdma_get_peer_addr(xprt->cm_id); __rpc_set_address(&xprt->xprt.xp_remote, ss, 0); svc_rdma_ops(&xprt->xprt); if (xdr_rdma_create(&sm->sm_xdrs, xprt, sendsize, recvsize, flags)) { goto freedata; } if (rpc_rdma_accept_finalize(xprt)) { goto freedata; } return (&xprt->xprt); freedata: mem_free(sm, sizeof (*sm)); xprt->xprt.xp_p2 = NULL; xprt_unregister(&xprt->xprt); return (NULL); }
static int fi_ibv_pep_listen(struct fid_pep *pep_fid) { struct fi_ibv_pep *pep; struct sockaddr *addr; pep = container_of(pep_fid, struct fi_ibv_pep, pep_fid); addr = rdma_get_local_addr(pep->id); if (addr) { FI_INFO(&fi_ibv_prov, FI_LOG_CORE, "Listening on %s:%d\n", inet_ntoa(((struct sockaddr_in *)addr)->sin_addr), ntohs(((struct sockaddr_in *)addr)->sin_port)); } return rdma_listen(pep->id, pep->backlog) ? -errno : 0; }
void fi_ibv_log_ep_conn(struct fi_ibv_xrc_ep *ep, char *desc) { struct sockaddr *addr; char buf[OFI_ADDRSTRLEN]; size_t len = sizeof(buf); if (!fi_log_enabled(&fi_ibv_prov, FI_LOG_INFO, FI_LOG_FABRIC)) return; VERBS_INFO(FI_LOG_FABRIC, "EP %p, %s\n", ep, desc); VERBS_INFO(FI_LOG_FABRIC, "EP %p, CM ID %p, TGT CM ID %p, SRQN %d Peer SRQN %d\n", ep, ep->base_ep.id, ep->tgt_id, ep->srqn, ep->peer_srqn); assert(ep->base_ep.id); addr = rdma_get_local_addr(ep->base_ep.id); if (addr) { ofi_straddr(buf, &len, ep->base_ep.info->addr_format, addr); VERBS_INFO(FI_LOG_FABRIC, "EP %p src_addr: %s\n", ep, buf); } addr = rdma_get_peer_addr(ep->base_ep.id); if (addr) { len = sizeof(buf); ofi_straddr(buf, &len, ep->base_ep.info->addr_format, addr); VERBS_INFO(FI_LOG_FABRIC, "EP %p dst_addr: %s\n", ep, buf); } if (ep->base_ep.ibv_qp) { VERBS_INFO(FI_LOG_FABRIC, "EP %p, INI QP Num %d\n", ep, ep->base_ep.ibv_qp->qp_num); VERBS_INFO(FI_LOG_FABRIC, "EP %p, Remote TGT QP Num %d\n", ep, ep->ini_conn->tgt_qpn); } if (ep->tgt_ibv_qp) VERBS_INFO(FI_LOG_FABRIC, "EP %p, TGT QP Num %d\n", ep, ep->tgt_ibv_qp->qp_num); if (ep->conn_setup && ep->conn_setup->rsvd_ini_qpn) VERBS_INFO(FI_LOG_FABRIC, "EP %p, Reserved INI QPN %d\n", ep, ep->conn_setup->rsvd_ini_qpn->qp_num); if (ep->conn_setup && ep->conn_setup->rsvd_tgt_qpn) VERBS_INFO(FI_LOG_FABRIC, "EP %p, Reserved TGT QPN %d\n", ep, ep->conn_setup->rsvd_tgt_qpn->qp_num); }
static int fi_ibv_msg_ep_connect(struct fid_ep *ep, const void *addr, const void *param, size_t paramlen) { struct fi_ibv_msg_ep *_ep; struct rdma_conn_param conn_param; struct sockaddr *src_addr, *dst_addr; int ret; _ep = container_of(ep, struct fi_ibv_msg_ep, ep_fid); if (!_ep->id->qp) { ret = ep->fid.ops->control(&ep->fid, FI_ENABLE, NULL); if (ret) return ret; } memset(&conn_param, 0, sizeof conn_param); conn_param.private_data = param; conn_param.private_data_len = paramlen; conn_param.responder_resources = RDMA_MAX_RESP_RES; conn_param.initiator_depth = RDMA_MAX_INIT_DEPTH; conn_param.flow_control = 1; conn_param.retry_count = 15; conn_param.rnr_retry_count = 7; if (_ep->srq_ep) conn_param.srq = 1; src_addr = rdma_get_local_addr(_ep->id); if (src_addr) { FI_INFO(&fi_ibv_prov, FI_LOG_CORE, "src_addr: %s:%d\n", inet_ntoa(((struct sockaddr_in *)src_addr)->sin_addr), ntohs(((struct sockaddr_in *)src_addr)->sin_port)); } dst_addr = rdma_get_peer_addr(_ep->id); if (dst_addr) { FI_INFO(&fi_ibv_prov, FI_LOG_CORE, "dst_addr: %s:%d\n", inet_ntoa(((struct sockaddr_in *)dst_addr)->sin_addr), ntohs(((struct sockaddr_in *)dst_addr)->sin_port)); } return rdma_connect(_ep->id, &conn_param) ? -errno : 0; }
int fi_ibv_connect_xrc(struct fi_ibv_xrc_ep *ep, struct sockaddr *addr, int reciprocal, void *param, size_t paramlen) { struct fi_ibv_domain *domain = fi_ibv_ep_to_domain(&ep->base_ep); struct sockaddr *peer_addr; int ret; assert(ep->base_ep.id && !ep->base_ep.ibv_qp && !ep->ini_conn); peer_addr = rdma_get_local_addr(ep->base_ep.id); if (peer_addr) ofi_straddr_dbg(&fi_ibv_prov, FI_LOG_FABRIC, "XRC connect src_addr", peer_addr); peer_addr = rdma_get_peer_addr(ep->base_ep.id); if (peer_addr) ofi_straddr_dbg(&fi_ibv_prov, FI_LOG_FABRIC, "XRC connect dest_addr", peer_addr); if (!reciprocal) { ep->conn_setup = calloc(1, sizeof(*ep->conn_setup)); if (!ep->conn_setup) return -FI_ENOMEM; } fastlock_acquire(&domain->xrc.ini_mgmt_lock); ret = fi_ibv_get_shared_ini_conn(ep, &ep->ini_conn); if (ret) { VERBS_WARN(FI_LOG_FABRIC, "Get of shared XRC INI connection failed %d\n", ret); fastlock_release(&domain->xrc.ini_mgmt_lock); if (!reciprocal) { free(ep->conn_setup); ep->conn_setup = NULL; } return ret; } fi_ibv_add_pending_ini_conn(ep, reciprocal, param, paramlen); fi_ibv_sched_ini_conn(ep->ini_conn); fastlock_release(&domain->xrc.ini_mgmt_lock); return FI_SUCCESS; }
int fi_ibv_create_ep(const char *node, const char *service, uint64_t flags, const struct fi_info *hints, struct rdma_addrinfo **rai, struct rdma_cm_id **id) { struct rdma_addrinfo *_rai; struct sockaddr *local_addr; int ret; ret = fi_ibv_get_rdma_rai(node, service, flags, hints, &_rai); if (ret) { return ret; } ret = rdma_create_ep(id, _rai, NULL, NULL); if (ret) { VERBS_INFO_ERRNO(FI_LOG_FABRIC, "rdma_create_ep", errno); ret = -errno; goto err1; } if (rai && !_rai->ai_src_addr) { local_addr = rdma_get_local_addr(*id); _rai->ai_src_len = fi_ibv_sockaddr_len(local_addr); if (!(_rai->ai_src_addr = malloc(_rai->ai_src_len))) { ret = -FI_ENOMEM; goto err2; } memcpy(_rai->ai_src_addr, local_addr, _rai->ai_src_len); } if (rai) { *rai = _rai; } else { rdma_freeaddrinfo(_rai); } return ret; err2: rdma_destroy_ep(*id); err1: rdma_freeaddrinfo(_rai); return ret; }
int kiro_server_start (KiroServer *self, const char *address, const char *port, void *mem, size_t mem_size) { g_return_val_if_fail (self != NULL, -1); KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE (self); if (priv->base) { g_debug ("Server already started."); return -1; } if (!mem || mem_size == 0) { g_warning ("Invalid memory given to provide."); return -1; } struct rdma_addrinfo hints, *res_addrinfo; memset (&hints, 0, sizeof (hints)); hints.ai_port_space = RDMA_PS_IB; hints.ai_flags = RAI_PASSIVE; char *addr_c = g_strdup (address); char *port_c = g_strdup (port); int rtn = rdma_getaddrinfo (addr_c, port_c, &hints, &res_addrinfo); g_free (addr_c); g_free (port_c); if (rtn) { g_critical ("Failed to create address information: %s", strerror (errno)); return -1; } struct ibv_qp_init_attr qp_attr; memset (&qp_attr, 0, sizeof (qp_attr)); qp_attr.cap.max_send_wr = 10; qp_attr.cap.max_recv_wr = 10; qp_attr.cap.max_send_sge = 1; qp_attr.cap.max_recv_sge = 1; qp_attr.qp_context = priv->base; qp_attr.sq_sig_all = 1; if (rdma_create_ep (& (priv->base), res_addrinfo, NULL, &qp_attr)) { g_critical ("Endpoint creation failed: %s", strerror (errno)); g_free (res_addrinfo); return -1; } g_free (res_addrinfo); // No longer needed g_debug ("Endpoint created"); char *addr_local = NULL; struct sockaddr *src_addr = rdma_get_local_addr (priv->base); if (!src_addr) { addr_local = "NONE"; } else { addr_local = inet_ntoa (((struct sockaddr_in *)src_addr)->sin_addr); /* if(src_addr->sa_family == AF_INET) addr_local = &(((struct sockaddr_in*)src_addr)->sin_addr); else addr_local = &(((struct sockaddr_in6*)src_addr)->sin6_addr); */ } g_message ("Server bound to address %s:%s", addr_local, port); if (rdma_listen (priv->base, 0)) { g_critical ("Failed to put server into listening state: %s", strerror (errno)); rdma_destroy_ep (priv->base); return -1; } priv->mem = mem; priv->mem_size = mem_size; priv->ec = rdma_create_event_channel(); if (rdma_migrate_id (priv->base, priv->ec)) { g_critical ("Was unable to migrate connection to new Event Channel: %s", strerror (errno)); rdma_destroy_ep (priv->base); return -1; } priv->main_loop = g_main_loop_new (NULL, FALSE); priv->conn_ec = g_io_channel_unix_new (priv->ec->fd); g_io_add_watch (priv->conn_ec, G_IO_IN | G_IO_PRI, process_cm_event, (gpointer)priv); priv->main_thread = g_thread_new ("KIRO Server main loop", start_server_main_loop, priv->main_loop); // We gave control to the main_loop (with add_watch) and don't need our ref // any longer g_io_channel_unref (priv->conn_ec); g_message ("Enpoint listening"); return 0; }
static int xrc_test(void) { struct rdma_cm_id *conn_id, *lookup_id; struct ibv_qp_init_attr attr; struct rdma_conn_param param; struct rdma_cm_event *event; struct ibv_wc wc; int ret; conn_id = xrc_listen_recv(); if (!conn_id) return -1; ret = xrc_create_srq_listen(rdma_get_local_addr(conn_id), sizeof(struct sockaddr_storage)); if (ret) return -1; memset(&attr, 0, sizeof attr); attr.qp_type = IBV_QPT_XRC_RECV; attr.ext.xrc_recv.xrcd = srq_id->srq->ext.xrc.xrcd; ret = rdma_create_qp(conn_id, NULL, &attr); if (ret) { printf("Unable to create xrc recv qp %d\n", errno); return ret; } ret = rdma_accept(conn_id, NULL); if (ret) { printf("rdma_accept failed for xrc recv qp %d\n", errno); return ret; } ret = rdma_get_request(srq_id, &lookup_id); if (ret) { printf("rdma_get_request %d\n", errno); return ret; } mr = rdma_reg_msgs(srq_id, recv_msg, sizeof recv_msg); if (!mr) { printf("ibv_reg_msgs %d\n", errno); return ret; } ret = rdma_post_recv(srq_id, NULL, recv_msg, sizeof recv_msg, mr); if (ret) { printf("rdma_post_recv %d\n", errno); return ret; } memset(¶m, 0, sizeof param); param.qp_num = srq_id->srq->ext.xrc.srq_num; ret = rdma_accept(lookup_id, ¶m); if (ret) { printf("rdma_accept failed for srqn lookup %d\n", errno); return ret; } rdma_destroy_id(lookup_id); ret = rdma_get_recv_comp(srq_id, &wc); if (ret <= 0) { printf("rdma_get_recv_comp %d\n", ret); return ret; } ret = rdma_get_cm_event(conn_id->channel, &event); if (ret || event->event != RDMA_CM_EVENT_DISCONNECTED) { printf("Failed to get disconnect event\n"); return -1; } rdma_ack_cm_event(event); rdma_disconnect(conn_id); rdma_destroy_ep(conn_id); rdma_dereg_mr(mr); rdma_destroy_ep(srq_id); rdma_destroy_ep(listen_id); return 0; }