Evict USM cpu allocation after migration

Related-To: NEO-5007

Change-Id: I3c91af3ca22cb6233d530b252cc0c75d8fc2f8b5
Signed-off-by: Lukasz Jobczyk <lukasz.jobczyk@intel.com>
This commit is contained in:
Lukasz Jobczyk
2020-09-15 12:35:17 +02:00
committed by sys_ocldev
parent 6ae58249a1
commit b81a78d0e9
13 changed files with 116 additions and 0 deletions

View File

@@ -36,5 +36,7 @@ void PageFaultManager::transferToGpu(void *ptr, void *device) {
allocData->cpuAllocation,
allocData->size, false);
UNRECOVERABLE_IF(ret);
this->evictMemoryAfterImplCopy(allocData->cpuAllocation, deviceImp->getNEODevice());
}
} // namespace NEO

View File

@@ -24,5 +24,8 @@ void PageFaultManager::transferToGpu(void *ptr, void *cmdQ) {
UNRECOVERABLE_IF(retVal);
retVal = commandQueue->finish();
UNRECOVERABLE_IF(retVal);
auto allocData = memoryData[ptr].unifiedMemoryManager->getSVMAlloc(ptr);
this->evictMemoryAfterImplCopy(allocData->cpuAllocation, &commandQueue->getDevice());
}
} // namespace NEO

View File

@@ -19,6 +19,7 @@
#include "opencl/source/platform/platform.h"
#include "opencl/test/unit_test/command_queue/command_queue_fixture.h"
#include "opencl/test/unit_test/mocks/mock_cl_device.h"
#include "opencl/test/unit_test/mocks/mock_memory_operations_handler.h"
#include "opencl/test/unit_test/mocks/mock_platform.h"
#include "gtest/gtest.h"
@@ -42,6 +43,7 @@ class AUBFixture : public CommandQueueHwFixture {
executionEnvironment = platform()->peekExecutionEnvironment();
executionEnvironment->prepareRootDeviceEnvironments(1u);
executionEnvironment->rootDeviceEnvironments[0]->setHwInfo(&hwInfo);
executionEnvironment->rootDeviceEnvironments[0]->memoryOperationsInterface = std::make_unique<MockMemoryOperationsHandler>();
device = std::make_unique<MockClDevice>(MockDevice::create<MockDevice>(executionEnvironment, rootDeviceIndex));

View File

@@ -10,6 +10,7 @@
#include "shared/test/unit_test/test_macros/test_checks_shared.h"
#include "opencl/source/command_queue/command_queue.h"
#include "opencl/test/unit_test/mocks/mock_cl_device.h"
#include "opencl/test/unit_test/mocks/mock_command_queue.h"
#include "opencl/test/unit_test/mocks/mock_graphics_allocation.h"
#include "opencl/test/unit_test/mocks/mock_memory_manager.h"
@@ -52,7 +53,9 @@ TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenSynchronizeMemoryThenEnq
auto svmAllocsManager = std::make_unique<SVMAllocsManager>(memoryManager.get());
void *alloc = svmAllocsManager->createSVMAlloc(mockRootDeviceIndex, 256, {}, mockDeviceBitfield);
auto device = std::unique_ptr<MockClDevice>(new MockClDevice{MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr)});
auto cmdQ = std::make_unique<CommandQueueMock>();
cmdQ->device = device.get();
pageFaultManager->insertAllocation(alloc, 256, svmAllocsManager.get(), cmdQ.get(), {});
pageFaultManager->baseCpuTransfer(alloc, 10, cmdQ.get());
@@ -66,6 +69,7 @@ TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenSynchronizeMemoryThenEnq
EXPECT_EQ(cmdQ->finishCalled, 1);
svmAllocsManager->freeSVMAlloc(alloc);
cmdQ->device = nullptr;
}
TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenGpuTransferIsInvokedThenInsertMapOperation) {
@@ -83,7 +87,9 @@ TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenGpuTransferIsInvokedThen
auto memoryManager = std::make_unique<MockMemoryManager>(executionEnvironment);
auto svmAllocsManager = std::make_unique<MockSVMAllocsManager>(memoryManager.get());
void *alloc = svmAllocsManager->createSVMAlloc(mockRootDeviceIndex, 256, {}, mockDeviceBitfield);
auto device = std::unique_ptr<MockClDevice>(new MockClDevice{MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr)});
auto cmdQ = std::make_unique<CommandQueueMock>();
cmdQ->device = device.get();
pageFaultManager->insertAllocation(alloc, 256, svmAllocsManager.get(), cmdQ.get(), {});
EXPECT_EQ(svmAllocsManager->insertSvmMapOperationCalled, 0);
@@ -91,4 +97,5 @@ TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenGpuTransferIsInvokedThen
EXPECT_EQ(svmAllocsManager->insertSvmMapOperationCalled, 1);
svmAllocsManager->freeSVMAlloc(alloc);
cmdQ->device = nullptr;
}

View File

@@ -85,6 +85,7 @@ DirectSubmissionEnableDebugBuffer = 0
DirectSubmissionDiagnosticExecutionCount = 30
DirectSubmissionDisableCacheFlush = 0
DirectSubmissionDisableMonitorFence = 0
USMEvictAfterMigration = 1
EnableNullHardware = 0
ForceLinearImages = 0
ForceSLML3Config = 0

View File

@@ -137,6 +137,7 @@ DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionDiagnosticExecutionCount, 30, "N
DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionOverrideBlitterSupport, -1, "Overrides default blitter support: -1: do not override, 0: disable engine support, 1: enable engine support with init start, 2: enable engine support without init start")
DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionOverrideRenderSupport, -1, "Overrides default render support: -1: do not override, 0: disable engine support, 1: enable engine support with init start, 2: enable engine support without init start")
DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionOverrideComputeSupport, -1, "Overrides default compute support: -1: do not override, 0: disable engine support, 1: enable engine support with init start, 2: enable engine support without init start")
DECLARE_DEBUG_VARIABLE(bool, USMEvictAfterMigration, true, "Evict USM allocation after implicit migration to GPU")
DECLARE_DEBUG_VARIABLE(bool, DirectSubmissionDisableCacheFlush, false, "Disable dispatching cache flush commands")
DECLARE_DEBUG_VARIABLE(bool, DirectSubmissionDisableMonitorFence, false, "Disable dispatching monitor fence commands")

View File

@@ -16,6 +16,8 @@
#include <unordered_map>
namespace NEO {
class GraphicsAllocation;
class Device;
class SVMAllocsManager;
class PageFaultManager : public NonCopyableOrMovableClass {
@@ -46,6 +48,7 @@ class PageFaultManager : public NonCopyableOrMovableClass {
virtual void allowCPUMemoryAccess(void *ptr, size_t size) = 0;
virtual void protectCPUMemoryAccess(void *ptr, size_t size) = 0;
virtual void evictMemoryAfterImplCopy(GraphicsAllocation *allocation, Device *device) = 0;
virtual void broadcastWaitSignal() = 0;
MOCKABLE_VIRTUAL void waitForCopy();

View File

@@ -7,7 +7,10 @@
#include "shared/source/page_fault_manager/linux/cpu_page_fault_manager_linux.h"
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/device/device.h"
#include "shared/source/helpers/debug_helpers.h"
#include "shared/source/memory_manager/memory_operations_handler.h"
#include <dirent.h>
#include <sys/mman.h>
@@ -40,6 +43,9 @@ PageFaultManagerLinux::PageFaultManagerLinux() {
retVal = sigaction(SIGUSR1, &pageFaultManagerHandler, &previousUserSignalHandler);
UNRECOVERABLE_IF(retVal != 0);
this->evictMemoryAfterCopy = DebugManager.flags.EnableDirectSubmission.get() &&
DebugManager.flags.USMEvictAfterMigration.get();
}
PageFaultManagerLinux::~PageFaultManagerLinux() {
@@ -113,4 +119,10 @@ void PageFaultManagerLinux::sendSignalToThread(int threadId) {
syscall(SYS_tkill, threadId, SIGUSR1);
}
void PageFaultManagerLinux::evictMemoryAfterImplCopy(GraphicsAllocation *allocation, Device *device) {
if (evictMemoryAfterCopy) {
device->getRootDeviceEnvironment().memoryOperationsInterface->evict(device, *allocation);
}
};
} // namespace NEO

View File

@@ -24,6 +24,7 @@ class PageFaultManagerLinux : public PageFaultManager {
void allowCPUMemoryAccess(void *ptr, size_t size) override;
void protectCPUMemoryAccess(void *ptr, size_t size) override;
void evictMemoryAfterImplCopy(GraphicsAllocation *allocation, Device *device) override;
void broadcastWaitSignal() override;
MOCKABLE_VIRTUAL void sendSignalToThread(int threadId);
@@ -34,5 +35,7 @@ class PageFaultManagerLinux : public PageFaultManager {
struct sigaction previousPageFaultHandler = {};
struct sigaction previousUserSignalHandler = {};
bool evictMemoryAfterCopy = false;
};
} // namespace NEO

View File

@@ -51,6 +51,8 @@ void PageFaultManagerWindows::protectCPUMemoryAccess(void *ptr, size_t size) {
UNRECOVERABLE_IF(!retVal);
}
void PageFaultManagerWindows::evictMemoryAfterImplCopy(GraphicsAllocation *allocation, Device *device) {}
void PageFaultManagerWindows::broadcastWaitSignal() {}
} // namespace NEO

View File

@@ -25,6 +25,7 @@ class PageFaultManagerWindows : public PageFaultManager {
void allowCPUMemoryAccess(void *ptr, size_t size) override;
void protectCPUMemoryAccess(void *ptr, size_t size) override;
void evictMemoryAfterImplCopy(GraphicsAllocation *allocation, Device *device) override;
void broadcastWaitSignal() override;
static std::function<LONG(struct _EXCEPTION_POINTERS *exceptionInfo)> pageFaultHandler;

View File

@@ -6,9 +6,14 @@
*/
#include "shared/source/page_fault_manager/linux/cpu_page_fault_manager_linux.h"
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
#include "shared/test/unit_test/mocks/mock_device.h"
#include "shared/test/unit_test/page_fault_manager/cpu_page_fault_manager_tests_fixture.h"
#include "shared/test/unit_test/page_fault_manager/mock_cpu_page_fault_manager.h"
#include "opencl/test/unit_test/mocks/mock_graphics_allocation.h"
#include "opencl/test/unit_test/mocks/mock_memory_operations_handler.h"
#include "gtest/gtest.h"
#include <csignal>
@@ -73,6 +78,78 @@ TEST_F(PageFaultManagerLinuxTest, whenPageFaultIsRaisedThenHandlerIsInvoked) {
EXPECT_TRUE(pageFaultManager->handlerInvoked);
}
struct MockOperationsInterface : public MockMemoryOperationsHandler {
bool evictCalled = false;
MemoryOperationsStatus evict(Device *device, GraphicsAllocation &gfxAllocation) override {
this->evictCalled = true;
return MemoryOperationsStatus::UNSUPPORTED;
}
};
TEST_F(PageFaultManagerLinuxTest, givenDirectSubmissionAndUSMEvictWaEnabledWhenEvitMemoryAfterCopyThenMemoryOperationsHandlerEvictMethodIsCalled) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDirectSubmission.set(true);
DebugManager.flags.USMEvictAfterMigration.set(true);
auto pageFaultManager = std::make_unique<MockPageFaultManagerLinux>();
std::unique_ptr<Device> device(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
device->getExecutionEnvironment()->rootDeviceEnvironments[0u]->memoryOperationsInterface = std::make_unique<MockOperationsInterface>();
auto operationInterface = static_cast<MockOperationsInterface *>(device->getExecutionEnvironment()->rootDeviceEnvironments[0u]->memoryOperationsInterface.get());
MockGraphicsAllocation allocation;
EXPECT_FALSE(operationInterface->evictCalled);
pageFaultManager->evictMemoryAfterImplCopy(&allocation, device.get());
EXPECT_TRUE(operationInterface->evictCalled);
}
TEST_F(PageFaultManagerLinuxTest, givenDirectSubmissionEnabledAndUSMEvictWaDisabledWhenEvitMemoryAfterCopyThenMemoryOperationsHandlerEvictMethodIsNotCalled) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDirectSubmission.set(true);
DebugManager.flags.USMEvictAfterMigration.set(false);
auto pageFaultManager = std::make_unique<MockPageFaultManagerLinux>();
std::unique_ptr<Device> device(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
device->getExecutionEnvironment()->rootDeviceEnvironments[0u]->memoryOperationsInterface = std::make_unique<MockOperationsInterface>();
auto operationInterface = static_cast<MockOperationsInterface *>(device->getExecutionEnvironment()->rootDeviceEnvironments[0u]->memoryOperationsInterface.get());
MockGraphicsAllocation allocation;
EXPECT_FALSE(operationInterface->evictCalled);
pageFaultManager->evictMemoryAfterImplCopy(&allocation, device.get());
EXPECT_FALSE(operationInterface->evictCalled);
}
TEST_F(PageFaultManagerLinuxTest, givenDirectSubmissionAndUSMEvictWaDisabledWhenEvitMemoryAfterCopyThenMemoryOperationsHandlerEvictMethodIsNotCalled) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDirectSubmission.set(false);
DebugManager.flags.USMEvictAfterMigration.set(false);
auto pageFaultManager = std::make_unique<MockPageFaultManagerLinux>();
std::unique_ptr<Device> device(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
device->getExecutionEnvironment()->rootDeviceEnvironments[0u]->memoryOperationsInterface = std::make_unique<MockOperationsInterface>();
auto operationInterface = static_cast<MockOperationsInterface *>(device->getExecutionEnvironment()->rootDeviceEnvironments[0u]->memoryOperationsInterface.get());
MockGraphicsAllocation allocation;
EXPECT_FALSE(operationInterface->evictCalled);
pageFaultManager->evictMemoryAfterImplCopy(&allocation, device.get());
EXPECT_FALSE(operationInterface->evictCalled);
}
TEST_F(PageFaultManagerLinuxTest, givenDirectSubmissionDisabledAndUSMEvictWaEnabledWhenEvitMemoryAfterCopyThenMemoryOperationsHandlerEvictMethodIsNotCalled) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDirectSubmission.set(false);
DebugManager.flags.USMEvictAfterMigration.set(true);
auto pageFaultManager = std::make_unique<MockPageFaultManagerLinux>();
std::unique_ptr<Device> device(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
device->getExecutionEnvironment()->rootDeviceEnvironments[0u]->memoryOperationsInterface = std::make_unique<MockOperationsInterface>();
auto operationInterface = static_cast<MockOperationsInterface *>(device->getExecutionEnvironment()->rootDeviceEnvironments[0u]->memoryOperationsInterface.get());
MockGraphicsAllocation allocation;
EXPECT_FALSE(operationInterface->evictCalled);
pageFaultManager->evictMemoryAfterImplCopy(&allocation, device.get());
EXPECT_FALSE(operationInterface->evictCalled);
}
TEST_F(PageFaultManagerLinuxTest, givenProtectedMemoryWhenTryingToAccessThenPageFaultIsRaisedAndMemoryIsAccessibleAfterHandling) {
auto pageFaultManager = std::make_unique<MockPageFaultManagerLinux>();
pageFaultManager->allowCPUMemoryAccessOnPageFault = true;

View File

@@ -50,6 +50,7 @@ class MockPageFaultManager : public PageFaultManager {
PageFaultManager::transferToGpu(ptr, cmdQ);
}
void broadcastWaitSignal() override {}
void evictMemoryAfterImplCopy(GraphicsAllocation *allocation, Device *device) override {}
int allowMemoryAccessCalled = 0;
int protectMemoryCalled = 0;
@@ -69,6 +70,7 @@ template <class T>
class MockPageFaultManagerHandlerInvoke : public T {
public:
using T::allowCPUMemoryAccess;
using T::evictMemoryAfterImplCopy;
using T::protectCPUMemoryAccess;
using T::T;