#include <ofi_mr.h>
#include <ofi_util.h>
#include <ofi_hmem.h>
static int ipc_cache_add_region(struct ofi_mr_cache *cache, struct ofi_mr_entry *entry)
{
int ret;
ret = ofi_hmem_open_handle(entry->info.iface, (void **)&entry->info.handle,
entry->info.iov.iov_len, entry->info.device,
&entry->info.mapped_addr);
if (ret == -FI_EALREADY) {
ofi_mr_cache_flush(cache, false);
ret = ofi_hmem_open_handle(entry->info.iface, (void **)&entry->info.handle,
entry->info.iov.iov_len, entry->info.device,
&entry->info.mapped_addr);
}
if (ret) {
FI_WARN(&core_prov, FI_LOG_CORE,
"Failed to open hmem handle, addr: %p, len: %lu\n",
entry->info.iov.iov_base, entry->info.iov.iov_len);
}
return ret;
}
static void ipc_cache_delete_region(struct ofi_mr_cache *cache,
struct ofi_mr_entry *entry)
{
ofi_hmem_close_handle(entry->info.iface,
entry->info.mapped_addr);
}
int ofi_ipc_cache_open(struct ofi_mr_cache **cache,
struct util_domain *domain)
{
struct ofi_mem_monitor *memory_monitors[OFI_HMEM_MAX] = {0};
int ret;
if (!ofi_hmem_is_ipc_enabled(FI_HMEM_CUDA) &&
!ofi_hmem_is_ipc_enabled(FI_HMEM_ROCR))
return FI_SUCCESS;
memory_monitors[FI_HMEM_CUDA] = cuda_ipc_monitor;
memory_monitors[FI_HMEM_ROCR] = rocr_ipc_monitor;
*cache = calloc(1, sizeof(*(*cache)));
if (!*cache) {
ret = -FI_ENOMEM;
goto out;
}
(*cache)->add_region = ipc_cache_add_region;
(*cache)->delete_region = ipc_cache_delete_region;
ret = ofi_mr_cache_init(domain, memory_monitors,
*cache);
if (ret)
goto cleanup;
FI_INFO(&core_prov, FI_LOG_CORE,
"ipc cache enabled, max_cnt: %zu max_size: %zu\n",
cache_params.max_cnt, cache_params.max_size);
return FI_SUCCESS;
cleanup:
free(*cache);
*cache = NULL;
out:
return ret;
}
void ofi_ipc_cache_destroy(struct ofi_mr_cache *cache)
{
ofi_mr_cache_cleanup(cache);
free(cache);
}
int ofi_ipc_cache_search(struct ofi_mr_cache *cache, uint64_t peer_id,
struct ipc_info *ipc_info,
struct ofi_mr_entry **mr_entry)
{
struct ofi_mr_info info = {0};
struct ofi_mr_entry *entry;
int ret;
size_t ipc_handle_size;
info.iov.iov_base = (void *) (uintptr_t) ipc_info->base_addr;
info.iov.iov_len = ipc_info->base_length;
info.iface = ipc_info->iface;
info.peer_id = peer_id;
ipc_handle_size = ofi_hmem_get_ipc_handle_size(info.iface);
assert(ipc_handle_size);
memcpy(&info.handle, &ipc_info->ipc_handle, ipc_handle_size);
ret = ofi_mr_cache_search(cache, &info, &entry);
if (ret)
goto out;
*mr_entry = entry;
out:
return ret;
}