int ofi_check_tx_attr(const struct fi_provider *prov, const struct fi_tx_attr *prov_attr, const struct fi_tx_attr *user_attr) { if (user_attr->caps & ~(prov_attr->caps)) { FI_INFO(prov, FI_LOG_CORE, "caps not supported\n"); FI_INFO_CAPS(prov, prov_attr, user_attr, caps, FI_TYPE_CAPS); return -FI_ENODATA; } if ((user_attr->mode & prov_attr->mode) != prov_attr->mode) { FI_INFO(prov, FI_LOG_CORE, "needed mode not set\n"); FI_INFO_MODE(prov, prov_attr, user_attr); return -FI_ENODATA; } if (prov_attr->op_flags & ~(prov_attr->op_flags)) { FI_INFO(prov, FI_LOG_CORE, "op_flags not supported\n"); FI_INFO_CAPS(prov, prov_attr, user_attr, op_flags, FI_TYPE_OP_FLAGS); return -FI_ENODATA; } if (user_attr->msg_order & ~(prov_attr->msg_order)) { FI_INFO(prov, FI_LOG_CORE, "msg_order not supported\n"); FI_INFO_CAPS(prov, prov_attr, user_attr, msg_order, FI_TYPE_MSG_ORDER); return -FI_ENODATA; } if (user_attr->comp_order & ~(prov_attr->comp_order)) { FI_INFO(prov, FI_LOG_CORE, "comp_order not supported\n"); FI_INFO_CAPS(prov, prov_attr, user_attr, comp_order, FI_TYPE_MSG_ORDER); return -FI_ENODATA; } if (user_attr->inject_size > prov_attr->inject_size) { FI_INFO(prov, FI_LOG_CORE, "inject_size too large\n"); return -FI_ENODATA; } if (user_attr->size > prov_attr->size) { FI_INFO(prov, FI_LOG_CORE, "size is greater than supported\n"); return -FI_ENODATA; } if (user_attr->iov_limit > prov_attr->iov_limit) { FI_INFO(prov, FI_LOG_CORE, "iov_limit too large\n"); return -FI_ENODATA; } if (user_attr->rma_iov_limit > prov_attr->rma_iov_limit) { FI_INFO(prov, FI_LOG_CORE, "rma_iov_limit too large\n"); return -FI_ENODATA; } return 0; }
int fi_ibv_check_tx_attr(const struct fi_tx_attr *attr, const struct fi_info *hints, const struct fi_info *info) { if (attr->caps & ~(info->tx_attr->caps)) { VERBS_INFO(FI_LOG_CORE, "Given tx_attr->caps not supported\n"); FI_INFO_CHECK(&fi_ibv_prov, (info->tx_attr), attr, caps, FI_TYPE_CAPS); return -FI_ENODATA; } if (((attr->mode ? attr->mode : hints->mode) & info->tx_attr->mode) != info->tx_attr->mode) { size_t user_mode = (attr->mode ? attr->mode : hints->mode); VERBS_INFO(FI_LOG_CORE, "Given tx_attr->mode not supported\n"); FI_INFO_MODE(&fi_ibv_prov, info->tx_attr->mode, user_mode); return -FI_ENODATA; } if (attr->op_flags & ~(info->tx_attr->op_flags)) { VERBS_INFO(FI_LOG_CORE, "Given tx_attr->op_flags not supported\n"); return -FI_ENODATA; } if (attr->msg_order & ~(info->tx_attr->msg_order)) { VERBS_INFO(FI_LOG_CORE, "Given tx_attr->msg_order not supported\n"); return -FI_ENODATA; } if (attr->size > info->tx_attr->size) { VERBS_INFO(FI_LOG_CORE, "Given tx_attr->size is greater than supported\n"); FI_INFO_CHECK_VAL(&fi_ibv_prov, (info->tx_attr), attr, size); return -FI_ENODATA; } if (attr->iov_limit > info->tx_attr->iov_limit) { VERBS_INFO(FI_LOG_CORE, "Given tx_attr->iov_limit greater than supported\n"); FI_INFO_CHECK_VAL(&fi_ibv_prov, (info->tx_attr), attr, iov_limit); return -FI_ENODATA; } if (attr->rma_iov_limit > info->tx_attr->rma_iov_limit) { VERBS_INFO(FI_LOG_CORE, "Given tx_attr->rma_iov_limit greater than supported\n"); FI_INFO_CHECK_VAL(&fi_ibv_prov, (info->tx_attr), attr, rma_iov_limit); return -FI_ENODATA; } return 0; }
static int fi_ibv_check_hints(uint32_t version, const struct fi_info *hints, const struct fi_info *info) { int ret; uint64_t prov_mode; if (hints->caps & ~(info->caps)) { VERBS_INFO(FI_LOG_CORE, "Unsupported capabilities\n"); FI_INFO_CHECK(&fi_ibv_prov, info, hints, caps, FI_TYPE_CAPS); return -FI_ENODATA; } prov_mode = ofi_mr_get_prov_mode(version, hints, info); if ((hints->mode & prov_mode) != prov_mode) { VERBS_INFO(FI_LOG_CORE, "needed mode not set\n"); FI_INFO_MODE(&fi_ibv_prov, prov_mode, hints->mode); return -FI_ENODATA; } if (hints->fabric_attr) { ret = ofi_check_fabric_attr(&fi_ibv_prov, info->fabric_attr, hints->fabric_attr); if (ret) return ret; } if (hints->domain_attr) { ret = ofi_check_domain_attr(&fi_ibv_prov, version, info->domain_attr, hints->domain_attr); if (ret) return ret; } if (hints->ep_attr) { ret = fi_ibv_check_ep_attr(hints->ep_attr, info); if (ret) return ret; } if (hints->rx_attr) { ret = fi_ibv_check_rx_attr(hints->rx_attr, hints, info); if (ret) return ret; } if (hints->tx_attr) { ret = fi_ibv_check_tx_attr(hints->tx_attr, hints, info); if (ret) return ret; } return 0; }
static int efa_check_hints(uint32_t version, const struct fi_info *hints, const struct fi_info *info) { uint64_t prov_mode; size_t size; int ret; if (hints->caps & ~(info->caps)) { EFA_INFO(FI_LOG_CORE, "Unsupported capabilities\n"); FI_INFO_CHECK(&efa_prov, info, hints, caps, FI_TYPE_CAPS); return -FI_ENODATA; } prov_mode = ofi_mr_get_prov_mode(version, hints, info); if ((hints->mode & prov_mode) != prov_mode) { EFA_INFO(FI_LOG_CORE, "Required hints mode bits not set\n"); FI_INFO_MODE(&efa_prov, prov_mode, hints->mode); return -FI_ENODATA; } if (hints->fabric_attr) { ret = ofi_check_fabric_attr(&efa_prov, info->fabric_attr, hints->fabric_attr); if (ret) return ret; } switch (hints->addr_format) { case FI_FORMAT_UNSPEC: case FI_ADDR_EFA: size = EFA_EP_ADDR_LEN; break; default: EFA_INFO(FI_LOG_CORE, "Address format not supported: hints[%u], supported[%u,%u]\n", hints->addr_format, FI_FORMAT_UNSPEC, FI_ADDR_EFA); return -FI_ENODATA; } if (hints->src_addr && hints->src_addrlen < size) return -FI_ENODATA; if (hints->dest_addr && hints->dest_addrlen < size) return -FI_ENODATA; if (hints->domain_attr) { ret = ofi_check_domain_attr(&efa_prov, version, info->domain_attr, hints); if (ret) return ret; } if (hints->ep_attr) { ret = ofi_check_ep_attr(&efa_util_prov, info->fabric_attr->api_version, info, hints); if (ret) return ret; } if (hints->rx_attr) { ret = ofi_check_rx_attr(&efa_prov, info, hints->rx_attr, hints->mode); if (ret) return ret; } if (hints->tx_attr) { ret = ofi_check_tx_attr(&efa_prov, info->tx_attr, hints->tx_attr, hints->mode); if (ret) return ret; } return 0; }
int ofi_check_info(const struct util_prov *util_prov, const struct fi_info *user_info, enum fi_match_type type) { const struct fi_info *prov_info = util_prov->info; const struct fi_provider *prov = util_prov->prov; int ret; if (!user_info) return 0; if (user_info->caps & ~(prov_info->caps)) { FI_INFO(prov, FI_LOG_CORE, "Unsupported capabilities\n"); FI_INFO_CAPS(prov, prov_info, user_info, caps, FI_TYPE_CAPS); return -FI_ENODATA; } if ((user_info->mode & prov_info->mode) != prov_info->mode) { FI_INFO(prov, FI_LOG_CORE, "needed mode not set\n"); FI_INFO_MODE(prov, prov_info, user_info); return -FI_ENODATA; } if (!fi_valid_addr_format(prov_info->addr_format, user_info->addr_format)) { FI_INFO(prov, FI_LOG_CORE, "address format not supported\n"); return -FI_ENODATA; } if (user_info->fabric_attr) { ret = ofi_check_fabric_attr(prov, prov_info->fabric_attr, user_info->fabric_attr, type); if (ret) return ret; } if (user_info->domain_attr) { ret = ofi_check_domain_attr(prov, prov_info->domain_attr, user_info->domain_attr, type); if (ret) return ret; } if (user_info->ep_attr) { ret = ofi_check_ep_attr(util_prov, user_info->ep_attr); if (ret) return ret; } if (user_info->rx_attr) { ret = ofi_check_rx_attr(prov, prov_info->rx_attr, user_info->rx_attr); if (ret) return ret; } if (user_info->tx_attr) { ret = ofi_check_tx_attr(prov, prov_info->tx_attr, user_info->tx_attr); if (ret) return ret; } return 0; }
int ofi_check_domain_attr(const struct fi_provider *prov, const struct fi_domain_attr *prov_attr, const struct fi_domain_attr *user_attr, enum fi_match_type type) { if (user_attr->name && fi_check_name(user_attr->name, prov_attr->name, type)) { FI_INFO(prov, FI_LOG_CORE, "Unknown domain name\n"); return -FI_ENODATA; } if (fi_thread_level(user_attr->threading) < fi_thread_level(prov_attr->threading)) { FI_INFO(prov, FI_LOG_CORE, "Invalid threading model\n"); return -FI_ENODATA; } if (fi_progress_level(user_attr->control_progress) < fi_progress_level(prov_attr->control_progress)) { FI_INFO(prov, FI_LOG_CORE, "Invalid control progress model\n"); return -FI_ENODATA; } if (fi_progress_level(user_attr->data_progress) < fi_progress_level(prov_attr->data_progress)) { FI_INFO(prov, FI_LOG_CORE, "Invalid data progress model\n"); return -FI_ENODATA; } if (fi_resource_mgmt_level(user_attr->resource_mgmt) < fi_resource_mgmt_level(prov_attr->resource_mgmt)) { FI_INFO(prov, FI_LOG_CORE, "Invalid resource mgmt model\n"); return -FI_ENODATA; } if ((prov_attr->av_type != FI_AV_UNSPEC) && (user_attr->av_type != FI_AV_UNSPEC) && (prov_attr->av_type != user_attr->av_type)) { FI_INFO(prov, FI_LOG_CORE, "Invalid AV type\n"); return -FI_ENODATA; } if (user_attr->mr_mode && (user_attr->mr_mode != prov_attr->mr_mode)) { FI_INFO(prov, FI_LOG_CORE, "Invalid memory registration mode\n"); return -FI_ENODATA; } if (user_attr->cq_data_size > prov_attr->cq_data_size) { FI_INFO(prov, FI_LOG_CORE, "CQ data size too large\n"); return -FI_ENODATA; } if (user_attr->caps & ~(prov_attr->caps)) { FI_INFO(prov, FI_LOG_CORE, "Requested domain caps not supported\n"); FI_INFO_CAPS(prov, prov_attr, user_attr, caps, FI_TYPE_CAPS); return -FI_ENODATA; } if ((user_attr->mode & prov_attr->mode) != prov_attr->mode) { FI_INFO(prov, FI_LOG_CORE, "Required domain mode missing\n"); FI_INFO_MODE(prov, prov_attr, user_attr); return -FI_ENODATA; } return 0; }
/* if there is only single fi_info in the provider */ int ofi_check_info(const struct util_prov *util_prov, const struct fi_info *prov_info, uint32_t api_version, const struct fi_info *user_info) { const struct fi_provider *prov = util_prov->prov; uint64_t prov_mode; int ret; if (!user_info) return 0; /* Check oft-used endpoint type attribute first to avoid any other * unnecessary check */ if (user_info->ep_attr) { ret = ofi_check_ep_type(prov, prov_info->ep_attr, user_info->ep_attr); if (ret) return ret; } if (user_info->caps & ~(prov_info->caps)) { FI_INFO(prov, FI_LOG_CORE, "Unsupported capabilities\n"); FI_INFO_CHECK(prov, prov_info, user_info, caps, FI_TYPE_CAPS); return -FI_ENODATA; } prov_mode = ofi_mr_get_prov_mode(api_version, user_info, prov_info); if ((user_info->mode & prov_mode) != prov_mode) { FI_INFO(prov, FI_LOG_CORE, "needed mode not set\n"); FI_INFO_MODE(prov, prov_mode, user_info->mode); return -FI_ENODATA; } if (!fi_valid_addr_format(prov_info->addr_format, user_info->addr_format)) { FI_INFO(prov, FI_LOG_CORE, "address format not supported\n"); FI_INFO_CHECK(prov, prov_info, user_info, addr_format, FI_TYPE_ADDR_FORMAT); return -FI_ENODATA; } if (user_info->fabric_attr) { ret = ofi_check_fabric_attr(prov, prov_info->fabric_attr, user_info->fabric_attr); if (ret) return ret; } if (user_info->domain_attr) { ret = ofi_check_domain_attr(prov, api_version, prov_info->domain_attr, user_info); if (ret) return ret; } if (user_info->ep_attr) { ret = ofi_check_ep_attr(util_prov, api_version, prov_info, user_info); if (ret) return ret; } if (user_info->rx_attr) { ret = ofi_check_rx_attr(prov, prov_info, user_info->rx_attr, user_info->mode); if (ret) return ret; } if (user_info->tx_attr) { ret = ofi_check_tx_attr(prov, prov_info->tx_attr, user_info->tx_attr, user_info->mode); if (ret) return ret; } return 0; }
int ofi_check_rx_attr(const struct fi_provider *prov, const struct fi_info *prov_info, const struct fi_rx_attr *user_attr, uint64_t info_mode) { const struct fi_rx_attr *prov_attr = prov_info->rx_attr; int rm_enabled = (prov_info->domain_attr->resource_mgmt == FI_RM_ENABLED); if (user_attr->caps & ~(prov_attr->caps)) { FI_INFO(prov, FI_LOG_CORE, "caps not supported\n"); FI_INFO_CHECK(prov, prov_attr, user_attr, caps, FI_TYPE_CAPS); return -FI_ENODATA; } info_mode = user_attr->mode ? user_attr->mode : info_mode; if ((info_mode & prov_attr->mode) != prov_attr->mode) { FI_INFO(prov, FI_LOG_CORE, "needed mode not set\n"); FI_INFO_MODE(prov, prov_attr->mode, user_attr->mode); return -FI_ENODATA; } if (prov_attr->op_flags & ~(prov_attr->op_flags)) { FI_INFO(prov, FI_LOG_CORE, "op_flags not supported\n"); FI_INFO_CHECK(prov, prov_attr, user_attr, op_flags, FI_TYPE_OP_FLAGS); return -FI_ENODATA; } if (user_attr->msg_order & ~(prov_attr->msg_order)) { FI_INFO(prov, FI_LOG_CORE, "msg_order not supported\n"); FI_INFO_CHECK(prov, prov_attr, user_attr, msg_order, FI_TYPE_MSG_ORDER); return -FI_ENODATA; } if (user_attr->comp_order & ~(prov_attr->comp_order)) { FI_INFO(prov, FI_LOG_CORE, "comp_order not supported\n"); FI_INFO_CHECK(prov, prov_attr, user_attr, comp_order, FI_TYPE_MSG_ORDER); return -FI_ENODATA; } if (user_attr->total_buffered_recv > prov_attr->total_buffered_recv) { FI_INFO(prov, FI_LOG_CORE, "total_buffered_recv too large\n"); FI_INFO_CHECK_VAL(prov, prov_attr, user_attr, total_buffered_recv); return -FI_ENODATA; } if (user_attr->size > prov_attr->size) { FI_INFO(prov, FI_LOG_CORE, "size is greater than supported\n"); FI_INFO_CHECK_VAL(prov, prov_attr, user_attr, size); return -FI_ENODATA; } if (user_attr->iov_limit > prov_attr->iov_limit) { FI_INFO(prov, FI_LOG_CORE, "iov_limit too large\n"); FI_INFO_CHECK_VAL(prov, prov_attr, user_attr, iov_limit); return -FI_ENODATA; } if (!rm_enabled && user_attr->total_buffered_recv > prov_attr->total_buffered_recv) { /* Just log a notification, but ignore the value */ FI_INFO(prov, FI_LOG_CORE, "Total buffered recv size exceeds supported size\n"); FI_INFO_CHECK_VAL(prov, prov_attr, user_attr, total_buffered_recv); } return 0; }
int ofi_check_domain_attr(const struct fi_provider *prov, uint32_t api_version, const struct fi_domain_attr *prov_attr, const struct fi_info *user_info) { const struct fi_domain_attr *user_attr = user_info->domain_attr; if (prov_attr->name && user_attr->name && strcasecmp(user_attr->name, prov_attr->name)) { FI_INFO(prov, FI_LOG_CORE, "Unknown domain name\n"); FI_INFO_NAME(prov, prov_attr, user_attr); return -FI_ENODATA; } if (fi_thread_level(user_attr->threading) < fi_thread_level(prov_attr->threading)) { FI_INFO(prov, FI_LOG_CORE, "Invalid threading model\n"); return -FI_ENODATA; } if (fi_progress_level(user_attr->control_progress) < fi_progress_level(prov_attr->control_progress)) { FI_INFO(prov, FI_LOG_CORE, "Invalid control progress model\n"); return -FI_ENODATA; } if (fi_progress_level(user_attr->data_progress) < fi_progress_level(prov_attr->data_progress)) { FI_INFO(prov, FI_LOG_CORE, "Invalid data progress model\n"); return -FI_ENODATA; } if (fi_resource_mgmt_level(user_attr->resource_mgmt) < fi_resource_mgmt_level(prov_attr->resource_mgmt)) { FI_INFO(prov, FI_LOG_CORE, "Invalid resource mgmt model\n"); return -FI_ENODATA; } if ((prov_attr->av_type != FI_AV_UNSPEC) && (user_attr->av_type != FI_AV_UNSPEC) && (prov_attr->av_type != user_attr->av_type)) { FI_INFO(prov, FI_LOG_CORE, "Invalid AV type\n"); return -FI_ENODATA; } if (user_attr->cq_data_size > prov_attr->cq_data_size) { FI_INFO(prov, FI_LOG_CORE, "CQ data size too large\n"); FI_INFO_CHECK_VAL(prov, prov_attr, user_attr, cq_data_size); return -FI_ENODATA; } if (ofi_check_mr_mode(prov, api_version, prov_attr->mr_mode, user_info)) return -FI_ENODATA; if (user_attr->max_ep_stx_ctx > prov_attr->max_ep_stx_ctx) { FI_INFO(prov, FI_LOG_CORE, "max_ep_stx_ctx greater than supported\n"); FI_INFO_CHECK_VAL(prov, prov_attr, user_attr, max_ep_stx_ctx); } if (user_attr->max_ep_srx_ctx > prov_attr->max_ep_srx_ctx) { FI_INFO(prov, FI_LOG_CORE, "max_ep_srx_ctx greater than supported\n"); FI_INFO_CHECK_VAL(prov, prov_attr, user_attr, max_ep_srx_ctx); } /* following checks only apply to api 1.5 and beyond */ if (FI_VERSION_LT(api_version, FI_VERSION(1, 5))) return 0; if (user_attr->cntr_cnt > prov_attr->cntr_cnt) { FI_INFO(prov, FI_LOG_CORE, "Cntr count too large\n"); return -FI_ENODATA; } if (user_attr->mr_iov_limit > prov_attr->mr_iov_limit) { FI_INFO(prov, FI_LOG_CORE, "MR iov limit too large\n"); FI_INFO_CHECK_VAL(prov, prov_attr, user_attr, mr_iov_limit); return -FI_ENODATA; } if (user_attr->caps & ~(prov_attr->caps)) { FI_INFO(prov, FI_LOG_CORE, "Requested domain caps not supported\n"); FI_INFO_CHECK(prov, prov_attr, user_attr, caps, FI_TYPE_CAPS); return -FI_ENODATA; } if ((user_attr->mode & prov_attr->mode) != prov_attr->mode) { FI_INFO(prov, FI_LOG_CORE, "Required domain mode missing\n"); FI_INFO_MODE(prov, prov_attr->mode, user_attr->mode); return -FI_ENODATA; } if (user_attr->max_err_data > prov_attr->max_err_data) { FI_INFO(prov, FI_LOG_CORE, "Max err data too large\n"); FI_INFO_CHECK_VAL(prov, prov_attr, user_attr, max_err_data); return -FI_ENODATA; } if (user_attr->mr_cnt > prov_attr->mr_cnt) { FI_INFO(prov, FI_LOG_CORE, "MR count too large\n"); FI_INFO_CHECK_VAL(prov, prov_attr, user_attr, mr_cnt); return -FI_ENODATA; } return 0; }
int fi_ibv_check_rx_attr(const struct fi_rx_attr *attr, const struct fi_info *hints, const struct fi_info *info) { uint64_t compare_mode, check_mode; int rm_enabled; if (attr->caps & ~(info->rx_attr->caps)) { VERBS_INFO(FI_LOG_CORE, "Given rx_attr->caps not supported\n"); return -FI_ENODATA; } compare_mode = attr->mode ? attr->mode : hints->mode; check_mode = (hints->caps & FI_RMA) ? info->rx_attr->mode : (info->rx_attr->mode & ~FI_RX_CQ_DATA); if ((compare_mode & check_mode) != check_mode) { VERBS_INFO(FI_LOG_CORE, "Given rx_attr->mode not supported\n"); FI_INFO_MODE(&fi_ibv_prov, check_mode, compare_mode); return -FI_ENODATA; } if (attr->op_flags & ~(info->rx_attr->op_flags)) { VERBS_INFO(FI_LOG_CORE, "Given rx_attr->op_flags not supported\n"); return -FI_ENODATA; } if (attr->msg_order & ~(info->rx_attr->msg_order)) { VERBS_INFO(FI_LOG_CORE, "Given rx_attr->msg_order not supported\n"); return -FI_ENODATA; } if (attr->size > info->rx_attr->size) { VERBS_INFO(FI_LOG_CORE, "Given rx_attr->size is greater than supported\n"); FI_INFO_CHECK_VAL(&fi_ibv_prov, info->rx_attr, attr, size); return -FI_ENODATA; } rm_enabled =(info->domain_attr && info->domain_attr->resource_mgmt == FI_RM_ENABLED); if (!rm_enabled && (attr->total_buffered_recv > info->rx_attr->total_buffered_recv)) { VERBS_INFO(FI_LOG_CORE, "Given rx_attr->total_buffered_recv " "exceeds supported size\n"); FI_INFO_CHECK_VAL(&fi_ibv_prov, info->rx_attr, attr, total_buffered_recv); return -FI_ENODATA; } if (attr->iov_limit > info->rx_attr->iov_limit) { VERBS_INFO(FI_LOG_CORE, "Given rx_attr->iov_limit greater than supported\n"); FI_INFO_CHECK_VAL(&fi_ibv_prov, info->rx_attr, attr, iov_limit); return -FI_ENODATA; } return 0; }