/* create a portal, after listening starts all events * are received in isert_cm_evt_handler() */ struct isert_portal *isert_portal_create(void) { struct isert_portal *portal; struct rdma_cm_id *cm_id; int err; if (unlikely(!try_module_get(THIS_MODULE))) { pr_err("Unable increment module reference\n"); portal = ERR_PTR(-EINVAL); goto out; } portal = kzalloc(sizeof(*portal), GFP_KERNEL); if (unlikely(!portal)) { pr_err("Unable to allocate struct portal\n"); portal = ERR_PTR(-ENOMEM); goto err_alloc; } #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0) && \ (!defined(RHEL_MAJOR) || RHEL_MAJOR -0 <= 5) cm_id = rdma_create_id(isert_cm_evt_handler, portal, RDMA_PS_TCP); #else cm_id = rdma_create_id(isert_cm_evt_handler, portal, RDMA_PS_TCP, IB_QPT_RC); #endif if (unlikely(IS_ERR(cm_id))) { err = PTR_ERR(cm_id); pr_err("Failed to create rdma id, err:%d\n", err); goto create_id_err; } portal->cm_id = cm_id; INIT_LIST_HEAD(&portal->conn_list); isert_portal_list_add(portal); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) rdma_set_afonly(cm_id, 1); #endif pr_info("Created iser portal cm_id:%p\n", cm_id); out: return portal; create_id_err: kfree(portal); portal = ERR_PTR(err); err_alloc: module_put(THIS_MODULE); goto out; }
/* * 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 socket\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 = rdma_create_xprt(serv, 1); if (!cma_xprt) return ERR_PTR(-ENOMEM); listen_id = rdma_create_id(&init_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); }