Disallow CPU buffer read/write operation if CPU access is disallowed

Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski 2021-03-01 19:07:28 +00:00 committed by Compute-Runtime-Automation
parent 102de8ffd5
commit a33d74bb79
12 changed files with 59 additions and 11 deletions

View File

@ -692,7 +692,7 @@ bool CommandQueue::bufferCpuCopyAllowed(Buffer *buffer, cl_command_type commandT
}
//check if buffer is compatible
if (!buffer->isReadWriteOnCpuAllowed(device->getRootDeviceIndex())) {
if (!buffer->isReadWriteOnCpuAllowed(device->getDevice())) {
return false;
}

View File

@ -595,11 +595,13 @@ size_t Buffer::calculateHostPtrSize(const size_t *origin, const size_t *region,
return hostPtrSize;
}
bool Buffer::isReadWriteOnCpuAllowed(uint32_t rootDeviceIndex) {
bool Buffer::isReadWriteOnCpuAllowed(const Device &device) {
if (forceDisallowCPUCopy) {
return false;
}
auto rootDeviceIndex = device.getRootDeviceIndex();
if (this->isCompressed(rootDeviceIndex)) {
return false;
}
@ -613,6 +615,13 @@ bool Buffer::isReadWriteOnCpuAllowed(uint32_t rootDeviceIndex) {
if (graphicsAllocation->storageInfo.getNumBanks() > 1) {
return false;
}
const auto &hardwareInfo = device.getHardwareInfo();
auto &hwHelper = HwHelper::get(hardwareInfo.platform.eRenderCoreFamily);
auto isCpuAccessDisallowed = LocalMemoryAccessMode::CpuAccessDisallowed == hwHelper.getLocalMemoryAccessMode(hardwareInfo);
if (isCpuAccessDisallowed) {
return false;
}
return true;
}

View File

@ -151,7 +151,7 @@ class Buffer : public MemObj {
void transferDataToHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) override;
void transferDataFromHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) override;
bool isReadWriteOnCpuAllowed(uint32_t rootDeviceIndex);
bool isReadWriteOnCpuAllowed(const Device &device);
bool isReadWriteOnCpuPreferred(void *ptr, size_t size, const Device &device);
uint32_t getMocsValue(bool disableL3Cache, bool isReadOnlyArgument, uint32_t rootDeviceIndex) const;

View File

@ -1379,6 +1379,7 @@ HWTEST_TEMPLATED_F(BlitEnqueueTaskCountTests, givenBlockedEnqueueWithoutKernelWh
HWTEST_TEMPLATED_F(BlitEnqueueTaskCountTests, givenEventFromCpuCopyWhenWaitingForCompletionThenWaitForCurrentBcsTaskCount) {
DebugManager.flags.DoCpuCopyOnWriteBuffer.set(1);
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
auto buffer = createBuffer(1, false);
int hostPtr = 0;

View File

@ -102,6 +102,7 @@ TEST_F(EnqueueReadBuffer, WhenReadingBufferThenEventReturnedShouldBeMaxOfInputEv
TEST_F(EnqueueReadBuffer, givenInOrderQueueAndForcedCpuCopyOnReadBufferAndDstPtrEqualSrcPtrWithEventsNotBlockedWhenReadBufferIsExecutedThenTaskLevelShouldNotBeIncreased) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.DoCpuCopyOnReadBuffer.set(1);
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
cl_int retVal = CL_SUCCESS;
uint32_t taskLevelCmdQ = 17;
pCmdQ->taskLevel = taskLevelCmdQ;
@ -144,6 +145,7 @@ TEST_F(EnqueueReadBuffer, givenInOrderQueueAndForcedCpuCopyOnReadBufferAndDstPtr
TEST_F(EnqueueReadBuffer, givenInOrderQueueAndForcedCpuCopyOnReadBufferAndDstPtrEqualSrcPtrWhenReadBufferIsExecutedThenTaskLevelShouldNotBeIncreased) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.DoCpuCopyOnReadBuffer.set(1);
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
cl_int retVal = CL_SUCCESS;
uint32_t taskLevelCmdQ = 17;
pCmdQ->taskLevel = taskLevelCmdQ;
@ -177,6 +179,7 @@ TEST_F(EnqueueReadBuffer, givenInOrderQueueAndForcedCpuCopyOnReadBufferAndDstPtr
TEST_F(EnqueueReadBuffer, givenOutOfOrderQueueAndForcedCpuCopyOnReadBufferAndDstPtrEqualSrcPtrWithEventsNotBlockedWhenReadBufferIsExecutedThenTaskLevelShouldNotBeIncreased) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.DoCpuCopyOnReadBuffer.set(1);
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
std::unique_ptr<CommandQueue> pCmdOOQ(createCommandQueue(pClDevice, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE));
cl_int retVal = CL_SUCCESS;
uint32_t taskLevelCmdQ = 17;

View File

@ -558,6 +558,7 @@ HWTEST_F(EnqueueReadBufferTypeTest, givenEnqueueReadBufferCalledWhenLockedPtrInT
HWTEST_F(EnqueueReadBufferTypeTest, givenForcedCpuCopyWhenEnqueueReadCompressedBufferThenDontCopyOnCpu) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.DoCpuCopyOnReadBuffer.set(1);
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
MockExecutionEnvironment executionEnvironment(defaultHwInfo.get());
MockMemoryManager memoryManager(false, true, executionEnvironment);

View File

@ -219,6 +219,7 @@ HWTEST_F(EnqueueUnmapMemObjTest, givenEnqueueUnmapMemObjectWhenNonAubWritableBuf
HWTEST_F(EnqueueUnmapMemObjTest, givenWriteBufferIsServicedOnCPUWhenBufferIsNonAubTbxWriteableThanFlagsChange) {
DebugManagerStateRestore restorer;
DebugManager.flags.DoCpuCopyOnWriteBuffer.set(1);
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create());
ASSERT_NE(nullptr, buffer);
auto graphicsAllocation = buffer->getGraphicsAllocation(pClDevice->getRootDeviceIndex());

View File

@ -103,6 +103,7 @@ TEST_F(EnqueueWriteBufferTypeTest, WhenWritingBufferThenReturnedEventShouldBeMax
TEST_F(EnqueueWriteBufferTypeTest, givenInOrderQueueAndForcedCpuCopyOnWriteBufferAndDstPtrEqualSrcPtrWithEventsNotBlockedWhenWriteBufferIsExecutedThenTaskLevelShouldNotBeIncreased) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.DoCpuCopyOnWriteBuffer.set(1);
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
cl_int retVal = CL_SUCCESS;
uint32_t taskLevelCmdQ = 17;
pCmdQ->taskLevel = taskLevelCmdQ;
@ -217,6 +218,7 @@ TEST_F(EnqueueWriteBufferTypeTest, givenInOrderQueueAndForcedCpuCopyOnWriteBuffe
TEST_F(EnqueueWriteBufferTypeTest, givenOutOfOrderQueueAndForcedCpuCopyOnWriteBufferAndDstPtrEqualSrcPtrWithEventsWhenWriteBufferIsExecutedThenTaskLevelShouldNotBeIncreased) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.DoCpuCopyOnWriteBuffer.set(1);
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
std::unique_ptr<CommandQueue> pCmdOOQ(createCommandQueue(pClDevice, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE));
cl_int retVal = CL_SUCCESS;
uint32_t taskLevelCmdQ = 17;

View File

@ -414,6 +414,7 @@ HWTEST_F(EnqueueWriteBufferTypeTest, givenEnqueueWriteBufferCalledWhenLockedPtrI
HWTEST_F(EnqueueWriteBufferTypeTest, givenForcedCpuCopyWhenEnqueueWriteCompressedBufferThenDontCopyOnCpu) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.DoCpuCopyOnWriteBuffer.set(1);
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
MockExecutionEnvironment executionEnvironment(defaultHwInfo.get());
MockMemoryManager memoryManager(false, true, executionEnvironment);

View File

@ -18,6 +18,8 @@ using namespace NEO;
typedef EnqueueReadBufferTypeTest ReadWriteBufferCpuCopyTest;
HWTEST_F(ReadWriteBufferCpuCopyTest, givenRenderCompressedGmmWhenAskingForCpuOperationThenDisallow) {
DebugManagerStateRestore restorer;
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
cl_int retVal;
auto rootDeviceIndex = context->getDevice(0)->getRootDeviceIndex();
std::unique_ptr<Buffer> buffer(Buffer::create(context, CL_MEM_READ_WRITE, 1, nullptr, retVal));
@ -29,17 +31,31 @@ HWTEST_F(ReadWriteBufferCpuCopyTest, givenRenderCompressedGmmWhenAskingForCpuOpe
auto alignedPtr = alignedMalloc(2, MemoryConstants::cacheLineSize);
auto unalignedPtr = ptrOffset(alignedPtr, 1);
EXPECT_EQ(1u, allocation->storageInfo.getNumBanks());
EXPECT_TRUE(buffer->isReadWriteOnCpuAllowed(rootDeviceIndex));
EXPECT_TRUE(buffer->isReadWriteOnCpuAllowed(*pDevice));
EXPECT_TRUE(buffer->isReadWriteOnCpuPreferred(unalignedPtr, 1, *pDevice));
gmm->isRenderCompressed = true;
EXPECT_FALSE(buffer->isReadWriteOnCpuAllowed(rootDeviceIndex));
EXPECT_FALSE(buffer->isReadWriteOnCpuAllowed(*pDevice));
EXPECT_TRUE(buffer->isReadWriteOnCpuPreferred(unalignedPtr, 1, *pDevice));
alignedFree(alignedPtr);
}
HWTEST_F(ReadWriteBufferCpuCopyTest, givenDisallowedCpuAccessWhenAskingForCpuOperationThenDisallow) {
DebugManagerStateRestore restorer;
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
cl_int retVal;
std::unique_ptr<Buffer> buffer(Buffer::create(context, CL_MEM_READ_WRITE, 1, nullptr, retVal));
EXPECT_TRUE(buffer->isReadWriteOnCpuAllowed(*pDevice));
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::CpuAccessDisallowed));
EXPECT_FALSE(buffer->isReadWriteOnCpuAllowed(*pDevice));
}
HWTEST_F(ReadWriteBufferCpuCopyTest, GivenUnalignedReadPtrWhenReadingBufferThenMemoryIsReadCorrectly) {
DebugManagerStateRestore restorer;
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
cl_int retVal;
size_t offset = 1;
size_t size = 4;
@ -57,7 +73,7 @@ HWTEST_F(ReadWriteBufferCpuCopyTest, GivenUnalignedReadPtrWhenReadingBufferThenM
bool aligned = (reinterpret_cast<uintptr_t>(unalignedReadPtr) & (MemoryConstants::cacheLineSize - 1)) == 0;
EXPECT_TRUE(!aligned || buffer->isMemObjZeroCopy());
ASSERT_TRUE(buffer->isReadWriteOnCpuAllowed(pCmdQ->getDevice().getRootDeviceIndex()));
ASSERT_TRUE(buffer->isReadWriteOnCpuAllowed(pCmdQ->getDevice()));
ASSERT_TRUE(buffer->isReadWriteOnCpuPreferred(unalignedReadPtr, size, context->getDevice(0)->getDevice()));
retVal = EnqueueReadBufferHelper<>::enqueueReadBuffer(pCmdQ,
@ -79,6 +95,8 @@ HWTEST_F(ReadWriteBufferCpuCopyTest, GivenUnalignedReadPtrWhenReadingBufferThenM
}
HWTEST_F(ReadWriteBufferCpuCopyTest, GivenUnalignedSrcPtrWhenWritingBufferThenMemoryIsWrittenCorrectly) {
DebugManagerStateRestore restorer;
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
cl_int retVal;
size_t offset = 1;
size_t size = 4;
@ -98,7 +116,7 @@ HWTEST_F(ReadWriteBufferCpuCopyTest, GivenUnalignedSrcPtrWhenWritingBufferThenMe
bool aligned = (reinterpret_cast<uintptr_t>(unalignedWritePtr) & (MemoryConstants::cacheLineSize - 1)) == 0;
EXPECT_TRUE(!aligned || buffer->isMemObjZeroCopy());
ASSERT_TRUE(buffer->isReadWriteOnCpuAllowed(pCmdQ->getDevice().getRootDeviceIndex()));
ASSERT_TRUE(buffer->isReadWriteOnCpuAllowed(pCmdQ->getDevice()));
ASSERT_TRUE(buffer->isReadWriteOnCpuPreferred(unalignedWritePtr, size, context->getDevice(0)->getDevice()));
retVal = EnqueueWriteBufferHelper<>::enqueueWriteBuffer(pCmdQ,
@ -125,6 +143,8 @@ HWTEST_F(ReadWriteBufferCpuCopyTest, GivenUnalignedSrcPtrWhenWritingBufferThenMe
}
HWTEST_F(ReadWriteBufferCpuCopyTest, GivenSpecificMemoryStructuresWhenReadingWritingMemoryThenCpuReadWriteIsAllowed) {
DebugManagerStateRestore restorer;
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
cl_int retVal;
size_t size = MemoryConstants::cacheLineSize;
auto alignedBufferPtr = alignedMalloc(MemoryConstants::cacheLineSize + 1, MemoryConstants::cacheLineSize);
@ -218,6 +238,7 @@ HWTEST_F(ReadWriteBufferCpuCopyTest, GivenSpecificMemoryStructuresWhenReadingWri
HWTEST_F(ReadWriteBufferCpuCopyTest, givenDebugVariableToDisableCpuCopiesWhenBufferCpuCopyAllowedIsCalledThenItReturnsFalse) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableLocalMemory.set(false);
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
cl_int retVal;
@ -242,6 +263,8 @@ HWTEST_F(ReadWriteBufferCpuCopyTest, givenDebugVariableToDisableCpuCopiesWhenBuf
}
TEST(ReadWriteBufferOnCpu, givenNoHostPtrAndAlignedSizeWhenMemoryAllocationIsInNonSystemMemoryPoolThenIsReadWriteOnCpuAllowedReturnsFalse) {
DebugManagerStateRestore restorer;
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
auto memoryManager = new MockMemoryManager(*device->getExecutionEnvironment());
@ -254,15 +277,17 @@ TEST(ReadWriteBufferOnCpu, givenNoHostPtrAndAlignedSizeWhenMemoryAllocationIsInN
std::unique_ptr<Buffer> buffer(Buffer::create(&ctx, flags, MemoryConstants::pageSize, nullptr, retVal));
ASSERT_NE(nullptr, buffer.get());
EXPECT_TRUE(buffer->isReadWriteOnCpuAllowed(device->getRootDeviceIndex()));
EXPECT_TRUE(buffer->isReadWriteOnCpuAllowed(device->getDevice()));
EXPECT_TRUE(buffer->isReadWriteOnCpuPreferred(reinterpret_cast<void *>(0x1000), MemoryConstants::pageSize, device->getDevice()));
reinterpret_cast<MemoryAllocation *>(buffer->getGraphicsAllocation(device->getRootDeviceIndex()))->overrideMemoryPool(MemoryPool::SystemCpuInaccessible);
//read write on CPU is allowed, but not preferred. We can access this memory via Lock.
EXPECT_TRUE(buffer->isReadWriteOnCpuAllowed(device->getRootDeviceIndex()));
EXPECT_TRUE(buffer->isReadWriteOnCpuAllowed(device->getDevice()));
EXPECT_FALSE(buffer->isReadWriteOnCpuPreferred(reinterpret_cast<void *>(0x1000), MemoryConstants::pageSize, device->getDevice()));
}
TEST(ReadWriteBufferOnCpu, givenPointerThatRequiresCpuCopyWhenCpuCopyIsEvaluatedThenTrueIsReturned) {
DebugManagerStateRestore restorer;
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
auto memoryManager = new MockMemoryManager(*device->getExecutionEnvironment());
@ -283,6 +308,8 @@ TEST(ReadWriteBufferOnCpu, givenPointerThatRequiresCpuCopyWhenCpuCopyIsEvaluated
}
TEST(ReadWriteBufferOnCpu, givenPointerThatRequiresCpuCopyButItIsNotPossibleWhenCpuCopyIsEvaluatedThenFalseIsReturned) {
DebugManagerStateRestore restorer;
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
auto memoryManager = new MockMemoryManager(*device->getExecutionEnvironment());
@ -304,6 +331,8 @@ TEST(ReadWriteBufferOnCpu, givenPointerThatRequiresCpuCopyButItIsNotPossibleWhen
}
TEST(ReadWriteBufferOnCpu, whenLocalMemoryPoolAllocationIsAskedForPreferenceThenCpuIsNotChoosen) {
DebugManagerStateRestore restorer;
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
MockContext ctx(device.get());
@ -312,6 +341,6 @@ TEST(ReadWriteBufferOnCpu, whenLocalMemoryPoolAllocationIsAskedForPreferenceThen
ASSERT_NE(nullptr, buffer.get());
reinterpret_cast<MemoryAllocation *>(buffer->getGraphicsAllocation(device->getRootDeviceIndex()))->overrideMemoryPool(MemoryPool::LocalMemory);
EXPECT_TRUE(buffer->isReadWriteOnCpuAllowed(device->getRootDeviceIndex()));
EXPECT_TRUE(buffer->isReadWriteOnCpuAllowed(device->getDevice()));
EXPECT_FALSE(buffer->isReadWriteOnCpuPreferred(reinterpret_cast<void *>(0x1000), MemoryConstants::pageSize, device->getDevice()));
}

View File

@ -761,6 +761,7 @@ TEST(UnfiedSharedMemoryTransferCalls, givenDeviceUsmAllocationWhenPtrIsUsedForTr
TEST(UnfiedSharedMemoryTransferCalls, givenHostUsmAllocationWhenPtrIsUsedForTransferCallsThenCPUPathIsChoosen) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableLocalMemory.set(false);
DebugManager.flags.ForceLocalMemoryAccessMode.set(static_cast<int32_t>(LocalMemoryAccessMode::Default));
MockContext mockContext;
cl_context clContext = &mockContext;

View File

@ -217,7 +217,7 @@ TEST_F(glSharingTests, givenClGLBufferWhenItIsAcquiredThenAcuqireCountIsIncremen
auto memObject = castToObject<Buffer>(glBuffer);
EXPECT_FALSE(memObject->isMemObjZeroCopy());
EXPECT_FALSE(memObject->isReadWriteOnCpuAllowed(rootDeviceIndex));
EXPECT_FALSE(memObject->isReadWriteOnCpuAllowed(context.getDevice(0)->getDevice()));
auto currentGraphicsAllocation = memObject->getGraphicsAllocation(rootDeviceIndex);
memObject->peekSharingHandler()->acquire(memObject, rootDeviceIndex);