Add blocking version of SVM free.

- Allows to synchronize prior to destruction.
Signed-off-by: Michal Mrozek <michal.mrozek@intel.com>

Change-Id: I9a3a8a2f87a272f45c4921d8e77c705455576ce0
This commit is contained in:
Michal Mrozek 2020-02-11 13:54:40 +01:00 committed by sys_ocldev
parent 023d49b77c
commit 545b79cf5f
3 changed files with 86 additions and 3 deletions

View File

@ -161,9 +161,16 @@ SvmAllocationData *SVMAllocsManager::getSVMAlloc(const void *ptr) {
return SVMAllocs.get(ptr);
}
bool SVMAllocsManager::freeSVMAlloc(void *ptr) {
bool SVMAllocsManager::freeSVMAlloc(void *ptr, bool blocking) {
SvmAllocationData *svmData = getSVMAlloc(ptr);
if (svmData) {
if (blocking) {
if (svmData->cpuAllocation) {
this->memoryManager->waitForEnginesCompletion(*svmData->cpuAllocation);
}
this->memoryManager->waitForEnginesCompletion(*svmData->gpuAllocation);
}
auto pageFaultManager = this->memoryManager->getPageFaultManager();
if (pageFaultManager) {
pageFaultManager->removeAllocation(ptr);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017-2019 Intel Corporation
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -85,7 +85,8 @@ class SVMAllocsManager {
void *createUnifiedMemoryAllocation(uint32_t rootDeviceIndex, size_t size, const UnifiedMemoryProperties &svmProperties);
void *createSharedUnifiedMemoryAllocation(uint32_t rootDeviceIndex, size_t size, const UnifiedMemoryProperties &svmProperties, void *cmdQ);
SvmAllocationData *getSVMAlloc(const void *ptr);
bool freeSVMAlloc(void *ptr);
bool freeSVMAlloc(void *ptr, bool blocking);
bool freeSVMAlloc(void *ptr) { return freeSVMAlloc(ptr, false); }
size_t getNumAllocs() const { return SVMAllocs.getNumAllocs(); }
MapBasedAllocationTracker *getSVMAllocs() { return &SVMAllocs; }

View File

@ -6,7 +6,9 @@
*/
#include "core/memory_manager/allocations_list.h"
#include "core/memory_manager/unified_memory_manager.h"
#include "core/os_interface/os_context.h"
#include "runtime/api/api.h"
#include "runtime/helpers/memory_properties_flags_helpers.h"
#include "runtime/mem_obj/mem_obj.h"
#include "runtime/platform/platform.h"
@ -314,3 +316,76 @@ INSTANTIATE_TEST_CASE_P(
MemObjTests,
MemObjSyncDestructionTest,
testing::Bool());
using UsmDestructionTests = ::testing::Test;
HWTEST_F(UsmDestructionTests, givenSharedUsmAllocationWhenBlockingFreeIsCalledThenWaitForCompletionIsCalled) {
MockDevice mockDevice;
mockDevice.incRefInternal();
MockClDevice mockClDevice(&mockDevice);
MockContext mockContext(&mockClDevice, false);
if (mockContext.getDevice(0u)->getHardwareInfo().capabilityTable.clVersionSupport < 20) {
GTEST_SKIP();
}
auto mockCsr = new ::testing::NiceMock<MyCsr<FamilyType>>(*mockDevice.executionEnvironment);
auto osContext = mockDevice.executionEnvironment->memoryManager->createAndRegisterOsContext(mockDevice.engines[0].commandStreamReceiver, aub_stream::ENGINE_RCS, {}, PreemptionMode::Disabled, false);
mockDevice.engines[0].osContext = osContext;
mockDevice.resetCommandStreamReceiver(mockCsr);
*mockCsr->getTagAddress() = 5u;
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::SHARED_UNIFIED_MEMORY);
auto svmAllocationsManager = mockContext.getSVMAllocsManager();
auto sharedMemory = svmAllocationsManager->createUnifiedAllocationWithDeviceStorage(0u, 4096u, {}, unifiedMemoryProperties);
ASSERT_NE(nullptr, sharedMemory);
auto svmEntry = svmAllocationsManager->getSVMAlloc(sharedMemory);
auto waitForCompletionWithTimeoutMock = [=](bool enableTimeout, int64_t timeoutMs, uint32_t taskCountToWait) -> bool { return true; };
ON_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, ::testing::_, ::testing::_))
.WillByDefault(::testing::Invoke(waitForCompletionWithTimeoutMock));
svmEntry->gpuAllocation->updateTaskCount(6u, 0u);
svmEntry->cpuAllocation->updateTaskCount(6u, 0u);
EXPECT_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, TimeoutControls::maxTimeout, 6u))
.Times(2);
svmAllocationsManager->freeSVMAlloc(sharedMemory, true);
}
HWTEST_F(UsmDestructionTests, givenUsmAllocationWhenBlockingFreeIsCalledThenWaitForCompletionIsCalled) {
MockDevice mockDevice;
mockDevice.incRefInternal();
MockClDevice mockClDevice(&mockDevice);
MockContext mockContext(&mockClDevice, false);
if (mockContext.getDevice(0u)->getHardwareInfo().capabilityTable.clVersionSupport < 20) {
GTEST_SKIP();
}
auto mockCsr = new ::testing::NiceMock<MyCsr<FamilyType>>(*mockDevice.executionEnvironment);
auto osContext = mockDevice.executionEnvironment->memoryManager->createAndRegisterOsContext(mockDevice.engines[0].commandStreamReceiver, aub_stream::ENGINE_RCS, {}, PreemptionMode::Disabled, false);
mockDevice.engines[0].osContext = osContext;
mockDevice.resetCommandStreamReceiver(mockCsr);
*mockCsr->getTagAddress() = 5u;
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::HOST_UNIFIED_MEMORY);
auto svmAllocationsManager = mockContext.getSVMAllocsManager();
auto hostMemory = svmAllocationsManager->createUnifiedMemoryAllocation(0u, 4096u, unifiedMemoryProperties);
ASSERT_NE(nullptr, hostMemory);
auto svmEntry = svmAllocationsManager->getSVMAlloc(hostMemory);
auto waitForCompletionWithTimeoutMock = [=](bool enableTimeout, int64_t timeoutMs, uint32_t taskCountToWait) -> bool { return true; };
ON_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, ::testing::_, ::testing::_))
.WillByDefault(::testing::Invoke(waitForCompletionWithTimeoutMock));
svmEntry->gpuAllocation->updateTaskCount(6u, 0u);
EXPECT_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, TimeoutControls::maxTimeout, 6u))
.Times(1);
svmAllocationsManager->freeSVMAlloc(hostMemory, true);
}