mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-11 08:07:19 +08:00
Move drm_memory_manager_tests.h and related fixtures to shared
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
d2a29ce458
commit
58ebebeec6
182
shared/test/common/fixtures/memory_management_fixture.cpp
Normal file
182
shared/test/common/fixtures/memory_management_fixture.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/test/common/fixtures/memory_management_fixture.h"
|
||||
|
||||
#include "shared/test/common/helpers/memory_leak_listener.h"
|
||||
#include "shared/test/common/helpers/memory_management.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#if defined(__linux__)
|
||||
#include <cstdio>
|
||||
#include <cxxabi.h>
|
||||
#include <dlfcn.h>
|
||||
#include <execinfo.h>
|
||||
#elif defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable : 4091) // Temporarily disables warning 4091.
|
||||
#include <DbgHelp.h>
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#pragma comment(lib, "Dbghelp.lib")
|
||||
#endif
|
||||
|
||||
namespace Os {
|
||||
extern const char *frontEndDllName;
|
||||
extern const char *igcDllName;
|
||||
} // namespace Os
|
||||
|
||||
void MemoryManagementFixture::SetUp() {
|
||||
EXPECT_EQ(static_cast<size_t>(-1), MemoryManagement::failingAllocation);
|
||||
MemoryManagement::indexAllocation = 0;
|
||||
MemoryManagement::indexDeallocation = 0;
|
||||
MemoryManagement::failingAllocation = -1;
|
||||
previousAllocations = MemoryManagement::numAllocations.load();
|
||||
MemoryManagement::logTraces = MemoryManagement::captureCallStacks;
|
||||
}
|
||||
|
||||
void MemoryManagementFixture::TearDown() {
|
||||
clearFailingAllocation();
|
||||
checkForLeaks();
|
||||
MemoryManagement::logTraces = false;
|
||||
}
|
||||
|
||||
void MemoryManagementFixture::setFailingAllocation(size_t allocation) {
|
||||
MemoryManagement::indexAllocation = 0;
|
||||
MemoryManagement::failingAllocation = allocation;
|
||||
}
|
||||
|
||||
void MemoryManagementFixture::clearFailingAllocation() {
|
||||
MemoryManagement::failingAllocation = -1;
|
||||
}
|
||||
|
||||
::testing::AssertionResult MemoryManagementFixture::assertLeak(
|
||||
const char *leakExpr,
|
||||
size_t leakIndex) {
|
||||
using MemoryManagement::AllocationEvent;
|
||||
using MemoryManagement::eventsAllocated;
|
||||
|
||||
if (leakIndex == MemoryManagement::invalidLeakIndex) {
|
||||
return ::testing::AssertionSuccess();
|
||||
}
|
||||
auto &event = eventsAllocated[leakIndex];
|
||||
|
||||
switch (event.event) {
|
||||
case AllocationEvent::EVENT_DELETE:
|
||||
return ::testing::AssertionFailure() << "event[" << leakIndex
|
||||
<< "]: delete doesn't have corresponding new. allocation address="
|
||||
<< event.address
|
||||
<< ", allocation size=" << event.size << printCallStack(event);
|
||||
break;
|
||||
case AllocationEvent::EVENT_DELETE_ARRAY:
|
||||
return ::testing::AssertionFailure() << "event[" << leakIndex
|
||||
<< "]: delete[] doesn't have corresponding new[]. allocation address="
|
||||
<< event.address
|
||||
<< ", allocation size=" << event.size << printCallStack(event);
|
||||
break;
|
||||
case AllocationEvent::EVENT_NEW:
|
||||
return ::testing::AssertionFailure() << "event[" << leakIndex
|
||||
<< "]: new doesn't have corresponding delete. allocation address="
|
||||
<< event.address
|
||||
<< ", allocation size=" << event.size << printCallStack(event);
|
||||
break;
|
||||
case AllocationEvent::EVENT_NEW_NOTHROW:
|
||||
return ::testing::AssertionFailure() << "event[" << leakIndex
|
||||
<< "]: new (std::nothrow) doesn't have corresponding delete. allocation address="
|
||||
<< event.address
|
||||
<< ", allocation size=" << event.size << printCallStack(event);
|
||||
break;
|
||||
case AllocationEvent::EVENT_NEW_ARRAY:
|
||||
return ::testing::AssertionFailure() << "event[" << leakIndex
|
||||
<< "]: new [] doesn't have corresponding delete[]. allocation address="
|
||||
<< event.address
|
||||
<< ", allocation size=" << event.size << printCallStack(event);
|
||||
break;
|
||||
case AllocationEvent::EVENT_NEW_ARRAY_NOTHROW:
|
||||
return ::testing::AssertionFailure() << "event[" << leakIndex
|
||||
<< "] new (std::nothrow) [] doesn't have corresponding delete[]. allocation address="
|
||||
<< event.address
|
||||
<< ", allocation size=" << event.size << printCallStack(event);
|
||||
break;
|
||||
case AllocationEvent::EVENT_NEW_ARRAY_NOTHROW_FAIL:
|
||||
case AllocationEvent::EVENT_NEW_ARRAY_FAIL:
|
||||
case AllocationEvent::EVENT_NEW_NOTHROW_FAIL:
|
||||
case AllocationEvent::EVENT_NEW_FAIL:
|
||||
case AllocationEvent::EVENT_UNKNOWN:
|
||||
default:
|
||||
return ::testing::AssertionFailure() << "Unknown event[" << leakIndex << "] detected. allocation size=" << event.size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryManagementFixture::checkForLeaks() {
|
||||
// We have to alias MemoryManagement::numAllocations because
|
||||
// the following EXPECT_EQ actually allocates more memory :-)
|
||||
auto currentAllocations = MemoryManagement::numAllocations.load();
|
||||
auto indexAllocationTop = MemoryManagement::indexAllocation.load();
|
||||
auto indexDellocationTop = MemoryManagement::indexDeallocation.load();
|
||||
if (previousAllocations != currentAllocations) {
|
||||
auto testInfo = ::testing::UnitTest::GetInstance()->current_test_info();
|
||||
auto testResult = testInfo->result();
|
||||
if (testResult->Passed()) {
|
||||
//EXPECT_EQ(previousAllocations, currentAllocations);
|
||||
size_t leakEventIndex;
|
||||
do {
|
||||
leakEventIndex = MemoryManagement::enumerateLeak(indexAllocationTop, indexDellocationTop, false, false);
|
||||
EXPECT_PRED_FORMAT1(assertLeak, leakEventIndex);
|
||||
auto invalidLeakIndexValues = MemoryManagement::invalidLeakIndex;
|
||||
EXPECT_EQ(leakEventIndex, invalidLeakIndexValues);
|
||||
} while (leakEventIndex != MemoryManagement::invalidLeakIndex);
|
||||
} else {
|
||||
printf("*** WARNING: Leaks found but dumping disabled during test failure ***\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryManagementFixture::injectFailures(InjectedFunction &method, uint32_t maxIndex) {
|
||||
MemoryManagement::indexAllocation = 0;
|
||||
method(-1);
|
||||
auto numCurrentAllocations = MemoryManagement::indexAllocation.load();
|
||||
|
||||
for (auto i = 0u; i < numCurrentAllocations; i++) {
|
||||
// Force a failure
|
||||
MemoryManagement::indexAllocation = numCurrentAllocations;
|
||||
MemoryManagement::failingAllocation = i + numCurrentAllocations;
|
||||
if (MemoryManagement::eventsAllocated[i].event == MemoryManagement::AllocationEvent::EVENT_NEW ||
|
||||
MemoryManagement::eventsAllocated[i].event == MemoryManagement::AllocationEvent::EVENT_NEW_ARRAY) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (maxIndex != 0 && i > maxIndex) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Call the method under test
|
||||
method(i);
|
||||
|
||||
// Restore allocations
|
||||
MemoryManagement::failingAllocation = -1;
|
||||
}
|
||||
MemoryManagement::failingAllocation = -1;
|
||||
}
|
||||
|
||||
void MemoryManagementFixture::injectFailureOnIndex(InjectedFunction &method, uint32_t index) {
|
||||
MemoryManagement::indexAllocation = 0;
|
||||
method(-1);
|
||||
auto numCurrentAllocations = MemoryManagement::indexAllocation.load();
|
||||
|
||||
// Force a failure
|
||||
MemoryManagement::indexAllocation = numCurrentAllocations;
|
||||
MemoryManagement::failingAllocation = index + numCurrentAllocations;
|
||||
|
||||
// Call the method under test
|
||||
method(index);
|
||||
|
||||
// Restore allocations
|
||||
MemoryManagement::failingAllocation = -1;
|
||||
}
|
||||
42
shared/test/common/fixtures/memory_management_fixture.h
Normal file
42
shared/test/common/fixtures/memory_management_fixture.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared/test/common/helpers/memory_management.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
struct MemoryManagementFixture {
|
||||
MemoryManagementFixture() {
|
||||
MemoryManagement::detailedAllocationLoggingActive = true;
|
||||
};
|
||||
virtual ~MemoryManagementFixture() { MemoryManagement::detailedAllocationLoggingActive = false; };
|
||||
|
||||
// Typical Fixture methods
|
||||
virtual void SetUp(void);
|
||||
virtual void TearDown(void);
|
||||
|
||||
// Helper methods
|
||||
void setFailingAllocation(size_t allocation);
|
||||
void clearFailingAllocation(void);
|
||||
|
||||
::testing::AssertionResult assertLeak(
|
||||
const char *leakExpr,
|
||||
size_t leakIndex);
|
||||
|
||||
void checkForLeaks(void);
|
||||
|
||||
typedef std::function<void(size_t)> InjectedFunction;
|
||||
void injectFailures(InjectedFunction &method, uint32_t maxIndex = 0);
|
||||
void injectFailureOnIndex(InjectedFunction &method, uint32_t index);
|
||||
|
||||
// Used to keep track of # of allocations prior at SetUp time
|
||||
// Gets compared to # at TearDown time
|
||||
size_t previousAllocations;
|
||||
};
|
||||
@@ -67,6 +67,8 @@ set(igdrcl_libult_common_SRCS_LIB_ULT
|
||||
${NEO_SHARED_TEST_DIRECTORY}/common/helpers/memory_leak_listener.h
|
||||
${NEO_SHARED_TEST_DIRECTORY}/common/helpers/memory_management.cpp
|
||||
${NEO_SHARED_TEST_DIRECTORY}/common/helpers/memory_management.h
|
||||
${NEO_SHARED_TEST_DIRECTORY}/common/fixtures/memory_management_fixture.cpp
|
||||
${NEO_SHARED_TEST_DIRECTORY}/common/fixtures/memory_management_fixture.h
|
||||
${NEO_SHARED_TEST_DIRECTORY}/common/helpers/sip_init.cpp
|
||||
${NEO_SHARED_TEST_DIRECTORY}/common/helpers/test_files.cpp
|
||||
${NEO_SHARED_TEST_DIRECTORY}/common/helpers/test_files.h
|
||||
@@ -114,8 +116,16 @@ set(igdrcl_libult_common_SRCS_LIB_ULT_WIN
|
||||
${NEO_SHARED_TEST_DIRECTORY}/common/os_interface/windows/ult_dxgi_factory.h
|
||||
)
|
||||
|
||||
set(igdrcl_libult_common_SRCS_LIB_ULT_LINUX
|
||||
${NEO_SHARED_TEST_DIRECTORY}/common/os_interface/linux/device_command_stream_fixture.cpp
|
||||
${NEO_SHARED_TEST_DIRECTORY}/common/os_interface/linux/device_command_stream_fixture.h
|
||||
)
|
||||
set_property(GLOBAL PROPERTY igdrcl_libult_common_SRCS_LIB_ULT_LINUX ${igdrcl_libult_common_SRCS_LIB_ULT_LINUX})
|
||||
|
||||
if(WIN32)
|
||||
target_sources(igdrcl_libult_common PRIVATE ${igdrcl_libult_common_SRCS_LIB_ULT_WIN})
|
||||
elseif(UNIX)
|
||||
target_sources(igdrcl_libult_common PRIVATE ${igdrcl_libult_common_SRCS_LIB_ULT_LINUX})
|
||||
endif()
|
||||
|
||||
target_include_directories(igdrcl_libult_common PRIVATE
|
||||
|
||||
@@ -90,6 +90,7 @@ if(WIN32)
|
||||
else()
|
||||
list(APPEND NEO_CORE_tests_mocks
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_allocation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_command_stream_receiver.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_memory_manager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_memory_manager.h
|
||||
)
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared/source/os_interface/linux/drm_command_stream.h"
|
||||
#include "shared/test/common/helpers/ult_hw_config.h"
|
||||
|
||||
using namespace NEO;
|
||||
|
||||
template <typename GfxFamily>
|
||||
class TestedDrmCommandStreamReceiver : public DrmCommandStreamReceiver<GfxFamily> {
|
||||
public:
|
||||
using CommandStreamReceiver::activePartitions;
|
||||
using CommandStreamReceiver::clearColorAllocation;
|
||||
using CommandStreamReceiver::commandStream;
|
||||
using CommandStreamReceiver::createPreemptionAllocation;
|
||||
using CommandStreamReceiver::flushStamp;
|
||||
using CommandStreamReceiver::getTagAddress;
|
||||
using CommandStreamReceiver::globalFenceAllocation;
|
||||
using CommandStreamReceiver::latestSentTaskCount;
|
||||
using CommandStreamReceiver::makeResident;
|
||||
using CommandStreamReceiver::taskCount;
|
||||
using CommandStreamReceiver::useGpuIdleImplicitFlush;
|
||||
using CommandStreamReceiver::useNewResourceImplicitFlush;
|
||||
using CommandStreamReceiver::useNotifyEnableForPostSync;
|
||||
using DrmCommandStreamReceiver<GfxFamily>::residency;
|
||||
using DrmCommandStreamReceiver<GfxFamily>::useContextForUserFenceWait;
|
||||
using DrmCommandStreamReceiver<GfxFamily>::useUserFenceWait;
|
||||
using CommandStreamReceiverHw<GfxFamily>::directSubmission;
|
||||
using CommandStreamReceiverHw<GfxFamily>::blitterDirectSubmission;
|
||||
using CommandStreamReceiverHw<GfxFamily>::CommandStreamReceiver::lastSentSliceCount;
|
||||
|
||||
TestedDrmCommandStreamReceiver(gemCloseWorkerMode mode,
|
||||
ExecutionEnvironment &executionEnvironment,
|
||||
const DeviceBitfield deviceBitfield)
|
||||
: DrmCommandStreamReceiver<GfxFamily>(executionEnvironment, 0, deviceBitfield, mode) {
|
||||
}
|
||||
TestedDrmCommandStreamReceiver(ExecutionEnvironment &executionEnvironment,
|
||||
uint32_t rootDeviceIndex,
|
||||
const DeviceBitfield deviceBitfield)
|
||||
: DrmCommandStreamReceiver<GfxFamily>(executionEnvironment, rootDeviceIndex, deviceBitfield, gemCloseWorkerMode::gemCloseWorkerInactive) {
|
||||
}
|
||||
|
||||
void overrideDispatchPolicy(DispatchMode overrideValue) {
|
||||
this->dispatchMode = overrideValue;
|
||||
}
|
||||
|
||||
void makeNonResident(GraphicsAllocation &gfxAllocation) override {
|
||||
makeNonResidentResult.called = true;
|
||||
makeNonResidentResult.allocation = &gfxAllocation;
|
||||
DrmCommandStreamReceiver<GfxFamily>::makeNonResident(gfxAllocation);
|
||||
}
|
||||
|
||||
struct MakeResidentNonResidentResult {
|
||||
bool called = false;
|
||||
GraphicsAllocation *allocation = nullptr;
|
||||
};
|
||||
|
||||
MakeResidentNonResidentResult makeNonResidentResult;
|
||||
|
||||
SubmissionAggregator *peekSubmissionAggregator() const {
|
||||
return this->submissionAggregator.get();
|
||||
}
|
||||
|
||||
void overrideSubmissionAggregator(SubmissionAggregator *newSubmissionsAggregator) {
|
||||
this->submissionAggregator.reset(newSubmissionsAggregator);
|
||||
}
|
||||
|
||||
std::vector<drm_i915_gem_exec_object2> &getExecStorage() {
|
||||
return this->execObjectsStorage;
|
||||
}
|
||||
|
||||
bool createPreemptionAllocation() override {
|
||||
if (ultHwConfig.csrBaseCallCreatePreemption) {
|
||||
return CommandStreamReceiver::createPreemptionAllocation();
|
||||
} else {
|
||||
return ultHwConfig.csrCreatePreemptionReturnValue;
|
||||
}
|
||||
}
|
||||
|
||||
struct WaitUserFenceResult {
|
||||
uint32_t called = 0u;
|
||||
uint32_t waitValue = 0u;
|
||||
int returnValue = 0;
|
||||
bool callParent = true;
|
||||
};
|
||||
|
||||
WaitUserFenceResult waitUserFenceResult;
|
||||
|
||||
int waitUserFence(uint32_t waitValue) override {
|
||||
waitUserFenceResult.called++;
|
||||
waitUserFenceResult.waitValue = waitValue;
|
||||
|
||||
if (waitUserFenceResult.callParent) {
|
||||
return DrmCommandStreamReceiver<GfxFamily>::waitUserFence(waitValue);
|
||||
} else {
|
||||
return waitUserFenceResult.returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
bool callHwFlush = true;
|
||||
|
||||
int flushInternal(const BatchBuffer &batchBuffer, const ResidencyContainer &allocationsForResidency) override {
|
||||
if (callHwFlush) {
|
||||
return DrmCommandStreamReceiver<GfxFamily>::flushInternal(batchBuffer, allocationsForResidency);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename GfxFamily>
|
||||
class TestedDrmCommandStreamReceiverWithFailingExec : public TestedDrmCommandStreamReceiver<GfxFamily> {
|
||||
public:
|
||||
TestedDrmCommandStreamReceiverWithFailingExec(gemCloseWorkerMode mode,
|
||||
ExecutionEnvironment &executionEnvironment,
|
||||
const DeviceBitfield deviceBitfield)
|
||||
: TestedDrmCommandStreamReceiver<GfxFamily>(mode,
|
||||
executionEnvironment,
|
||||
deviceBitfield) {
|
||||
}
|
||||
TestedDrmCommandStreamReceiverWithFailingExec(ExecutionEnvironment &executionEnvironment,
|
||||
uint32_t rootDeviceIndex,
|
||||
const DeviceBitfield deviceBitfield)
|
||||
: TestedDrmCommandStreamReceiver<GfxFamily>(executionEnvironment,
|
||||
rootDeviceIndex,
|
||||
deviceBitfield) {
|
||||
}
|
||||
|
||||
int exec(const BatchBuffer &batchBuffer, uint32_t vmHandleId, uint32_t drmContextId) override {
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
@@ -10,9 +10,9 @@
|
||||
#include "shared/source/command_stream/command_stream_receiver.h"
|
||||
#include "shared/source/command_stream/preemption.h"
|
||||
#include "shared/source/os_interface/os_context.h"
|
||||
#include "shared/test//common/mocks/mock_ostime.h"
|
||||
#include "shared/test/common/mocks/mock_execution_environment.h"
|
||||
#include "shared/test/common/mocks/mock_memory_manager.h"
|
||||
#include "shared/test/common/mocks/mock_ostime.h"
|
||||
#include "shared/test/common/mocks/ult_device_factory.h"
|
||||
#include "shared/test/unit_test/tests_configuration.h"
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
if(UNIX)
|
||||
target_sources(${TARGET_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drm_memory_manager_tests.h
|
||||
)
|
||||
|
||||
add_subdirectories()
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/test/common/os_interface/linux/device_command_stream_fixture.h"
|
||||
|
||||
const int mockFd = 33;
|
||||
const char *mockPciPath = "";
|
||||
|
||||
void DrmMockCustom::Ioctls::reset() {
|
||||
total = 0;
|
||||
execbuffer2 = 0;
|
||||
gemUserptr = 0;
|
||||
gemCreate = 0;
|
||||
gemSetTiling = 0;
|
||||
gemGetTiling = 0;
|
||||
primeFdToHandle = 0;
|
||||
handleToPrimeFd = 0;
|
||||
gemMmap = 0;
|
||||
gemSetDomain = 0;
|
||||
gemWait = 0;
|
||||
gemClose = 0;
|
||||
regRead = 0;
|
||||
getParam = 0;
|
||||
contextGetParam = 0;
|
||||
contextCreate = 0;
|
||||
contextDestroy = 0;
|
||||
}
|
||||
|
||||
void DrmMockCustom::testIoctls() {
|
||||
if (this->ioctl_expected.total == -1)
|
||||
return;
|
||||
|
||||
#define NEO_IOCTL_EXPECT_EQ(PARAM) \
|
||||
if (this->ioctl_expected.PARAM >= 0) { \
|
||||
EXPECT_EQ(this->ioctl_expected.PARAM, this->ioctl_cnt.PARAM); \
|
||||
}
|
||||
NEO_IOCTL_EXPECT_EQ(execbuffer2);
|
||||
NEO_IOCTL_EXPECT_EQ(gemUserptr);
|
||||
NEO_IOCTL_EXPECT_EQ(gemCreate);
|
||||
NEO_IOCTL_EXPECT_EQ(gemSetTiling);
|
||||
NEO_IOCTL_EXPECT_EQ(gemGetTiling);
|
||||
NEO_IOCTL_EXPECT_EQ(primeFdToHandle);
|
||||
NEO_IOCTL_EXPECT_EQ(handleToPrimeFd);
|
||||
NEO_IOCTL_EXPECT_EQ(gemMmap);
|
||||
NEO_IOCTL_EXPECT_EQ(gemSetDomain);
|
||||
NEO_IOCTL_EXPECT_EQ(gemWait);
|
||||
NEO_IOCTL_EXPECT_EQ(gemClose);
|
||||
NEO_IOCTL_EXPECT_EQ(regRead);
|
||||
NEO_IOCTL_EXPECT_EQ(getParam);
|
||||
NEO_IOCTL_EXPECT_EQ(contextGetParam);
|
||||
NEO_IOCTL_EXPECT_EQ(contextCreate);
|
||||
NEO_IOCTL_EXPECT_EQ(contextDestroy);
|
||||
#undef NEO_IOCTL_EXPECT_EQ
|
||||
}
|
||||
|
||||
int DrmMockCustom::ioctl(unsigned long request, void *arg) {
|
||||
auto ext = ioctl_res_ext.load();
|
||||
|
||||
//store flags
|
||||
switch (request) {
|
||||
case DRM_IOCTL_I915_GEM_EXECBUFFER2: {
|
||||
drm_i915_gem_execbuffer2 *execbuf = (drm_i915_gem_execbuffer2 *)arg;
|
||||
this->execBuffer = *execbuf;
|
||||
this->execBufferBufferObjects =
|
||||
*reinterpret_cast<drm_i915_gem_exec_object2 *>(this->execBuffer.buffers_ptr);
|
||||
ioctl_cnt.execbuffer2++;
|
||||
} break;
|
||||
|
||||
case DRM_IOCTL_I915_GEM_USERPTR: {
|
||||
auto *userPtrParams = (drm_i915_gem_userptr *)arg;
|
||||
userPtrParams->handle = returnHandle;
|
||||
returnHandle++;
|
||||
ioctl_cnt.gemUserptr++;
|
||||
} break;
|
||||
|
||||
case DRM_IOCTL_I915_GEM_CREATE: {
|
||||
auto *createParams = (drm_i915_gem_create *)arg;
|
||||
this->createParamsSize = createParams->size;
|
||||
this->createParamsHandle = createParams->handle = 1u;
|
||||
ioctl_cnt.gemCreate++;
|
||||
} break;
|
||||
case DRM_IOCTL_I915_GEM_SET_TILING: {
|
||||
auto *setTilingParams = (drm_i915_gem_set_tiling *)arg;
|
||||
setTilingMode = setTilingParams->tiling_mode;
|
||||
setTilingHandle = setTilingParams->handle;
|
||||
setTilingStride = setTilingParams->stride;
|
||||
ioctl_cnt.gemSetTiling++;
|
||||
} break;
|
||||
case DRM_IOCTL_I915_GEM_GET_TILING: {
|
||||
auto *getTilingParams = (drm_i915_gem_get_tiling *)arg;
|
||||
getTilingParams->tiling_mode = getTilingModeOut;
|
||||
getTilingHandleIn = getTilingParams->handle;
|
||||
ioctl_cnt.gemGetTiling++;
|
||||
} break;
|
||||
case DRM_IOCTL_PRIME_FD_TO_HANDLE: {
|
||||
auto *primeToHandleParams = (drm_prime_handle *)arg;
|
||||
//return BO
|
||||
primeToHandleParams->handle = outputHandle;
|
||||
inputFd = primeToHandleParams->fd;
|
||||
ioctl_cnt.primeFdToHandle++;
|
||||
} break;
|
||||
case DRM_IOCTL_PRIME_HANDLE_TO_FD: {
|
||||
auto *handleToPrimeParams = (drm_prime_handle *)arg;
|
||||
//return FD
|
||||
inputHandle = handleToPrimeParams->handle;
|
||||
inputFlags = handleToPrimeParams->flags;
|
||||
handleToPrimeParams->fd = outputFd;
|
||||
ioctl_cnt.handleToPrimeFd++;
|
||||
} break;
|
||||
case DRM_IOCTL_I915_GEM_MMAP: {
|
||||
auto mmapParams = (drm_i915_gem_mmap *)arg;
|
||||
mmapHandle = mmapParams->handle;
|
||||
mmapPad = mmapParams->pad;
|
||||
mmapOffset = mmapParams->offset;
|
||||
mmapSize = mmapParams->size;
|
||||
mmapFlags = mmapParams->flags;
|
||||
mmapParams->addr_ptr = mmapAddrPtr;
|
||||
ioctl_cnt.gemMmap++;
|
||||
} break;
|
||||
case DRM_IOCTL_I915_GEM_SET_DOMAIN: {
|
||||
auto setDomainParams = (drm_i915_gem_set_domain *)arg;
|
||||
setDomainHandle = setDomainParams->handle;
|
||||
setDomainReadDomains = setDomainParams->read_domains;
|
||||
setDomainWriteDomain = setDomainParams->write_domain;
|
||||
ioctl_cnt.gemSetDomain++;
|
||||
} break;
|
||||
|
||||
case DRM_IOCTL_I915_GEM_WAIT: {
|
||||
auto gemWaitParams = (drm_i915_gem_wait *)arg;
|
||||
gemWaitTimeout = gemWaitParams->timeout_ns;
|
||||
ioctl_cnt.gemWait++;
|
||||
} break;
|
||||
|
||||
case DRM_IOCTL_GEM_CLOSE:
|
||||
ioctl_cnt.gemClose++;
|
||||
break;
|
||||
|
||||
case DRM_IOCTL_I915_REG_READ:
|
||||
ioctl_cnt.regRead++;
|
||||
break;
|
||||
|
||||
case DRM_IOCTL_I915_GETPARAM: {
|
||||
ioctl_cnt.contextGetParam++;
|
||||
auto getParam = (drm_i915_getparam_t *)arg;
|
||||
recordedGetParam = *getParam;
|
||||
*getParam->value = getParamRetValue;
|
||||
} break;
|
||||
|
||||
case DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM: {
|
||||
} break;
|
||||
|
||||
case DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM: {
|
||||
ioctl_cnt.contextGetParam++;
|
||||
auto getContextParam = (drm_i915_gem_context_param *)arg;
|
||||
recordedGetContextParam = *getContextParam;
|
||||
getContextParam->value = getContextParamRetValue;
|
||||
} break;
|
||||
|
||||
case DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT: {
|
||||
auto contextCreateParam = reinterpret_cast<drm_i915_gem_context_create_ext *>(arg);
|
||||
contextCreateParam->ctx_id = ++ioctl_cnt.contextCreate;
|
||||
} break;
|
||||
case DRM_IOCTL_I915_GEM_CONTEXT_DESTROY: {
|
||||
ioctl_cnt.contextDestroy++;
|
||||
} break;
|
||||
|
||||
default:
|
||||
int res = ioctlExtra(request, arg);
|
||||
if (returnIoctlExtraErrorValue) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ext->no.empty() && std::find(ext->no.begin(), ext->no.end(), ioctl_cnt.total.load()) != ext->no.end()) {
|
||||
ioctl_cnt.total.fetch_add(1);
|
||||
return ext->res;
|
||||
}
|
||||
ioctl_cnt.total.fetch_add(1);
|
||||
return ioctl_res.load();
|
||||
}
|
||||
|
||||
DrmMockCustom::DrmMockCustom(RootDeviceEnvironment &rootDeviceEnvironment)
|
||||
: Drm(std::make_unique<HwDeviceIdDrm>(mockFd, mockPciPath), rootDeviceEnvironment) {
|
||||
reset();
|
||||
ioctl_expected.contextCreate = static_cast<int>(NEO::HwHelper::get(NEO::defaultHwInfo->platform.eRenderCoreFamily).getGpgpuEngineInstances(*NEO::defaultHwInfo).size());
|
||||
ioctl_expected.contextDestroy = ioctl_expected.contextCreate.load();
|
||||
createVirtualMemoryAddressSpace(NEO::HwHelper::getSubDevicesCount(rootDeviceEnvironment.getHardwareInfo()));
|
||||
isVmBindAvailable();
|
||||
reset();
|
||||
}
|
||||
|
||||
int DrmMockCustom::waitUserFence(uint32_t ctxId, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout, uint16_t flags) {
|
||||
waitUserFenceCall.called++;
|
||||
waitUserFenceCall.ctxId = ctxId;
|
||||
waitUserFenceCall.address = address;
|
||||
waitUserFenceCall.dataWidth = dataWidth;
|
||||
waitUserFenceCall.value = value;
|
||||
waitUserFenceCall.timeout = timeout;
|
||||
waitUserFenceCall.flags = flags;
|
||||
return Drm::waitUserFence(ctxId, address, value, dataWidth, timeout, flags);
|
||||
}
|
||||
|
||||
bool DrmMockCustom::isVmBindAvailable() {
|
||||
isVmBindAvailableCall.called++;
|
||||
if (isVmBindAvailableCall.callParent) {
|
||||
return Drm::isVmBindAvailable();
|
||||
} else {
|
||||
return isVmBindAvailableCall.returnValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared/source/helpers/aligned_memory.h"
|
||||
#include "shared/source/helpers/hw_helper.h"
|
||||
#include "shared/source/os_interface/linux/drm_memory_manager.h"
|
||||
#include "shared/source/os_interface/linux/drm_neo.h"
|
||||
#include "shared/test/common/helpers/default_hw_info.h"
|
||||
|
||||
#include "drm/i915_drm.h"
|
||||
#include "engine_node.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
using NEO::Drm;
|
||||
using NEO::HwDeviceIdDrm;
|
||||
using NEO::RootDeviceEnvironment;
|
||||
|
||||
extern const int mockFd;
|
||||
extern const char *mockPciPath;
|
||||
|
||||
class DrmMockImpl : public Drm {
|
||||
public:
|
||||
DrmMockImpl(int fd, RootDeviceEnvironment &rootDeviceEnvironment) : Drm(std::make_unique<HwDeviceIdDrm>(fd, mockPciPath), rootDeviceEnvironment){};
|
||||
|
||||
MOCK_METHOD2(ioctl, int(unsigned long request, void *arg));
|
||||
};
|
||||
|
||||
class DrmMockSuccess : public Drm {
|
||||
public:
|
||||
DrmMockSuccess(int fd, RootDeviceEnvironment &rootDeviceEnvironment) : Drm(std::make_unique<HwDeviceIdDrm>(fd, mockPciPath), rootDeviceEnvironment) {}
|
||||
|
||||
int ioctl(unsigned long request, void *arg) override { return 0; };
|
||||
};
|
||||
|
||||
class DrmMockFail : public Drm {
|
||||
public:
|
||||
DrmMockFail(RootDeviceEnvironment &rootDeviceEnvironment) : Drm(std::make_unique<HwDeviceIdDrm>(mockFd, mockPciPath), rootDeviceEnvironment) {}
|
||||
|
||||
int ioctl(unsigned long request, void *arg) override { return -1; };
|
||||
};
|
||||
|
||||
class DrmMockTime : public DrmMockSuccess {
|
||||
public:
|
||||
using DrmMockSuccess::DrmMockSuccess;
|
||||
int ioctl(unsigned long request, void *arg) override {
|
||||
drm_i915_reg_read *reg = reinterpret_cast<drm_i915_reg_read *>(arg);
|
||||
reg->val = getVal() << 32;
|
||||
return 0;
|
||||
};
|
||||
|
||||
uint64_t getVal() {
|
||||
static uint64_t val = 0;
|
||||
return ++val;
|
||||
}
|
||||
};
|
||||
|
||||
class DrmMockCustom : public Drm {
|
||||
public:
|
||||
using Drm::bindAvailable;
|
||||
using Drm::cacheInfo;
|
||||
using Drm::memoryInfo;
|
||||
|
||||
struct IoctlResExt {
|
||||
std::vector<int32_t> no;
|
||||
int32_t res;
|
||||
|
||||
IoctlResExt(int32_t no, int32_t res) : no(1u, no), res(res) {}
|
||||
};
|
||||
|
||||
class Ioctls {
|
||||
public:
|
||||
void reset();
|
||||
|
||||
std::atomic<int32_t> total;
|
||||
std::atomic<int32_t> execbuffer2;
|
||||
std::atomic<int32_t> gemUserptr;
|
||||
std::atomic<int32_t> gemCreate;
|
||||
std::atomic<int32_t> gemSetTiling;
|
||||
std::atomic<int32_t> gemGetTiling;
|
||||
std::atomic<int32_t> primeFdToHandle;
|
||||
std::atomic<int32_t> handleToPrimeFd;
|
||||
std::atomic<int32_t> gemMmap;
|
||||
std::atomic<int32_t> gemSetDomain;
|
||||
std::atomic<int32_t> gemWait;
|
||||
std::atomic<int32_t> gemClose;
|
||||
std::atomic<int32_t> regRead;
|
||||
std::atomic<int32_t> getParam;
|
||||
std::atomic<int32_t> contextGetParam;
|
||||
std::atomic<int32_t> contextCreate;
|
||||
std::atomic<int32_t> contextDestroy;
|
||||
};
|
||||
|
||||
struct WaitUserFenceCall {
|
||||
uint64_t address = 0u;
|
||||
uint64_t value = 0u;
|
||||
uint32_t ctxId = 0u;
|
||||
ValueWidth dataWidth = ValueWidth::U8;
|
||||
int64_t timeout = 0;
|
||||
uint16_t flags = 0;
|
||||
|
||||
uint32_t called = 0u;
|
||||
};
|
||||
|
||||
struct IsVmBindAvailableCall {
|
||||
bool callParent = true;
|
||||
bool returnValue = true;
|
||||
uint32_t called = 0u;
|
||||
};
|
||||
|
||||
DrmMockCustom(RootDeviceEnvironment &rootDeviceEnvironment);
|
||||
|
||||
int waitUserFence(uint32_t ctxId, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout, uint16_t flags) override;
|
||||
|
||||
bool isVmBindAvailable() override;
|
||||
|
||||
void testIoctls();
|
||||
|
||||
int ioctl(unsigned long request, void *arg) override;
|
||||
|
||||
virtual int ioctlExtra(unsigned long request, void *arg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getErrno() override {
|
||||
return errnoValue;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
ioctl_res = 0;
|
||||
ioctl_cnt.reset();
|
||||
ioctl_expected.reset();
|
||||
ioctl_res_ext = &NONE;
|
||||
}
|
||||
|
||||
Ioctls ioctl_cnt;
|
||||
Ioctls ioctl_expected;
|
||||
|
||||
IoctlResExt NONE = {-1, 0};
|
||||
|
||||
WaitUserFenceCall waitUserFenceCall{};
|
||||
IsVmBindAvailableCall isVmBindAvailableCall{};
|
||||
|
||||
std::atomic<int> ioctl_res;
|
||||
std::atomic<IoctlResExt *> ioctl_res_ext;
|
||||
|
||||
//DRM_IOCTL_I915_GEM_EXECBUFFER2
|
||||
drm_i915_gem_execbuffer2 execBuffer = {0};
|
||||
|
||||
//First exec object
|
||||
drm_i915_gem_exec_object2 execBufferBufferObjects = {0};
|
||||
|
||||
//DRM_IOCTL_I915_GEM_CREATE
|
||||
__u64 createParamsSize = 0;
|
||||
__u32 createParamsHandle = 0;
|
||||
//DRM_IOCTL_I915_GEM_SET_TILING
|
||||
__u32 setTilingMode = 0;
|
||||
__u32 setTilingHandle = 0;
|
||||
__u32 setTilingStride = 0;
|
||||
//DRM_IOCTL_I915_GEM_GET_TILING
|
||||
__u32 getTilingModeOut = I915_TILING_NONE;
|
||||
__u32 getTilingHandleIn = 0;
|
||||
//DRM_IOCTL_PRIME_FD_TO_HANDLE
|
||||
__u32 outputHandle = 0;
|
||||
__s32 inputFd = 0;
|
||||
//DRM_IOCTL_PRIME_HANDLE_TO_FD
|
||||
__u32 inputHandle = 0;
|
||||
__s32 outputFd = 0;
|
||||
__s32 inputFlags = 0;
|
||||
//DRM_IOCTL_I915_GEM_USERPTR
|
||||
__u32 returnHandle = 0;
|
||||
//DRM_IOCTL_I915_GEM_MMAP
|
||||
__u32 mmapHandle = 0;
|
||||
__u32 mmapPad = 0;
|
||||
__u64 mmapOffset = 0;
|
||||
__u64 mmapSize = 0;
|
||||
__u64 mmapAddrPtr = 0x7F4000001000;
|
||||
__u64 mmapFlags = 0;
|
||||
//DRM_IOCTL_I915_GEM_SET_DOMAIN
|
||||
__u32 setDomainHandle = 0;
|
||||
__u32 setDomainReadDomains = 0;
|
||||
__u32 setDomainWriteDomain = 0;
|
||||
//DRM_IOCTL_I915_GETPARAM
|
||||
drm_i915_getparam_t recordedGetParam = {0};
|
||||
int getParamRetValue = 0;
|
||||
//DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM
|
||||
drm_i915_gem_context_param recordedGetContextParam = {0};
|
||||
__u64 getContextParamRetValue = 0;
|
||||
//DRM_IOCTL_I915_GEM_WAIT
|
||||
int64_t gemWaitTimeout = 0;
|
||||
|
||||
int errnoValue = 0;
|
||||
|
||||
bool returnIoctlExtraErrorValue = false;
|
||||
};
|
||||
225
shared/test/common/os_interface/linux/drm_memory_manager_tests.h
Normal file
225
shared/test/common/os_interface/linux/drm_memory_manager_tests.h
Normal file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (C) 2019-2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared/source/os_interface/linux/drm_memory_operations_handler.h"
|
||||
#include "shared/source/os_interface/linux/memory_info.h"
|
||||
#include "shared/source/os_interface/os_interface.h"
|
||||
#include "shared/test/common/fixtures/memory_management_fixture.h"
|
||||
#include "shared/test/common/helpers/debug_manager_state_restore.h"
|
||||
#include "shared/test/common/helpers/ult_hw_config.h"
|
||||
#include "shared/test/common/helpers/variable_backup.h"
|
||||
#include "shared/test/common/mocks/linux/mock_drm_command_stream_receiver.h"
|
||||
#include "shared/test/common/mocks/linux/mock_drm_memory_manager.h"
|
||||
#include "shared/test/common/mocks/mock_builtins.h"
|
||||
#include "shared/test/common/mocks/mock_device.h"
|
||||
#include "shared/test/common/mocks/mock_execution_environment.h"
|
||||
#include "shared/test/common/os_interface/linux/device_command_stream_fixture.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
extern std::vector<void *> mmapVector;
|
||||
|
||||
class DrmMemoryManagerBasic : public ::testing::Test {
|
||||
public:
|
||||
DrmMemoryManagerBasic() : executionEnvironment(defaultHwInfo.get(), false, numRootDevices){};
|
||||
void SetUp() override {
|
||||
for (auto i = 0u; i < numRootDevices; i++) {
|
||||
executionEnvironment.rootDeviceEnvironments[i]->osInterface = std::make_unique<OSInterface>();
|
||||
auto drm = Drm::create(nullptr, *executionEnvironment.rootDeviceEnvironments[i]);
|
||||
executionEnvironment.rootDeviceEnvironments[i]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(drm));
|
||||
executionEnvironment.rootDeviceEnvironments[i]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*drm, i);
|
||||
}
|
||||
}
|
||||
const uint32_t rootDeviceIndex = 1u;
|
||||
const uint32_t numRootDevices = 2u;
|
||||
MockExecutionEnvironment executionEnvironment;
|
||||
};
|
||||
|
||||
class DrmMemoryManagerFixture : public MemoryManagementFixture {
|
||||
public:
|
||||
DrmMockCustom *mock = nullptr;
|
||||
bool dontTestIoctlInTearDown = false;
|
||||
const uint32_t rootDeviceIndex = 1u;
|
||||
const uint32_t numRootDevices = 2u;
|
||||
TestedDrmMemoryManager *memoryManager = nullptr;
|
||||
MockDevice *device = nullptr;
|
||||
|
||||
void SetUp() override {
|
||||
MemoryManagementFixture::SetUp();
|
||||
|
||||
executionEnvironment = MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), numRootDevices - 1);
|
||||
SetUp(new DrmMockCustom(*executionEnvironment->rootDeviceEnvironments[0]), false);
|
||||
}
|
||||
|
||||
void SetUp(DrmMockCustom *mock, bool localMemoryEnabled) {
|
||||
ASSERT_NE(nullptr, executionEnvironment);
|
||||
executionEnvironment->incRefInternal();
|
||||
DebugManager.flags.DeferOsContextInitialization.set(0);
|
||||
|
||||
environmentWrapper.setCsrType<TestedDrmCommandStreamReceiver<DEFAULT_TEST_FAMILY_NAME>>();
|
||||
allocationData.rootDeviceIndex = rootDeviceIndex;
|
||||
this->mock = mock;
|
||||
for (auto i = 0u; i < numRootDevices; i++) {
|
||||
auto rootDeviceEnvironment = executionEnvironment->rootDeviceEnvironments[i].get();
|
||||
rootDeviceEnvironment->osInterface = std::make_unique<OSInterface>();
|
||||
rootDeviceEnvironment->osInterface->setDriverModel(std::unique_ptr<DriverModel>(new DrmMockCustom(*rootDeviceEnvironment)));
|
||||
rootDeviceEnvironment->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*rootDeviceEnvironment->osInterface->getDriverModel()->as<Drm>(), i);
|
||||
rootDeviceEnvironment->builtins.reset(new MockBuiltins);
|
||||
}
|
||||
|
||||
rootDeviceEnvironment = executionEnvironment->rootDeviceEnvironments[rootDeviceIndex].get();
|
||||
rootDeviceEnvironment->osInterface->setDriverModel(std::unique_ptr<DriverModel>(mock));
|
||||
|
||||
memoryManager = new (std::nothrow) TestedDrmMemoryManager(localMemoryEnabled, false, false, *executionEnvironment);
|
||||
executionEnvironment->memoryManager.reset(memoryManager);
|
||||
//assert we have memory manager
|
||||
ASSERT_NE(nullptr, memoryManager);
|
||||
if (memoryManager->getgemCloseWorker()) {
|
||||
memoryManager->getgemCloseWorker()->close(true);
|
||||
}
|
||||
device = MockDevice::create<MockDevice>(executionEnvironment, rootDeviceIndex);
|
||||
mock->reset();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
mock->testIoctls();
|
||||
mock->reset();
|
||||
|
||||
int enginesCount = static_cast<int>(device->getMemoryManager()->getRegisteredEnginesCount());
|
||||
|
||||
mock->ioctl_expected.contextDestroy = enginesCount;
|
||||
mock->ioctl_expected.gemClose = enginesCount;
|
||||
mock->ioctl_expected.gemWait = enginesCount;
|
||||
|
||||
auto csr = static_cast<TestedDrmCommandStreamReceiver<DEFAULT_TEST_FAMILY_NAME> *>(device->getDefaultEngine().commandStreamReceiver);
|
||||
if (csr->globalFenceAllocation) {
|
||||
mock->ioctl_expected.gemClose += enginesCount;
|
||||
mock->ioctl_expected.gemWait += enginesCount;
|
||||
}
|
||||
if (csr->getPreemptionAllocation()) {
|
||||
mock->ioctl_expected.gemClose += enginesCount;
|
||||
mock->ioctl_expected.gemWait += enginesCount;
|
||||
}
|
||||
mock->ioctl_expected.gemWait += additionalDestroyDeviceIoctls.gemWait.load();
|
||||
mock->ioctl_expected.gemClose += additionalDestroyDeviceIoctls.gemClose.load();
|
||||
delete device;
|
||||
if (dontTestIoctlInTearDown) {
|
||||
mock->reset();
|
||||
}
|
||||
mock->testIoctls();
|
||||
executionEnvironment->decRefInternal();
|
||||
MemoryManagementFixture::TearDown();
|
||||
mmapVector.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
ExecutionEnvironment *executionEnvironment = nullptr;
|
||||
RootDeviceEnvironment *rootDeviceEnvironment = nullptr;
|
||||
DrmMockCustom::IoctlResExt ioctlResExt = {0, 0};
|
||||
AllocationData allocationData{};
|
||||
DrmMockCustom::Ioctls additionalDestroyDeviceIoctls{};
|
||||
EnvironmentWithCsrWrapper environmentWrapper;
|
||||
DebugManagerStateRestore restore;
|
||||
};
|
||||
|
||||
class DrmMemoryManagerWithLocalMemoryFixture : public DrmMemoryManagerFixture {
|
||||
public:
|
||||
void SetUp() override {
|
||||
backup = std::make_unique<VariableBackup<UltHwConfig>>(&ultHwConfig);
|
||||
ultHwConfig.csrBaseCallCreatePreemption = false;
|
||||
|
||||
MemoryManagementFixture::SetUp();
|
||||
executionEnvironment = MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), numRootDevices - 1);
|
||||
DrmMemoryManagerFixture::SetUp(new DrmMockCustom(*executionEnvironment->rootDeviceEnvironments[0]), true);
|
||||
}
|
||||
void TearDown() override {
|
||||
DrmMemoryManagerFixture::TearDown();
|
||||
}
|
||||
std::unique_ptr<VariableBackup<UltHwConfig>> backup;
|
||||
};
|
||||
|
||||
struct MockMemoryInfoImpl : public NEO::MemoryInfo {
|
||||
MockMemoryInfoImpl() {}
|
||||
~MockMemoryInfoImpl() override{};
|
||||
size_t getMemoryRegionSize(uint32_t memoryBank) override {
|
||||
return 1024u;
|
||||
}
|
||||
uint32_t createGemExt(Drm *drm, void *data, uint32_t dataSize, size_t allocSize, uint32_t &handle) override {
|
||||
if (allocSize == 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
handle = 1u;
|
||||
return 0u;
|
||||
}
|
||||
uint32_t createGemExtWithSingleRegion(Drm *drm, uint32_t memoryBanks, size_t allocSize, uint32_t &handle) override {
|
||||
if (allocSize == 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
handle = 1u;
|
||||
return 0u;
|
||||
}
|
||||
};
|
||||
|
||||
class DrmMemoryManagerFixtureWithoutQuietIoctlExpectation {
|
||||
public:
|
||||
std::unique_ptr<TestedDrmMemoryManager> memoryManager;
|
||||
DrmMockCustom *mock;
|
||||
|
||||
void SetUp() {
|
||||
SetUp(false);
|
||||
}
|
||||
|
||||
void SetUp(bool enableLocalMem) {
|
||||
DebugManager.flags.DeferOsContextInitialization.set(0);
|
||||
|
||||
executionEnvironment = new ExecutionEnvironment;
|
||||
executionEnvironment->prepareRootDeviceEnvironments(numRootDevices);
|
||||
uint32_t i = 0;
|
||||
for (auto &rootDeviceEnvironment : executionEnvironment->rootDeviceEnvironments) {
|
||||
rootDeviceEnvironment->setHwInfo(defaultHwInfo.get());
|
||||
rootDeviceEnvironment->osInterface = std::make_unique<OSInterface>();
|
||||
rootDeviceEnvironment->osInterface->setDriverModel(std::unique_ptr<DriverModel>(new DrmMockCustom(*rootDeviceEnvironment)));
|
||||
rootDeviceEnvironment->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*rootDeviceEnvironment->osInterface->getDriverModel()->as<Drm>(), i);
|
||||
i++;
|
||||
}
|
||||
mock = static_cast<DrmMockCustom *>(executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->osInterface->getDriverModel()->as<Drm>());
|
||||
mock->memoryInfo.reset(new MockMemoryInfoImpl());
|
||||
executionEnvironment->rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*mock, 0u);
|
||||
memoryManager.reset(new TestedDrmMemoryManager(enableLocalMem, false, false, *executionEnvironment));
|
||||
|
||||
ASSERT_NE(nullptr, memoryManager);
|
||||
if (memoryManager->getgemCloseWorker()) {
|
||||
memoryManager->getgemCloseWorker()->close(true);
|
||||
}
|
||||
device.reset(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, rootDeviceIndex));
|
||||
}
|
||||
|
||||
void TearDown() {
|
||||
}
|
||||
|
||||
protected:
|
||||
ExecutionEnvironment *executionEnvironment = nullptr;
|
||||
std::unique_ptr<MockDevice> device;
|
||||
DrmMockCustom::IoctlResExt ioctlResExt = {0, 0};
|
||||
DebugManagerStateRestore restore;
|
||||
const uint32_t rootDeviceIndex = 1u;
|
||||
const uint32_t numRootDevices = 2u;
|
||||
};
|
||||
|
||||
class DrmMemoryManagerFixtureWithLocalMemoryAndWithoutQuietIoctlExpectation : public DrmMemoryManagerFixtureWithoutQuietIoctlExpectation {
|
||||
public:
|
||||
void SetUp() {
|
||||
DrmMemoryManagerFixtureWithoutQuietIoctlExpectation::SetUp(true);
|
||||
}
|
||||
void TearDown() {
|
||||
DrmMemoryManagerFixtureWithoutQuietIoctlExpectation::TearDown();
|
||||
}
|
||||
};
|
||||
} // namespace NEO
|
||||
@@ -18,8 +18,8 @@
|
||||
#include "shared/test/common/libult/linux/drm_mock.h"
|
||||
#include "shared/test/common/libult/ult_command_stream_receiver.h"
|
||||
#include "shared/test/common/mocks/mock_device.h"
|
||||
#include "shared/test/common/os_interface/linux/drm_memory_manager_tests.h"
|
||||
|
||||
#include "opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.h"
|
||||
#include "test.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
Reference in New Issue
Block a user