From 726b6769834d5f786c40b43f4fa08b101a005fea Mon Sep 17 00:00:00 2001 From: Fabian Zwolinski Date: Wed, 16 Mar 2022 15:52:08 +0000 Subject: [PATCH] Remove DrmMockImpl and use DrmMock instead Related-To: NEO-4914 Signed-off-by: Fabian Zwolinski --- .../linux/drm_command_stream_fixture.h | 26 +- .../linux/drm_command_stream_tests_1.cpp | 365 ++++++------------ .../drm_residency_handler_prelim_tests.cpp | 22 +- .../os_interface/linux/drm_tests.cpp | 13 +- shared/test/common/libult/linux/drm_mock.cpp | 32 +- shared/test/common/libult/linux/drm_mock.h | 28 +- .../linux/device_command_stream_fixture.cpp | 6 +- .../linux/device_command_stream_fixture.h | 60 ++- .../linux/drm_memory_manager_tests.h | 2 +- .../linux/drm_command_stream_l0_tests.cpp | 20 +- 10 files changed, 245 insertions(+), 329 deletions(-) diff --git a/opencl/test/unit_test/os_interface/linux/drm_command_stream_fixture.h b/opencl/test/unit_test/os_interface/linux/drm_command_stream_fixture.h index 196fc29ca5..4bfe6eacb3 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_command_stream_fixture.h +++ b/opencl/test/unit_test/os_interface/linux/drm_command_stream_fixture.h @@ -13,6 +13,7 @@ #include "shared/source/os_interface/os_interface.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/engine_descriptor_helper.h" +#include "shared/test/common/libult/linux/drm_mock.h" #include "shared/test/common/mocks/linux/mock_drm_command_stream_receiver.h" #include "shared/test/common/mocks/mock_execution_environment.h" #include "shared/test/common/os_interface/linux/device_command_stream_fixture.h" @@ -32,7 +33,7 @@ class DrmCommandStreamTest : public ::testing::Test { //make sure this is disabled, we don't want to test this now DebugManager.flags.EnableForcePin.set(false); - mock = new ::testing::NiceMock(mockFd, *executionEnvironment.rootDeviceEnvironments[0]); + mock = new DrmMock(mockFd, *executionEnvironment.rootDeviceEnvironments[0]); auto hwInfo = executionEnvironment.rootDeviceEnvironments[0]->getHardwareInfo(); mock->setupIoctlHelper(hwInfo->platform.eProductFamily); @@ -50,18 +51,19 @@ class DrmCommandStreamTest : public ::testing::Test { ASSERT_NE(nullptr, csr); csr->setupContext(*osContext); - // Memory manager creates pinBB with ioctl, expect one call - EXPECT_CALL(*mock, ioctl(::testing::_, ::testing::_)) - .Times(1); + mock->ioctlCallsCount = 0u; memoryManager = new DrmMemoryManager(gemCloseWorkerMode::gemCloseWorkerActive, DebugManager.flags.EnableForcePin.get(), true, executionEnvironment); executionEnvironment.memoryManager.reset(memoryManager); - ::testing::Mock::VerifyAndClearExpectations(mock); + // Memory manager creates pinBB with ioctl, expect one call + EXPECT_EQ(1u, mock->ioctlCallsCount); //assert we have memory manager ASSERT_NE(nullptr, memoryManager); + mock->ioctlCount.reset(); + mock->ioctlTearDownExpected.reset(); } template @@ -69,15 +71,19 @@ class DrmCommandStreamTest : public ::testing::Test { memoryManager->waitForDeletions(); memoryManager->peekGemCloseWorker()->close(true); delete csr; - ::testing::Mock::VerifyAndClearExpectations(mock); - // Memory manager closes pinBB with ioctl, expect one call - EXPECT_CALL(*mock, ioctl(::testing::_, ::testing::_)) - .Times(::testing::AtLeast(1)); + if (mock->ioctlTearDownExpects) { + EXPECT_EQ(mock->ioctlCount.gemWait, mock->ioctlTearDownExpected.gemWait); + EXPECT_EQ(mock->ioctlCount.gemClose, mock->ioctlTearDownExpected.gemClose); + } + // Expect 1 call with DRM_IOCTL_I915_GEM_CONTEXT_DESTROY request on destroyDrmContext + // Expect 1 call with DRM_IOCTL_GEM_CLOSE request on BufferObject close + mock->expectedIoctlCallsOnDestruction = mock->ioctlCallsCount + 2; + mock->expectIoctlCallsOnDestruction = true; } CommandStreamReceiver *csr = nullptr; DrmMemoryManager *memoryManager = nullptr; - ::testing::NiceMock *mock; + DrmMock *mock = nullptr; const int mockFd = 33; static const uint64_t alignment = MemoryConstants::allocationAlignment; DebugManagerStateRestore dbgState; diff --git a/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests_1.cpp b/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests_1.cpp index 5c237c7937..fb25a8b153 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests_1.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests_1.cpp @@ -46,133 +46,76 @@ using namespace NEO; -ACTION_P(copyIoctlParam, dstValue) { - *dstValue = *static_cast(arg1); - return 0; -}; - HWTEST_TEMPLATED_F(DrmCommandStreamTest, givenFlushStampWhenWaitCalledThenWaitForSpecifiedBoHandle) { FlushStamp handleToWait = 123; drm_i915_gem_wait expectedWait = {}; - drm_i915_gem_wait calledWait = {}; expectedWait.bo_handle = static_cast(handleToWait); expectedWait.timeout_ns = -1; - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(1) - .WillRepeatedly(copyIoctlParam(&calledWait)); - csr->waitForFlushStamp(handleToWait); - EXPECT_TRUE(memcmp(&expectedWait, &calledWait, sizeof(drm_i915_gem_wait)) == 0); + EXPECT_TRUE(memcmp(&expectedWait, &mock->receivedGemWait, sizeof(drm_i915_gem_wait)) == 0); + EXPECT_EQ(1, mock->ioctlCount.gemWait); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, WhenMakingResidentThenSucceeds) { - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .Times(0); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_EXECBUFFER2, ::testing::_)) - .Times(0); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, ::testing::_)) - .Times(0); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(0); DrmAllocation graphicsAllocation(0, AllocationType::UNKNOWN, nullptr, nullptr, 1024, static_cast(1u), MemoryPool::MemoryNull); csr->makeResident(graphicsAllocation); + + EXPECT_EQ(0, mock->ioctlCount.gemUserptr); + EXPECT_EQ(0, mock->ioctlCount.execbuffer2); + + mock->ioctlTearDownExpected.gemWait = 0; + mock->ioctlTearDownExpected.gemClose = 0; + mock->ioctlTearDownExpects = true; } HWTEST_TEMPLATED_F(DrmCommandStreamTest, WhenMakingResidentTwiceThenSucceeds) { - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .Times(0); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_EXECBUFFER2, ::testing::_)) - .Times(0); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, ::testing::_)) - .Times(0); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(0); - DrmAllocation graphicsAllocation(0, AllocationType::UNKNOWN, nullptr, nullptr, 1024, static_cast(1u), MemoryPool::MemoryNull); csr->makeResident(graphicsAllocation); csr->makeResident(graphicsAllocation); + + EXPECT_EQ(0, mock->ioctlCount.gemUserptr); + EXPECT_EQ(0, mock->ioctlCount.execbuffer2); + + mock->ioctlTearDownExpected.gemWait = 0; + mock->ioctlTearDownExpected.gemClose = 0; + mock->ioctlTearDownExpects = true; } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenSizeZeroWhenMakingResidentTwiceThenSucceeds) { - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .Times(0); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_EXECBUFFER2, ::testing::_)) - .Times(0); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, ::testing::_)) - .Times(0); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(0); - DrmAllocation graphicsAllocation(0, AllocationType::UNKNOWN, nullptr, nullptr, 0, static_cast(1u), MemoryPool::MemoryNull); csr->makeResident(graphicsAllocation); + + EXPECT_EQ(0, mock->ioctlCount.gemUserptr); + EXPECT_EQ(0, mock->ioctlCount.execbuffer2); + + mock->ioctlTearDownExpected.gemWait = 0; + mock->ioctlTearDownExpected.gemClose = 0; + mock->ioctlTearDownExpects = true; } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenResizedWhenMakingResidentTwiceThenSucceeds) { - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .Times(0); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_EXECBUFFER2, ::testing::_)) - .Times(0); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, ::testing::_)) - .Times(0); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(0); - DrmAllocation graphicsAllocation(0, AllocationType::UNKNOWN, nullptr, nullptr, 1024, static_cast(1u), MemoryPool::MemoryNull); DrmAllocation graphicsAllocation2(0, AllocationType::UNKNOWN, nullptr, nullptr, 8192, static_cast(1u), MemoryPool::MemoryNull); csr->makeResident(graphicsAllocation); csr->makeResident(graphicsAllocation2); -} -// matcher to check batch buffer offset and len on execbuffer2 call -MATCHER_P2(BoExecFlushEq, batch_start_offset, batch_len, "") { - drm_i915_gem_execbuffer2 *exec2 = (drm_i915_gem_execbuffer2 *)arg; + EXPECT_EQ(0, mock->ioctlCount.gemUserptr); + EXPECT_EQ(0, mock->ioctlCount.execbuffer2); - return (exec2->batch_start_offset == batch_start_offset) && (exec2->batch_len == batch_len); -} - -// matcher to check DrmContextId -MATCHER_P2(BoExecFlushContextEq, drmContextId, numExecs, "") { - auto execBuff2 = reinterpret_cast(arg); - - bool allExecsWithTheSameId = (execBuff2->buffer_count == numExecs); - allExecsWithTheSameId &= (execBuff2->rsvd1 == drmContextId); - - auto execObjects = reinterpret_cast(execBuff2->buffers_ptr); - for (uint32_t i = 0; i < execBuff2->buffer_count - 1; i++) { - allExecsWithTheSameId &= (execObjects[i].rsvd1 == drmContextId); - } - - return allExecsWithTheSameId; + mock->ioctlTearDownExpected.gemWait = 0; + mock->ioctlTearDownExpected.gemClose = 0; + mock->ioctlTearDownExpects = true; } HWTEST_TEMPLATED_F(DrmCommandStreamTest, WhenFlushingThenAvailableSpaceDoesNotChange) { auto expectedSize = alignUp(8u, MemoryConstants::cacheLineSize); // bbEnd int boHandle = 123; - auto setBoHandle = [&](unsigned long request, void *arg) { - auto userptr = static_cast(arg); - userptr->handle = boHandle; - return 0; - }; - ::testing::InSequence inSequence; - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .Times(1) - .WillRepeatedly(::testing::Invoke(setBoHandle)) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_EXECBUFFER2, BoExecFlushEq(0u, expectedSize))) - .Times(1) - .WillRepeatedly(::testing::Return(0)) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(2) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, ::testing::_)) - .Times(1) - .RetiresOnSaturation(); + mock->returnHandle = boHandle; auto &cs = csr->getCS(); auto commandBuffer = static_cast(cs.getGraphicsAllocation()); @@ -188,6 +131,16 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, WhenFlushingThenAvailableSpaceDoesNotCh EXPECT_EQ(static_cast(boHandle), csr->obtainCurrentFlushStamp()); EXPECT_NE(cs.getCpuBase(), nullptr); EXPECT_EQ(availableSpacePriorToFlush, cs.getAvailableSpace()); + + mock->ioctlTearDownExpected.gemWait = 2; + mock->ioctlTearDownExpected.gemClose = 1; + mock->ioctlTearDownExpects = true; + + EXPECT_EQ(1, mock->ioctlCount.gemUserptr); + EXPECT_EQ(1, mock->ioctlCount.execbuffer2); + + EXPECT_EQ(0u, mock->execBuffers.back().batch_start_offset); + EXPECT_EQ(expectedSize, mock->execBuffers.back().batch_len); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, givenPrintIndicesEnabledWhenFlushThenPrintIndices) { @@ -215,28 +168,12 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, givenDrmContextIdWhenFlushingThenSetIdT uint32_t expectedDrmContextId = 321; uint32_t numAllocations = 3; - auto createdContextId = [&expectedDrmContextId](unsigned long request, void *arg) { - auto contextCreate = static_cast(arg); - contextCreate->ctx_id = expectedDrmContextId; - return 0; - }; - auto allocation1 = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), MemoryConstants::pageSize}); auto allocation2 = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), MemoryConstants::pageSize}); csr->makeResident(*allocation1); csr->makeResident(*allocation2); - EXPECT_CALL(*mock, ioctl(::testing::_, ::testing::_)).WillRepeatedly(::testing::Return(0)).RetiresOnSaturation(); - - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT, ::testing::_)) - .Times(1) - .WillRepeatedly(::testing::Invoke(createdContextId)) - .RetiresOnSaturation(); - - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_EXECBUFFER2, BoExecFlushContextEq(expectedDrmContextId, numAllocations))) - .Times(1) - .WillRepeatedly(::testing::Return(0)) - .RetiresOnSaturation(); + mock->storedDrmContextId = expectedDrmContextId; osContext = std::make_unique(*mock, 1, EngineDescriptorHelper::getDefaultDescriptor(HwHelper::get(defaultHwInfo->platform.eRenderCoreFamily).getGpgpuEngineInstances(*defaultHwInfo)[0], @@ -253,28 +190,21 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, givenDrmContextIdWhenFlushingThenSetIdT memoryManager->freeGraphicsMemory(allocation1); memoryManager->freeGraphicsMemory(allocation2); + + EXPECT_EQ(1, mock->ioctlCount.contextCreate); + EXPECT_EQ(1, mock->ioctlCount.execbuffer2); + + EXPECT_EQ(numAllocations, mock->execBuffers.back().buffer_count); + EXPECT_EQ(expectedDrmContextId, mock->execBuffers.back().rsvd1); + + for (uint32_t i = 0; i < mock->receivedBos.size(); i++) { + EXPECT_EQ(expectedDrmContextId, mock->receivedBos[i].rsvd1); + } } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenLowPriorityContextWhenFlushingThenSucceeds) { auto expectedSize = alignUp(8u, MemoryConstants::cacheLineSize); // bbEnd - ::testing::InSequence inSequence; - - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .Times(1) - .WillRepeatedly(::testing::Return(0)) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_EXECBUFFER2, BoExecFlushEq(0u, expectedSize))) - .Times(1) - .WillRepeatedly(::testing::Return(0)) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(2) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, ::testing::_)) - .Times(1) - .RetiresOnSaturation(); - auto &cs = csr->getCS(); auto commandBuffer = static_cast(cs.getGraphicsAllocation()); @@ -286,24 +216,19 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenLowPriorityContextWhenFlushingThen BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 0, 0, nullptr, false, true, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false}; csr->flush(batchBuffer, csr->getResidencyAllocations()); EXPECT_NE(cs.getCpuBase(), nullptr); + + EXPECT_EQ(1, mock->ioctlCount.gemUserptr); + EXPECT_EQ(1, mock->ioctlCount.execbuffer2); + + mock->ioctlTearDownExpected.gemWait = 2; + mock->ioctlTearDownExpected.gemClose = 1; + mock->ioctlTearDownExpects = true; + + EXPECT_EQ(0u, mock->execBuffers.back().batch_start_offset); + EXPECT_EQ(expectedSize, mock->execBuffers.back().batch_len); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenInvalidAddressWhenFlushingThenSucceeds) { - ::testing::InSequence inSequence; - - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .Times(0) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_EXECBUFFER2, BoExecFlushEq(0u, 8u))) - .Times(0) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(0) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, ::testing::_)) - .Times(0) - .RetiresOnSaturation(); - //allocate command buffer manually char *commandBuffer = new (std::nothrow) char[1024]; ASSERT_NE(nullptr, commandBuffer); @@ -315,29 +240,19 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenInvalidAddressWhenFlushingThenSucc BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 0, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false}; csr->flush(batchBuffer, csr->getResidencyAllocations()); delete[] commandBuffer; + + EXPECT_EQ(0, mock->ioctlCount.gemUserptr); + EXPECT_EQ(0, mock->ioctlCount.execbuffer2); + + mock->ioctlTearDownExpected.gemWait = 0; + mock->ioctlTearDownExpected.gemClose = 0; + mock->ioctlTearDownExpects = true; } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenNotEmptyBbWhenFlushingThenSucceeds) { uint32_t bbUsed = 16 * sizeof(uint32_t); auto expectedSize = alignUp(bbUsed + 8, MemoryConstants::cacheLineSize); // bbUsed + bbEnd - ::testing::InSequence inSequence; - - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .Times(1) - .WillRepeatedly(::testing::Return(0)) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_EXECBUFFER2, BoExecFlushEq(0u, expectedSize))) - .Times(1) - .WillRepeatedly(::testing::Return(0)) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(2) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, ::testing::_)) - .Times(1) - .RetiresOnSaturation(); - auto &cs = csr->getCS(); cs.getSpace(bbUsed); @@ -345,28 +260,21 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenNotEmptyBbWhenFlushingThenSucceeds EncodeNoop::alignToCacheLine(cs); BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 0, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false}; csr->flush(batchBuffer, csr->getResidencyAllocations()); + + EXPECT_EQ(1, mock->ioctlCount.gemUserptr); + EXPECT_EQ(1, mock->ioctlCount.execbuffer2); + + mock->ioctlTearDownExpected.gemWait = 2; + mock->ioctlTearDownExpected.gemClose = 1; + mock->ioctlTearDownExpects = true; + + EXPECT_EQ(0u, mock->execBuffers.back().batch_start_offset); + EXPECT_EQ(expectedSize, mock->execBuffers.back().batch_len); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenNotEmptyNotPaddedBbWhenFlushingThenSucceeds) { uint32_t bbUsed = 15 * sizeof(uint32_t); - ::testing::InSequence inSequence; - - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .Times(1) - .WillRepeatedly(::testing::Return(0)) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_EXECBUFFER2, BoExecFlushEq(0u, bbUsed + 4))) - .Times(1) - .WillRepeatedly(::testing::Return(0)) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(2) - .RetiresOnSaturation(); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, ::testing::_)) - .Times(1) - .RetiresOnSaturation(); - auto &cs = csr->getCS(); cs.getSpace(bbUsed); @@ -374,13 +282,19 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenNotEmptyNotPaddedBbWhenFlushingThe EncodeNoop::alignToCacheLine(cs); BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 0, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false}; csr->flush(batchBuffer, csr->getResidencyAllocations()); + + EXPECT_EQ(1, mock->ioctlCount.gemUserptr); + EXPECT_EQ(1, mock->ioctlCount.execbuffer2); + + mock->ioctlTearDownExpected.gemWait = 2; + mock->ioctlTearDownExpected.gemClose = 1; + mock->ioctlTearDownExpects = true; + + EXPECT_EQ(0u, mock->execBuffers.back().batch_start_offset); + EXPECT_EQ(bbUsed + 4, mock->execBuffers.back().batch_len); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenNotAlignedWhenFlushingThenSucceeds) { - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .Times(1) - .WillRepeatedly(::testing::Return(0)); - auto &cs = csr->getCS(); auto commandBuffer = static_cast(cs.getGraphicsAllocation()); @@ -388,63 +302,28 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenNotAlignedWhenFlushingThenSucceeds ASSERT_NE(0u, (reinterpret_cast(commandBuffer->getUnderlyingBuffer()) + 4) & (this->alignment - 1)); ASSERT_EQ(4u, (reinterpret_cast(commandBuffer->getUnderlyingBuffer()) + 4) & 0x7F); + auto expectedBatchStartOffset = (reinterpret_cast(commandBuffer->getUnderlyingBuffer()) + 4) & (this->alignment - 1); auto expectedSize = alignUp(8u, MemoryConstants::cacheLineSize); // bbEnd - EXPECT_CALL(*mock, ioctl( - DRM_IOCTL_I915_GEM_EXECBUFFER2, - BoExecFlushEq((reinterpret_cast(commandBuffer->getUnderlyingBuffer()) + 4) & (this->alignment - 1), expectedSize))) - .Times(1) - .WillRepeatedly(::testing::Return(0)); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, ::testing::_)) - .Times(1); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(2); - CommandStreamReceiverHw::addBatchBufferEnd(cs, nullptr); EncodeNoop::alignToCacheLine(cs); - BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 4, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false}; csr->flush(batchBuffer, csr->getResidencyAllocations()); -} -ACTION_P(UserptrSetHandle, _set_handle) { - struct drm_i915_gem_userptr *userptr = reinterpret_cast(arg1); - userptr->handle = _set_handle; -} + EXPECT_EQ(1, mock->ioctlCount.gemUserptr); + EXPECT_EQ(1, mock->ioctlCount.execbuffer2); -MATCHER_P(GemCloseEq, handle, "") { - drm_gem_close *gemClose = (drm_gem_close *)arg; + mock->ioctlTearDownExpected.gemWait = 2; + mock->ioctlTearDownExpected.gemClose = 1; + mock->ioctlTearDownExpects = true; - return (gemClose->handle == handle); -} - -MATCHER(BoExecFlushCheckFlags, "") { - drm_i915_gem_execbuffer2 *exec2 = (drm_i915_gem_execbuffer2 *)arg; - drm_i915_gem_exec_object2 *exec_objects = (drm_i915_gem_exec_object2 *)exec2->buffers_ptr; - - for (unsigned int i = 0; i < exec2->buffer_count; i++) { - EXPECT_TRUE(exec_objects[i].flags == (EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS)); - } - - return true; + EXPECT_EQ(expectedBatchStartOffset, mock->execBuffers.back().batch_start_offset); + EXPECT_EQ(expectedSize, mock->execBuffers.back().batch_len); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenCheckFlagsWhenFlushingThenSucceeds) { - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .WillRepeatedly(::testing::Return(0)); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, ::testing::_)) - .WillRepeatedly(::testing::Return(0)); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .WillRepeatedly(::testing::Return(0)); - auto &cs = csr->getCS(); - EXPECT_CALL(*mock, ioctl( - DRM_IOCTL_I915_GEM_EXECBUFFER2, - BoExecFlushCheckFlags())) - .Times(1) - .WillRepeatedly(::testing::Return(0)); - DrmAllocation allocation(0, AllocationType::UNKNOWN, nullptr, (void *)0x7FFFFFFF, 1024, static_cast(0u), MemoryPool::MemoryNull); DrmAllocation allocation2(0, AllocationType::UNKNOWN, nullptr, (void *)0x307FFFFFFF, 1024, static_cast(0u), MemoryPool::MemoryNull); csr->makeResident(allocation); @@ -453,12 +332,12 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenCheckFlagsWhenFlushingThenSucceeds EncodeNoop::alignToCacheLine(cs); BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 0, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false}; csr->flush(batchBuffer, csr->getResidencyAllocations()); + + EXPECT_EQ(1, mock->ioctlCount.execbuffer2); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenCheckDrmFreeWhenFlushingThenSucceeds) { - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .Times(1) - .WillOnce(::testing::DoAll(UserptrSetHandle(17), ::testing::Return(0))); + mock->returnHandle = 17; auto &cs = csr->getCS(); auto commandBuffer = static_cast(cs.getGraphicsAllocation()); @@ -467,18 +346,9 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenCheckDrmFreeWhenFlushingThenSuccee ASSERT_NE(0u, (reinterpret_cast(commandBuffer->getUnderlyingBuffer()) + 4) & (this->alignment - 1)); ASSERT_EQ(4u, (reinterpret_cast(commandBuffer->getUnderlyingBuffer()) + 4) & 0x7F); + auto expectedBatchStartOffset = (reinterpret_cast(commandBuffer->getUnderlyingBuffer()) + 4) & (this->alignment - 1); auto expectedSize = alignUp(8u, MemoryConstants::cacheLineSize); // bbEnd - EXPECT_CALL(*mock, ioctl( - DRM_IOCTL_I915_GEM_EXECBUFFER2, - BoExecFlushEq((reinterpret_cast(commandBuffer->getUnderlyingBuffer()) + 4) & (this->alignment - 1), expectedSize))) - .Times(1) - .WillRepeatedly(::testing::Return(0)); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, GemCloseEq(17u))) - .Times(1); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(2); - DrmAllocation allocation(0, AllocationType::UNKNOWN, nullptr, nullptr, 1024, static_cast(0u), MemoryPool::MemoryNull); csr->makeResident(allocation); @@ -486,6 +356,16 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenCheckDrmFreeWhenFlushingThenSuccee EncodeNoop::alignToCacheLine(cs); BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 4, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false}; csr->flush(batchBuffer, csr->getResidencyAllocations()); + + EXPECT_EQ(1, mock->ioctlCount.gemUserptr); + EXPECT_EQ(1, mock->ioctlCount.execbuffer2); + + mock->ioctlTearDownExpected.gemClose = 1; + mock->ioctlTearDownExpected.gemWait = 2; + mock->ioctlTearDownExpects = true; + + EXPECT_EQ(expectedBatchStartOffset, mock->execBuffers.back().batch_start_offset); + EXPECT_EQ(expectedSize, mock->execBuffers.back().batch_len); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, WhenGettingDrmThenNonNullPointerIsReturned) { @@ -497,9 +377,7 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, WhenGettingDrmThenNonNullPointerIsRetur } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenCheckDrmFreeCloseFailedWhenFlushingThenSucceeds) { - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_USERPTR, ::testing::_)) - .Times(1) - .WillOnce(::testing::DoAll(UserptrSetHandle(17), ::testing::Return(0))); + mock->returnHandle = 17; auto &cs = csr->getCS(); auto commandBuffer = static_cast(cs.getGraphicsAllocation()); @@ -508,18 +386,11 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenCheckDrmFreeCloseFailedWhenFlushin ASSERT_NE(0u, (reinterpret_cast(commandBuffer->getUnderlyingBuffer()) + 4) & (this->alignment - 1)); ASSERT_EQ(4u, (reinterpret_cast(commandBuffer->getUnderlyingBuffer()) + 4) & 0x7F); + auto expectedBatchStartOffset = (reinterpret_cast(commandBuffer->getUnderlyingBuffer()) + 4) & (this->alignment - 1); auto expectedSize = alignUp(8u, MemoryConstants::cacheLineSize); // bbEnd - EXPECT_CALL(*mock, ioctl( - DRM_IOCTL_I915_GEM_EXECBUFFER2, - BoExecFlushEq((reinterpret_cast(commandBuffer->getUnderlyingBuffer()) + 4) & (this->alignment - 1), expectedSize))) - .Times(1) - .WillRepeatedly(::testing::Return(0)); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_GEM_CLOSE, GemCloseEq(17u))) - .Times(1) - .WillOnce(::testing::Return(-1)); - EXPECT_CALL(*mock, ioctl(DRM_IOCTL_I915_GEM_WAIT, ::testing::_)) - .Times(2); + mock->storedRetValForGemClose = -1; + DrmAllocation allocation(0, AllocationType::UNKNOWN, nullptr, nullptr, 1024, static_cast(0u), MemoryPool::MemoryNull); csr->makeResident(allocation); @@ -527,6 +398,16 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenCheckDrmFreeCloseFailedWhenFlushin EncodeNoop::alignToCacheLine(cs); BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 4, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false}; csr->flush(batchBuffer, csr->getResidencyAllocations()); + + EXPECT_EQ(1, mock->ioctlCount.gemUserptr); + EXPECT_EQ(1, mock->ioctlCount.execbuffer2); + + mock->ioctlTearDownExpected.gemClose = 1; + mock->ioctlTearDownExpected.gemWait = 2; + mock->ioctlTearDownExpects = true; + + EXPECT_EQ(expectedBatchStartOffset, mock->execBuffers.back().batch_start_offset); + EXPECT_EQ(expectedSize, mock->execBuffers.back().batch_len); } class DrmCommandStreamBatchingTests : public DrmCommandStreamEnhancedTest { diff --git a/opencl/test/unit_test/os_interface/linux/drm_residency_handler_prelim_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_residency_handler_prelim_tests.cpp index 9feccd72ee..cb358bc24a 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_residency_handler_prelim_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_residency_handler_prelim_tests.cpp @@ -528,10 +528,8 @@ HWTEST_F(DrmMemoryOperationsHandlerBindTest, givenVmBindSupportAndMultiSubdevice pinBB.pin(&boToPinPtr, 1u, device->getDefaultEngine().osContext, 0u, 0u); - EXPECT_EQ(mock->execBuffer.buffers_ptr, 0u); - EXPECT_EQ(mock->execBuffer.buffer_count, 0u); - EXPECT_EQ(mock->execBuffer.rsvd1, 0u); EXPECT_EQ(mock->context.vmBindCalled, 2u); + EXPECT_EQ(0, mock->ioctlCount.execbuffer2); } HWTEST_F(DrmMemoryOperationsHandlerBindTest, givenVmBindSupportAndMultiSubdeviceWhenValidateHostptrThenOnlyBindToSingleVMIsCalled) { @@ -544,9 +542,8 @@ HWTEST_F(DrmMemoryOperationsHandlerBindTest, givenVmBindSupportAndMultiSubdevice pinBB.validateHostPtr(&boToPinPtr, 1u, device->getDefaultEngine().osContext, 0u, 0u); - EXPECT_EQ(mock->execBuffer.buffers_ptr, 0u); - EXPECT_EQ(mock->execBuffer.buffer_count, 0u); EXPECT_EQ(mock->context.vmBindCalled, 1u); + EXPECT_EQ(0, mock->ioctlCount.execbuffer2); } HWTEST_F(DrmMemoryOperationsHandlerBindTest, givenVmBindSupportAndMultiSubdeviceWhenValidateHostptrThenBindToGivenVm) { @@ -560,9 +557,8 @@ HWTEST_F(DrmMemoryOperationsHandlerBindTest, givenVmBindSupportAndMultiSubdevice pinBB.validateHostPtr(&boToPinPtr, 1u, device->getDefaultEngine().osContext, vmHandleId, 0u); - EXPECT_EQ(mock->execBuffer.buffers_ptr, 0u); - EXPECT_EQ(mock->execBuffer.buffer_count, 0u); EXPECT_EQ(mock->context.vmBindCalled, 1u); + EXPECT_EQ(0, mock->ioctlCount.execbuffer2); EXPECT_EQ(mock->context.receivedVmBind->vmId, mock->getVirtualMemoryAddressSpace(vmHandleId)); } @@ -579,9 +575,9 @@ HWTEST_F(DrmMemoryOperationsHandlerBindTest, givenVmBindSupportAndMultiSubdevice auto ret = pinBB.validateHostPtr(boToPinPtr, 2u, device->getDefaultEngine().osContext, 0u, 0u); EXPECT_EQ(ret, -1); - EXPECT_EQ(mock->execBuffer.buffers_ptr, 0u); - EXPECT_EQ(mock->execBuffer.buffer_count, 0u); + EXPECT_EQ(mock->context.receivedVmBind->handle, 2u); + EXPECT_EQ(0, mock->ioctlCount.execbuffer2); } HWTEST_F(DrmMemoryOperationsHandlerBindTest, givenDirectSubmissionWhenPinBOThenVmBindIsCalledInsteadOfExec) { @@ -595,10 +591,8 @@ HWTEST_F(DrmMemoryOperationsHandlerBindTest, givenDirectSubmissionWhenPinBOThenV pinBB.pin(&boToPinPtr, 1u, device->getDefaultEngine().osContext, 0u, 0u); - EXPECT_EQ(mock->execBuffer.buffers_ptr, 0u); - EXPECT_EQ(mock->execBuffer.buffer_count, 0u); - EXPECT_EQ(mock->execBuffer.rsvd1, 0u); EXPECT_TRUE(mock->context.vmBindCalled); + EXPECT_EQ(0, mock->ioctlCount.execbuffer2); } HWTEST_F(DrmMemoryOperationsHandlerBindTest, givenDirectSubmissionAndValidateHostptrWhenPinBOThenVmBindIsCalledInsteadOfExec) { @@ -612,10 +606,8 @@ HWTEST_F(DrmMemoryOperationsHandlerBindTest, givenDirectSubmissionAndValidateHos pinBB.validateHostPtr(&boToPinPtr, 1u, device->getDefaultEngine().osContext, 0u, 0u); - EXPECT_EQ(mock->execBuffer.buffers_ptr, 0u); - EXPECT_EQ(mock->execBuffer.buffer_count, 0u); - EXPECT_EQ(mock->execBuffer.rsvd1, 0u); EXPECT_TRUE(mock->context.vmBindCalled); + EXPECT_EQ(0, mock->ioctlCount.execbuffer2); } HWTEST_F(DrmMemoryOperationsHandlerBindTest, givenVmBindSupportWhenPinBOThenAllocIsBound) { diff --git a/opencl/test/unit_test/os_interface/linux/drm_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_tests.cpp index c9905df302..1601cf00d2 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_tests.cpp @@ -199,14 +199,14 @@ TEST(DrmTest, givenDrmWhenOsContextIsCreatedThenCreateAndDestroyNewDrmOsContext) osContext1.ensureContextInitialized(); EXPECT_EQ(1u, osContext1.getDrmContextIds().size()); - EXPECT_EQ(drmMock.receivedCreateContextId, osContext1.getDrmContextIds()[0]); + EXPECT_EQ(drmMock.storedDrmContextId, osContext1.getDrmContextIds()[0]); EXPECT_EQ(0u, drmMock.receivedDestroyContextId); { OsContextLinux osContext2(drmMock, 0u, EngineDescriptorHelper::getDefaultDescriptor()); osContext2.ensureContextInitialized(); EXPECT_EQ(1u, osContext2.getDrmContextIds().size()); - EXPECT_EQ(drmMock.receivedCreateContextId, osContext2.getDrmContextIds()[0]); + EXPECT_EQ(drmMock.storedDrmContextId, osContext2.getDrmContextIds()[0]); EXPECT_EQ(0u, drmMock.receivedDestroyContextId); } } @@ -240,7 +240,6 @@ TEST(DrmTest, whenCreatingDrmContextWithNoVirtualMemoryAddressSpaceThenProperCon OsContextLinux osContext(drmMock, 0u, EngineDescriptorHelper::getDefaultDescriptor()); osContext.ensureContextInitialized(); - EXPECT_EQ(0u, drmMock.receivedCreateContextId); EXPECT_EQ(0u, drmMock.receivedContextParamRequestCount); } @@ -293,7 +292,7 @@ TEST(DrmTest, givenDrmPreemptionEnabledAndLowPriorityEngineWhenCreatingOsContext OsContextLinux osContext4(drmMock, 0u, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::LowPriority})); osContext4.ensureContextInitialized(); EXPECT_EQ(5u, drmMock.receivedContextParamRequestCount); - EXPECT_EQ(drmMock.receivedCreateContextId, drmMock.receivedContextParamRequest.ctx_id); + EXPECT_EQ(drmMock.storedDrmContextId, drmMock.receivedContextParamRequest.ctx_id); EXPECT_EQ(static_cast(I915_CONTEXT_PARAM_PRIORITY), drmMock.receivedContextParamRequest.param); EXPECT_EQ(static_cast(-1023), drmMock.receivedContextParamRequest.value); EXPECT_EQ(0u, drmMock.receivedContextParamRequest.size); @@ -503,11 +502,9 @@ TEST(DrmTest, givenDrmWithPerContextVMRequiredWhenCreatingOsContextsThenImplicit OsContextLinux osContext1(drmMock, 0u, EngineDescriptorHelper::getDefaultDescriptor()); osContext1.ensureContextInitialized(); - EXPECT_EQ(0u, drmMock.receivedCreateContextId); OsContextLinux osContext2(drmMock, 5u, EngineDescriptorHelper::getDefaultDescriptor()); osContext2.ensureContextInitialized(); - EXPECT_EQ(0u, drmMock.receivedCreateContextId); } TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextsThenImplicitVmIdPerContextIsQueriedAndStored) { @@ -521,7 +518,6 @@ TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextsThenImplicitVmIdPer OsContextLinux osContext(drmMock, 0u, EngineDescriptorHelper::getDefaultDescriptor()); osContext.ensureContextInitialized(); - EXPECT_EQ(0u, drmMock.receivedCreateContextId); EXPECT_EQ(2u, drmMock.receivedContextParamRequestCount); auto &drmVmIds = osContext.getDrmVmIds(); @@ -542,7 +538,6 @@ TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextForSubDeviceThenImpl OsContextLinux osContext(drmMock, 0u, EngineDescriptorHelper::getDefaultDescriptor(deviceBitfield)); osContext.ensureContextInitialized(); - EXPECT_EQ(0u, drmMock.receivedCreateContextId); EXPECT_EQ(2u, drmMock.receivedContextParamRequestCount); auto &drmVmIds = osContext.getDrmVmIds(); @@ -566,7 +561,6 @@ TEST(DrmTest, givenPerContextVMRequiredWhenCreatingOsContextsForRootDeviceThenIm OsContextLinux osContext(drmMock, 0u, EngineDescriptorHelper::getDefaultDescriptor(deviceBitfield)); osContext.ensureContextInitialized(); - EXPECT_EQ(0u, drmMock.receivedCreateContextId); EXPECT_EQ(2 * 2u, drmMock.receivedContextParamRequestCount); auto &drmVmIds = osContext.getDrmVmIds(); @@ -590,7 +584,6 @@ TEST(DrmTest, givenNoPerContextVmsDrmWhenCreatingOsContextsThenVmIdIsNotQueriedA OsContextLinux osContext(drmMock, 0u, EngineDescriptorHelper::getDefaultDescriptor()); osContext.ensureContextInitialized(); - EXPECT_EQ(0u, drmMock.receivedCreateContextId); EXPECT_EQ(1u, drmMock.receivedContextParamRequestCount); auto &drmVmIds = osContext.getDrmVmIds(); diff --git a/shared/test/common/libult/linux/drm_mock.cpp b/shared/test/common/libult/linux/drm_mock.cpp index ab648ab39b..0582327537 100644 --- a/shared/test/common/libult/linux/drm_mock.cpp +++ b/shared/test/common/libult/linux/drm_mock.cpp @@ -20,8 +20,10 @@ const uint32_t DrmMockResources::registerResourceReturnHandle = 3; int DrmMock::ioctl(unsigned long request, void *arg) { ioctlCallsCount++; + ioctlCount.total++; if ((request == DRM_IOCTL_I915_GETPARAM) && (arg != nullptr)) { + ioctlCount.contextGetParam++; auto gp = static_cast(arg); if (gp->param == I915_PARAM_EU_TOTAL) { if (0 == this->storedRetValForEUVal) { @@ -74,8 +76,10 @@ int DrmMock::ioctl(unsigned long request, void *arg) { } if ((request == DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT) && (arg != nullptr)) { + ioctlCount.contextCreate++; auto create = static_cast(arg); - this->receivedCreateContextId = create->ctx_id; + auto contextCreate = static_cast(arg); + contextCreate->ctx_id = this->storedDrmContextId; this->receivedContextCreateFlags = create->flags; if (create->extensions == 0) { return this->storedRetVal; @@ -91,12 +95,14 @@ int DrmMock::ioctl(unsigned long request, void *arg) { } if ((request == DRM_IOCTL_I915_GEM_CONTEXT_DESTROY) && (arg != nullptr)) { + ioctlCount.contextDestroy++; auto destroy = static_cast(arg); this->receivedDestroyContextId = destroy->ctx_id; return this->storedRetVal; } if ((request == DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM) && (arg != nullptr)) { + ioctlCount.contextSetParam++; receivedContextParamRequestCount++; receivedContextParamRequest = *static_cast(arg); if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_PRIORITY) { @@ -124,6 +130,7 @@ int DrmMock::ioctl(unsigned long request, void *arg) { } if ((request == DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM) && (arg != nullptr)) { + ioctlCount.contextGetParam++; receivedContextParamRequestCount++; receivedContextParamRequest = *static_cast(arg); if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_GTT_SIZE) { @@ -148,18 +155,24 @@ int DrmMock::ioctl(unsigned long request, void *arg) { } if (request == DRM_IOCTL_I915_GEM_EXECBUFFER2) { + ioctlCount.execbuffer2++; auto execbuf = static_cast(arg); - this->execBuffer = *execbuf; - this->bbFlags = reinterpret_cast(execbuf->buffers_ptr)[execbuf->buffer_count - 1].flags; + auto execObjects = reinterpret_cast(execbuf->buffers_ptr); + this->execBuffers.push_back(*execbuf); + for (uint32_t i = 0; i < execbuf->buffer_count; i++) { + this->receivedBos.push_back(execObjects[i]); + } return 0; } if (request == DRM_IOCTL_I915_GEM_USERPTR) { + ioctlCount.gemUserptr++; auto userPtrParams = static_cast(arg); userPtrParams->handle = returnHandle; returnHandle++; return 0; } if (request == DRM_IOCTL_I915_GEM_CREATE) { + ioctlCount.gemCreate++; auto createParams = static_cast(arg); this->createParamsSize = createParams->size; this->createParamsHandle = createParams->handle = 1u; @@ -169,6 +182,7 @@ int DrmMock::ioctl(unsigned long request, void *arg) { return 0; } if (request == DRM_IOCTL_I915_GEM_SET_TILING) { + ioctlCount.gemSetTiling++; auto setTilingParams = static_cast(arg); setTilingMode = setTilingParams->tiling_mode; setTilingHandle = setTilingParams->handle; @@ -176,6 +190,7 @@ int DrmMock::ioctl(unsigned long request, void *arg) { return 0; } if (request == DRM_IOCTL_PRIME_FD_TO_HANDLE) { + ioctlCount.primeFdToHandle++; auto primeToHandleParams = static_cast(arg); //return BO primeToHandleParams->handle = outputHandle; @@ -183,28 +198,35 @@ int DrmMock::ioctl(unsigned long request, void *arg) { return fdToHandleRetVal; } if (request == DRM_IOCTL_PRIME_HANDLE_TO_FD) { + ioctlCount.handleToPrimeFd++; auto primeToFdParams = static_cast(arg); primeToFdParams->fd = outputFd; return 0; } if (request == DRM_IOCTL_I915_GEM_GET_APERTURE) { + ioctlCount.gemGetAperture++; auto aperture = static_cast(arg); aperture->aper_available_size = gpuMemSize; aperture->aper_size = gpuMemSize; return 0; } if (request == DRM_IOCTL_I915_GEM_MMAP) { + ioctlCount.gemMmap++; auto mmap_arg = static_cast(arg); mmap_arg->addr_ptr = reinterpret_cast<__u64>(lockedPtr); return 0; } if (request == DRM_IOCTL_I915_GEM_WAIT) { + ioctlCount.gemWait++; + receivedGemWait = *static_cast(arg); return 0; } if (request == DRM_IOCTL_GEM_CLOSE) { - return 0; + ioctlCount.gemClose++; + return storedRetValForGemClose; } if (request == DRM_IOCTL_I915_GET_RESET_STATS && arg != nullptr) { + ioctlCount.gemResetStats++; auto outResetStats = static_cast(arg); for (const auto &resetStats : resetStatsToReturn) { if (resetStats.ctx_id == outResetStats->ctx_id) { @@ -217,6 +239,7 @@ int DrmMock::ioctl(unsigned long request, void *arg) { } if (request == DRM_IOCTL_I915_QUERY && arg != nullptr) { + ioctlCount.query++; auto queryArg = static_cast(arg); auto queryItemArg = reinterpret_cast(queryArg->items_ptr); storedQueryItem = *queryItemArg; @@ -252,7 +275,6 @@ int DrmMock::ioctl(unsigned long request, void *arg) { return handleRemainingRequests(request, arg); } - int DrmMock::waitUserFence(uint32_t ctxIdx, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout, uint16_t flags) { waitUserFenceParams.push_back({ctxIdx, address, value, dataWidth, timeout, flags}); return Drm::waitUserFence(ctxIdx, address, value, dataWidth, timeout, flags); diff --git a/shared/test/common/libult/linux/drm_mock.h b/shared/test/common/libult/linux/drm_mock.h index c957df293d..bf367b1681 100644 --- a/shared/test/common/libult/linux/drm_mock.h +++ b/shared/test/common/libult/linux/drm_mock.h @@ -12,6 +12,9 @@ #include "shared/source/helpers/string.h" #include "shared/source/os_interface/linux/drm_neo.h" #include "shared/test/common/helpers/default_hw_info.h" +#include "shared/test/common/os_interface/linux/device_command_stream_fixture.h" + +#include "gtest/gtest.h" #include #include @@ -63,6 +66,12 @@ class DrmMock : public Drm { } DrmMock(RootDeviceEnvironment &rootDeviceEnvironment) : DrmMock(mockFd, rootDeviceEnvironment) {} + ~DrmMock() { + if (expectIoctlCallsOnDestruction) { + EXPECT_EQ(expectedIoctlCallsOnDestruction, ioctlCallsCount); + } + } + int ioctl(unsigned long request, void *arg) override; int getErrno() override { if (baseErrno) { @@ -177,7 +186,6 @@ class DrmMock : public Drm { drm_i915_gem_context_create_ext_setparam receivedContextCreateSetParam = {}; uint32_t receivedContextCreateFlags = 0; - uint32_t receivedCreateContextId = 0; uint32_t receivedDestroyContextId = 0; uint32_t ioctlCallsCount = 0; @@ -188,9 +196,8 @@ class DrmMock : public Drm { bool queryPageFaultSupportCalled = false; //DRM_IOCTL_I915_GEM_EXECBUFFER2 - drm_i915_gem_execbuffer2 execBuffer = {0}; - uint64_t bbFlags; - + std::vector execBuffers{}; + std::vector receivedBos{}; //DRM_IOCTL_I915_GEM_CREATE __u64 createParamsSize = 0; __u32 createParamsHandle = 0; @@ -211,10 +218,23 @@ class DrmMock : public Drm { uint64_t lockedPtr[4]; //DRM_IOCTL_I915_QUERY drm_i915_query_item storedQueryItem = {}; + //DRM_IOCTL_I915_GEM_WAIT + drm_i915_gem_wait receivedGemWait = {}; + //DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT + uint32_t storedDrmContextId{}; + //DRM_IOCTL_GEM_CLOSE + int storedRetValForGemClose = 0; uint64_t storedGTTSize = 1ull << 47; uint64_t storedParamSseu = ULONG_MAX; + Ioctls ioctlCount{}; + Ioctls ioctlTearDownExpected{}; + bool ioctlTearDownExpects = false; + + bool expectIoctlCallsOnDestruction = false; + uint32_t expectedIoctlCallsOnDestruction = 0u; + virtual int handleRemainingRequests(unsigned long request, void *arg) { return -1; } struct WaitUserFenceParams { diff --git a/shared/test/common/os_interface/linux/device_command_stream_fixture.cpp b/shared/test/common/os_interface/linux/device_command_stream_fixture.cpp index 23cc80f3a6..c5b5f18e16 100644 --- a/shared/test/common/os_interface/linux/device_command_stream_fixture.cpp +++ b/shared/test/common/os_interface/linux/device_command_stream_fixture.cpp @@ -10,13 +10,15 @@ const int mockFd = 33; const char *mockPciPath = ""; -void DrmMockCustom::Ioctls::reset() { +void Ioctls::reset() { total = 0; + query = 0; execbuffer2 = 0; gemUserptr = 0; gemCreate = 0; gemSetTiling = 0; gemGetTiling = 0; + gemGetAperture = 0; primeFdToHandle = 0; handleToPrimeFd = 0; gemMmap = 0; @@ -24,9 +26,11 @@ void DrmMockCustom::Ioctls::reset() { gemSetDomain = 0; gemWait = 0; gemClose = 0; + gemResetStats = 0; regRead = 0; getParam = 0; contextGetParam = 0; + contextSetParam = 0; contextCreate = 0; contextDestroy = 0; } diff --git a/shared/test/common/os_interface/linux/device_command_stream_fixture.h b/shared/test/common/os_interface/linux/device_command_stream_fixture.h index 58e0a7dfbf..4c09581b01 100644 --- a/shared/test/common/os_interface/linux/device_command_stream_fixture.h +++ b/shared/test/common/os_interface/linux/device_command_stream_fixture.h @@ -28,12 +28,34 @@ using NEO::RootDeviceEnvironment; extern const int mockFd; extern const char *mockPciPath; -class DrmMockImpl : public Drm { +class Ioctls { public: - using Drm::setupIoctlHelper; - DrmMockImpl(int fd, RootDeviceEnvironment &rootDeviceEnvironment) : Drm(std::make_unique(fd, mockPciPath), rootDeviceEnvironment){}; - - MOCK_METHOD2(ioctl, int(unsigned long request, void *arg)); + Ioctls() { + reset(); + } + void reset(); + std::atomic total; + std::atomic query; + std::atomic execbuffer2; + std::atomic gemUserptr; + std::atomic gemCreate; + std::atomic gemSetTiling; + std::atomic gemGetTiling; + std::atomic gemGetAperture; + std::atomic primeFdToHandle; + std::atomic handleToPrimeFd; + std::atomic gemMmap; + std::atomic gemMmapOffset; + std::atomic gemSetDomain; + std::atomic gemWait; + std::atomic gemClose; + std::atomic gemResetStats; + std::atomic regRead; + std::atomic getParam; + std::atomic contextGetParam; + std::atomic contextSetParam; + std::atomic contextCreate; + std::atomic contextDestroy; }; class DrmMockSuccess : public Drm { @@ -81,30 +103,6 @@ class DrmMockCustom : public Drm { IoctlResExt(int32_t no, int32_t res) : no(1u, no), res(res) {} }; - class Ioctls { - public: - void reset(); - - std::atomic total; - std::atomic execbuffer2; - std::atomic gemUserptr; - std::atomic gemCreate; - std::atomic gemSetTiling; - std::atomic gemGetTiling; - std::atomic primeFdToHandle; - std::atomic handleToPrimeFd; - std::atomic gemMmap; - std::atomic gemMmapOffset; - std::atomic gemSetDomain; - std::atomic gemWait; - std::atomic gemClose; - std::atomic regRead; - std::atomic getParam; - std::atomic contextGetParam; - std::atomic contextCreate; - std::atomic contextDestroy; - }; - struct WaitUserFenceCall { uint64_t address = 0u; uint64_t value = 0u; @@ -154,8 +152,8 @@ class DrmMockCustom : public Drm { virtual void execBufferExtensions(void *execbuf) { } - Ioctls ioctl_cnt; - Ioctls ioctl_expected; + Ioctls ioctl_cnt{}; + Ioctls ioctl_expected{}; IoctlResExt NONE = {-1, 0}; diff --git a/shared/test/common/os_interface/linux/drm_memory_manager_tests.h b/shared/test/common/os_interface/linux/drm_memory_manager_tests.h index 14fb10266d..a7bab19c71 100644 --- a/shared/test/common/os_interface/linux/drm_memory_manager_tests.h +++ b/shared/test/common/os_interface/linux/drm_memory_manager_tests.h @@ -124,7 +124,7 @@ class DrmMemoryManagerFixture : public MemoryManagementFixture { RootDeviceEnvironment *rootDeviceEnvironment = nullptr; DrmMockCustom::IoctlResExt ioctlResExt = {0, 0}; AllocationData allocationData{}; - DrmMockCustom::Ioctls additionalDestroyDeviceIoctls{}; + Ioctls additionalDestroyDeviceIoctls{}; EnvironmentWithCsrWrapper environmentWrapper; DebugManagerStateRestore restore; }; diff --git a/shared/test/unit_test/os_interface/linux/drm_command_stream_l0_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_command_stream_l0_tests.cpp index 758bd62c2c..d0d66e1aff 100644 --- a/shared/test/unit_test/os_interface/linux/drm_command_stream_l0_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_command_stream_l0_tests.cpp @@ -14,6 +14,7 @@ #include "shared/test/common/helpers/default_hw_info.h" #include "shared/test/common/helpers/engine_descriptor_helper.h" #include "shared/test/common/helpers/variable_backup.h" +#include "shared/test/common/libult/linux/drm_mock.h" #include "shared/test/common/mocks/linux/mock_drm_command_stream_receiver.h" #include "shared/test/common/mocks/mock_execution_environment.h" #include "shared/test/common/os_interface/linux/device_command_stream_fixture.h" @@ -37,7 +38,7 @@ class DrmCommandStreamTestL0 : public ::testing::Test { DebugManager.flags.EnableForcePin.set(false); auto hwInfo = executionEnvironment.rootDeviceEnvironments[0]->getHardwareInfo(); - mock = new ::testing::NiceMock(mockFd, *executionEnvironment.rootDeviceEnvironments[0]); + mock = new DrmMock(mockFd, *executionEnvironment.rootDeviceEnvironments[0]); mock->setupIoctlHelper(hwInfo->platform.eProductFamily); executionEnvironment.rootDeviceEnvironments[0]->osInterface = std::make_unique(); @@ -54,15 +55,14 @@ class DrmCommandStreamTestL0 : public ::testing::Test { ASSERT_NE(nullptr, csr); csr->setupContext(*osContext); - // Memory manager creates pinBB with ioctl, expect one call - EXPECT_CALL(*mock, ioctl(::testing::_, ::testing::_)) - .Times(1); + mock->ioctlCallsCount = 0u; memoryManager = new DrmMemoryManager(gemCloseWorkerMode::gemCloseWorkerActive, DebugManager.flags.EnableForcePin.get(), true, executionEnvironment); executionEnvironment.memoryManager.reset(memoryManager); - ::testing::Mock::VerifyAndClearExpectations(mock); + // Memory manager creates pinBB with ioctl, expect one call + EXPECT_EQ(1u, mock->ioctlCallsCount); //assert we have memory manager ASSERT_NE(nullptr, memoryManager); @@ -73,15 +73,15 @@ class DrmCommandStreamTestL0 : public ::testing::Test { memoryManager->waitForDeletions(); memoryManager->peekGemCloseWorker()->close(true); delete csr; - ::testing::Mock::VerifyAndClearExpectations(mock); - // Memory manager closes pinBB with ioctl, expect one call - EXPECT_CALL(*mock, ioctl(::testing::_, ::testing::_)) - .Times(::testing::AtLeast(1)); + // Expect 1 call with DRM_IOCTL_I915_GEM_CONTEXT_DESTROY request on destroyDrmContext + // Expect 1 call with DRM_IOCTL_GEM_CLOSE request on BufferObject close + mock->expectedIoctlCallsOnDestruction = mock->ioctlCallsCount + 2; + mock->expectIoctlCallsOnDestruction = true; } CommandStreamReceiver *csr = nullptr; DrmMemoryManager *memoryManager = nullptr; - ::testing::NiceMock *mock; + DrmMock *mock = nullptr; const int mockFd = 33; static const uint64_t alignment = MemoryConstants::allocationAlignment; DebugManagerStateRestore dbgState;