Example #1
0
static int sock_ep_tx_ctx(struct fid_ep *ep, int index, struct fi_tx_attr *attr,
			  struct fid_ep **tx_ep, void *context)
{
	struct sock_ep *sock_ep;
	struct sock_tx_ctx *tx_ctx;

	sock_ep = container_of(ep, struct sock_ep, ep);
	if (sock_ep->attr->fclass != FI_CLASS_SEP ||
		index >= sock_ep->attr->ep_attr.tx_ctx_cnt)
		return -FI_EINVAL;

	tx_ctx = sock_tx_ctx_alloc(&sock_ep->tx_attr, context, 0);
	if (!tx_ctx)
		return -FI_ENOMEM;

	tx_ctx->tx_id = index;
	tx_ctx->ep_attr = sock_ep->attr;
	tx_ctx->domain = sock_ep->attr->domain;
	tx_ctx->av = sock_ep->attr->av;
	dlist_insert_tail(&sock_ep->attr->tx_ctx_entry, &tx_ctx->ep_list);

	tx_ctx->fid.ctx.fid.ops = &sock_ctx_ops;
	tx_ctx->fid.ctx.ops = &sock_ctx_ep_ops;
	tx_ctx->fid.ctx.msg = &sock_ep_msg_ops;
	tx_ctx->fid.ctx.tagged = &sock_ep_tagged;
	tx_ctx->fid.ctx.rma = &sock_ep_rma;
	tx_ctx->fid.ctx.atomic = &sock_ep_atomic;

	*tx_ep = &tx_ctx->fid.ctx;
	sock_ep->attr->tx_array[index] = tx_ctx;
	atomic_inc(&sock_ep->attr->num_tx_ctx);
	atomic_inc(&sock_ep->attr->domain->ref);
	return 0;
}
Example #2
0
int sock_stx_ctx(struct fid_domain *domain,
		 struct fi_tx_attr *attr, struct fid_stx **stx, void *context)
{
	struct sock_domain *dom;
	struct sock_tx_ctx *tx_ctx;

	if (attr && sock_verify_tx_attr(attr))
		return -FI_EINVAL;

	dom = container_of(domain, struct sock_domain, dom_fid);
	
	tx_ctx = sock_tx_ctx_alloc(attr ? attr : &sock_stx_attr, context);
	if (!tx_ctx)
		return -FI_ENOMEM;

	tx_ctx->domain = dom;
	tx_ctx->fid.stx.fid.fclass = FI_CLASS_STX_CTX;

	tx_ctx->fid.stx.fid.ops = &sock_ctx_ops;
	tx_ctx->fid.stx.ops = &sock_ep_ops;
	atomic_inc(&dom->ref);

	*stx = &tx_ctx->fid.stx;
	return 0;
}
Example #3
0
static int sock_ep_tx_ctx(struct fid_ep *ep, int index, struct fi_tx_attr *attr,
			  struct fid_ep **tx_ep, void *context)
{
	struct sock_ep *sock_ep;
	struct sock_tx_ctx *tx_ctx;

	sock_ep = container_of(ep, struct sock_ep, ep);
	if (sock_ep->attr->fclass != FI_CLASS_SEP ||
		index >= (int)sock_ep->attr->ep_attr.tx_ctx_cnt)
		return -FI_EINVAL;

	if (attr) {
		if (ofi_check_tx_attr(&sock_prov, sock_ep->attr->info.tx_attr,
				      attr, 0) ||
			ofi_check_attr_subset(&sock_prov,
				sock_ep->attr->info.tx_attr->caps, attr->caps))
			return -FI_ENODATA;
		tx_ctx = sock_tx_ctx_alloc(attr, context, 0);
	} else {
		tx_ctx = sock_tx_ctx_alloc(&sock_ep->tx_attr, context, 0);
	}
	if (!tx_ctx)
		return -FI_ENOMEM;

	tx_ctx->tx_id = index;
	tx_ctx->ep_attr = sock_ep->attr;
	tx_ctx->domain = sock_ep->attr->domain;
	if (tx_ctx->rx_ctrl_ctx && tx_ctx->rx_ctrl_ctx->is_ctrl_ctx)
		tx_ctx->rx_ctrl_ctx->domain = sock_ep->attr->domain;
	tx_ctx->av = sock_ep->attr->av;
	dlist_insert_tail(&sock_ep->attr->tx_ctx_entry, &tx_ctx->ep_list);

	tx_ctx->fid.ctx.fid.ops = &sock_ctx_ops;
	tx_ctx->fid.ctx.ops = &sock_ctx_ep_ops;
	tx_ctx->fid.ctx.msg = &sock_ep_msg_ops;
	tx_ctx->fid.ctx.tagged = &sock_ep_tagged;
	tx_ctx->fid.ctx.rma = &sock_ep_rma;
	tx_ctx->fid.ctx.atomic = &sock_ep_atomic;

	*tx_ep = &tx_ctx->fid.ctx;
	sock_ep->attr->tx_array[index] = tx_ctx;
	ofi_atomic_inc32(&sock_ep->attr->num_tx_ctx);
	ofi_atomic_inc32(&sock_ep->attr->domain->ref);
	return 0;
}
Example #4
0
int sock_alloc_endpoint(struct fid_domain *domain, struct fi_info *info,
		  struct sock_ep **ep, void *context, size_t fclass)
{	
	int ret, flags;
	struct sock_ep *sock_ep;
	struct sock_tx_ctx *tx_ctx;
	struct sock_rx_ctx *rx_ctx;
	struct sock_domain *sock_dom;

	if (info) {
		ret = sock_verify_info(info);
		if (ret) {
			SOCK_LOG_INFO("Cannot support requested options!\n");
			return -FI_EINVAL;
		}
	}

	sock_dom = container_of(domain, struct sock_domain, dom_fid);
	sock_ep = (struct sock_ep*)calloc(1, sizeof(*sock_ep));
	if (!sock_ep)
		return -FI_ENOMEM;

	switch (fclass) {
	case FI_CLASS_EP:
		sock_ep->ep.fid.fclass = FI_CLASS_EP;
		sock_ep->ep.fid.context = context;	
		sock_ep->ep.fid.ops = &sock_ep_fi_ops;
		
		sock_ep->ep.ops = &sock_ep_ops;
		sock_ep->ep.cm = &sock_ep_cm_ops;
		sock_ep->ep.msg = &sock_ep_msg_ops;
		sock_ep->ep.rma = &sock_ep_rma;
		sock_ep->ep.tagged = &sock_ep_tagged;
		sock_ep->ep.atomic = &sock_ep_atomic;
		break;

	case FI_CLASS_SEP:
		sock_ep->ep.fid.fclass = FI_CLASS_SEP;
		sock_ep->ep.fid.context = context;	
		sock_ep->ep.fid.ops = &sock_ep_fi_ops;
		
		sock_ep->ep.ops = &sock_ep_ops;
		sock_ep->ep.cm = &sock_ep_cm_ops;
		break;

	default:
		goto err;
	}

	sock_ep->fclass = fclass;
	*ep = sock_ep;	

	fastlock_acquire(&sock_dom->lock);
	fastlock_release(&sock_dom->lock);

	if (info) {
		sock_ep->info.caps = info->caps;
		sock_ep->info.addr_format = FI_SOCKADDR_IN;

		if (info->ep_attr) {
			sock_ep->ep_type = info->ep_attr->type;
			sock_ep->ep_attr.tx_ctx_cnt = info->ep_attr->tx_ctx_cnt;
			sock_ep->ep_attr.rx_ctx_cnt = info->ep_attr->rx_ctx_cnt;
		}
		
		if (info->src_addr) {
			sock_ep->src_addr = calloc(1, sizeof(struct sockaddr_in));
			memcpy(sock_ep->src_addr, info->src_addr, 
			       sizeof(struct sockaddr_in));
		}
		
		if (info->dest_addr) {
			sock_ep->dest_addr = calloc(1, sizeof(struct sockaddr_in));
			memcpy(sock_ep->dest_addr, info->dest_addr, 
			       sizeof(struct sockaddr_in));
		}
		
		if (info->tx_attr) {
			sock_ep->tx_attr = *info->tx_attr;
			sock_ep->op_flags = info->tx_attr->op_flags;
			sock_ep->tx_attr.size = sock_ep->tx_attr.size ?
				sock_ep->tx_attr.size : 
				(SOCK_EP_TX_SZ * SOCK_EP_TX_ENTRY_SZ);
		}
		
		if (info->rx_attr) {
			sock_ep->rx_attr = *info->rx_attr;
			sock_ep->op_flags |= info->rx_attr->op_flags;
			sock_ep->rx_attr.total_buffered_recv = 
				sock_ep->rx_attr.total_buffered_recv ?
				sock_ep->rx_attr.total_buffered_recv : 
				SOCK_EP_MAX_BUFF_RECV;
		}
		sock_ep->info.connreq = info->connreq;
	}
	
	atomic_init(&sock_ep->ref, 0);
	atomic_init(&sock_ep->num_tx_ctx, 0);
	atomic_init(&sock_ep->num_rx_ctx, 0);

	if (sock_ep->ep_attr.tx_ctx_cnt == FI_SHARED_CONTEXT)
		sock_ep->tx_shared = 1;
	if (sock_ep->ep_attr.rx_ctx_cnt == FI_SHARED_CONTEXT)
		sock_ep->rx_shared = 1;

	if (sock_ep->fclass != FI_CLASS_SEP) {
		sock_ep->ep_attr.tx_ctx_cnt = 1;
		sock_ep->ep_attr.rx_ctx_cnt = 1;
	}

	sock_ep->tx_array = calloc(sock_ep->ep_attr.tx_ctx_cnt, 
				   sizeof(struct sock_tx_ctx *));
	
	sock_ep->rx_array = calloc(sock_ep->ep_attr.rx_ctx_cnt,
				   sizeof(struct sock_rx_ctx *));

	if (sock_ep->fclass != FI_CLASS_SEP &&
	    sock_ep->ep_attr.tx_ctx_cnt != FI_SHARED_CONTEXT) {
		/* default tx ctx */
		tx_ctx = sock_tx_ctx_alloc(&sock_ep->tx_attr, context);
		tx_ctx->ep = sock_ep;
		tx_ctx->domain = sock_dom;
		tx_ctx->tx_id = 0;
		dlist_insert_tail(&sock_ep->tx_ctx_entry, &tx_ctx->ep_list);
		sock_ep->tx_array[0] = tx_ctx;
		sock_ep->tx_ctx = tx_ctx;
	}

	if (sock_ep->fclass != FI_CLASS_SEP &&
	    sock_ep->ep_attr.rx_ctx_cnt != FI_SHARED_CONTEXT) {
		/* default rx_ctx */
		rx_ctx = sock_rx_ctx_alloc(&sock_ep->rx_attr, context);
		rx_ctx->ep = sock_ep;
		rx_ctx->domain = sock_dom;
		rx_ctx->rx_id = 0;
		dlist_insert_tail(&sock_ep->rx_ctx_entry, &rx_ctx->ep_list);
		sock_ep->rx_array[0] = rx_ctx;
		sock_ep->rx_ctx = rx_ctx;
	}
	
	/* default config */
	sock_ep->min_multi_recv = SOCK_EP_MIN_MULTI_RECV;
	
	if (info) {
		memcpy(&sock_ep->info, info, sizeof(struct fi_info));
	}

  	sock_ep->domain = sock_dom;
	if (sock_conn_listen(sock_ep))
		goto err;

	if (sock_ep->ep_type == FI_EP_MSG) {
		dlist_init(&sock_ep->cm.msg_list);
		if (socketpair(AF_UNIX, SOCK_STREAM, 0, 
			       sock_ep->cm.signal_fds) < 0)
			goto err;

		flags = fcntl(sock_ep->cm.signal_fds[1], F_GETFL, 0);
		if (fcntl(sock_ep->cm.signal_fds[1], F_SETFL, flags | O_NONBLOCK))
			SOCK_LOG_ERROR("fcntl failed");
	}

	atomic_inc(&sock_dom->ref);
	return 0;
	
err:
	free(sock_ep);
	return -FI_EINVAL;
}