fix: remap virtual alloc when access attribute changed

Related-To: NEO-13468
Signed-off-by: Maciej Plewka <maciej.plewka@intel.com>
This commit is contained in:
Maciej Plewka
2025-11-27 10:26:09 +00:00
committed by Compute-Runtime-Automation
parent e6dda55428
commit 18073ee50e
4 changed files with 399 additions and 0 deletions

View File

@@ -1649,6 +1649,7 @@ ze_result_t ContextImp::setVirtualMemAccessAttribute(const void *ptr,
auto lockVirtual = this->driverHandle->getMemoryManager()->lockVirtualMemoryReservationMap();
virtualMemoryReservation = findSupportedVirtualReservation(ptr, size);
if (virtualMemoryReservation) {
NEO::MemoryFlags flagsBefore = virtualMemoryReservation->flags;
switch (access) {
case ZE_MEMORY_ACCESS_ATTRIBUTE_NONE:
virtualMemoryReservation->flags.readOnly = false;
@@ -1668,6 +1669,17 @@ ze_result_t ContextImp::setVirtualMemAccessAttribute(const void *ptr,
default:
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
}
if (flagsBefore != virtualMemoryReservation->flags &&
virtualMemoryReservation->mappedAllocations.size() > 0) {
std::map<void *, NEO::MemoryMappedRange *>::iterator physicalMapIt;
physicalMapIt = virtualMemoryReservation->mappedAllocations.find(const_cast<void *>(ptr));
if (physicalMapIt != virtualMemoryReservation->mappedAllocations.end()) {
auto allocation = physicalMapIt->second->mappedAllocation.allocation;
lockVirtual.unlock();
unMapVirtualMem(ptr, size);
mapVirtualMem(ptr, size, reinterpret_cast<ze_physical_mem_handle_t>(allocation), 0, access);
}
}
return ZE_RESULT_SUCCESS;
} else {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;

View File

@@ -90,6 +90,70 @@ struct Mock<Context> : public Context {
ADDMETHOD_NOBASE(systemBarrier, ze_result_t, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice));
};
template <>
struct Mock<ContextImp> : public ContextImp {
Mock(DriverHandle *driverHandle) : ContextImp(driverHandle){};
~Mock() override = default;
using BaseClass = ContextImp;
ADDMETHOD(destroy, ze_result_t, false, ZE_RESULT_SUCCESS, (), ());
ADDMETHOD(getStatus, ze_result_t, false, ZE_RESULT_SUCCESS, (), ());
ADDMETHOD(getDriverHandle, DriverHandle *, false, nullptr, (), ());
ADDMETHOD(allocHostMem, ze_result_t, false, ZE_RESULT_SUCCESS, (const ze_host_mem_alloc_desc_t *hostDesc, size_t size, size_t alignment, void **ptr), (hostDesc, size, alignment, ptr));
ADDMETHOD(allocDeviceMem, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, const ze_device_mem_alloc_desc_t *deviceDesc, size_t size, size_t alignment, void **ptr), (hDevice, deviceDesc, size, alignment, ptr));
ADDMETHOD(allocSharedMem, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, const ze_device_mem_alloc_desc_t *deviceDesc, const ze_host_mem_alloc_desc_t *hostDesc, size_t size, size_t alignment, void **ptr), (hDevice, deviceDesc, hostDesc, size, alignment, ptr));
ADDMETHOD(makeMemoryResident, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, void *ptr, size_t size), (hDevice, ptr, size));
ADDMETHOD(evictMemory, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, void *ptr, size_t size), (hDevice, ptr, size));
ADDMETHOD(makeImageResident, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, ze_image_handle_t hImage), (hDevice, hImage));
ADDMETHOD(evictImage, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, ze_image_handle_t hImage), (hDevice, hImage));
ADDMETHOD(freeMem, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *ptr), (ptr));
ADDMETHOD(getMemAllocProperties, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *ptr, ze_memory_allocation_properties_t *pMemAllocProperties, ze_device_handle_t *phDevice), (ptr, pMemAllocProperties, phDevice));
ADDMETHOD(getMemAddressRange, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *ptr, void **pBase, size_t *pSize), (ptr, pBase, pSize));
ADDMETHOD(getIpcMemHandle, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *ptr, ze_ipc_mem_handle_t *pIpcHandle), (ptr, pIpcHandle));
ADDMETHOD(closeIpcMemHandle, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *ptr), (ptr));
ADDMETHOD(openIpcMemHandle, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, const ze_ipc_mem_handle_t &handle, ze_ipc_memory_flags_t flags, void **ptr), (hDevice, handle, flags, ptr));
ADDMETHOD(createModule, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, const ze_module_desc_t *desc, ze_module_handle_t *phModule, ze_module_build_log_handle_t *phBuildLog), (hDevice, desc, phModule, phBuildLog));
ADDMETHOD(createSampler, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, const ze_sampler_desc_t *pDesc, ze_sampler_handle_t *phSampler), (hDevice, pDesc, phSampler));
ADDMETHOD(createCommandQueue, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, const ze_command_queue_desc_t *desc, ze_command_queue_handle_t *commandQueue), (hDevice, desc, commandQueue));
ADDMETHOD(createCommandList, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, const ze_command_list_desc_t *desc, ze_command_list_handle_t *commandList), (hDevice, desc, commandList));
ADDMETHOD(createCommandListImmediate, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, const ze_command_queue_desc_t *desc, ze_command_list_handle_t *commandList), (hDevice, desc, commandList));
ADDMETHOD(activateMetricGroups, ze_result_t, false, ZE_RESULT_SUCCESS, (zet_device_handle_t hDevice, uint32_t count, zet_metric_group_handle_t *phMetricGroups), (hDevice, count, phMetricGroups));
ADDMETHOD(reserveVirtualMem, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *pStart, size_t size, void **pptr), (pStart, size, pptr));
ADDMETHOD(freeVirtualMem, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *ptr, size_t size), (ptr, size));
ADDMETHOD(queryVirtualMemPageSizeWithStartAddress, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, const void *pStart, size_t size, size_t *pagesize), (hDevice, pStart, size, pagesize));
ADDMETHOD(queryVirtualMemPageSize, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, size_t size, size_t *pagesize), (hDevice, size, pagesize));
ADDMETHOD(createPhysicalMem, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, ze_physical_mem_desc_t *desc, ze_physical_mem_handle_t *phPhysicalMemory), (hDevice, desc, phPhysicalMemory));
ADDMETHOD(destroyPhysicalMem, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_physical_mem_handle_t hPhysicalMemory), (hPhysicalMemory));
ADDMETHOD(mapVirtualMem, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *ptr, size_t size, ze_physical_mem_handle_t hPhysicalMemory, size_t offset, ze_memory_access_attribute_t access), (ptr, size, hPhysicalMemory, offset, access));
ADDMETHOD(unMapVirtualMem, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *ptr, size_t size), (ptr, size));
ADDMETHOD(setVirtualMemAccessAttribute, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *ptr, size_t size, ze_memory_access_attribute_t access), (ptr, size, access));
ADDMETHOD(getVirtualMemAccessAttribute, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *ptr, size_t size, ze_memory_access_attribute_t *access, size_t *outSize), (ptr, size, access, outSize));
ADDMETHOD(openEventPoolIpcHandle, ze_result_t, false, ZE_RESULT_SUCCESS, (const ze_ipc_event_pool_handle_t &ipcEventPoolHandle, ze_event_pool_handle_t *eventPoolHandle), (ipcEventPoolHandle, eventPoolHandle));
ADDMETHOD(createEventPool, ze_result_t, false, ZE_RESULT_SUCCESS, (const ze_event_pool_desc_t *desc, uint32_t numDevices, ze_device_handle_t *phDevices, ze_event_pool_handle_t *phEventPool), (desc, numDevices, phDevices, phEventPool));
ADDMETHOD(createImage, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, const ze_image_desc_t *desc, ze_image_handle_t *phImage), (hDevice, desc, phImage));
ADDMETHOD_OVERLOAD(freeMem, _BL, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *ptr, bool blocking), (ptr, blocking));
ADDMETHOD(freeMemExt, ze_result_t, false, ZE_RESULT_SUCCESS, (const ze_memory_free_ext_desc_t *pMemFreeDesc, void *ptr), (pMemFreeDesc, ptr));
ADDMETHOD(registerMemoryFreeCallback, ze_result_t, false, ZE_RESULT_SUCCESS, (zex_memory_free_callback_ext_desc_t * pfnCallbackDesc, void *ptr), (pfnCallbackDesc, ptr));
ADDMETHOD(getIpcMemHandles, ze_result_t, false, ZE_RESULT_SUCCESS, (const void *p, uint32_t *numIpcHandles, ze_ipc_mem_handle_t *pIpcHandles), (p, numIpcHandles, pIpcHandles));
ADDMETHOD(putIpcMemHandle, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_ipc_mem_handle_t ipcHandle), (ipcHandle));
ADDMETHOD(getIpcHandleFromFd, ze_result_t, false, ZE_RESULT_SUCCESS, (uint64_t handle, ze_ipc_mem_handle_t *pIpcHandle), (handle, pIpcHandle));
ADDMETHOD(getFdFromIpcHandle, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_ipc_mem_handle_t ipcHandle, uint64_t *pHandle), (ipcHandle, pHandle));
ADDMETHOD(openIpcMemHandles, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, uint32_t numIpcHandles, ze_ipc_mem_handle_t *pIpcHandles, ze_ipc_memory_flags_t flags, void **pptr), (hDevice, numIpcHandles, pIpcHandles, flags, pptr));
ADDMETHOD(getImageAllocProperties, ze_result_t, false, ZE_RESULT_SUCCESS, (L0::Image * image, ze_image_allocation_ext_properties_t *pAllocProperties), (image, pAllocProperties));
ADDMETHOD(setAtomicAccessAttribute, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, const void *ptr, size_t size, ze_memory_atomic_attr_exp_flags_t attr), (hDevice, ptr, size, attr));
ADDMETHOD(getAtomicAccessAttribute, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, const void *ptr, size_t size, ze_memory_atomic_attr_exp_flags_t *pAttr), (hDevice, ptr, size, pAttr));
ADDMETHOD(getVirtualAddressSpaceIpcHandle, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, ze_ipc_mem_handle_t *pIpcHandle), (hDevice, pIpcHandle));
ADDMETHOD(putVirtualAddressSpaceIpcHandle, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_ipc_mem_handle_t ipcHandle), (ipcHandle));
ADDMETHOD(lockMemory, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, void *ptr, size_t size), (hDevice, ptr, size));
ADDMETHOD(isShareableMemory, bool, false, true, (const void *exportDesc, bool exportableMemory, NEO::Device *neoDevice, bool shareableWithoutNTHandle), (exportDesc, exportableMemory, neoDevice, shareableWithoutNTHandle));
ADDMETHOD(isOpaqueHandleSupported, bool, false, true, (IpcHandleType * handleType), (handleType));
ADDMETHOD(getMemHandlePtr, void *, false, nullptr, (ze_device_handle_t hDevice, uint64_t handle, NEO::AllocationType allocationType, unsigned int processId, ze_ipc_memory_flags_t flags), (hDevice, handle, allocationType, processId, flags));
ADDMETHOD_VOIDRETURN(getDataFromIpcHandle, false, (ze_device_handle_t hDevice, const ze_ipc_mem_handle_t ipcHandle, uint64_t &handle, uint8_t &type, unsigned int &processId, uint64_t &poolOffset), (hDevice, ipcHandle, handle, type, processId, poolOffset));
ADDMETHOD(getPitchFor2dImage, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice, size_t imageWidth, size_t imageHeight, unsigned int elementSizeInBytes, size_t *rowPitch), (hDevice, imageWidth, imageHeight, elementSizeInBytes, rowPitch));
ADDMETHOD(getContextExt, ContextExt *, false, nullptr, (), ());
ADDMETHOD(systemBarrier, ze_result_t, false, ZE_RESULT_SUCCESS, (ze_device_handle_t hDevice), (hDevice));
};
struct ContextShareableMock : public L0::ContextImp {
ContextShareableMock(L0::DriverHandle *driverHandle) : L0::ContextImp(driverHandle) {}
bool isShareableMemory(const void *pNext, bool exportableMemory, NEO::Device *neoDevice, bool shareableWithoutNTHandle) override {

View File

@@ -28,6 +28,7 @@
#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h"
#include "level_zero/core/test/unit_tests/fixtures/host_pointer_manager_fixture.h"
#include "level_zero/core/test/unit_tests/mocks/mock_cmdlist.h"
#include "level_zero/core/test/unit_tests/mocks/mock_context.h"
#include "level_zero/include/level_zero/driver_experimental/zex_context.h"
#include "gtest/gtest.h"
@@ -3885,5 +3886,325 @@ TEST_F(ZexMemFreeRegisterCallbackExtTests, whenCallingZexMemFreeRegisterCallback
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
}
TEST_F(ContextTest, whenSettingVirtualMemAccessAttributeWithChangedFlagsAndMappedAllocationsThenUnmapAndRemapIsCalled) {
ze_context_handle_t hContext;
ze_context_desc_t desc = {ZE_STRUCTURE_TYPE_CONTEXT_DESC, nullptr, 0};
ze_result_t res = driverHandle->createContext(&desc, 0u, nullptr, &hContext);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ContextImp *contextImp = static_cast<ContextImp *>(L0::Context::fromHandle(hContext));
// Reserve virtual memory
void *pStart = 0x0;
size_t size = 4096u;
void *ptr = nullptr;
size_t pagesize = 0u;
res = contextImp->queryVirtualMemPageSize(device, size, &pagesize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = contextImp->reserveVirtualMem(pStart, pagesize, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
// Create physical memory and map it
ze_physical_mem_desc_t descMem = {ZE_STRUCTURE_TYPE_PHYSICAL_MEM_DESC, nullptr, 0, pagesize};
ze_physical_mem_handle_t mem = {};
res = contextImp->createPhysicalMem(device, &descMem, &mem);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_memory_access_attribute_t access = {ZE_MEMORY_ACCESS_ATTRIBUTE_READWRITE};
size_t offset = 0;
res = contextImp->mapVirtualMem(ptr, pagesize, mem, offset, access);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
// Change access attribute to trigger unmap/remap logic
ze_memory_access_attribute_t newAccess = {ZE_MEMORY_ACCESS_ATTRIBUTE_READONLY};
res = contextImp->setVirtualMemAccessAttribute(ptr, pagesize, newAccess);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
// Check that the new access attribute is set
ze_memory_access_attribute_t outAccess = {};
size_t outSize = 0;
res = contextImp->getVirtualMemAccessAttribute(ptr, pagesize, &outAccess, &outSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
EXPECT_EQ(outAccess, newAccess);
// Clean up
res = contextImp->unMapVirtualMem(ptr, pagesize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = contextImp->destroyPhysicalMem(mem);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = contextImp->freeVirtualMem(ptr, pagesize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = contextImp->destroy();
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
}
TEST_F(ContextTest, givenContextWhenChangingVirtualMemAccessAttributeThenUnmapAndMapAreCalled) {
auto ctx = std::make_unique<Mock<ContextImp>>(driverHandle.get());
ctx->createPhysicalMemCallBase = true;
ctx->queryVirtualMemPageSizeCallBase = true;
ctx->reserveVirtualMemCallBase = true;
ctx->queryVirtualMemPageSizeWithStartAddressCallBase = true;
ctx->mapVirtualMemCallBase = true;
ctx->setVirtualMemAccessAttributeCallBase = true;
ctx->unMapVirtualMemCallBase = true;
ctx->destroyPhysicalMemCallBase = true;
ctx->freeVirtualMemCallBase = true;
void *pStart = 0x0;
size_t size = 4096u;
void *ptr = nullptr;
size_t pagesize = 0u;
ze_result_t res = ctx->queryVirtualMemPageSize(device, size, &pagesize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->reserveVirtualMem(pStart, pagesize, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_physical_mem_desc_t descMem = {ZE_STRUCTURE_TYPE_PHYSICAL_MEM_DESC, nullptr, 0, pagesize};
ze_physical_mem_handle_t mem = {};
res = ctx->createPhysicalMem(device, &descMem, &mem);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_memory_access_attribute_t access = {ZE_MEMORY_ACCESS_ATTRIBUTE_READWRITE};
size_t offset = 0;
res = ctx->mapVirtualMem(ptr, pagesize, mem, offset, access);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_memory_access_attribute_t newAccess = {ZE_MEMORY_ACCESS_ATTRIBUTE_READONLY};
res = ctx->setVirtualMemAccessAttribute(ptr, pagesize, newAccess);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
EXPECT_EQ(ctx->mapVirtualMemCalled, 2u);
EXPECT_EQ(ctx->unMapVirtualMemCalled, 1u);
res = ctx->unMapVirtualMem(ptr, pagesize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->destroyPhysicalMem(mem);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->freeVirtualMem(ptr, pagesize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
}
TEST_F(ContextTest, givenContextWhenChangingVirtualMemAccessAttributeToNoneThenUnmapAndMapAreCalled) {
auto ctx = std::make_unique<Mock<ContextImp>>(driverHandle.get());
ctx->createPhysicalMemCallBase = true;
ctx->queryVirtualMemPageSizeCallBase = true;
ctx->reserveVirtualMemCallBase = true;
ctx->queryVirtualMemPageSizeWithStartAddressCallBase = true;
ctx->mapVirtualMemCallBase = true;
ctx->setVirtualMemAccessAttributeCallBase = true;
ctx->unMapVirtualMemCallBase = true;
ctx->destroyPhysicalMemCallBase = true;
ctx->freeVirtualMemCallBase = true;
void *pStart = 0x0;
size_t size = 4096u;
void *ptr = nullptr;
size_t pagesize = 0u;
ze_result_t res = ctx->queryVirtualMemPageSize(device, size, &pagesize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->reserveVirtualMem(pStart, pagesize, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_physical_mem_desc_t descMem = {ZE_STRUCTURE_TYPE_PHYSICAL_MEM_DESC, nullptr, 0, pagesize};
ze_physical_mem_handle_t mem = {};
res = ctx->createPhysicalMem(device, &descMem, &mem);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_memory_access_attribute_t access = {ZE_MEMORY_ACCESS_ATTRIBUTE_READONLY};
size_t offset = 0;
res = ctx->mapVirtualMem(ptr, pagesize, mem, offset, access);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_memory_access_attribute_t newAccess = {ZE_MEMORY_ACCESS_ATTRIBUTE_NONE};
res = ctx->setVirtualMemAccessAttribute(ptr, pagesize, newAccess);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
EXPECT_EQ(ctx->mapVirtualMemCalled, 2u);
EXPECT_EQ(ctx->unMapVirtualMemCalled, 1u);
res = ctx->unMapVirtualMem(ptr, pagesize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->destroyPhysicalMem(mem);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->freeVirtualMem(ptr, pagesize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
}
TEST_F(ContextTest, givenContextWhenChangingVirtualMemAccessAttributeToReadWriteThenUnmapAndMapAreCalled) {
auto ctx = std::make_unique<Mock<ContextImp>>(driverHandle.get());
ctx->createPhysicalMemCallBase = true;
ctx->queryVirtualMemPageSizeCallBase = true;
ctx->reserveVirtualMemCallBase = true;
ctx->queryVirtualMemPageSizeWithStartAddressCallBase = true;
ctx->mapVirtualMemCallBase = true;
ctx->setVirtualMemAccessAttributeCallBase = true;
ctx->unMapVirtualMemCallBase = true;
ctx->destroyPhysicalMemCallBase = true;
ctx->freeVirtualMemCallBase = true;
void *pStart = 0x0;
size_t size = 4096u;
void *ptr = nullptr;
size_t pagesize = 0u;
ze_result_t res = ctx->queryVirtualMemPageSize(device, size, &pagesize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->reserveVirtualMem(pStart, pagesize, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_physical_mem_desc_t descMem = {ZE_STRUCTURE_TYPE_PHYSICAL_MEM_DESC, nullptr, 0, pagesize};
ze_physical_mem_handle_t mem = {};
res = ctx->createPhysicalMem(device, &descMem, &mem);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_memory_access_attribute_t access = {ZE_MEMORY_ACCESS_ATTRIBUTE_NONE};
size_t offset = 0;
res = ctx->mapVirtualMem(ptr, pagesize, mem, offset, access);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
NEO::VirtualMemoryReservation *virtualMemoryReservation = nullptr;
auto lockVirtual = this->driverHandle->getMemoryManager()->lockVirtualMemoryReservationMap();
virtualMemoryReservation = ctx->findSupportedVirtualReservation(ptr, size);
virtualMemoryReservation->flags.readOnly = false;
virtualMemoryReservation->flags.noAccess = false;
virtualMemoryReservation->flags.readWrite = false;
lockVirtual.unlock();
ze_memory_access_attribute_t newAccess = {ZE_MEMORY_ACCESS_ATTRIBUTE_READWRITE};
res = ctx->setVirtualMemAccessAttribute(ptr, pagesize, newAccess);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
EXPECT_EQ(ctx->mapVirtualMemCalled, 2u);
EXPECT_EQ(ctx->unMapVirtualMemCalled, 1u);
res = ctx->unMapVirtualMem(ptr, pagesize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->destroyPhysicalMem(mem);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->freeVirtualMem(ptr, pagesize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
}
TEST_F(ContextTest, givenContextWhenChangingVirtualMemAccessAttributeAndNoMappedAllocationsThenUnmapAndMapAreNotCalled) {
auto ctx = std::make_unique<Mock<ContextImp>>(driverHandle.get());
ctx->queryVirtualMemPageSizeCallBase = true;
ctx->reserveVirtualMemCallBase = true;
ctx->setVirtualMemAccessAttributeCallBase = true;
ctx->freeVirtualMemCallBase = true;
ctx->queryVirtualMemPageSizeWithStartAddressCallBase = true;
void *pStart = 0x0;
size_t size = 4096u;
void *ptr = nullptr;
size_t pageSize = 0u;
ze_result_t res = ctx->queryVirtualMemPageSize(device, size, &pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->reserveVirtualMem(pStart, pageSize, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_memory_access_attribute_t newAccess = {ZE_MEMORY_ACCESS_ATTRIBUTE_READONLY};
res = ctx->setVirtualMemAccessAttribute(ptr, pageSize, newAccess);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
EXPECT_EQ(ctx->mapVirtualMemCalled, 0u);
EXPECT_EQ(ctx->unMapVirtualMemCalled, 0u);
res = ctx->freeVirtualMem(ptr, pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
}
TEST_F(ContextTest, givenContextWhenChangingVirtualMemAccessAttributeAndFlagsUnchangedThenUnmapAndMapAreNotCalled) {
auto ctx = std::make_unique<Mock<ContextImp>>(driverHandle.get());
ctx->queryVirtualMemPageSizeCallBase = true;
ctx->reserveVirtualMemCallBase = true;
ctx->createPhysicalMemCallBase = true;
ctx->mapVirtualMemCallBase = true;
ctx->setVirtualMemAccessAttributeCallBase = true;
ctx->unMapVirtualMemCallBase = true;
ctx->destroyPhysicalMemCallBase = true;
ctx->freeVirtualMemCallBase = true;
ctx->queryVirtualMemPageSizeWithStartAddressCallBase = true;
void *pStart = 0x0;
size_t size = 4096u;
void *ptr = nullptr;
size_t pageSize = 0u;
ze_result_t res = ctx->queryVirtualMemPageSize(device, size, &pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->reserveVirtualMem(pStart, pageSize, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_physical_mem_desc_t descMem = {ZE_STRUCTURE_TYPE_PHYSICAL_MEM_DESC, nullptr, 0, pageSize};
ze_physical_mem_handle_t mem = {};
res = ctx->createPhysicalMem(device, &descMem, &mem);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_memory_access_attribute_t access = {ZE_MEMORY_ACCESS_ATTRIBUTE_READWRITE};
res = ctx->mapVirtualMem(ptr, pageSize, mem, 0, access);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
EXPECT_EQ(ctx->mapVirtualMemCalled, 1u);
res = ctx->setVirtualMemAccessAttribute(ptr, pageSize, access);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
EXPECT_EQ(ctx->mapVirtualMemCalled, 1u);
EXPECT_EQ(ctx->unMapVirtualMemCalled, 0u);
res = ctx->unMapVirtualMem(ptr, pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->destroyPhysicalMem(mem);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->freeVirtualMem(ptr, pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
}
TEST_F(ContextTest, givenContextWhenChangingVirtualMemAccessAttributeAndPtrNotInMappedAllocationsThenUnmapAndMapAreNotCalled) {
auto ctx = std::make_unique<Mock<ContextImp>>(driverHandle.get());
ctx->queryVirtualMemPageSizeCallBase = true;
ctx->reserveVirtualMemCallBase = true;
ctx->createPhysicalMemCallBase = true;
ctx->mapVirtualMemCallBase = true;
ctx->setVirtualMemAccessAttributeCallBase = true;
ctx->unMapVirtualMemCallBase = true;
ctx->destroyPhysicalMemCallBase = true;
ctx->freeVirtualMemCallBase = true;
ctx->queryVirtualMemPageSizeWithStartAddressCallBase = true;
void *pStart = 0x0;
size_t totalSize = 8192u;
void *reservationBase = nullptr;
size_t pageSize = 0u;
ze_result_t res = ctx->queryVirtualMemPageSize(device, totalSize, &pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->reserveVirtualMem(pStart, pageSize * 2, &reservationBase);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
void *secondPagePtr = reinterpret_cast<void *>(reinterpret_cast<uint64_t>(reservationBase) + pageSize);
ze_physical_mem_desc_t descMem = {ZE_STRUCTURE_TYPE_PHYSICAL_MEM_DESC, nullptr, 0, pageSize};
ze_physical_mem_handle_t mem = {};
res = ctx->createPhysicalMem(device, &descMem, &mem);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_memory_access_attribute_t access = {ZE_MEMORY_ACCESS_ATTRIBUTE_READWRITE};
res = ctx->mapVirtualMem(secondPagePtr, pageSize, mem, 0, access);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
EXPECT_EQ(ctx->mapVirtualMemCalled, 1u);
ze_memory_access_attribute_t newAccess = {ZE_MEMORY_ACCESS_ATTRIBUTE_READONLY};
res = ctx->setVirtualMemAccessAttribute(reservationBase, pageSize, newAccess);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
EXPECT_EQ(ctx->mapVirtualMemCalled, 1u);
EXPECT_EQ(ctx->unMapVirtualMemCalled, 0u);
res = ctx->unMapVirtualMem(secondPagePtr, pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->destroyPhysicalMem(mem);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
res = ctx->freeVirtualMem(reservationBase, pageSize * 2);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
}
} // namespace ult
} // namespace L0