Esempio n. 1
3
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;
}
Esempio n. 2
0
void Acceptor::listen(std::string const& hostname, std::string const& port) {
  auto res = create_addr_info(hostname, port);
  ibv_qp_init_attr init_attr;
  memset(&init_attr, 0, sizeof(init_attr));
  init_attr.cap.max_send_wr = m_credits;
  init_attr.cap.max_recv_wr = m_credits;
  init_attr.cap.max_send_sge = 1;
  init_attr.cap.max_recv_sge = 1;
  init_attr.cap.max_inline_data = 0;
  init_attr.sq_sig_all = 1;
  init_attr.qp_type = IBV_QPT_RC;
  int ret = rdma_create_ep(&m_cm_id, res, NULL, &init_attr);
  destroy_addr_info(res);
  if (ret) {
    rdma_destroy_ep(m_cm_id);
    throw exception::acceptor::generic_error(
        "Error on rdma_create_ep: " + std::string(strerror(errno)));
  }

  if (rdma_listen(m_cm_id, 128)) {
    rdma_destroy_ep(m_cm_id);
    throw exception::acceptor::generic_error(
        "Error on rdma_listen: " + std::string(strerror(errno)));
  }
}
Esempio n. 3
0
File: rping.c Progetto: hkimura/pib
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;
}
Esempio n. 4
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;
}
Esempio n. 5
0
static int __fi_pep_listen(struct fid_pep *pep)
{
	struct __fid_pep *_pep;

	_pep = container_of(pep, struct __fid_pep, pep_fid);
	return rdma_listen(_pep->id, 0) ? -errno : 0;
}
Esempio n. 6
0
void RDMAServerSocket::listen(int backlog) {
  if (rdma_listen(id.get(), backlog))
    throw_errno("rdma_listen");
  
  log_info() << "server listening on "
             << inet_ntoa(id->route.addr.src_sin.sin_addr) << ":"
             << ntohs(id->route.addr.src_sin.sin_port) << " " << id.get() << " " << (void*) this;
}
Esempio n. 7
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);
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
/*
 * Create SRQ and listen for XRC SRQN lookup request.
 */
static int xrc_create_srq_listen(struct sockaddr *addr, socklen_t addr_len)
{
	struct rdma_addrinfo rai;
	struct sockaddr_storage ss;
	struct ibv_srq_init_attr attr;
	int ret;

	memset(&rai, 0, sizeof rai);
	rai.ai_flags = RAI_PASSIVE;
	rai.ai_family = addr->sa_family;
	rai.ai_qp_type = IBV_QPT_UD; /* for now */
	rai.ai_port_space = RDMA_PS_IB;
	memcpy(&ss, addr, addr_len);
	rai.ai_src_len = addr_len;
	rai.ai_src_addr = (struct sockaddr *) &ss;
	((struct sockaddr_in *) &ss)->sin_port = htons((short) atoi(port) + 1);

	ret = rdma_create_ep(&srq_id, &rai, NULL, NULL);
	if (ret) {
		printf("rdma_create_ep srq ep %d\n", errno);
		return ret;
	}

	if (!srq_id->verbs) {
		printf("rdma_create_ep failed to bind to device.\n");
		printf("XRC tests cannot use loopback addressing\n");
		return -1;
	}

	memset(&attr, 0, sizeof attr);
	attr.attr.max_wr = 1;
	attr.attr.max_sge = 1;
	attr.srq_type = IBV_SRQT_XRC;

	attr.ext.xrc.xrcd = ibv_open_xrcd(srq_id->verbs, -1, 0);
	if (!attr.ext.xrc.xrcd) {
		printf("Unable to open xrcd\n");
		return -1;
	}

	ret = rdma_create_srq(srq_id, NULL, &attr);
	if (ret) {
		printf("Unable to create srq %d\n", errno);
		return ret;
	}

	ret = rdma_listen(srq_id, 0);
	if (ret) {
		printf("rdma_listen srq id %d\n", errno);
		return ret;
	}

	return 0;
}
Esempio n. 11
0
int ibw_listen(struct ibw_ctx *ctx, int backlog)
{
	struct ibw_ctx_priv *pctx = talloc_get_type(ctx->internal, struct ibw_ctx_priv);
	int	rc;

	DEBUG(DEBUG_DEBUG, ("ibw_listen\n"));
	rc = rdma_listen(pctx->cm_id, backlog);
	if (rc) {
		sprintf(ibw_lasterr, "rdma_listen failed: %d\n", rc);
		DEBUG(DEBUG_ERR, (ibw_lasterr));
		return rc;
	}

	return 0;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
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;
}
Esempio n. 15
0
File: diod_rdma.c Progetto: 8l/diod
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;
}
Esempio n. 16
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;
}
Esempio n. 17
0
static int dsm_init(void)
{
    struct dsm_module_state *dsm_state = create_dsm_module_state();

    dsm_zero_pfn_init();

    printk("[dsm_init] ip : %s\n", ip);
    printk("[dsm_init] port : %d\n", port);

    if (create_rcm(dsm_state, ip, port))
        goto err;

    if (dsm_sysfs_setup(dsm_state)) {
        destroy_rcm(dsm_state);
    }

    rdma_listen(dsm_state->rcm->cm_id, 2);
    dsm_hook_write(&my_dsm_hook);
err: 
    return misc_register(&rdma_misc);
}
Esempio n. 18
0
    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";
    }
Esempio n. 19
0
/*
 * Listen for XRC RECV QP connection request.
 */
static struct rdma_cm_id * xrc_listen_recv(void)
{
	struct rdma_addrinfo hints, *res;
	struct rdma_cm_id *id;
	int ret;

	memset(&hints, 0, sizeof hints);
	hints.ai_flags = RAI_PASSIVE;
	hints.ai_port_space = RDMA_PS_IB;
	hints.ai_qp_type = IBV_QPT_XRC_RECV;
	ret = rdma_getaddrinfo(NULL, port, &hints, &res);
	if (ret) {
		printf("rdma_getaddrinfo listen recv %d\n", errno);
		return NULL;
	}

	ret = rdma_create_ep(&listen_id, res, NULL, NULL);
	rdma_freeaddrinfo(res);
	if (ret) {
		printf("rdma_create_ep listen recv %d\n", errno);
		return NULL;
	}

	ret = rdma_listen(listen_id, 0);
	if (ret) {
		printf("rdma_listen %d\n", errno);
		return NULL;
	}

	ret = rdma_get_request(listen_id, &id);
	if (ret) {
		printf("rdma_get_request %d\n", errno);
		return NULL;
	}

	return id;
}
Esempio n. 20
0
        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);
            }
        }
Esempio n. 21
0
static int rc_test(void)
{
	struct rdma_addrinfo hints, *res;
	struct ibv_qp_init_attr attr;
	struct ibv_wc wc;
	int ret;

	memset(&hints, 0, sizeof hints);
	hints.ai_flags = RAI_PASSIVE;
	hints.ai_port_space = RDMA_PS_TCP;
	ret = rdma_getaddrinfo(NULL, port, &hints, &res);
	if (ret) {
		printf("rdma_getaddrinfo %d\n", errno);
		return ret;
	}

	memset(&attr, 0, sizeof attr);
	attr.cap.max_send_wr = attr.cap.max_recv_wr = 1;
	attr.cap.max_send_sge = attr.cap.max_recv_sge = 1;
	attr.cap.max_inline_data = sizeof send_msg;
	attr.sq_sig_all = 1;
	ret = rdma_create_ep(&listen_id, res, NULL, &attr);
	rdma_freeaddrinfo(res);
	if (ret) {
		printf("rdma_create_ep %d\n", errno);
		return ret;
	}

	ret = rdma_listen(listen_id, 0);
	if (ret) {
		printf("rdma_listen %d\n", errno);
		return ret;
	}

	ret = rdma_get_request(listen_id, &id);
	if (ret) {
		printf("rdma_get_request %d\n", errno);
		return ret;
	}

	mr = rdma_reg_msgs(id, recv_msg, sizeof recv_msg);
	if (!mr) {
		printf("rdma_reg_msgs %d\n", errno);
		return ret;
	}

	ret = rdma_post_recv(id, NULL, recv_msg, sizeof recv_msg, mr);
	if (ret) {
		printf("rdma_post_recv %d\n", errno);
		return ret;
	}

	ret = rdma_accept(id, NULL);
	if (ret) {
		printf("rdma_accept %d\n", errno);
		return ret;
	}

	ret = rdma_get_recv_comp(id, &wc);
	if (ret <= 0) {
		printf("rdma_get_recv_comp %d\n", ret);
		return ret;
	}

	ret = rdma_post_send(id, NULL, send_msg, sizeof send_msg, NULL, IBV_SEND_INLINE);
	if (ret) {
		printf("rdma_post_send %d\n", errno);
		return ret;
	}

	ret = rdma_get_send_comp(id, &wc);
	if (ret <= 0) {
		printf("rdma_get_send_comp %d\n", ret);
		return ret;
	}

	rdma_disconnect(id);
	rdma_dereg_mr(mr);
	rdma_destroy_ep(id);
	rdma_destroy_ep(listen_id);
	return 0;
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
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;

}
Esempio n. 24
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;
}
Esempio n. 25
0
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;
  */
}
Esempio n. 26
0
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;
}
Esempio n. 27
0
/******************************************************************************
  + *
  + ******************************************************************************/
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;
}
Esempio n. 28
0
/*
 * 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);
}