static int fi_bgq_tx_ctx(struct fid_ep *sep, int index, struct fi_tx_attr *attr, struct fid_ep **tx_ep, void *context) { int ret; struct fi_info info = {0}; struct fi_tx_attr tx_attr = {0}; struct fi_ep_attr ep_attr = {0}; struct fi_domain_attr dom_attr = {0}; struct fi_fabric_attr fab_attr = {0}; struct fi_bgq_sep *bgq_sep; struct fi_bgq_ep *bgq_tx_ep; if (!sep || !attr || !tx_ep) { errno = FI_EINVAL; return -errno; } bgq_sep = container_of(sep, struct fi_bgq_sep, ep_fid); uint64_t caps = attr->caps; /* TODO - "By default, a transmit context inherits the properties of its associated endpoint. However, applications may request context specific attributes through the attr parameter." */ if ((caps & FI_MSG || caps & FI_TAGGED) && (caps & FI_RECV)) { FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_DOMAIN, "FI_MSG|FI_TAGGED with FI_RECV capability specified for a TX context\n"); caps &= ~FI_RECV; } if ((caps & FI_RMA || caps & FI_ATOMIC) && (caps & FI_REMOTE_READ || caps & FI_REMOTE_WRITE)) { FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_DOMAIN, "FI_RMA|FI_ATOMIC with FI_REMOTE_READ|FI_REMOTE_WRITE capability specified for a TX context\n"); caps &= ~FI_REMOTE_READ; caps &= ~FI_REMOTE_WRITE; } if (caps & FI_MSG || caps & FI_TAGGED) { caps |= FI_SEND; } if (caps & FI_RMA || caps & FI_ATOMIC) { caps |= FI_READ; caps |= FI_WRITE; } if (ofi_recv_allowed(caps) || ofi_rma_target_allowed(caps)) { FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_DOMAIN, "RX capabilities specified for TX context\n"); errno = FI_EINVAL; return -errno; } if (!ofi_send_allowed(caps) && !ofi_rma_initiate_allowed(caps)) { FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_DOMAIN, "TX capabilities not specified for TX context\n"); errno = FI_EINVAL; return -errno; } if (bgq_sep->domain->tx.count >= fi_bgq_domain_get_tx_max(bgq_sep->domain)) { FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_DOMAIN, "TX ctx count exceeded (max %lu, created %lu)\n", fi_bgq_domain_get_tx_max(bgq_sep->domain), bgq_sep->domain->tx.count); errno = FI_EINVAL; return -errno; } info.caps = caps; info.mode = attr->mode; info.tx_attr = &tx_attr; memcpy(info.tx_attr, attr, sizeof(*info.tx_attr)); info.ep_attr = &ep_attr; memcpy(info.ep_attr, bgq_sep->info->ep_attr, sizeof(*info.ep_attr)); info.domain_attr = &dom_attr; memcpy(info.domain_attr, bgq_sep->info->domain_attr, sizeof(*info.domain_attr)); info.fabric_attr = &fab_attr; memcpy(info.fabric_attr, bgq_sep->info->fabric_attr, sizeof(*info.fabric_attr)); ret = fi_bgq_endpoint_rx_tx((struct fid_domain *)bgq_sep->domain, &info, tx_ep, context, -1, index); if (ret) { goto err; } bgq_tx_ep = container_of(*tx_ep, struct fi_bgq_ep, ep_fid); bgq_tx_ep->ep_fid.fid.fclass = FI_CLASS_TX_CTX; bgq_tx_ep->av = bgq_sep->av; fi_bgq_ref_inc(&bgq_tx_ep->av->ref_cnt, "address vector"); bgq_tx_ep->sep = container_of(sep, struct fi_bgq_sep, ep_fid); ++ bgq_sep->domain->tx.count; fi_bgq_ref_inc(&bgq_sep->ref_cnt, "scalable endpoint"); attr->caps = caps; return 0; err: return -errno; }
static int fi_ibv_msg_ep_enable(struct fid_ep *ep) { struct ibv_qp_init_attr attr; struct fi_ibv_msg_ep *_ep; struct ibv_pd *pd; _ep = container_of(ep, struct fi_ibv_msg_ep, ep_fid); if (!_ep->eq) { VERBS_WARN(FI_LOG_EP_CTRL, "Endpoint is not bound to an event queue\n"); return -FI_ENOEQ; } if (!_ep->scq && !_ep->rcq) { VERBS_WARN(FI_LOG_EP_CTRL, "Endpoint is not bound to " "a send or receive completion queue\n"); return -FI_ENOCQ; } if (!_ep->scq && (ofi_send_allowed(_ep->info->caps) || ofi_rma_initiate_allowed(_ep->info->caps))) { VERBS_WARN(FI_LOG_EP_CTRL, "Endpoint is not bound to " "a send completion queue when it has transmit " "capabilities enabled (FI_SEND | FI_RMA).\n"); return -FI_ENOCQ; } if (!_ep->rcq && ofi_recv_allowed(_ep->info->caps)) { VERBS_WARN(FI_LOG_EP_CTRL, "Endpoint is not bound to " "a receive completion queue when it has receive " "capabilities enabled. (FI_RECV)\n"); return -FI_ENOCQ; } memset(&attr, 0, sizeof attr); if (_ep->scq) { attr.cap.max_send_wr = _ep->info->tx_attr->size; attr.cap.max_send_sge = _ep->info->tx_attr->iov_limit; attr.send_cq = _ep->scq->cq; pd = _ep->scq->domain->pd; } else { attr.send_cq = _ep->rcq->cq; pd = _ep->rcq->domain->pd; } if (_ep->rcq) { attr.cap.max_recv_wr = _ep->info->rx_attr->size; attr.cap.max_recv_sge = _ep->info->rx_attr->iov_limit; attr.recv_cq = _ep->rcq->cq; } else { attr.recv_cq = _ep->scq->cq; } attr.cap.max_inline_data = _ep->info->tx_attr->inject_size; if (_ep->srq_ep) { attr.srq =_ep->srq_ep->srq; /* Use of SRQ, no need to allocate recv_wr entries in the QP */ attr.cap.max_recv_wr = 0; /* Override the default ops to prevent the user from posting WRs to a * QP where a SRQ is attached to */ _ep->ep_fid.msg = fi_ibv_msg_srq_ep_ops_msg(_ep); } attr.qp_type = IBV_QPT_RC; attr.sq_sig_all = 0; attr.qp_context = _ep; return rdma_create_qp(_ep->id, pd, &attr) ? -errno : 0; }
static int fi_bgq_rx_ctx(struct fid_ep *sep, int index, struct fi_rx_attr *attr, struct fid_ep **rx_ep, void *context) { int ret; struct fi_info info = {0}; struct fi_bgq_sep *bgq_sep; struct fi_bgq_ep *bgq_rx_ep; if (!sep || !attr || !rx_ep) { errno = FI_EINVAL; return -errno; } bgq_sep = container_of(sep, struct fi_bgq_sep, ep_fid); uint64_t caps = attr->caps; /* TODO - "By default, a receive context inherits the properties of its associated endpoint. However, applications may request context specific attributes through the attr parameter." */ if ((caps & FI_MSG || caps & FI_TAGGED) && (caps & FI_SEND)) { FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_DOMAIN, "FI_MSG|FI_TAGGED with FI_SEND capability specified for a RX context\n"); caps &= ~FI_SEND; } if ((caps & FI_RMA || caps & FI_ATOMIC) && (caps & FI_READ || caps & FI_WRITE)) { FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_DOMAIN, "FI_RMA|FI_ATOMIC with FI_READ|FI_WRITE capability specified for a RX context\n"); caps &= ~FI_READ; caps &= ~FI_WRITE; } if (caps & FI_MSG || caps & FI_TAGGED) { caps |= FI_RECV; } if (caps & FI_RMA || caps & FI_ATOMIC) { caps |= FI_REMOTE_READ; caps |= FI_REMOTE_WRITE; } if (ofi_send_allowed(caps) || ofi_rma_initiate_allowed(caps)) { FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_DOMAIN, "TX capabilities specified for RX context\n"); errno = FI_EINVAL; return -errno; } if (!ofi_recv_allowed(caps) && !ofi_rma_target_allowed(caps)) { FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_DOMAIN, "RX capabilities not specified for RX context\n"); errno = FI_EINVAL; return -errno; } if (bgq_sep->domain->rx.count >= fi_bgq_domain_get_rx_max(bgq_sep->domain)) { FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_DOMAIN, "RX ctx count exceeded (max %lu, created %lu)\n", fi_bgq_domain_get_rx_max(bgq_sep->domain), bgq_sep->domain->rx.count); errno = FI_EINVAL; return -errno; } info.caps = caps; info.mode = attr->mode; info.rx_attr = calloc(1, sizeof(*info.rx_attr)); if (!info.rx_attr) { errno = FI_ENOMEM; goto err; } info.rx_attr->caps = caps; info.rx_attr->mode = attr->mode; info.rx_attr->op_flags = attr->op_flags; info.rx_attr->msg_order = attr->msg_order; info.rx_attr->total_buffered_recv = attr->total_buffered_recv; info.rx_attr->iov_limit = attr->iov_limit; info.ep_attr = calloc(1, sizeof(*info.ep_attr)); if (!info.ep_attr) { errno = FI_ENOMEM; goto err; } memcpy(info.ep_attr, bgq_sep->info->ep_attr, sizeof(*info.ep_attr)); info.domain_attr = calloc(1, sizeof(*info.domain_attr)); if (!info.domain_attr) { errno = FI_ENOMEM; goto err; } memcpy(info.domain_attr, bgq_sep->info->domain_attr, sizeof(*info.domain_attr)); info.fabric_attr = calloc(1, sizeof(*info.fabric_attr)); if (!info.fabric_attr) { errno = FI_ENOMEM; goto err; } memcpy(info.fabric_attr, bgq_sep->info->fabric_attr, sizeof(*info.fabric_attr)); ret = fi_bgq_endpoint_rx_tx(&bgq_sep->domain->domain_fid, &info, rx_ep, context, index, -1); if (ret) { goto err; } bgq_rx_ep = container_of(*rx_ep, struct fi_bgq_ep, ep_fid); bgq_rx_ep->ep_fid.fid.fclass = FI_CLASS_RX_CTX; bgq_rx_ep->sep = container_of(sep, struct fi_bgq_sep, ep_fid); bgq_rx_ep->av = bgq_sep->av; fi_bgq_ref_inc(&bgq_rx_ep->av->ref_cnt, "address vector"); ++ bgq_sep->domain->rx.count; fi_bgq_ref_inc(&bgq_sep->ref_cnt, "scalable endpoint"); return 0; err: if (info.fabric_attr) free(info.fabric_attr); if (info.domain_attr) free(info.domain_attr); if (info.ep_attr) free(info.ep_attr); if (info.tx_attr) free(info.tx_attr); return -errno; }