Exemplo n.º 1
0
static int sock_ep_cm_accept(struct fid_ep *ep, const void *param, size_t paramlen)
{
	struct sock_conn_req *req;
	struct fi_eq_cm_entry cm_entry;
	struct sock_conn_response *response;
	struct sockaddr_in *addr;
	struct sock_ep *_ep;
	struct sock_eq *_eq;
	int ret;

	_ep = container_of(ep, struct sock_ep, ep);
	_eq = _ep->eq;
	if (!_eq || paramlen > SOCK_EP_MAX_CM_DATA_SZ) 
		return -FI_EINVAL;

	response = (struct sock_conn_response*)calloc(1, 
						 sizeof(*response) + paramlen);
	if (!response)
		return -FI_ENOMEM;

	req = (struct sock_conn_req *)_ep->info.connreq;
	if (!req) {
		SOCK_LOG_ERROR("invalid connreq for cm_accept\n");
		return -FI_EINVAL;
	}
	
	memcpy(&response->hdr, &req->hdr, sizeof(struct sock_conn_hdr));
	if (param && paramlen)
		memcpy(&response->user_data, param, paramlen);

	addr = &req->from_addr;
	_ep->rem_ep_id = req->ep_id;
	response->hdr.type = SOCK_CONN_ACCEPT;
	response->hdr.s_fid = &ep->fid;

	_ep->socket = sock_ep_cm_create_socket();
	if (!_ep->socket) {
		ret = -FI_EIO;
		goto out;
	}
	
	if (sock_ep_cm_send_msg(_ep->socket, addr, response, 
				sizeof (*response) + paramlen)) {
		close(_ep->socket);
		ret = -FI_EIO;
		goto out;
	}
	    
	sock_ep_enable(ep);
	memset(&cm_entry, 0, sizeof(cm_entry));
	cm_entry.fid = &ep->fid;
	_ep->connected = 1;
	ret = sock_eq_report_event(_eq, FI_CONNECTED, &cm_entry, 
				   sizeof(cm_entry), 0);
out:
	free(req);
	free(response);
	_ep->info.connreq = NULL;
	return ret;
}
Exemplo n.º 2
0
static int sock_regattr(struct fid_domain *domain, const struct fi_mr_attr *attr,
		uint64_t flags, struct fid_mr **mr)
{
	struct fi_eq_entry eq_entry;
	struct sock_domain *dom;
	struct sock_mr *_mr;
	uint64_t key;

	dom = container_of(domain, struct sock_domain, dom_fid);
	if (!(dom->info.mode & FI_PROV_MR_ATTR) && 
	    ((attr->requested_key > IDX_MAX_INDEX) ||
	    idm_lookup(&dom->mr_idm, (int) attr->requested_key)))
		return -FI_ENOKEY;

	_mr = calloc(1, sizeof(*_mr) + sizeof(_mr->mr_iov) * (attr->iov_count - 1));
	if (!_mr)
		return -FI_ENOMEM;

	_mr->mr_fid.fid.fclass = FI_CLASS_MR;
	_mr->mr_fid.fid.context = attr->context;
	_mr->mr_fid.fid.ops = &sock_mr_fi_ops;

	_mr->domain = dom;
	_mr->access = attr->access;
	_mr->flags = flags;
	_mr->offset = (flags & FI_MR_OFFSET) ?
		(uintptr_t) attr->mr_iov[0].iov_base + attr->offset : 
		(uintptr_t) attr->mr_iov[0].iov_base;

	fastlock_acquire(&dom->lock);
	key = (dom->info.mode & FI_PROV_MR_ATTR) ?
	      sock_get_mr_key(dom) : (uint16_t) attr->requested_key;
	if (idm_set(&dom->mr_idm, key, _mr) < 0)
		goto err;
	_mr->mr_fid.key = key;
	_mr->mr_fid.mem_desc = (void *)key;
	fastlock_release(&dom->lock);

	_mr->iov_count = attr->iov_count;
	memcpy(&_mr->mr_iov, attr->mr_iov, sizeof(_mr->mr_iov) * attr->iov_count);

	*mr = &_mr->mr_fid;
	atomic_inc(&dom->ref);

	if (dom->mr_eq) {
		eq_entry.fid = &domain->fid;
		eq_entry.context = attr->context;
		return sock_eq_report_event(dom->mr_eq, FI_MR_COMPLETE,
					    &eq_entry, sizeof(eq_entry), 0);
	}

	return 0;

err:
	fastlock_release(&dom->lock);
	free(_mr);
	return -errno;
}
Exemplo n.º 3
0
static inline void sock_av_report_success(struct sock_av *av, void *context,
					  int num_done, uint64_t flags)
{
	struct fi_eq_entry eq_entry;

	if (!av->eq)
		return;

	eq_entry.fid = &av->av_fid.fid;
	eq_entry.context = context;
	eq_entry.data = num_done;
	sock_eq_report_event(av->eq, FI_AV_COMPLETE,
			     &eq_entry, sizeof(eq_entry), flags);
}
Exemplo n.º 4
0
static int sock_regattr(struct fid *fid, const struct fi_mr_attr *attr,
		uint64_t flags, struct fid_mr **mr)
{
	struct fi_eq_entry eq_entry;
	struct sock_domain *dom;
	struct sock_mr *_mr;
	uint64_t key;
	struct fid_domain *domain;
	RbtStatus res;
	int ret = 0;

	if (fid->fclass != FI_CLASS_DOMAIN || !attr || attr->iov_count <= 0) {
		return -FI_EINVAL;
	}

	domain = container_of(fid, struct fid_domain, fid);
	dom = container_of(domain, struct sock_domain, dom_fid);

	_mr = calloc(1, sizeof(*_mr) +
		     sizeof(_mr->mr_iov) * (attr->iov_count - 1));
	if (!_mr)
		return -FI_ENOMEM;

	fastlock_acquire(&dom->lock);
	if (dom->attr.mr_mode == FI_MR_SCALABLE &&
	    sock_mr_get_entry(dom, attr->requested_key) != NULL) {
		ret = -FI_ENOKEY;
		goto err;
	}

	_mr->mr_fid.fid.fclass = FI_CLASS_MR;
	_mr->mr_fid.fid.context = attr->context;
	_mr->mr_fid.fid.ops = &sock_mr_fi_ops;

	_mr->domain = dom;
	_mr->access = attr->access;
	_mr->flags = flags;
	_mr->offset = (dom->attr.mr_mode == FI_MR_SCALABLE) ?
		(uintptr_t) attr->mr_iov[0].iov_base + attr->offset :
		(uintptr_t) attr->mr_iov[0].iov_base;

	key = (dom->attr.mr_mode == FI_MR_BASIC) ?
		sock_get_mr_key(dom) : attr->requested_key;

	_mr->key = key;
	res = rbtInsert(dom->mr_heap, &_mr->key, _mr);
	if (res != RBT_STATUS_OK) {
		ret = -FI_ENOMEM;
		goto err;
	}

	_mr->mr_fid.key = key;
	_mr->mr_fid.mem_desc = (void *) (uintptr_t) key;
	fastlock_release(&dom->lock);

	_mr->iov_count = attr->iov_count;
	memcpy(&_mr->mr_iov, attr->mr_iov, sizeof(_mr->mr_iov) * attr->iov_count);

	*mr = &_mr->mr_fid;
	atomic_inc(&dom->ref);

	if (dom->mr_eq) {
		eq_entry.fid = &domain->fid;
		eq_entry.context = attr->context;
		return sock_eq_report_event(dom->mr_eq, FI_MR_COMPLETE,
					    &eq_entry, sizeof(eq_entry), 0);
	}

	return 0;

err:
	fastlock_release(&dom->lock);
	free(_mr);
	return ret;
}
Exemplo n.º 5
0
static void *sock_pep_listener_thread (void *data)
{
	struct sock_pep *pep = (struct sock_pep *)data;
	struct sock_conn_req *conn_req = NULL;
	struct fi_eq_cm_entry cm_entry;
	struct sockaddr_in from_addr;
	struct pollfd poll_fds[2];

	socklen_t addr_len;
	int ret, user_data_sz, tmp;

	SOCK_LOG_INFO("Starting listener thread for PEP: %p\n", pep);

	poll_fds[0].fd = pep->socket;
	poll_fds[1].fd = pep->signal_fds[1];
	poll_fds[0].events = poll_fds[1].events = POLLIN;
	while((volatile int)pep->do_listen) {
		if (poll(poll_fds, 2, -1) > 0) {
			if (poll_fds[1].revents & POLLIN) {
				read(pep->signal_fds[1], &tmp, 1);
				continue;
			}
		} else
			return NULL;
		
		if (conn_req == NULL) {
			conn_req = (struct sock_conn_req*)calloc(1, 
								 sizeof(*conn_req) + 
								 SOCK_EP_MAX_CM_DATA_SZ);
			if (!conn_req) {
				SOCK_LOG_ERROR("cannot allocate\n");
				return NULL;
			}
		}
		
		addr_len = sizeof(struct sockaddr_in);
		ret = recvfrom(pep->socket, (char*)conn_req, 
			       sizeof(*conn_req) + SOCK_EP_MAX_CM_DATA_SZ, 0, 
			       (struct sockaddr *) &from_addr, &addr_len);
		if (ret <= 0)
			continue;
		memcpy(&conn_req->from_addr, &from_addr, sizeof(struct sockaddr_in));
		
		SOCK_LOG_INFO("Msg received: %d\n", ret);
		memset(&cm_entry, 0, sizeof(cm_entry));
		user_data_sz = 0;

		if (conn_req->hdr.type == SOCK_CONN_REQ) {
			SOCK_LOG_INFO("Received SOCK_CONN_REQ\n");
			if (ret < sizeof(*conn_req) || 
			    !sock_ep_cm_send_ack(pep->socket, &from_addr)) {
				SOCK_LOG_ERROR("Invalid connection request\n");
				break;
			}
			
			cm_entry.info = sock_ep_msg_process_info(conn_req);
			cm_entry.info->connreq = (fi_connreq_t)conn_req;
			if (ret > sizeof(struct sock_conn_req)) {
				user_data_sz = ret - sizeof(struct sock_conn_req);
				memcpy(&cm_entry.data,
				       (char *)conn_req + sizeof(struct sock_conn_req),
					user_data_sz);
			}
			
			if (sock_eq_report_event(pep->eq, FI_CONNREQ, &cm_entry, 
						 sizeof(cm_entry) + user_data_sz, 0)) 
				SOCK_LOG_ERROR("Error in writing to EQ\n");
		} else {
			SOCK_LOG_ERROR("Invalid event\n");
		}
		conn_req = NULL;
	}

	if (conn_req)
		free(conn_req);
	close(pep->socket);
	pep->socket = 0;
	return NULL;
}
Exemplo n.º 6
0
static void *sock_msg_ep_listener_thread (void *data)
{
	struct sock_ep *ep = (struct sock_ep *)data;
	struct sock_conn_response *conn_response = NULL;

	struct fi_eq_cm_entry cm_entry;
	struct fi_eq_err_entry cm_err_entry;

	struct sockaddr_in from_addr;
	socklen_t addr_len;
	int ret, user_data_sz;
	struct fid_ep *fid_ep;
	struct sock_ep *sock_ep;

	SOCK_LOG_INFO("Starting listener thread for EP: %p\n", ep);
	ep->do_listen = 1;

	while((volatile int)ep->do_listen) {
		ret = fi_poll_fd(ep->socket, -1);
		if (ret <= 0)
			continue;
		
		if (conn_response == NULL) {
			conn_response = (struct sock_conn_response*)
				calloc(1, sizeof(*conn_response) + 
				       SOCK_EP_MAX_CM_DATA_SZ);
			if (!conn_response) {
				SOCK_LOG_ERROR("cannot allocate\n");
				return NULL;
			}
		}
		
		addr_len = sizeof(struct sockaddr_in);
		ret = recvfrom(ep->socket, (char*)conn_response, 
			       sizeof(*conn_response) + SOCK_EP_MAX_CM_DATA_SZ,
			       0, (struct sockaddr *) &from_addr, &addr_len);
		if (ret <= 0)
			continue;
		
		SOCK_LOG_INFO("Total received: %d\n", ret);
		
		if (ret < sizeof(*conn_response) || 
		    !sock_ep_cm_send_ack(ep->socket, &from_addr))
			continue;

		user_data_sz = 0;
		switch (conn_response->hdr.type) {
			
		case SOCK_CONN_ACCEPT:
			SOCK_LOG_INFO("Received SOCK_CONN_ACCEPT\n");
			memset(&cm_entry, 0, sizeof(cm_entry));
			cm_entry.fid = conn_response->hdr.c_fid;

			if (ret > sizeof(struct sock_conn_response)) {
				user_data_sz = ret - 
					sizeof(struct sock_conn_response);
				memcpy(&cm_entry.data,
				       (char *)conn_response + 
				       sizeof(struct sock_conn_response),
				       user_data_sz);
			}

			fid_ep = container_of(conn_response->hdr.c_fid, 
					      struct fid_ep, fid);
			sock_ep = container_of(fid_ep, struct sock_ep, ep);
			sock_ep->connected = 1;
			sock_ep_enable(&ep->ep);
			if (sock_eq_report_event(ep->eq, FI_CONNECTED, &cm_entry, 
						 sizeof(cm_entry) + user_data_sz, 0)) 
				SOCK_LOG_ERROR("Error in writing to EQ\n");
			break;

		case SOCK_CONN_REJECT:
			SOCK_LOG_INFO("Received SOCK_CONN_REJECT\n");
			memset(&cm_err_entry, 0, sizeof(cm_err_entry));
			cm_err_entry.fid = conn_response->hdr.c_fid;
			cm_err_entry.context = NULL;
			cm_err_entry.data = 0;
			cm_err_entry.err = -FI_ECONNREFUSED;
			cm_err_entry.prov_errno = 0;
			cm_err_entry.err_data = NULL;

			if (ret > sizeof(struct sock_conn_response)) {
				user_data_sz = ret - 
					sizeof(struct sock_conn_response);
				memcpy(&cm_entry.data,
				       (char *)conn_response + 
				       sizeof(struct sock_conn_response),
				       user_data_sz);
			}

			if (sock_eq_report_event(ep->eq, FI_ECONNREFUSED, 
						 &cm_err_entry, 
						 sizeof (cm_err_entry) + 
						 user_data_sz, 0))
				SOCK_LOG_ERROR("Error in writing to EQ\n");
			goto out;

		default:
			SOCK_LOG_ERROR("Invalid event\n");
			break;
		}
		conn_response = NULL;
	}

out:
	if (conn_response)
		free(conn_response);
	close(ep->socket);
	ep->socket = 0;
	return NULL;
}