diff --git a/opencl/test/unit_test/command_stream/command_stream_receiver_tests.cpp b/opencl/test/unit_test/command_stream/command_stream_receiver_tests.cpp index 159eb1f841..c83d242f60 100644 --- a/opencl/test/unit_test/command_stream/command_stream_receiver_tests.cpp +++ b/opencl/test/unit_test/command_stream/command_stream_receiver_tests.cpp @@ -1113,6 +1113,22 @@ TEST_F(CreateAllocationForHostSurfaceTest, givenTemporaryAllocationWhenCreateAll EXPECT_EQ(allocationPtr, hostSurfaceAllocationPtr); } +TEST_F(CreateAllocationForHostSurfaceTest, whenCreatingAllocationFromHostPtrSurfaceThenLockMutex) { + const char memory[8] = {1, 2, 3, 4, 5, 6, 7, 8}; + size_t size = sizeof(memory); + HostPtrSurface surface(const_cast(memory), size, true); + + MockExecutionEnvironment executionEnvironment; + executionEnvironment.initializeMemoryManager(); + DeviceBitfield deviceBitfield(1); + MockCommandStreamReceiver commandStreamReceiver(executionEnvironment, 0u, deviceBitfield); + auto osContext = executionEnvironment.memoryManager->createAndRegisterOsContext(&commandStreamReceiver, EngineDescriptorHelper::getDefaultDescriptor(deviceBitfield)); + commandStreamReceiver.osContext = osContext; + EXPECT_EQ(0, commandStreamReceiver.hostPtrSurfaceCreationMutexLockCount); + commandStreamReceiver.createAllocationForHostSurface(surface, true); + EXPECT_EQ(1, commandStreamReceiver.hostPtrSurfaceCreationMutexLockCount); +} + TEST_F(CreateAllocationForHostSurfaceTest, givenReadOnlyHostPointerWhenAllocationForHostSurfaceWithPtrCopyAllowedIsCreatedThenCopyAllocationIsCreatedAndMemoryCopied) { const char memory[8] = {1, 2, 3, 4, 5, 6, 7, 8}; size_t size = sizeof(memory); diff --git a/shared/source/command_stream/command_stream_receiver.cpp b/shared/source/command_stream/command_stream_receiver.cpp index a0f6a72017..faedbbadb1 100644 --- a/shared/source/command_stream/command_stream_receiver.cpp +++ b/shared/source/command_stream/command_stream_receiver.cpp @@ -601,10 +601,14 @@ bool CommandStreamReceiver::createPreemptionAllocation() { std::unique_lock CommandStreamReceiver::obtainUniqueOwnership() { return std::unique_lock(this->ownershipMutex); } +std::unique_lock CommandStreamReceiver::obtainHostPtrSurfaceCreationLock() { + return std::unique_lock(this->hostPtrSurfaceCreationMutex); +} AllocationsList &CommandStreamReceiver::getTemporaryAllocations() { return internalAllocationStorage->getTemporaryAllocations(); } AllocationsList &CommandStreamReceiver::getAllocationsForReuse() { return internalAllocationStorage->getAllocationsForReuse(); } bool CommandStreamReceiver::createAllocationForHostSurface(HostPtrSurface &surface, bool requiresL3Flush) { + std::unique_lock lock = this->obtainHostPtrSurfaceCreationLock(); auto allocation = internalAllocationStorage->obtainTemporaryAllocationWithPtr(surface.getSurfaceSize(), surface.getMemoryPointer(), GraphicsAllocation::AllocationType::EXTERNAL_HOST_PTR); if (allocation == nullptr) { diff --git a/shared/source/command_stream/command_stream_receiver.h b/shared/source/command_stream/command_stream_receiver.h index 92eab4482b..6cf4cd633e 100644 --- a/shared/source/command_stream/command_stream_receiver.h +++ b/shared/source/command_stream/command_stream_receiver.h @@ -281,6 +281,7 @@ class CommandStreamReceiver { void printDeviceIndex(); void checkForNewResources(uint32_t submittedTaskCount, uint32_t allocationTaskCount, GraphicsAllocation &gfxAllocation); bool checkImplicitFlushForGpuIdle(); + MOCKABLE_VIRTUAL std::unique_lock obtainHostPtrSurfaceCreationLock(); std::unique_ptr flushStamp; std::unique_ptr submissionAggregator; @@ -297,6 +298,7 @@ class CommandStreamReceiver { ResidencyContainer residencyAllocations; ResidencyContainer evictionAllocations; MutexType ownershipMutex; + MutexType hostPtrSurfaceCreationMutex; ExecutionEnvironment &executionEnvironment; LinearStream commandStream; diff --git a/shared/source/memory_manager/allocations_list.cpp b/shared/source/memory_manager/allocations_list.cpp index 57c688271a..03440d499d 100644 --- a/shared/source/memory_manager/allocations_list.cpp +++ b/shared/source/memory_manager/allocations_list.cpp @@ -28,9 +28,9 @@ AllocationsList::AllocationsList() std::unique_ptr AllocationsList::detachAllocation(size_t requiredMinimalSize, const void *requiredPtr, CommandStreamReceiver *commandStreamReceiver, GraphicsAllocation::AllocationType allocationType) { ReusableAllocationRequirements req; req.requiredMinimalSize = requiredMinimalSize; - commandStreamReceiver == nullptr ? req.csrTagAddress = nullptr : req.csrTagAddress = commandStreamReceiver->getTagAddress(); + req.csrTagAddress = (commandStreamReceiver == nullptr) ? nullptr : commandStreamReceiver->getTagAddress(); req.allocationType = allocationType; - commandStreamReceiver == nullptr ? req.contextId = UINT32_MAX : req.contextId = commandStreamReceiver->getOsContext().getContextId(); + req.contextId = (commandStreamReceiver == nullptr) ? UINT32_MAX : commandStreamReceiver->getOsContext().getContextId(); req.requiredPtr = requiredPtr; GraphicsAllocation *a = nullptr; GraphicsAllocation *retAlloc = processLocked(a, static_cast(&req)); diff --git a/shared/test/common/mocks/mock_command_stream_receiver.h b/shared/test/common/mocks/mock_command_stream_receiver.h index 2ba64b4446..9c07fcb8c7 100644 --- a/shared/test/common/mocks/mock_command_stream_receiver.h +++ b/shared/test/common/mocks/mock_command_stream_receiver.h @@ -117,6 +117,11 @@ class MockCommandStreamReceiver : public CommandStreamReceiver { makeResidentCalledTimes++; } + std::unique_lock obtainHostPtrSurfaceCreationLock() override { + ++hostPtrSurfaceCreationMutexLockCount; + return CommandStreamReceiver::obtainHostPtrSurfaceCreationLock(); + } + void postInitFlagsSetup() override {} std::vector instructionHeapReserveredData; @@ -131,6 +136,7 @@ class MockCommandStreamReceiver : public CommandStreamReceiver { bool callParentGetTagAddress = true; bool createPreemptionAllocationReturn = true; bool createPreemptionAllocationParentCall = false; + int hostPtrSurfaceCreationMutexLockCount = 0; }; template