/** * Register the memory on all PDs, except maybe for alloc_pd. * In case alloc_pd != NULL, alloc_pd_memh will hold the memory key obtained from * allocation. It will be put in the array of keys in the proper index. */ static ucs_status_t ucp_memh_reg_pds(ucp_context_h context, ucp_mem_h memh, uct_mem_h alloc_pd_memh) { uct_mem_h dummy_pd_memh; unsigned uct_memh_count; ucs_status_t status; unsigned pd_index; memh->pd_map = 0; uct_memh_count = 0; /* Register on all transports (except the one we used to allocate) */ for (pd_index = 0; pd_index < context->num_pds; ++pd_index) { if (context->pds[pd_index] == memh->alloc_pd) { /* Add the memory handle we got from allocation */ ucs_assert(memh->alloc_method == UCT_ALLOC_METHOD_PD); memh->pd_map |= UCS_BIT(pd_index); memh->uct[uct_memh_count++] = alloc_pd_memh; } else if (context->pd_attrs[pd_index].cap.flags & UCT_PD_FLAG_REG) { /* If the PD supports registration, register on it as well */ status = uct_pd_mem_reg(context->pds[pd_index], memh->address, memh->length, &memh->uct[uct_memh_count]); if (status != UCS_OK) { ucp_memh_dereg_pds(context, memh, &dummy_pd_memh); return status; } memh->pd_map |= UCS_BIT(pd_index); ++uct_memh_count; } } return UCS_OK; }
ucs_status_t uct_iface_mem_alloc(uct_iface_h tl_iface, size_t length, const char *name, uct_allocated_memory_t *mem) { uct_base_iface_t *iface = ucs_derived_of(tl_iface, uct_base_iface_t); uct_pd_attr_t pd_attr; ucs_status_t status; status = uct_mem_alloc(length, iface->config.alloc_methods, iface->config.num_alloc_methods, &iface->pd, 1, name, mem); if (status != UCS_OK) { goto err; } /* If the memory was not allocated using PD, register it */ if (mem->method != UCT_ALLOC_METHOD_PD) { status = uct_pd_query(iface->pd, &pd_attr); if (status != UCS_OK) { goto err_free; } /* If PD does not support registration, allow only the PD method */ if (!(pd_attr.cap.flags & UCT_PD_FLAG_REG)) { ucs_error("%s pd does not supprt registration, so cannot use any allocation " "method except 'pd'", iface->pd->component->name); status = UCS_ERR_NO_MEMORY; goto err_free; } status = uct_pd_mem_reg(iface->pd, mem->address, mem->length, &mem->memh); if (status != UCS_OK) { goto err_free; } mem->pd = iface->pd; } return UCS_OK; err_free: uct_mem_free(mem); err: return status; }