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; }
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; }
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; }
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; }