static int __gnix_dom_ops_set_val(struct fid *fid, dom_ops_val_t t, void *val) { struct gnix_fid_domain *domain; int ret, type; GNIX_TRACE(FI_LOG_DOMAIN, "\n"); assert(val); domain = container_of(fid, struct gnix_fid_domain, domain_fid.fid); if (domain->domain_fid.fid.fclass != FI_CLASS_DOMAIN) { GNIX_WARN(FI_LOG_DOMAIN, ("Invalid domain\n")); return -FI_EINVAL; } switch (t) { case GNI_MSG_RENDEZVOUS_THRESHOLD: domain->params.msg_rendezvous_thresh = *(uint32_t *)val; break; case GNI_RMA_RDMA_THRESHOLD: domain->params.rma_rdma_thresh = *(uint32_t *)val; break; case GNI_CONN_TABLE_INITIAL_SIZE: domain->params.ct_init_size = *(uint32_t *)val; break; case GNI_CONN_TABLE_MAX_SIZE: domain->params.ct_max_size = *(uint32_t *)val; break; case GNI_CONN_TABLE_STEP_SIZE: domain->params.ct_step = *(uint32_t *)val; break; case GNI_VC_ID_TABLE_CAPACITY: domain->params.vc_id_table_capacity = *(uint32_t *)val; break; case GNI_MBOX_PAGE_SIZE: domain->params.mbox_page_size = *(uint32_t *)val; break; case GNI_MBOX_NUM_PER_SLAB: domain->params.mbox_num_per_slab = *(uint32_t *)val; break; case GNI_MBOX_MAX_CREDIT: domain->params.mbox_maxcredit = *(uint32_t *)val; break; case GNI_MBOX_MSG_MAX_SIZE: domain->params.mbox_msg_maxsize = *(uint32_t *)val; break; case GNI_RX_CQ_SIZE: domain->params.rx_cq_size = *(uint32_t *)val; break; case GNI_TX_CQ_SIZE: domain->params.tx_cq_size = *(uint32_t *)val; break; case GNI_MAX_RETRANSMITS: domain->params.max_retransmits = *(uint32_t *)val; break; case GNI_ERR_INJECT_COUNT: domain->params.err_inject_count = *(int32_t *)val; break; case GNI_MR_CACHE_LAZY_DEREG: domain->mr_cache_attr.lazy_deregistration = *(int32_t *)val; break; case GNI_MR_CACHE: if (val != NULL) { GNIX_DEBUG(FI_LOG_DOMAIN, "user provided value=%s\n", *(char **) val); type = __gnix_string_to_mr_type(*(const char **) val); if (type < 0 || type >= GNIX_MR_MAX_TYPE) return -FI_EINVAL; GNIX_DEBUG(FI_LOG_DOMAIN, "setting domain mr type to %s\n", __gnix_mr_type_to_str[type]); ret = _gnix_open_cache(domain, type); if (ret != FI_SUCCESS) return -FI_EINVAL; } break; case GNI_MR_HARD_REG_LIMIT: domain->mr_cache_attr.hard_reg_limit = *(int32_t *) val; break; case GNI_MR_SOFT_REG_LIMIT: domain->mr_cache_attr.soft_reg_limit = *(int32_t *) val; break; case GNI_MR_HARD_STALE_REG_LIMIT: domain->mr_cache_attr.hard_stale_limit = *(int32_t *) val; break; case GNI_MR_UDREG_REG_LIMIT: if (*(int32_t *) val < 0) return -FI_EINVAL; domain->udreg_reg_limit = *(int32_t *) val; break; case GNI_XPMEM_ENABLE: #if HAVE_XPMEM domain->params.xpmem_enabled = *(bool *)val; #else GNIX_WARN(FI_LOG_DOMAIN, "GNI provider XPMEM support not configured\n"); #endif break; default: GNIX_WARN(FI_LOG_DOMAIN, ("Invalid dom_ops_val\n")); return -FI_EINVAL; } return FI_SUCCESS; }
DIRECT_FN int gnix_domain_open(struct fid_fabric *fabric, struct fi_info *info, struct fid_domain **dom, void *context) { struct gnix_fid_domain *domain = NULL; int ret = FI_SUCCESS; uint8_t ptag; uint32_t cookie; struct gnix_fid_fabric *fabric_priv; GNIX_TRACE(FI_LOG_DOMAIN, "\n"); fabric_priv = container_of(fabric, struct gnix_fid_fabric, fab_fid); /* * check cookie/ptag credentials - for FI_EP_MSG we may be creating a * domain * using a cookie supplied being used by the server. Otherwise, we use * use the cookie/ptag supplied by the job launch system. */ if (info->dest_addr) { ret = gnixu_get_rdma_credentials(info->dest_addr, &ptag, &cookie); if (ret) { GNIX_WARN(FI_LOG_DOMAIN, "gnixu_get_rdma_credentials returned ptag %u cookie 0x%x\n", ptag, cookie); goto err; } } else { ret = gnixu_get_rdma_credentials(NULL, &ptag, &cookie); } GNIX_INFO(FI_LOG_DOMAIN, "gnix rdma credentials returned ptag %u cookie 0x%x\n", ptag, cookie); domain = calloc(1, sizeof *domain); if (domain == NULL) { ret = -FI_ENOMEM; goto err; } domain->mr_cache_attr = _gnix_default_mr_cache_attr; domain->mr_cache_attr.reg_context = (void *) domain; domain->mr_cache_attr.dereg_context = NULL; domain->mr_cache_attr.destruct_context = NULL; ret = _gnix_notifier_open(&domain->mr_cache_attr.notifier); if (ret != FI_SUCCESS) goto err; domain->mr_cache_ro = NULL; domain->mr_cache_rw = NULL; fastlock_init(&domain->mr_cache_lock); domain->udreg_reg_limit = 4096; dlist_init(&domain->nic_list); dlist_init(&domain->list); dlist_insert_after(&domain->list, &fabric_priv->domain_list); domain->fabric = fabric_priv; _gnix_ref_get(domain->fabric); domain->ptag = ptag; domain->cookie = cookie; domain->cdm_id_seed = getpid(); /* TODO: direct syscall better */ /* user tunables */ domain->params.msg_rendezvous_thresh = default_msg_rendezvous_thresh; domain->params.rma_rdma_thresh = default_rma_rdma_thresh; domain->params.ct_init_size = default_ct_init_size; domain->params.ct_max_size = default_ct_max_size; domain->params.ct_step = default_ct_step; domain->params.vc_id_table_capacity = default_vc_id_table_capacity; domain->params.mbox_page_size = default_mbox_page_size; domain->params.mbox_num_per_slab = default_mbox_num_per_slab; domain->params.mbox_maxcredit = default_mbox_maxcredit; domain->params.mbox_msg_maxsize = default_mbox_msg_maxsize; domain->params.max_retransmits = default_max_retransmits; domain->params.err_inject_count = default_err_inject_count; #if HAVE_XPMEM domain->params.xpmem_enabled = true; #else domain->params.xpmem_enabled = false; #endif domain->gni_tx_cq_size = default_tx_cq_size; domain->gni_rx_cq_size = default_rx_cq_size; domain->gni_cq_modes = gnix_def_gni_cq_modes; _gnix_ref_init(&domain->ref_cnt, 1, __domain_destruct); domain->domain_fid.fid.fclass = FI_CLASS_DOMAIN; domain->domain_fid.fid.context = context; domain->domain_fid.fid.ops = &gnix_domain_fi_ops; domain->domain_fid.ops = &gnix_domain_ops; domain->domain_fid.mr = &gnix_domain_mr_ops; domain->control_progress = info->domain_attr->control_progress; domain->data_progress = info->domain_attr->data_progress; domain->thread_model = info->domain_attr->threading; domain->mr_is_init = 0; domain->mr_iov_limit = info->domain_attr->mr_iov_limit; fastlock_init(&domain->cm_nic_lock); _gnix_open_cache(domain, GNIX_DEFAULT_CACHE_TYPE); *dom = &domain->domain_fid; return FI_SUCCESS; err: if (domain != NULL) { free(domain); } return ret; }
DIRECT_FN int gnix_mr_reg(struct fid *fid, const void *buf, size_t len, uint64_t access, uint64_t offset, uint64_t requested_key, uint64_t flags, struct fid_mr **mr_o, void *context) { struct gnix_fid_mem_desc *mr = NULL; struct gnix_fid_domain *domain; int rc; uint64_t reg_addr, reg_len; struct _gnix_fi_reg_context fi_reg_context = { .access = access, .offset = offset, .requested_key = requested_key, .flags = flags, .context = context, }; GNIX_TRACE(FI_LOG_MR, "\n"); /* Flags are reserved for future use and must be 0. */ if (unlikely(flags)) return -FI_EBADFLAGS; /* The offset parameter is reserved for future use and must be 0. * Additionally, check for invalid pointers, bad access flags and the * correct fclass on associated fid */ if (offset || !buf || !mr_o || !access || (access & ~(FI_READ | FI_WRITE | FI_RECV | FI_SEND | FI_REMOTE_READ | FI_REMOTE_WRITE)) || (fid->fclass != FI_CLASS_DOMAIN)) return -FI_EINVAL; domain = container_of(fid, struct gnix_fid_domain, domain_fid.fid); reg_addr = ((uint64_t) buf) & ~((1 << GNIX_MR_PAGE_SHIFT) - 1); reg_len = __calculate_length((uint64_t) buf, len, 1 << GNIX_MR_PAGE_SHIFT); /* call cache register op to retrieve the right entry */ fastlock_acquire(&domain->mr_cache_lock); if (unlikely(!domain->mr_ops)) _gnix_open_cache(domain, GNIX_DEFAULT_CACHE_TYPE); if (unlikely(!domain->mr_ops->is_init(domain))) { rc = domain->mr_ops->init(domain); if (rc != FI_SUCCESS) { fastlock_release(&domain->mr_cache_lock); goto err; } } rc = domain->mr_ops->reg_mr(domain, (uint64_t) reg_addr, reg_len, &fi_reg_context, (void **) &mr); fastlock_release(&domain->mr_cache_lock); /* check retcode */ if (unlikely(rc != FI_SUCCESS)) goto err; /* md.mr_fid */ mr->mr_fid.mem_desc = mr; mr->mr_fid.fid.fclass = FI_CLASS_MR; mr->mr_fid.fid.context = context; mr->mr_fid.fid.ops = &fi_gnix_mr_ops; /* setup internal key structure */ mr->mr_fid.key = _gnix_convert_mhdl_to_key(&mr->mem_hndl); _gnix_ref_get(mr->domain); /* set up mr_o out pointer */ *mr_o = &mr->mr_fid; return FI_SUCCESS; err: return rc; }