예제 #1
0
struct sock_conn *sock_av_lookup_addr(struct sock_ep *ep,
				      struct sock_av *av, 
				      fi_addr_t addr)
{
	int idx, ret;
	int index = ((uint64_t)addr & av->mask);
	struct sock_av_addr *av_addr;

	if (index >= av->table_hdr->stored || index < 0) {
		SOCK_LOG_ERROR("requested rank is larger than av table\n");
		errno = EINVAL;
		return NULL;
	}

	if (!av->cmap) {
		SOCK_LOG_ERROR("EP with no AV bound\n");
		errno = EINVAL;
		return NULL;
	}

	av_addr = idm_lookup(&av->addr_idm, index);
	idx = av_addr - &av->table[0];
	if (!av->key[idx]) {
		ret = sock_conn_map_match_or_connect(
			ep, av->domain, av->cmap, 
			(struct sockaddr_in*)&av_addr->addr,
			&av->key[idx]);
		if (ret) {
			SOCK_LOG_ERROR("failed to match or connect to addr %"
					PRIu64 "\n", addr);
			return NULL;
		}
	}
	return sock_conn_map_lookup_key(av->cmap, av->key[idx]);
}
예제 #2
0
파일: sock_comm.c 프로젝트: nkogteva/ompi
int sock_comm_buffer_init(struct sock_conn *conn)
{
	int optval;
	socklen_t size = SOCK_COMM_BUF_SZ;
	socklen_t optlen = sizeof(socklen_t);

	optval = 1;
	if (setsockopt(conn->sock_fd, IPPROTO_TCP, TCP_NODELAY,
		       &optval, sizeof optval))
		SOCK_LOG_ERROR("setsockopt failed\n");

	fd_set_nonblock(conn->sock_fd);
	rbinit(&conn->inbuf, SOCK_COMM_BUF_SZ);
	rbinit(&conn->outbuf, SOCK_COMM_BUF_SZ);

	if (setsockopt(conn->sock_fd, SOL_SOCKET, SO_RCVBUF, &size, optlen))
		SOCK_LOG_ERROR("setsockopt failed\n");

	if (setsockopt(conn->sock_fd, SOL_SOCKET, SO_SNDBUF, &size, optlen))
		SOCK_LOG_ERROR("setsockopt failed\n");

	if (!getsockopt(conn->sock_fd, SOL_SOCKET, SO_RCVBUF, &size, &optlen))
		SOCK_LOG_INFO("SO_RCVBUF: %d\n", size);
	
	optlen = sizeof(socklen_t);
	if (!getsockopt(conn->sock_fd, SOL_SOCKET, SO_SNDBUF, &size, &optlen))
		SOCK_LOG_INFO("SO_SNDBUF: %d\n", size);
	return 0;
}
예제 #3
0
static int sock_ctx_enable(struct fid_ep *ep)
{
	struct sock_tx_ctx *tx_ctx;
	struct sock_rx_ctx *rx_ctx;

	switch (ep->fid.fclass) {
	case FI_CLASS_RX_CTX:
		rx_ctx = container_of(ep, struct sock_rx_ctx, ctx.fid);
		rx_ctx->enabled = 1;
		sock_pe_add_rx_ctx(rx_ctx->domain->pe, rx_ctx);

		if (!rx_ctx->ep_attr->listener.listener_thread &&
		    sock_conn_listen(rx_ctx->ep_attr)) {
			SOCK_LOG_ERROR("failed to create listener\n");
		}
		return 0;

	case FI_CLASS_TX_CTX:
		tx_ctx = container_of(ep, struct sock_tx_ctx, fid.ctx.fid);
		tx_ctx->enabled = 1;
		sock_pe_add_tx_ctx(tx_ctx->domain->pe, tx_ctx);

		if (!tx_ctx->ep_attr->listener.listener_thread &&
		    sock_conn_listen(tx_ctx->ep_attr)) {
			SOCK_LOG_ERROR("failed to create listener\n");
		}
		return 0;

	default:
		SOCK_LOG_ERROR("Invalid CTX\n");
		break;
	}
	return -FI_EINVAL;
}
예제 #4
0
static struct sock_conn *sock_conn_map_insert(struct sock_ep *ep,
				struct sockaddr_in *addr, int conn_fd,
				int addr_published)
{
	int index;
	struct sock_conn_map *map = &ep->cmap;

	if (map->size == map->used) {
		if (sock_conn_map_increase(map, map->size * 2))
			return 0;
	}

	index = map->used;
	map->used++;

	map->table[index].addr = *addr;
	map->table[index].sock_fd = conn_fd;
	map->table[index].ep = ep;
	sock_set_sockopts(conn_fd);

	fastlock_acquire(&ep->lock);
	dlist_insert_tail(&map->table[index].ep_entry, &ep->conn_list);
	fastlock_release(&ep->lock);

	if (idm_set(&ep->conn_idm, conn_fd, &map->table[index]) < 0)
                SOCK_LOG_ERROR("idm_set failed\n");

	if (sock_epoll_add(&map->epoll_set, conn_fd))
                SOCK_LOG_ERROR("failed to add to epoll set: %d\n", conn_fd);

	map->table[index].address_published = addr_published;
	sock_pe_poll_add(ep->domain->pe, conn_fd);
	return &map->table[index];
}
예제 #5
0
static int sock_ctx_bind_cntr(struct fid *fid, struct fid *bfid, uint64_t flags)
{
	struct sock_cntr *cntr;
	struct sock_tx_ctx *tx_ctx;
	struct sock_rx_ctx *rx_ctx;

	if ((flags | SOCK_EP_CNTR_FLAGS) != SOCK_EP_CNTR_FLAGS) {
		SOCK_LOG_ERROR("Invalid cntr flag\n");
		return -FI_EINVAL;
	}

	cntr = container_of(bfid, struct sock_cntr, cntr_fid.fid);
	switch (fid->fclass) {
	case FI_CLASS_TX_CTX:
		tx_ctx = container_of(fid, struct sock_tx_ctx, fid.ctx.fid);
		if (flags & FI_SEND) {
			tx_ctx->comp.send_cntr = cntr;
			sock_cntr_add_tx_ctx(cntr, tx_ctx);
		}

		if (flags & FI_READ) {
			tx_ctx->comp.read_cntr = cntr;
			sock_cntr_add_tx_ctx(cntr, tx_ctx);
		}

		if (flags & FI_WRITE) {
			tx_ctx->comp.write_cntr = cntr;
			sock_cntr_add_tx_ctx(cntr, tx_ctx);
		}
		break;

	case FI_CLASS_RX_CTX:
		rx_ctx = container_of(fid, struct sock_rx_ctx, ctx.fid);
		if (flags & FI_RECV) {
			rx_ctx->comp.recv_cntr = cntr;
			sock_cntr_add_rx_ctx(cntr, rx_ctx);
		}

		if (flags & FI_REMOTE_READ) {
			rx_ctx->comp.rem_read_cntr = cntr;
			sock_cntr_add_rx_ctx(cntr, rx_ctx);
		}

		if (flags & FI_REMOTE_WRITE) {
			rx_ctx->comp.rem_write_cntr = cntr;
			sock_cntr_add_rx_ctx(cntr, rx_ctx);
		}
		break;

	default:
		SOCK_LOG_ERROR("Invalid fid\n");
		return -FI_EINVAL;
	}
	return 0;
}
예제 #6
0
static void *_sock_conn_listen(void *arg)
{
	int conn_fd, ret;
	char tmp;
	socklen_t addr_size;
	struct sockaddr_in remote;
	struct pollfd poll_fds[2];

	struct sock_ep_attr *ep_attr = (struct sock_ep_attr *)arg;
	struct sock_conn_listener *listener = &ep_attr->listener;
	struct sock_conn_map *map = &ep_attr->cmap;

	poll_fds[0].fd = listener->sock;
	poll_fds[1].fd = listener->signal_fds[1];
	poll_fds[0].events = poll_fds[1].events = POLLIN;
	listener->is_ready = 1;

	while (listener->do_listen) {
		if (poll(poll_fds, 2, -1) > 0) {
			if (poll_fds[1].revents & POLLIN) {
				ret = ofi_read_socket(listener->signal_fds[1], &tmp, 1);
				if (ret != 1) {
					SOCK_LOG_ERROR("Invalid signal\n");
					goto err;
				}
				continue;
			}
		} else {
			goto err;
		}

		addr_size = sizeof(remote);
		conn_fd = accept(listener->sock, (struct sockaddr *) &remote,
					&addr_size);
		SOCK_LOG_DBG("CONN: accepted conn-req: %d\n", conn_fd);
		if (conn_fd < 0) {
			SOCK_LOG_ERROR("failed to accept: %s\n", strerror(errno));
			goto err;
		}

		SOCK_LOG_DBG("ACCEPT: %s, %d\n", inet_ntoa(remote.sin_addr),
				ntohs(remote.sin_port));

		fastlock_acquire(&map->lock);
		sock_conn_map_insert(ep_attr, &remote, conn_fd, 1);
		fastlock_release(&map->lock);
		sock_pe_signal(ep_attr->domain->pe);
	}

err:
	ofi_close_socket(listener->sock);
	SOCK_LOG_DBG("Listener thread exited\n");
	return NULL;
}
예제 #7
0
static int sock_av_insertsym(struct fid_av *av, const char *node, size_t nodecnt,
		      const char *service, size_t svccnt, fi_addr_t *fi_addr,
		      uint64_t flags, void *context)
{
	int ret = 0, success = 0, err_code = 0, len1, len2;
	int var_port, var_host;
	char base_host[FI_NAME_MAX] = {0};
	char tmp_host[FI_NAME_MAX] = {0};
	char tmp_port[FI_NAME_MAX] = {0};
	int hostlen, offset = 0, fmt, i, j;

	if (!node || !service || node[0] == '\0') {
		SOCK_LOG_ERROR("Node/service not provided\n");
		return -FI_EINVAL;
	}

	hostlen = strlen(node);
	while (isdigit(*(node + hostlen - (offset + 1))))
		offset++;

	if (*(node + hostlen - offset) == '.')
		fmt = 0;
	else
		fmt = offset;

	assert((hostlen-offset) < FI_NAME_MAX);
	strncpy(base_host, node, hostlen - (offset));
	var_port = atoi(service);
	var_host = atoi(node + hostlen - offset);

	for (i = 0; i < nodecnt; i++) {
		for (j = 0; j < svccnt; j++) {
			len1 = snprintf(tmp_host, FI_NAME_MAX, "%s%0*d",
					base_host, fmt, var_host + i);
			len2 = snprintf(tmp_port, FI_NAME_MAX,  "%d",
					var_port + j);
			if (len1 > 0 && len1 < FI_NAME_MAX && len2 > 0 && len2 < FI_NAME_MAX) {
				ret = _sock_av_insertsvc(av, tmp_host, tmp_port, fi_addr, flags, context, i * nodecnt + j);
				if (ret == 1)
					success++;
				else
					err_code = ret;
			} else {
				SOCK_LOG_ERROR("Node/service value is not valid\n");
				err_code = FI_ETOOSMALL;
			}
		}
	}
	return success > 0 ? success : err_code;
}
예제 #8
0
static int sock_poll_del(struct fid_poll *pollset, struct fid *event_fid,
			 uint64_t flags)
{
	struct sock_poll *poll;
	struct sock_fid_list *list_item;
	struct dlist_entry *p, *head;
	struct sock_cq *cq;
	struct sock_cntr *cntr;

	poll = container_of(pollset, struct sock_poll, poll_fid.fid);
	head = &poll->fid_list;
	for (p = head->next; p != head; p = p->next) {
		list_item = container_of(p, struct sock_fid_list, entry);
		if (list_item->fid == event_fid) {
			dlist_remove(p);
			switch (list_item->fid->fclass) {
			case FI_CLASS_CQ:
				cq = container_of(list_item->fid, struct sock_cq, cq_fid);
				ofi_atomic_dec32(&cq->ref);
				break;
			case FI_CLASS_CNTR:
				cntr = container_of(list_item->fid, struct sock_cntr, cntr_fid);
				ofi_atomic_dec32(&cntr->ref);
				break;
			default:
				SOCK_LOG_ERROR("Invalid fid class\n");
				break;
			}
			free(list_item);
			break;
		}
	}
예제 #9
0
static int sock_poll_add(struct fid_poll *pollset, struct fid *event_fid,
			 uint64_t flags)
{
	struct sock_poll *poll;
	struct sock_fid_list *list_item;
	struct sock_cq *cq;
	struct sock_cntr *cntr;

	poll = container_of(pollset, struct sock_poll, poll_fid.fid);
	list_item = calloc(1, sizeof(*list_item));
	if (!list_item)
		return -FI_ENOMEM;

	list_item->fid = event_fid;
	dlist_init(&list_item->entry);
	dlist_insert_after(&list_item->entry, &poll->fid_list);

	switch (list_item->fid->fclass) {
	case FI_CLASS_CQ:
		cq = container_of(list_item->fid, struct sock_cq, cq_fid);
		ofi_atomic_inc32(&cq->ref);
		break;
	case FI_CLASS_CNTR:
		cntr = container_of(list_item->fid, struct sock_cntr, cntr_fid);
		ofi_atomic_inc32(&cntr->ref);
		break;
	default:
		SOCK_LOG_ERROR("Invalid fid class\n");
		return -FI_EINVAL;
	}
	return 0;
}
예제 #10
0
static ssize_t _sock_cq_write(struct sock_cq *cq, fi_addr_t addr,
			      const void *buf, size_t len)
{
	ssize_t ret;

	fastlock_acquire(&cq->lock);
	if (rbfdavail(&cq->cq_rbfd) < len) {
		ret = -FI_ENOSPC;
		SOCK_LOG_ERROR("Not enough space in CQ\n");
		goto out;
	}


	rbwrite(&cq->addr_rb, &addr, sizeof(addr));
	rbcommit(&cq->addr_rb);

	rbfdwrite(&cq->cq_rbfd, buf, len);
	rbfdcommit(&cq->cq_rbfd);
	ret = len;

	if (cq->signal) 
		sock_wait_signal(cq->waitset);
out:
	fastlock_release(&cq->lock);
	return ret;
}
예제 #11
0
struct sock_mr *sock_mr_verify_key(struct sock_domain *domain, uint64_t key,
				   void *buf, size_t len, uint64_t access)
{
	int i;
	struct sock_mr *mr;

	fastlock_acquire(&domain->lock);
	mr = sock_mr_get_entry(domain, key);
	if (!mr) {
		fastlock_release(&domain->lock);
		return NULL;
	}

	if (domain->attr.mr_mode == FI_MR_SCALABLE)
		buf = (char *)buf + mr->offset;

	for (i = 0; i < mr->iov_count; i++) {
		if ((uintptr_t)buf >= (uintptr_t)mr->mr_iov[i].iov_base &&
		    ((uintptr_t)buf + len <= (uintptr_t) mr->mr_iov[i].iov_base +
		     mr->mr_iov[i].iov_len)) {
			if ((access & mr->access) == access)
				goto out;
		}
	}
	SOCK_LOG_ERROR("MR check failed\n");
	mr = NULL;
out:
	fastlock_release(&domain->lock);
	return mr;
}
예제 #12
0
파일: sock_rx_entry.c 프로젝트: ORNL/ompi
struct sock_rx_entry *sock_rx_new_buffered_entry(struct sock_rx_ctx *rx_ctx,
						 size_t len)
{
	struct sock_rx_entry *rx_entry;

	if (rx_ctx->buffered_len + len >= rx_ctx->attr.total_buffered_recv) {
		SOCK_LOG_ERROR("Reached max buffered recv limit\n");
		return NULL;
	}

	rx_entry = calloc(1, sizeof(*rx_entry) + len);
	if (!rx_entry)
		return NULL;

	SOCK_LOG_INFO("New buffered entry:%p len: %lu, ctx: %p\n", 
		       rx_entry, len, rx_ctx);

	rx_entry->is_busy = 1;
	rx_entry->is_buffered = 1;
	rx_entry->rx_op.dest_iov_len = 1;
	rx_entry->iov[0].iov.len = len;
	rx_entry->iov[0].iov.addr = (uintptr_t) (rx_entry + 1);
	rx_entry->total_len = len;
	
	rx_ctx->buffered_len += len;
	dlist_insert_tail(&rx_entry->entry, &rx_ctx->rx_buffered_list);
	rx_entry->is_busy = 1;
	rx_entry->is_tagged = 0;

	return rx_entry;
}
예제 #13
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;
}
예제 #14
0
static int sock_dom_close(struct fid *fid)
{
	struct sock_domain *dom;
	void *res;
	int c;

	dom = container_of(fid, struct sock_domain, dom_fid.fid);
	if (atomic_get(&dom->ref)) {
		return -FI_EBUSY;
	}

	dom->listening = 0;
	write(dom->signal_fds[0], &c, 1);
	if (pthread_join(dom->listen_thread, &res)) {
		SOCK_LOG_ERROR("could not join listener thread, errno = %d\n", errno);
		return -FI_EBUSY;
	}

	if (dom->r_cmap.size)
		sock_conn_map_destroy(&dom->r_cmap);
	fastlock_destroy(&dom->r_cmap.lock);

	sock_pe_finalize(dom->pe);
	fastlock_destroy(&dom->lock);
	free(dom);
	return 0;
}
예제 #15
0
파일: sock_cq.c 프로젝트: Slbomber/ompi
static ssize_t sock_cq_entry_size(struct sock_cq *sock_cq)
{
	ssize_t size;

	switch(sock_cq->attr.format) {
	case FI_CQ_FORMAT_CONTEXT:
		size = sizeof(struct fi_cq_entry);
		break;

	case FI_CQ_FORMAT_MSG:
		size = sizeof(struct fi_cq_msg_entry);
		break;

	case FI_CQ_FORMAT_DATA:
		size = sizeof(struct fi_cq_data_entry);
		break;

	case FI_CQ_FORMAT_TAGGED:
		size = sizeof(struct fi_cq_tagged_entry);
		break;

	case FI_CQ_FORMAT_UNSPEC:
	default:
		size = -1;
		SOCK_LOG_ERROR("Invalid CQ format\n");
		break;
	}
	return size;
}
예제 #16
0
static ssize_t sock_ep_atomic_writemsg(struct fid_ep *ep,
			const struct fi_msg_atomic *msg, uint64_t flags)
{
#if ENABLE_DEBUG
	switch (msg->op) {
	case FI_MIN:
	case FI_MAX:
	case FI_SUM:
	case FI_PROD:
	case FI_LOR:
	case FI_LAND:
	case FI_BOR:
	case FI_BAND:
	case FI_LXOR:
	case FI_BXOR:
	case FI_ATOMIC_WRITE:
		break;
	default:
		SOCK_LOG_ERROR("Invalid operation type\n");
		return -FI_EINVAL;
	}
#endif
	return sock_ep_tx_atomic(ep, msg, NULL, NULL, 0,
				  NULL, NULL, 0, flags);
}
예제 #17
0
파일: sock_ep.c 프로젝트: nkogteva/ompi
static int sock_ctx_enable(struct fid_ep *ep)
{
	struct sock_tx_ctx *tx_ctx;
	struct sock_rx_ctx *rx_ctx;

	switch (ep->fid.fclass) {
	case FI_CLASS_RX_CTX:
		rx_ctx = container_of(ep, struct sock_rx_ctx, ctx.fid);
		rx_ctx->enabled = 1;
		if (!rx_ctx->progress) {
			sock_pe_add_rx_ctx(rx_ctx->domain->pe, rx_ctx);
			rx_ctx->progress = 1;
		}
		return 0;

	case FI_CLASS_TX_CTX:
		tx_ctx = container_of(ep, struct sock_tx_ctx, fid.ctx.fid);
		tx_ctx->enabled = 1;
		if (!tx_ctx->progress) {
			sock_pe_add_tx_ctx(tx_ctx->domain->pe, tx_ctx);
			tx_ctx->progress = 1;
		}
		return 0;

	default:
		SOCK_LOG_ERROR("Invalid CTX\n");
		break;
	}
	return -FI_EINVAL;
}
예제 #18
0
파일: sock_cq.c 프로젝트: Slbomber/ompi
static void sock_cq_set_report_fn(struct sock_cq *sock_cq)
{
	switch(sock_cq->attr.format) {
	case FI_CQ_FORMAT_CONTEXT:
		sock_cq->report_completion = &sock_cq_report_context;
		break;

	case FI_CQ_FORMAT_MSG:
		sock_cq->report_completion = &sock_cq_report_msg;
		break;

	case FI_CQ_FORMAT_DATA:
		sock_cq->report_completion = &sock_cq_report_data;
		break;

	case FI_CQ_FORMAT_TAGGED:
		sock_cq->report_completion = &sock_cq_report_tagged;
		break;

	case FI_CQ_FORMAT_UNSPEC:
	default:
		SOCK_LOG_ERROR("Invalid CQ format\n");
		break;
	}
}
예제 #19
0
static ssize_t sock_ep_atomic_readwritemsg(struct fid_ep *ep,
				const struct fi_msg_atomic *msg,
				struct fi_ioc *resultv, void **result_desc,
				size_t result_count, uint64_t flags)
{
	switch (msg->op) {
	case FI_MIN:
	case FI_MAX:
	case FI_SUM:
	case FI_PROD:
	case FI_LOR:
	case FI_LAND:
	case FI_BOR:
	case FI_BAND:
	case FI_LXOR:
	case FI_BXOR:
	case FI_ATOMIC_READ:
	case FI_ATOMIC_WRITE:
		break;
	default:
		SOCK_LOG_ERROR("Invalid operation type\n");
		return -FI_EINVAL;
	}

	return sock_ep_tx_atomic(ep, msg, NULL, NULL, 0,
				 resultv, result_desc, result_count, flags);
}
예제 #20
0
static ssize_t sock_ep_cancel(fid_t fid, void *context)
{
	struct sock_rx_ctx *rx_ctx = NULL;
	struct sock_ep *sock_ep;

	switch (fid->fclass) {
	case FI_CLASS_EP:
		sock_ep = container_of(fid, struct sock_ep, ep.fid);
		rx_ctx = sock_ep->attr->rx_ctx;
		break;

	case FI_CLASS_RX_CTX:
	case FI_CLASS_SRX_CTX:
		rx_ctx = container_of(fid, struct sock_rx_ctx, ctx.fid);
		break;

	case FI_CLASS_TX_CTX:
	case FI_CLASS_STX_CTX:
		return -FI_ENOENT;

	default:
		SOCK_LOG_ERROR("Invalid ep type\n");
		return -FI_EINVAL;
	}

	return sock_rx_ctx_cancel(rx_ctx, context);
}
예제 #21
0
static ssize_t sock_tx_size_left(struct fid_ep *ep)
{
	struct sock_ep *sock_ep;
	struct sock_tx_ctx *tx_ctx;
	ssize_t num_left = 0;

	switch (ep->fid.fclass) {
	case FI_CLASS_EP:
		sock_ep = container_of(ep, struct sock_ep, ep);
		tx_ctx = sock_ep->attr->tx_ctx;
		break;

	case FI_CLASS_TX_CTX:
		tx_ctx = container_of(ep, struct sock_tx_ctx, fid.ctx);
		break;

	default:
		SOCK_LOG_ERROR("Invalid EP type\n");
		return -FI_EINVAL;
	}

	fastlock_acquire(&tx_ctx->wlock);
	num_left = rbavail(&tx_ctx->rb)/SOCK_EP_TX_ENTRY_SZ;
	fastlock_release(&tx_ctx->wlock);
	return num_left;
}
예제 #22
0
void sock_set_sockopt_reuseaddr(int sock)
{
	int optval;
	optval = 1;
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)))
		SOCK_LOG_ERROR("setsockopt reuseaddr failed\n");
}
예제 #23
0
int sock_getopflags(struct fi_tx_attr *tx_attr, struct fi_rx_attr *rx_attr,
			uint64_t *flags)
{
	if ((*flags & FI_TRANSMIT) && (*flags & FI_RECV)) {
		SOCK_LOG_ERROR("Both Tx/Rx flags cannot be specified\n");
		return -FI_EINVAL;
	} else if (tx_attr && (*flags & FI_TRANSMIT)) {
		*flags = tx_attr->op_flags;
	} else if (rx_attr && (*flags & FI_RECV)) {
		*flags = rx_attr->op_flags;
	} else {
		SOCK_LOG_ERROR("Tx/Rx flags not specified\n");
		return -FI_EINVAL;
	}
	return 0;
}
예제 #24
0
static struct sock_conn *sock_conn_map_insert(struct sock_ep_attr *ep_attr,
				struct sockaddr_in *addr, int conn_fd,
				int addr_published)
{
	int index;
	struct sock_conn_map *map = &ep_attr->cmap;

	if (map->size == map->used) {
		index = sock_conn_get_next_index(map);
		if (index < 0) {
			if (sock_conn_map_increase(map, map->size * 2))
				return NULL;
			index = map->used;
			map->used++;
		}
	} else {
		index = map->used;
		map->used++;
	}

	map->table[index].av_index = FI_ADDR_NOTAVAIL;
	map->table[index].connected = 1;
	map->table[index].addr = *addr;
	map->table[index].sock_fd = conn_fd;
	map->table[index].ep_attr = ep_attr;
	sock_set_sockopts(conn_fd);

	if (fi_epoll_add(map->epoll_set, conn_fd, &map->table[index]))
		SOCK_LOG_ERROR("failed to add to epoll set: %d\n", conn_fd);

	map->table[index].address_published = addr_published;
	sock_pe_poll_add(ep_attr->domain->pe, conn_fd);
	return &map->table[index];
}
예제 #25
0
void sock_cntr_add_rx_ctx(struct sock_cntr *cntr, struct sock_rx_ctx *rx_ctx)
{
	int ret;
	struct fid *fid = &rx_ctx->ctx.fid;
	ret = fid_list_insert(&cntr->rx_list, &cntr->list_lock, fid);
	if (ret)
		SOCK_LOG_ERROR("Error in adding ctx to progress list\n");
}
예제 #26
0
void sock_set_sockopts_conn(int sock)
{
	int optval;
	optval = 1;
	sock_set_sockopt_reuseaddr(sock);
	if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval)))
		SOCK_LOG_ERROR("setsockopt nodelay failed\n");
}
예제 #27
0
static uint64_t sock_get_mr_key(struct sock_domain *dom)
{
	uint64_t i;
	for (i = 0; i < UINT64_MAX; i++) {
		if (!sock_mr_get_entry(dom, i))
			return i;
	}
	SOCK_LOG_ERROR("failed to get a free key\n");
	return UINT64_MAX;
}
예제 #28
0
void sock_cntr_add_tx_ctx(struct sock_cntr *cntr, struct sock_tx_ctx *tx_ctx)
{
	int ret;
	struct fid *fid = &tx_ctx->fid.ctx.fid;
	ret = fid_list_insert(&cntr->tx_list, &cntr->list_lock, fid);
	if (ret)
		SOCK_LOG_ERROR("Error in adding ctx to progress list\n");
	else
		atomic_inc(&cntr->ref);
}
예제 #29
0
static int sock_ep_cm_connect(struct fid_ep *ep, const void *addr,
			   const void *param, size_t paramlen)
{
	struct sock_conn_req *req;
	struct sock_ep *_ep;
	struct sock_eq *_eq;
	_ep = container_of(ep, struct sock_ep, ep);
	_eq = _ep->eq;
	if (!_eq || paramlen > SOCK_EP_MAX_CM_DATA_SZ) 
		return -FI_EINVAL;

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

	_ep->rem_ep_id = ((struct sockaddr *)addr)->sa_family;
	((struct sockaddr *)addr)->sa_family = AF_INET;

	req->hdr.type = SOCK_CONN_REQ;
	req->ep_id = _ep->ep_id;
	req->hdr.c_fid = &ep->fid;
	req->hdr.s_fid = 0;
	memcpy(&req->info, &_ep->info, sizeof(struct fi_info));
	memcpy(&req->src_addr, _ep->info.src_addr, sizeof(struct sockaddr_in));
	memcpy(&req->dest_addr, _ep->info.dest_addr, sizeof(struct sockaddr_in));
	memcpy(&req->tx_attr, _ep->info.tx_attr, sizeof(struct fi_tx_attr));
	memcpy(&req->rx_attr, _ep->info.rx_attr, sizeof(struct fi_rx_attr));
	memcpy(&req->ep_attr, _ep->info.ep_attr, sizeof(struct fi_ep_attr));
	memcpy(&req->domain_attr, _ep->info.domain_attr, sizeof(struct fi_domain_attr));
	memcpy(&req->fabric_attr, _ep->info.fabric_attr, sizeof(struct fi_fabric_attr));
	if (param && paramlen)
		memcpy(&req->user_data, param, paramlen);
	
	if (!_ep->socket) {
		_ep->socket = sock_ep_cm_create_socket();
		if (!_ep->socket) {
			free (req);
			return -FI_EIO;
		}
	}

	if (sock_ep_cm_send_msg(_ep->socket, addr, req, sizeof (*req) + paramlen))
		return -FI_EIO;

	if (pthread_create(&_ep->listener_thread, NULL, 
			   sock_msg_ep_listener_thread, (void *)_ep)) {
		SOCK_LOG_ERROR("Couldn't create listener thread\n");
		free (req);
		return -FI_EINVAL;
	}

	free (req);
	return 0;
}
예제 #30
0
파일: sock_cq.c 프로젝트: Slbomber/ompi
int sock_cq_check_size_ok(struct sock_cq *cq)
{
	int ret = 1;
	fastlock_acquire(&cq->lock);
	if (rbfdavail(&cq->cq_rbfd) < sock_cq_entry_size(cq)) {
		ret = 0;
		SOCK_LOG_ERROR("Not enough space in CQ\n");
	}
	fastlock_release(&cq->lock);
	return ret;
}