コード例 #1
0
ファイル: cma.c プロジェクト: 2014-class/freerouter
int rdma_create_id(struct rdma_event_channel *channel,
		   struct rdma_cm_id **id, void *context,
		   enum rdma_port_space ps)
{
	struct ucma_abi_create_id_resp *resp;
	struct ucma_abi_create_id *cmd;
	struct cma_id_private *id_priv;
	void *msg;
	int ret, size;

	ret = cma_dev_cnt ? 0 : ucma_init();
	if (ret)
		return ret;

	id_priv = ucma_alloc_id(channel, context, ps);
	if (!id_priv)
		return ERR(ENOMEM);

	CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_CREATE_ID, size);
	cmd->uid = (uintptr_t) id_priv;
	cmd->ps = ps;

	ret = write(channel->fd, msg, size);
	if (ret != size)
		goto err;

	VALGRIND_MAKE_MEM_DEFINED(resp, sizeof *resp);

	id_priv->handle = resp->id;
	*id = &id_priv->id;
	return 0;

err:	ucma_free_id(id_priv);
	return ret;
}
コード例 #2
0
ファイル: addrinfo.c プロジェクト: digideskio/gpunet
int rdma_getaddrinfo(char *node, char *service,
		     struct rdma_addrinfo *hints,
		     struct rdma_addrinfo **res)
{
	struct rdma_addrinfo *rai;
	int ret;

	if (!service && !node && !hints)
		return ERR(EINVAL);

	ret = ucma_init();
	if (ret)
		return ret;

	rai = calloc(1, sizeof(*rai));
	if (!rai)
		return ERR(ENOMEM);

	if (!hints)
		hints = &nohints;

	if (node || service) {
		ret = ucma_getaddrinfo(node, service, hints, rai);
	} else {
		rai->ai_flags = hints->ai_flags;
		rai->ai_family = hints->ai_family;
		rai->ai_qp_type = hints->ai_qp_type;
		rai->ai_port_space = hints->ai_port_space;
		if (hints->ai_dst_len) {
			ret = ucma_copy_addr(&rai->ai_dst_addr, &rai->ai_dst_len,
					     hints->ai_dst_addr, hints->ai_dst_len);
		}
	}
	if (ret)
		goto err;

	if (!rai->ai_src_len && hints->ai_src_len) {
		ret = ucma_copy_addr(&rai->ai_src_addr, &rai->ai_src_len,
				     hints->ai_src_addr, hints->ai_src_len);
		if (ret)
			goto err;
	}

	if (!(rai->ai_flags & RAI_PASSIVE))
		ucma_ib_resolve(&rai, hints);

	*res = rai;
	return 0;

err:
	rdma_freeaddrinfo(rai);
	return ret;
}
コード例 #3
0
ファイル: cma.c プロジェクト: 2014-class/freerouter
struct rdma_event_channel *rdma_create_event_channel(void)
{
	struct rdma_event_channel *channel;

	if (!cma_dev_cnt && ucma_init())
		return NULL;

	channel = malloc(sizeof *channel);
	if (!channel)
		return NULL;

	channel->fd = open("/dev/rdma_cm", O_RDWR);
	if (channel->fd < 0) {
		printf("CMA: unable to open /dev/rdma_cm\n");
		goto err;
	}
	return channel;
err:
	free(channel);
	return NULL;
}
コード例 #4
0
ファイル: cma.c プロジェクト: 2014-class/freerouter
int rdma_get_cm_event(struct rdma_event_channel *channel,
		      struct rdma_cm_event **event)
{
	struct ucma_abi_event_resp *resp;
	struct ucma_abi_get_event *cmd;
	struct cma_event *evt;
	void *msg;
	int ret, size;

	ret = cma_dev_cnt ? 0 : ucma_init();
	if (ret)
		return ret;

	if (!event)
		return ERR(EINVAL);

	evt = malloc(sizeof *evt);
	if (!evt)
		return ERR(ENOMEM);

retry:
	memset(evt, 0, sizeof *evt);
	CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_GET_EVENT, size);
	ret = write(channel->fd, msg, size);
	if (ret != size) {
		free(evt);
		return (ret >= 0) ? ERR(ECONNREFUSED) : -1;
	}
	
	VALGRIND_MAKE_MEM_DEFINED(resp, sizeof *resp);

	evt->event.event = resp->event;
	evt->id_priv = (void *) (uintptr_t) resp->uid;
	evt->event.id = &evt->id_priv->id;
	evt->event.status = resp->status;

	switch (resp->event) {
	case RDMA_CM_EVENT_ADDR_RESOLVED:
		evt->event.status = ucma_query_route(&evt->id_priv->id);
		if (evt->event.status)
			evt->event.event = RDMA_CM_EVENT_ADDR_ERROR;
		break;
	case RDMA_CM_EVENT_ROUTE_RESOLVED:
		evt->event.status = ucma_query_route(&evt->id_priv->id);
		if (evt->event.status)
			evt->event.event = RDMA_CM_EVENT_ROUTE_ERROR;
		break;
	case RDMA_CM_EVENT_CONNECT_REQUEST:
		evt->id_priv = (void *) (uintptr_t) resp->uid;
		if (ucma_is_ud_ps(evt->id_priv->id.ps))
			ucma_copy_ud_event(evt, &resp->param.ud);
		else
			ucma_copy_conn_event(evt, &resp->param.conn);

		ret = ucma_process_conn_req(evt, resp->id);
		if (ret)
			goto retry;
		break;
	case RDMA_CM_EVENT_CONNECT_RESPONSE:
		ucma_copy_conn_event(evt, &resp->param.conn);
		evt->event.status = ucma_process_conn_resp(evt->id_priv);
		if (!evt->event.status)
			evt->event.event = RDMA_CM_EVENT_ESTABLISHED;
		else {
			evt->event.event = RDMA_CM_EVENT_CONNECT_ERROR;
			evt->id_priv->connect_error = 1;
		}
		break;
	case RDMA_CM_EVENT_ESTABLISHED:
		if (ucma_is_ud_ps(evt->id_priv->id.ps)) {
			ucma_copy_ud_event(evt, &resp->param.ud);
			break;
		}

		ucma_copy_conn_event(evt, &resp->param.conn);
		evt->event.status = ucma_process_establish(&evt->id_priv->id);
		if (evt->event.status) {
			evt->event.event = RDMA_CM_EVENT_CONNECT_ERROR;
			evt->id_priv->connect_error = 1;
		}
		break;
	case RDMA_CM_EVENT_REJECTED:
		if (evt->id_priv->connect_error) {
			ucma_complete_event(evt->id_priv);
			goto retry;
		}
		ucma_copy_conn_event(evt, &resp->param.conn);
		ucma_modify_qp_err(evt->event.id);
		break;
	case RDMA_CM_EVENT_DISCONNECTED:
		if (evt->id_priv->connect_error) {
			ucma_complete_event(evt->id_priv);
			goto retry;
		}
		ucma_copy_conn_event(evt, &resp->param.conn);
		break;
	case RDMA_CM_EVENT_MULTICAST_JOIN:
		evt->mc = (void *) (uintptr_t) resp->uid;
		evt->id_priv = evt->mc->id_priv;
		evt->event.id = &evt->id_priv->id;
		ucma_copy_ud_event(evt, &resp->param.ud);
		evt->event.param.ud.private_data = evt->mc->context;
		evt->event.status = ucma_process_join(evt);
		if (evt->event.status)
			evt->event.event = RDMA_CM_EVENT_MULTICAST_ERROR;
		break;
	case RDMA_CM_EVENT_MULTICAST_ERROR:
		evt->mc = (void *) (uintptr_t) resp->uid;
		evt->id_priv = evt->mc->id_priv;
		evt->event.id = &evt->id_priv->id;
		evt->event.param.ud.private_data = evt->mc->context;
		break;
	default:
		evt->id_priv = (void *) (uintptr_t) resp->uid;
		evt->event.id = &evt->id_priv->id;
		evt->event.status = resp->status;
		if (ucma_is_ud_ps(evt->id_priv->id.ps))
			ucma_copy_ud_event(evt, &resp->param.ud);
		else
			ucma_copy_conn_event(evt, &resp->param.conn);
		break;
	}

	*event = &evt->event;
	return 0;
}