feature: support L2 cache reservation

Related-To: NEO-12837
Signed-off-by: Maciej Bielski <maciej.bielski@intel.com>
This commit is contained in:
Maciej Bielski
2025-02-25 16:08:04 +00:00
committed by Compute-Runtime-Automation
parent 117f4c8d32
commit a7c46b8213
19 changed files with 539 additions and 178 deletions

View File

@@ -7,6 +7,7 @@
#include "level_zero/core/source/cache/linux/cache_reservation_impl_prelim.h"
#include "shared/source/helpers/common_types.h"
#include "shared/source/memory_manager/unified_memory_manager.h"
#include "shared/source/os_interface/linux/cache_info.h"
#include "shared/source/os_interface/linux/drm_allocation.h"
@@ -22,9 +23,13 @@ std::unique_ptr<CacheReservation> CacheReservation::create(Device &device) {
}
bool CacheReservationImpl::reserveCache(size_t cacheLevel, size_t cacheReservationSize) {
using NEO::toCacheLevel;
switch (cacheLevel) {
case 2U:
return reserveCacheForLevel(toCacheLevel(2U), cacheReservationSize, reservedL2CacheRegion, reservedL2CacheSize);
case 3U:
return reserveCacheForLevel(3U, cacheReservationSize, reservedL3CacheRegion, reservedL3CacheSize);
return reserveCacheForLevel(toCacheLevel(3U), cacheReservationSize, reservedL3CacheRegion, reservedL3CacheSize);
default:
return false;
}
@@ -32,18 +37,23 @@ bool CacheReservationImpl::reserveCache(size_t cacheLevel, size_t cacheReservati
return true;
}
bool CacheReservationImpl::reserveCacheForLevel(size_t cacheLevel, size_t cacheReservationSize, NEO::CacheRegion &reservedCacheRegion, size_t &reservedCacheSize) {
bool CacheReservationImpl::reserveCacheForLevel(NEO::CacheLevel cacheLevel, size_t cacheReservationSize, NEO::CacheRegion &reservedCacheRegion, size_t &reservedCacheSize) {
auto drm = device.getOsInterface()->getDriverModel()->as<NEO::Drm>();
auto cacheInfo = drm->getCacheInfo();
if (cacheReservationSize == 0) {
cacheInfo->freeCacheRegion(reservedCacheRegion);
cacheInfo->freeCacheRegion(cacheLevel, reservedCacheRegion);
reservedCacheRegion = NEO::CacheRegion::none;
reservedCacheSize = 0;
return true;
}
auto cacheRegion = cacheInfo->reserveCacheRegion(cacheReservationSize);
if (reservedCacheRegion != NEO::CacheRegion::none || reservedCacheSize != 0U) {
return false;
}
auto cacheRegion = cacheInfo->reserveCacheRegion(cacheLevel, cacheReservationSize);
if (cacheRegion == NEO::CacheRegion::none) {
return false;
}
@@ -55,12 +65,21 @@ bool CacheReservationImpl::reserveCacheForLevel(size_t cacheLevel, size_t cacheR
}
bool CacheReservationImpl::setCacheAdvice(void *ptr, [[maybe_unused]] size_t regionSize, ze_cache_ext_region_t cacheRegion) {
return setCacheAdviceImpl(ptr, regionSize, static_cast<uint32_t>(cacheRegion));
}
bool CacheReservationImpl::setCacheAdviceImpl(void *ptr, size_t regionSize, uint32_t cacheRegion) {
auto cacheRegionIdx = NEO::CacheRegion::defaultRegion;
size_t cacheRegionSize = 0;
if (cacheRegion == ze_cache_ext_region_t::ZE_CACHE_EXT_REGION_ZE_CACHE_RESERVE_REGION) {
constexpr auto l3CacheRegionId{static_cast<uint32_t>(ze_cache_ext_region_t::ZE_CACHE_EXT_REGION_RESERVED)};
constexpr auto l2CacheRegionId{1U + static_cast<uint32_t>(ze_cache_ext_region_t::ZE_CACHE_EXT_REGION_NON_RESERVED)};
if (cacheRegion == l3CacheRegionId) {
cacheRegionIdx = this->reservedL3CacheRegion;
cacheRegionSize = this->reservedL3CacheSize;
} else if (cacheRegion == l2CacheRegionId) {
cacheRegionIdx = this->reservedL2CacheRegion;
cacheRegionSize = this->reservedL2CacheSize;
}
auto allocData = device.getDriverHandle()->getSvmAllocsManager()->getSVMAlloc(ptr);
@@ -77,7 +96,9 @@ bool CacheReservationImpl::setCacheAdvice(void *ptr, [[maybe_unused]] size_t reg
}
size_t CacheReservationImpl::getMaxCacheReservationSize(size_t cacheLevel) {
if (cacheLevel != 3U) {
using NEO::toCacheLevel;
if (cacheLevel != 2U && cacheLevel != 3U) {
return 0U;
}
@@ -85,7 +106,7 @@ size_t CacheReservationImpl::getMaxCacheReservationSize(size_t cacheLevel) {
auto cacheInfo = drm->getCacheInfo();
DEBUG_BREAK_IF(cacheInfo == nullptr);
return cacheInfo->getMaxReservationCacheSize();
return cacheInfo->getMaxReservationCacheSize(toCacheLevel(static_cast<uint16_t>(cacheLevel)));
}
} // namespace L0

View File

@@ -23,9 +23,12 @@ class CacheReservationImpl : public CacheReservation {
size_t getMaxCacheReservationSize(size_t cacheLevel) override;
protected:
bool reserveCacheForLevel(size_t cacheLevel, size_t cacheReservationSize, NEO::CacheRegion &reservedCacheRegion, size_t &reservedCacheSize);
bool reserveCacheForLevel(NEO::CacheLevel cacheLevel, size_t cacheReservationSize, NEO::CacheRegion &reservedCacheRegion, size_t &reservedCacheSize);
bool setCacheAdviceImpl(void *ptr, size_t regionSize, uint32_t cacheRegion);
Device &device;
NEO::CacheRegion reservedL2CacheRegion = NEO::CacheRegion::none;
NEO::CacheRegion reservedL3CacheRegion = NEO::CacheRegion::none;
size_t reservedL2CacheSize = 0;
size_t reservedL3CacheSize = 0;
};

View File

@@ -6,6 +6,7 @@
*/
#include "shared/test/common/mocks/linux/mock_drm_allocation.h"
#include "shared/test/common/mocks/linux/mock_ioctl_helper.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/os_interface/linux/drm_mock_cache_info.h"
#include "shared/test/common/os_interface/linux/drm_mock_extended.h"
@@ -33,8 +34,11 @@ namespace ult {
class MockCacheReservationImpl : public CacheReservationImpl {
public:
using CacheReservationImpl::reservedL2CacheRegion;
using CacheReservationImpl::reservedL2CacheSize;
using CacheReservationImpl::reservedL3CacheRegion;
using CacheReservationImpl::reservedL3CacheSize;
using CacheReservationImpl::setCacheAdviceImpl;
};
class CacheReservationFixture : public DeviceFixture {
@@ -49,11 +53,15 @@ class CacheReservationFixture : public DeviceFixture {
mockDrm->ioctlHelper = IoctlHelper::getI915Helper(productFamily, "2.0", *mockDrm);
mockDrm->ioctlHelper->initialize();
CacheReservationParameters l2CacheParameters{};
l2CacheParameters.maxSize = 1;
l2CacheParameters.maxNumRegions = 1;
l2CacheParameters.maxNumWays = 2;
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 1024;
l3CacheParameters.maxNumRegions = 1;
l3CacheParameters.maxNumWays = 32;
mockDrm->cacheInfo.reset(new MockCacheInfo(*mockDrm->ioctlHelper, l3CacheParameters));
mockDrm->cacheInfo.reset(new MockCacheInfo(*mockDrm->ioctlHelper, l2CacheParameters, l3CacheParameters));
rootDeviceEnvironment.osInterface.reset(new NEO::OSInterface);
rootDeviceEnvironment.osInterface->setDriverModel(std::unique_ptr<DriverModel>(mockDrm));
rootDeviceEnvironment.initGmm();
@@ -71,7 +79,7 @@ class CacheReservationFixture : public DeviceFixture {
using CacheReservationTest = Test<CacheReservationFixture>;
HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingReserveCacheThenReservationIsAcquiredAndReleasedAppropriately, IsCacheReservationSupported) {
HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenReservingL3CacheThenReservationIsAcquiredAndReleasedAppropriately, IsCacheReservationSupported) {
constexpr size_t cacheLevel{3U};
constexpr size_t cacheReservationSize{128U};
@@ -88,10 +96,56 @@ HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingReserve
EXPECT_EQ(0u, cacheImpl->reservedL3CacheSize);
}
HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenReservingCacheMoreThanOnceThenOnlyTheFirtstIsAcquired, IsCacheReservationSupported) {
constexpr size_t cacheLevel{3U};
constexpr size_t cacheReservationSize1{128U};
constexpr size_t cacheReservationSize2{64U};
auto result1 = cache->reserveCache(cacheLevel, cacheReservationSize1);
EXPECT_TRUE(result1);
auto cacheImpl = static_cast<MockCacheReservationImpl *>(cache);
EXPECT_EQ(CacheRegion::region1, cacheImpl->reservedL3CacheRegion);
EXPECT_EQ(cacheReservationSize1, cacheImpl->reservedL3CacheSize);
cacheImpl->reservedL3CacheSize = 0U; // verification should fail on check for cache-region
auto result2 = cache->reserveCache(cacheLevel, cacheReservationSize2);
EXPECT_FALSE(result2);
EXPECT_EQ(CacheRegion::region1, cacheImpl->reservedL3CacheRegion);
cacheImpl->reservedL3CacheSize = cacheReservationSize1;
cacheImpl->reservedL3CacheRegion = CacheRegion::none; // verification should fail on check for reserved size
auto result3 = cache->reserveCache(cacheLevel, cacheReservationSize2);
EXPECT_FALSE(result3);
EXPECT_EQ(cacheReservationSize1, cacheImpl->reservedL3CacheSize);
cacheImpl->reservedL3CacheRegion = CacheRegion::region1;
auto result4 = cache->reserveCache(cacheLevel, 0U);
EXPECT_TRUE(result4);
EXPECT_EQ(CacheRegion::none, cacheImpl->reservedL3CacheRegion);
EXPECT_EQ(0u, cacheImpl->reservedL3CacheSize);
}
HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenReservingL2CacheThenReservationIsAcquiredAndReleasedAppropriately, IsCacheReservationSupported) {
constexpr size_t cacheLevel{2U};
constexpr size_t cacheReservationSize1{1U};
mockDrm->closIndex = 2U; // force next returned closIndex to be 3
auto result1 = cache->reserveCache(cacheLevel, cacheReservationSize1);
EXPECT_TRUE(result1);
auto cacheImpl = static_cast<MockCacheReservationImpl *>(cache);
EXPECT_EQ(CacheRegion::region3, cacheImpl->reservedL2CacheRegion);
EXPECT_EQ(cacheReservationSize1, cacheImpl->reservedL2CacheSize);
auto result3 = cache->reserveCache(cacheLevel, 0U);
EXPECT_TRUE(result3);
EXPECT_EQ(CacheRegion::none, cacheImpl->reservedL2CacheRegion);
EXPECT_EQ(0u, cacheImpl->reservedL2CacheSize);
}
HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingReserveCacheWithInvalidSizeThenDontReserveCacheRegion, IsCacheReservationSupported) {
size_t cacheLevel = 3;
uint16_t cacheLevel = 3U;
size_t cacheReservationSize = 2048;
ASSERT_GT(cacheReservationSize, mockDrm->getCacheInfo()->getMaxReservationCacheSize());
ASSERT_GT(cacheReservationSize, mockDrm->getCacheInfo()->getMaxReservationCacheSize(toCacheLevel(cacheLevel)));
auto result = cache->reserveCache(cacheLevel, cacheReservationSize);
EXPECT_FALSE(result);
@@ -234,13 +288,85 @@ HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingSetCach
}
HWTEST2_F(CacheReservationTest, GivenCacheReservationWhenCallingGetMaxCacheReservationSizeThenAppropriateValueReturned, IsCacheReservationSupported) {
auto cacheLevel{3U};
EXPECT_EQ(mockDrm->getCacheInfo()->getMaxReservationCacheSize(), cache->getMaxCacheReservationSize(cacheLevel));
uint16_t cacheLevel{3U};
EXPECT_EQ(mockDrm->getCacheInfo()->getMaxReservationCacheSize(toCacheLevel(cacheLevel)), cache->getMaxCacheReservationSize(cacheLevel));
cacheLevel = 2U;
EXPECT_EQ(0U, cache->getMaxCacheReservationSize(cacheLevel));
EXPECT_EQ(mockDrm->getCacheInfo()->getMaxReservationCacheSize(toCacheLevel(cacheLevel)), cache->getMaxCacheReservationSize(cacheLevel));
cacheLevel = 1U;
EXPECT_EQ(0U, cache->getMaxCacheReservationSize(cacheLevel));
}
class L2CacheReservationFixture : public DeviceFixture {
public:
void setUp() {
DeviceFixture::setUp();
l2CacheParameters.maxSize = 1;
l2CacheParameters.maxNumRegions = 1;
l2CacheParameters.maxNumWays = 2;
auto &rootDeviceEnvironment{*neoDevice->executionEnvironment->rootDeviceEnvironments[0]};
mockDrm = new DrmMockExtended(rootDeviceEnvironment);
auto mockIoctlHelper{new MockIoctlHelper{*mockDrm}};
mockDrm->ioctlHelper.reset(mockIoctlHelper);
mockIoctlHelper->closAllocResult = CacheRegion::region3;
mockIoctlHelper->closAllocWaysResult = l2CacheParameters.maxNumWays;
mockDrm->cacheInfo.reset(new MockCacheInfo(*mockDrm->ioctlHelper, l2CacheParameters, l3CacheParameters));
rootDeviceEnvironment.osInterface.reset(new NEO::OSInterface);
rootDeviceEnvironment.osInterface->setDriverModel(std::unique_ptr<DriverModel>(mockDrm));
cache = reinterpret_cast<MockCacheReservationImpl *>(static_cast<DeviceImp *>(device)->cacheReservation.get());
ASSERT_NE(nullptr, cache);
}
void tearDown() {
DeviceFixture::tearDown();
}
CacheReservationParameters l2CacheParameters{};
CacheReservationParameters l3CacheParameters{};
MockCacheReservationImpl *cache{nullptr};
DrmMockExtended *mockDrm{nullptr};
};
using L2CacheReservationTest = Test<L2CacheReservationFixture>;
HWTEST2_F(L2CacheReservationTest, GivenCacheReservationSupportedWhenCallingSetCacheAdviceOnL2RegionReservedThenSetCacheRegionCorrectly, IsCacheReservationSupported) {
auto &productHelper = neoDevice->getProductHelper();
if (productHelper.getNumCacheRegions() == 0) {
GTEST_SKIP();
}
constexpr size_t cacheLevel{2UL};
EXPECT_TRUE(cache->reserveCache(cacheLevel, l2CacheParameters.maxSize));
constexpr uint64_t gpuAddress{0x1200};
void *ptr{reinterpret_cast<void *>(gpuAddress)};
constexpr size_t size{16384UL};
MockDrmAllocation mockAllocation{rootDeviceIndex, AllocationType::unifiedSharedMemory, MemoryPool::localMemory};
MockBufferObject bo{rootDeviceIndex, mockDrm, 3, 0, 0, 1};
mockAllocation.bufferObjects[0] = &bo;
mockAllocation.setCpuPtrAndGpuAddress(ptr, gpuAddress);
NEO::SvmAllocationData allocData{0};
allocData.size = size;
allocData.gpuAllocations.addAllocation(&mockAllocation);
device->getDriverHandle()->getSvmAllocsManager()->insertSVMAlloc(allocData);
constexpr auto l2CacheRegionId{1U + static_cast<uint32_t>(ze_cache_ext_region_t::ZE_CACHE_EXT_REGION_NON_RESERVED)};
EXPECT_TRUE(cache->setCacheAdviceImpl(ptr, size, l2CacheRegionId));
auto svmData = device->getDriverHandle()->getSvmAllocsManager()->getSVMAlloc(ptr);
ASSERT_NE(nullptr, svmData);
auto drmAllocation = static_cast<DrmAllocation *>(svmData->gpuAllocations.getGraphicsAllocation(device->getRootDeviceIndex()));
for (auto bo : drmAllocation->getBOs()) {
if (bo != nullptr) {
EXPECT_EQ(CacheRegion::region3, bo->peekCacheRegion());
EXPECT_EQ(static_cast<MockCacheReservationImpl *>(cache)->reservedL2CacheRegion, bo->peekCacheRegion());
}
}
}
} // namespace ult
} // namespace L0

View File

@@ -33,11 +33,12 @@ struct BuffersWithClMemCacheClosTests : public DrmMemoryManagerLocalMemoryPrelim
mock->memoryInfo.reset(memoryInfo);
CacheReservationParameters l2CacheParameters{};
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 1024;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
mock->cacheInfo.reset(new MockCacheInfo(*mock->getIoctlHelper(), l3CacheParameters));
mock->cacheInfo.reset(new MockCacheInfo(*mock->getIoctlHelper(), l2CacheParameters, l3CacheParameters));
auto &multiTileArchInfo = executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->getMutableHardwareInfo()->gtSystemInfo.MultiTileArchInfo;
multiTileArchInfo.TileCount = (memoryInfo->getDrmRegionInfos().size() - 1);

View File

@@ -203,8 +203,10 @@ DECLARE_DEBUG_VARIABLE(int32_t, ProgramGlobalFenceAsPostSyncOperationInComputeWa
DECLARE_DEBUG_VARIABLE(int32_t, ProgramGlobalFenceAsKernelInstructionInEUKernel, -1, "-1: default, 0: disable, 1: enable, System Memory Fence executed as kernel instruction in EU kernel")
DECLARE_DEBUG_VARIABLE(int32_t, DoNotReportTile1BscWaActive, -1, "-1: default, 0: WA Disabled, 1: WA enabled")
DECLARE_DEBUG_VARIABLE(int32_t, ForceTile0PlacementForTile1ResourcesWaActive, -1, "-1: default, 0: WA Disabled, 1: WA enabled")
DECLARE_DEBUG_VARIABLE(int32_t, ClosEnabled, -1, "-1: default, 0: disabled, 1: enabled. Enable CLOS based cache reservation")
DECLARE_DEBUG_VARIABLE(int32_t, ClosNumCacheWays, -1, "-1: default, >= 0 Number of cache ways to allocate within previously reserved CLOS regions (0-32)")
DECLARE_DEBUG_VARIABLE(int32_t, ClosEnabled, -1, "-1: default, 0: disabled, 1: enabled. Enable L3 CLOS based cache reservation")
DECLARE_DEBUG_VARIABLE(int32_t, ClosNumCacheWays, -1, "-1: default, >= 0 Number of L3 cache ways to allocate within previously reserved L3 CLOS regions (0-32)")
DECLARE_DEBUG_VARIABLE(bool, ForceStaticL2ClosReservation, false, "Makes static L2 cache ways reservation at driver init")
DECLARE_DEBUG_VARIABLE(int32_t, L2ClosNumCacheWays, -1, "-1: HW-specific, >= 0 Number of L2 cache ways to allocate within previously reserved L2 CLOS regions (0-32)")
DECLARE_DEBUG_VARIABLE(int32_t, EngineUsageHint, -1, "-1: default, >=0: engine usage value to use when creating command queue on user selected engine")
DECLARE_DEBUG_VARIABLE(int32_t, ForceBcsEngineIndex, -1, "-1: default, >=0 Copy Engine index")
DECLARE_DEBUG_VARIABLE(int32_t, Force2dImageAsArray, -1, "-1: default, 0: WA Disabled, 1: Forces surface state of 2dImage to array")

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2024 Intel Corporation
* Copyright (C) 2019-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -32,10 +32,8 @@ constexpr auto toUnderlying(EnumT scopedEnumValue) {
}
template <typename EnumT>
requires(std::is_enum_v<EnumT> && !std::is_convertible_v<EnumT, std::underlying_type_t<EnumT>>)
constexpr auto toEnum(std::underlying_type_t<EnumT> region) {
static_assert(std::is_enum_v<EnumT>);
static_assert(!std::is_convertible_v<EnumT, std::underlying_type_t<EnumT>>);
return static_cast<EnumT>(region);
}
@@ -69,15 +67,25 @@ enum class CacheRegion : uint16_t {
defaultRegion = 0,
region1,
region2,
region3,
count,
none = 0xFFFF
};
constexpr auto toCacheRegion(std::underlying_type_t<CacheRegion> region) { return toEnum<CacheRegion>(region); }
constexpr inline auto toCacheRegion(std::underlying_type_t<CacheRegion> region) {
DEBUG_BREAK_IF(region >= toUnderlying(CacheRegion::count));
return toEnum<CacheRegion>(region);
}
enum class CacheLevel : uint16_t {
defaultLevel = 0,
level2 = 2,
level3 = 3
};
constexpr inline auto toCacheLevel(std::underlying_type_t<CacheRegion> level) {
DEBUG_BREAK_IF(level == 1U);
DEBUG_BREAK_IF(level > 3U);
return toEnum<CacheLevel>(level);
}
enum class CachePolicy : uint32_t {
uncached = 0,

View File

@@ -19,22 +19,29 @@ CacheInfo::~CacheInfo() {
constexpr auto regionEnd{toUnderlying(CacheRegion::count)};
for (auto regionIndex{regionStart}; regionIndex < regionEnd; ++regionIndex) {
const auto cacheLevel{getLevelForRegion(regionIndex)};
if (reservedCacheRegionsSize[regionIndex]) {
cacheReserve.freeCache(CacheLevel::level3, toCacheRegion(regionIndex));
cacheReserve.freeCache(cacheLevel, toCacheRegion(regionIndex));
reservedCacheRegionsSize[regionIndex] = 0u;
}
}
}
CacheRegion CacheInfo::reserveRegion(size_t cacheReservationSize) {
auto &limits{l3ReservationLimits};
CacheRegion CacheInfo::reserveRegion(CacheLevel cacheLevel, size_t cacheReservationSize) {
auto &limits{getLimitsForCacheLevel(cacheLevel)};
uint16_t numWays = (limits.maxNumWays * cacheReservationSize) / limits.maxSize;
if (limits.maxSize == 0U || limits.maxNumWays == 0U || limits.maxNumRegions == 0U) {
return CacheRegion::none;
}
auto numWays{static_cast<uint16_t>((limits.maxNumWays * cacheReservationSize) / limits.maxSize)};
if (debugManager.flags.ClosNumCacheWays.get() != -1) {
numWays = debugManager.flags.ClosNumCacheWays.get();
cacheReservationSize = (numWays * limits.maxSize) / limits.maxNumWays;
}
auto regionIndex = cacheReserve.reserveCache(CacheLevel::level3, numWays);
auto regionIndex = cacheReserve.reserveCache(cacheLevel, numWays);
if (regionIndex == CacheRegion::none) {
return CacheRegion::none;
}
@@ -45,16 +52,24 @@ CacheRegion CacheInfo::reserveRegion(size_t cacheReservationSize) {
return regionIndex;
}
CacheRegion CacheInfo::freeRegion(CacheRegion regionIndex) {
CacheRegion CacheInfo::freeRegion(CacheLevel cacheLevel, CacheRegion regionIndex) {
if (regionIndex < CacheRegion::count && reservedCacheRegionsSize[toUnderlying(regionIndex)] > 0u) {
reservedCacheRegionsSize[toUnderlying(regionIndex)] = 0u;
return cacheReserve.freeCache(CacheLevel::level3, regionIndex);
return cacheReserve.freeCache(cacheLevel, regionIndex);
}
return CacheRegion::none;
}
bool CacheInfo::isRegionReserved(CacheRegion regionIndex, [[maybe_unused]] size_t expectedRegionSize) const {
auto &limits{l3ReservationLimits};
DEBUG_BREAK_IF(regionIndex == CacheRegion::defaultRegion);
DEBUG_BREAK_IF(regionIndex >= CacheRegion::count);
const auto cacheLevel{getLevelForRegion(regionIndex)};
auto &limits{getLimitsForCacheLevel(cacheLevel)};
if (limits.maxSize == 0U || limits.maxNumWays == 0U || limits.maxNumRegions == 0U) {
return false;
}
if (regionIndex < CacheRegion::count && reservedCacheRegionsSize[toUnderlying(regionIndex)]) {
if (debugManager.flags.ClosNumCacheWays.get() != -1) {
@@ -68,11 +83,15 @@ bool CacheInfo::isRegionReserved(CacheRegion regionIndex, [[maybe_unused]] size_
}
bool CacheInfo::getRegion(size_t regionSize, CacheRegion regionIndex) {
DEBUG_BREAK_IF(regionIndex >= CacheRegion::count);
if (regionIndex == CacheRegion::defaultRegion) {
return true;
}
if (!isRegionReserved(regionIndex, regionSize)) {
auto regionIdx = reserveRegion(regionSize);
const auto cacheLevel{getLevelForRegion(regionIndex)};
auto regionIdx = reserveRegion(cacheLevel, regionSize);
if (regionIdx == CacheRegion::none) {
return false;
}
@@ -81,4 +100,15 @@ bool CacheInfo::getRegion(size_t regionSize, CacheRegion regionIndex) {
return true;
}
const CacheReservationParameters &CacheInfo::getLimitsForCacheLevel(CacheLevel cacheLevel) const {
switch (cacheLevel) {
case CacheLevel::level2:
return l2ReservationLimits;
case CacheLevel::level3:
return l3ReservationLimits;
default:
UNRECOVERABLE_IF(true);
}
}
} // namespace NEO

View File

@@ -27,8 +27,9 @@ struct CacheReservationParameters {
};
struct CacheInfo : NEO::NonCopyableAndNonMovableClass {
CacheInfo(IoctlHelper &ioctlHelper, const CacheReservationParameters l3Limits)
: l3ReservationLimits{l3Limits},
CacheInfo(IoctlHelper &ioctlHelper, const CacheReservationParameters l2Limits, const CacheReservationParameters l3Limits)
: l2ReservationLimits{l2Limits},
l3ReservationLimits{l3Limits},
cacheReserve{ioctlHelper} {
reservedCacheRegionsSize.fill(0UL);
@@ -36,29 +37,26 @@ struct CacheInfo : NEO::NonCopyableAndNonMovableClass {
MOCKABLE_VIRTUAL ~CacheInfo();
size_t getMaxReservationCacheSize() const {
const auto &limits{l3ReservationLimits};
return limits.maxSize;
size_t getMaxReservationCacheSize(CacheLevel cacheLevel) const {
return getLimitsForCacheLevel(cacheLevel).maxSize;
}
size_t getMaxReservationNumCacheRegions() const {
const auto &limits{l3ReservationLimits};
return limits.maxNumRegions;
size_t getMaxReservationNumCacheRegions(CacheLevel cacheLevel) const {
return getLimitsForCacheLevel(cacheLevel).maxNumRegions;
}
size_t getMaxReservationNumWays() const {
const auto &limits{l3ReservationLimits};
return limits.maxNumWays;
size_t getMaxReservationNumWays(CacheLevel cacheLevel) const {
return getLimitsForCacheLevel(cacheLevel).maxNumWays;
}
CacheRegion reserveCacheRegion(size_t cacheReservationSize) {
CacheRegion reserveCacheRegion(CacheLevel cacheLevel, size_t cacheReservationSize) {
std::unique_lock<SpinLock> lock{mtx};
return reserveRegion(cacheReservationSize);
return reserveRegion(cacheLevel, cacheReservationSize);
}
CacheRegion freeCacheRegion(CacheRegion regionIndex) {
CacheRegion freeCacheRegion(CacheLevel cacheLevel, CacheRegion regionIndex) {
std::unique_lock<SpinLock> lock{mtx};
return freeRegion(regionIndex);
return freeRegion(cacheLevel, regionIndex);
}
MOCKABLE_VIRTUAL bool getCacheRegion(size_t regionSize, CacheRegion regionIndex) {
@@ -66,14 +64,26 @@ struct CacheInfo : NEO::NonCopyableAndNonMovableClass {
return getRegion(regionSize, regionIndex);
}
protected:
CacheRegion reserveRegion(size_t cacheReservationSize);
CacheRegion freeRegion(CacheRegion regionIndex);
bool isRegionReserved(CacheRegion regionIndex, [[maybe_unused]] size_t regionSize) const;
bool getRegion(size_t regionSize, CacheRegion regionIndex);
CacheLevel getLevelForRegion(CacheRegion regionIndex) const {
DEBUG_BREAK_IF(regionIndex == CacheRegion::defaultRegion);
DEBUG_BREAK_IF(regionIndex >= CacheRegion::count);
return (regionIndex == CacheRegion::region3 ? CacheLevel::level2 : CacheLevel::level3);
}
CacheLevel getLevelForRegion(uint16_t regionIndex) const {
return getLevelForRegion(toCacheRegion(regionIndex));
}
protected:
CacheReservationParameters l3ReservationLimits;
CacheRegion reserveRegion(CacheLevel cacheLevel, size_t cacheReservationSize);
CacheRegion freeRegion(CacheLevel cacheLevel, CacheRegion regionIndex);
bool isRegionReserved(CacheRegion regionIndex, [[maybe_unused]] size_t regionSize) const;
bool getRegion(size_t regionSize, CacheRegion regionIndex);
const CacheReservationParameters &getLimitsForCacheLevel(CacheLevel cacheLevel) const;
protected:
CacheReservationParameters l2ReservationLimits{};
CacheReservationParameters l3ReservationLimits{};
ClosCacheReservation cacheReserve;
std::array<size_t, toUnderlying(CacheRegion::count)> reservedCacheRegionsSize;
SpinLock mtx;

View File

@@ -166,7 +166,10 @@ bool DrmAllocation::setCacheRegion(Drm *drm, CacheRegion regionIndex) {
return false;
}
auto regionSize = (cacheInfo->getMaxReservationNumCacheRegions() > 0) ? cacheInfo->getMaxReservationCacheSize() / cacheInfo->getMaxReservationNumCacheRegions() : 0;
const auto cacheLevel{cacheInfo->getLevelForRegion(regionIndex)};
const auto maxCacheRegions{cacheInfo->getMaxReservationNumCacheRegions(cacheLevel)};
const auto maxReservationCacheSize{cacheInfo->getMaxReservationCacheSize(cacheLevel)};
const auto regionSize{(maxCacheRegions > 0) ? maxReservationCacheSize / maxCacheRegions : 0};
if (regionSize == 0) {
return false;
}

View File

@@ -1018,15 +1018,36 @@ void Drm::setupSystemInfo(HardwareInfo *hwInfo, SystemInfo *sysInfo) {
void Drm::setupCacheInfo(const HardwareInfo &hwInfo) {
auto &productHelper = rootDeviceEnvironment.getHelper<ProductHelper>();
if (debugManager.flags.ForceStaticL2ClosReservation.get()) {
if (debugManager.flags.L2ClosNumCacheWays.get() == -1) {
debugManager.flags.L2ClosNumCacheWays.set(2U);
}
}
auto getL2CacheReservationLimits{[&productHelper]() {
CacheReservationParameters out{};
if (productHelper.getNumCacheRegions() == 0) {
return out;
}
if (auto numCacheWays{debugManager.flags.L2ClosNumCacheWays.get()}; numCacheWays != -1) {
out.maxSize = 1U;
out.maxNumRegions = 1U;
out.maxNumWays = static_cast<uint16_t>(numCacheWays);
return out;
}
return out;
}};
auto getL3CacheReservationLimits{[&hwInfo, &productHelper]() {
CacheReservationParameters out{};
if (debugManager.flags.ClosEnabled.get() == 0 || productHelper.getNumCacheRegions() == 0) {
return out;
}
constexpr uint16_t totalMaxNumWays = 32;
constexpr uint16_t globalReservationLimit = 16;
constexpr uint16_t clientReservationLimit = 8;
constexpr uint16_t totalMaxNumWays = 32U;
constexpr uint16_t globalReservationLimit = 16U;
constexpr uint16_t clientReservationLimit = 8U;
const size_t totalCacheSize = hwInfo.gtSystemInfo.L3CacheSizeInKb * MemoryConstants::kiloByte;
out.maxNumWays = std::min(globalReservationLimit, clientReservationLimit);
@@ -1036,7 +1057,12 @@ void Drm::setupCacheInfo(const HardwareInfo &hwInfo) {
return out;
}};
this->cacheInfo.reset(new CacheInfo(*ioctlHelper, getL3CacheReservationLimits()));
this->cacheInfo.reset(new CacheInfo(*ioctlHelper, getL2CacheReservationLimits(), getL3CacheReservationLimits()));
if (debugManager.flags.ForceStaticL2ClosReservation.get()) {
[[maybe_unused]] bool isReserved{this->cacheInfo->getCacheRegion(getL2CacheReservationLimits().maxSize, CacheRegion::region3)};
DEBUG_BREAK_IF(!isReserved);
}
}
void Drm::getPrelimVersion(std::string &prelimVersion) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Intel Corporation
* Copyright (C) 2022-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -102,7 +102,8 @@ int DrmMockPrelimContext::handlePrelimRequest(DrmIoctl request, void *arg) {
if (cacheReserveArg->clos_index > closIndex) {
return EINVAL;
}
auto maxReservationNumWays = cacheInfo ? cacheInfo->getMaxReservationNumWays() : maxNumWays;
const auto cacheLevel{toCacheLevel(cacheReserveArg->cache_level)};
auto maxReservationNumWays = cacheInfo ? cacheInfo->getMaxReservationNumWays(cacheLevel) : maxNumWays;
if (cacheReserveArg->num_ways > maxReservationNumWays) {
return EINVAL;
}

View File

@@ -20,6 +20,7 @@ struct ContextParamEnginesI915 {
class DrmQueryMock : public DrmMock {
public:
using Drm::ioctlHelper;
using Drm::rootDeviceEnvironment;
DrmQueryMock(RootDeviceEnvironment &rootDeviceEnvironment);

View File

@@ -42,6 +42,10 @@ class MockIoctlHelper : public IoctlHelperPrelim20 {
ADDMETHOD_CONST_NOBASE(getNumMediaEncoders, uint32_t, 0, ());
ADDMETHOD_NOBASE(queryDeviceParams, bool, true, (uint32_t *, uint16_t *));
ADDMETHOD_NOBASE(closAlloc, CacheRegion, CacheRegion::none, (CacheLevel));
ADDMETHOD_NOBASE(closFree, CacheRegion, CacheRegion::none, (CacheRegion));
ADDMETHOD_NOBASE(closAllocWays, uint16_t, 0U, (CacheRegion, uint16_t, uint16_t));
int getDrmParamValue(DrmParam drmParam) const override {
if (drmParam == DrmParam::memoryClassSystem) {
return memoryClassSystem;

View File

@@ -14,24 +14,31 @@ namespace NEO {
struct MockCacheInfo : public CacheInfo {
using CacheInfo::freeRegion;
using CacheInfo::getMaxReservationCacheSize;
using CacheInfo::getRegion;
using CacheInfo::isRegionReserved;
using CacheInfo::l2ReservationLimits;
using CacheInfo::l3ReservationLimits;
using CacheInfo::reservedCacheRegionsSize;
using CacheInfo::reserveRegion;
MockCacheInfo(IoctlHelper &ioctlHelper, CacheReservationParameters l3CacheReservationLimits)
: CacheInfo(ioctlHelper, l3CacheReservationLimits) {}
MockCacheInfo(IoctlHelper &ioctlHelper, CacheReservationParameters l2CacheReservationLimits, CacheReservationParameters l3CacheReservationLimits)
: CacheInfo(ioctlHelper, l2CacheReservationLimits, l3CacheReservationLimits) {}
~MockCacheInfo() override = default;
bool getCacheRegion(size_t regionSize, CacheRegion regionIndex) override {
if (regionIndex >= CacheRegion::count) {
switch (regionIndex) {
case CacheRegion::defaultRegion:
case CacheRegion::region1:
case CacheRegion::region2:
UNRECOVERABLE_IF(l3ReservationLimits.maxNumRegions == 0U);
return (regionSize <= (l3ReservationLimits.maxSize / l3ReservationLimits.maxNumRegions));
case CacheRegion::region3:
return CacheInfo::getCacheRegion(regionSize, regionIndex);
default:
return false;
}
if (regionSize > (l3ReservationLimits.maxSize / l3ReservationLimits.maxNumRegions)) {
return false;
}
return true;
}
};

View File

@@ -124,8 +124,9 @@ int DrmMockExtended::handleRemainingRequests(DrmIoctl request, void *arg) {
if (cacheReserveArg->clos_index > closIndex) {
return EINVAL;
}
const auto cacheLevel{toCacheLevel(cacheReserveArg->cache_level)};
auto cacheInfo = this->getCacheInfo();
auto maxReservationNumWays = cacheInfo ? cacheInfo->getMaxReservationNumWays() : maxNumWays;
auto maxReservationNumWays = cacheInfo ? cacheInfo->getMaxReservationNumWays(cacheLevel) : maxNumWays;
if (cacheReserveArg->num_ways > maxReservationNumWays) {
return EINVAL;
}

View File

@@ -416,6 +416,8 @@ ForceTile0PlacementForTile1ResourcesWaActive = -1
EnableFrontEndTracking = -1
ClosEnabled = -1
ClosNumCacheWays = -1
L2ClosNumCacheWays = -1
ForceStaticL2ClosReservation = 0
EngineUsageHint = -1
AddStatePrefetchCmdToMemoryPrefetchAPI = -1
UpdateCrossThreadDataSize = 0

View File

@@ -11,28 +11,52 @@
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/default_hw_info.h"
#include "shared/test/common/libult/linux/drm_query_mock.h"
#include "shared/test/common/mocks/linux/mock_ioctl_helper.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/os_interface/linux/drm_mock_cache_info.h"
#include "gtest/gtest.h"
#include "shared/test/common/test_macros/test.h"
using namespace NEO;
TEST(DrmCacheInfoTest, givenCacheRegionsExistsWhenCallingSetUpCacheInfoThenCacheInfoIsCreatedAndReturnsMaxReservationCacheLimits) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
struct DrmCacheInfoFixture {
static constexpr uint16_t maxNumCacheWays{32};
void setUp() {
executionEnvironment.reset(new MockExecutionEnvironment{});
drm.reset(new DrmQueryMock{*executionEnvironment->rootDeviceEnvironments[0]});
l2CacheParameters.maxSize = 1;
l2CacheParameters.maxNumRegions = 1;
l2CacheParameters.maxNumWays = 2;
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = maxNumCacheWays;
}
void tearDown() {
}
std::unique_ptr<MockExecutionEnvironment> executionEnvironment{nullptr};
std::unique_ptr<DrmQueryMock> drm{nullptr};
CacheReservationParameters l2CacheParameters{};
CacheReservationParameters l3CacheParameters{};
};
using DrmCacheInfoTest = Test<DrmCacheInfoFixture>;
TEST_F(DrmCacheInfoTest, givenCacheRegionsExistsWhenCallingSetUpCacheInfoThenCacheInfoIsCreatedAndReturnsMaxReservationCacheLimits) {
auto &productHelper = executionEnvironment->rootDeviceEnvironments[0]->getHelper<ProductHelper>();
drm.setupCacheInfo(*defaultHwInfo.get());
drm->setupCacheInfo(*defaultHwInfo.get());
auto cacheInfo = drm.getCacheInfo();
auto cacheInfo = drm->getCacheInfo();
EXPECT_NE(nullptr, cacheInfo);
constexpr auto cacheLevel{CacheLevel::level3};
if (productHelper.getNumCacheRegions() == 0) {
EXPECT_EQ(0u, cacheInfo->getMaxReservationCacheSize());
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumCacheRegions());
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumWays());
EXPECT_EQ(0u, cacheInfo->getMaxReservationCacheSize(cacheLevel));
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumCacheRegions(cacheLevel));
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumWays(cacheLevel));
} else {
const GT_SYSTEM_INFO *gtSysInfo = &defaultHwInfo->gtSystemInfo;
constexpr uint16_t maxNumWays = 32;
@@ -43,152 +67,237 @@ TEST(DrmCacheInfoTest, givenCacheRegionsExistsWhenCallingSetUpCacheInfoThenCache
const size_t maxReservationCacheSize = (totalCacheSize * maxReservationNumWays) / maxNumWays;
const size_t maxReservationNumCacheRegions = productHelper.getNumCacheRegions() - 1;
EXPECT_EQ(maxReservationCacheSize, cacheInfo->getMaxReservationCacheSize());
EXPECT_EQ(maxReservationNumCacheRegions, cacheInfo->getMaxReservationNumCacheRegions());
EXPECT_EQ(maxReservationNumWays, cacheInfo->getMaxReservationNumWays());
EXPECT_EQ(maxReservationCacheSize, cacheInfo->getMaxReservationCacheSize(cacheLevel));
EXPECT_EQ(maxReservationNumCacheRegions, cacheInfo->getMaxReservationNumCacheRegions(cacheLevel));
EXPECT_EQ(maxReservationNumWays, cacheInfo->getMaxReservationNumWays(cacheLevel));
}
}
TEST(DrmCacheInfoTest, givenDebugFlagSetWhenCallingSetUpCacheInfoThenCacheInfoIsCreatedWithoutValues) {
TEST_F(DrmCacheInfoTest, givenDebugFlagSetWhenCallingSetUpCacheInfoThenCacheInfoIsCreatedWithoutValues) {
DebugManagerStateRestore restorer;
debugManager.flags.ClosEnabled.set(0);
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
drm.setupCacheInfo(*defaultHwInfo.get());
EXPECT_NE(nullptr, drm.getCacheInfo());
auto cacheInfo = drm.getCacheInfo();
drm->setupCacheInfo(*defaultHwInfo.get());
EXPECT_NE(nullptr, drm->getCacheInfo());
auto cacheInfo = drm->getCacheInfo();
EXPECT_EQ(0u, cacheInfo->getMaxReservationCacheSize());
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumCacheRegions());
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumWays());
constexpr auto cacheLevel3{CacheLevel::level3};
EXPECT_EQ(0u, cacheInfo->getMaxReservationCacheSize(cacheLevel3));
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumCacheRegions(cacheLevel3));
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumWays(cacheLevel3));
constexpr auto cacheLevel2{CacheLevel::level2};
EXPECT_EQ(0u, cacheInfo->getMaxReservationCacheSize(cacheLevel2));
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumCacheRegions(cacheLevel2));
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumWays(cacheLevel2));
}
TEST(DrmCacheInfoTest, givenCacheInfoCreatedWhenGetCacheRegionSucceedsToReserveCacheRegionThenReturnTrue) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
TEST_F(DrmCacheInfoTest, givenDebugFlagSetWhenCallingSetUpCacheInfoThenL2CacheInfoIsCreatedAccordingly) {
DebugManagerStateRestore restorer;
debugManager.flags.L2ClosNumCacheWays.set(2);
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
CacheInfo cacheInfo(*drm.getIoctlHelper(), l3CacheParameters);
size_t cacheReservationSize = cacheInfo.getMaxReservationCacheSize();
drm->setupCacheInfo(*defaultHwInfo.get());
EXPECT_NE(nullptr, drm->getCacheInfo());
auto cacheInfo = drm->getCacheInfo();
auto &productHelper = executionEnvironment->rootDeviceEnvironments[0]->getHelper<ProductHelper>();
constexpr auto cacheLevel2{CacheLevel::level2};
if (productHelper.getNumCacheRegions() > 0) {
EXPECT_EQ(1u, cacheInfo->getMaxReservationCacheSize(cacheLevel2));
EXPECT_EQ(1u, cacheInfo->getMaxReservationNumCacheRegions(cacheLevel2));
EXPECT_EQ(2u, cacheInfo->getMaxReservationNumWays(cacheLevel2));
} else {
EXPECT_EQ(0u, cacheInfo->getMaxReservationCacheSize(cacheLevel2));
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumCacheRegions(cacheLevel2));
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumWays(cacheLevel2));
}
}
TEST_F(DrmCacheInfoTest, givenDebugFlagSetWhenCallingSetUpCacheInfoThenL2CacheInfoIsCreatedAndRegionReserved) {
constexpr auto staticL2CacheReservationSize{1U};
constexpr auto staticL2CacheNumWays{2U};
DebugManagerStateRestore restorer;
debugManager.flags.ForceStaticL2ClosReservation.set(true);
auto mockIoctlHelper{new MockIoctlHelper{*drm}};
drm->ioctlHelper.reset(mockIoctlHelper);
mockIoctlHelper->closAllocResult = CacheRegion::region3;
mockIoctlHelper->closAllocWaysResult = staticL2CacheNumWays;
drm->setupCacheInfo(*defaultHwInfo.get());
EXPECT_NE(nullptr, drm->getCacheInfo());
auto &productHelper = executionEnvironment->rootDeviceEnvironments[0]->getHelper<ProductHelper>();
auto *mockCacheInfo{static_cast<MockCacheInfo *>(drm->getCacheInfo())};
if (productHelper.getNumCacheRegions() > 0U) {
EXPECT_TRUE(mockCacheInfo->isRegionReserved(CacheRegion::region3, staticL2CacheReservationSize));
} else {
EXPECT_FALSE(mockCacheInfo->isRegionReserved(CacheRegion::region3, staticL2CacheReservationSize));
}
}
TEST_F(DrmCacheInfoTest, givenCacheInfoCreatedWhenGetCacheRegionSucceedsToReserveL3CacheRegionThenReturnTrue) {
CacheInfo cacheInfo(*drm->getIoctlHelper(), l2CacheParameters, l3CacheParameters);
constexpr auto cacheLevel{CacheLevel::level3};
size_t cacheReservationSize = cacheInfo.getMaxReservationCacheSize(cacheLevel);
EXPECT_TRUE(cacheInfo.getCacheRegion(cacheReservationSize, CacheRegion::region1));
EXPECT_EQ(CacheRegion::region1, cacheInfo.freeCacheRegion(CacheRegion::region1));
EXPECT_EQ(CacheRegion::region1, cacheInfo.freeCacheRegion(cacheLevel, CacheRegion::region1));
}
TEST(DrmCacheInfoTest, givenCacheInfoCreatedWhenGetCacheRegionFailsToReserveCacheRegionThenReturnFalse) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
TEST_F(DrmCacheInfoTest, givenCacheInfoCreatedWhenGetCacheRegionFailsToReserveCacheRegionThenReturnFalse) {
CacheInfo cacheInfo(*drm->getIoctlHelper(), l2CacheParameters, l3CacheParameters);
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
CacheInfo cacheInfo(*drm.getIoctlHelper(), l3CacheParameters);
size_t cacheReservationSize = cacheInfo.getMaxReservationCacheSize();
constexpr auto cacheLevel{CacheLevel::level3};
size_t cacheReservationSize = cacheInfo.getMaxReservationCacheSize(cacheLevel);
drm.context.closIndex = 0xFFFF;
drm->context.closIndex = 0xFFFF;
EXPECT_FALSE(cacheInfo.getCacheRegion(cacheReservationSize, CacheRegion::region1));
EXPECT_EQ(CacheRegion::none, cacheInfo.freeCacheRegion(CacheRegion::region1));
EXPECT_EQ(CacheRegion::none, cacheInfo.freeCacheRegion(cacheLevel, CacheRegion::region1));
}
TEST(DrmCacheInfoTest, givenCacheInfoWithReservedCacheRegionWhenGetCacheRegionIsCalledForReservedCacheRegionThenReturnTrue) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
TEST_F(DrmCacheInfoTest, givenCacheInfoWithAnyLimitParameterEqualToZeroWhenReservationIsTriedThenCacheRegionNoneIsReturned) {
MockCacheInfo cacheInfo(*drm->getIoctlHelper(), l2CacheParameters, l3CacheParameters);
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
CacheInfo cacheInfo(*drm.getIoctlHelper(), l3CacheParameters);
size_t cacheReservationSize = cacheInfo.getMaxReservationCacheSize();
constexpr auto cacheLevel{CacheLevel::level3};
size_t cacheReservationSize = cacheInfo.getMaxReservationCacheSize(cacheLevel);
EXPECT_EQ(CacheRegion::region1, cacheInfo.reserveCacheRegion(cacheReservationSize));
const auto maxSizeOrig = cacheInfo.l3ReservationLimits.maxSize;
cacheInfo.l3ReservationLimits.maxSize = 0;
EXPECT_EQ(CacheRegion::none, cacheInfo.reserveCacheRegion(cacheLevel, cacheReservationSize));
cacheInfo.l3ReservationLimits.maxSize = maxSizeOrig;
const auto maxNumWaysOrig = cacheInfo.l3ReservationLimits.maxNumWays;
cacheInfo.l3ReservationLimits.maxNumWays = 0;
EXPECT_EQ(CacheRegion::none, cacheInfo.reserveCacheRegion(cacheLevel, cacheReservationSize));
cacheInfo.l3ReservationLimits.maxNumWays = maxNumWaysOrig;
const auto maxNumRegionsOrig = cacheInfo.l3ReservationLimits.maxNumRegions;
cacheInfo.l3ReservationLimits.maxNumRegions = 0;
EXPECT_EQ(CacheRegion::none, cacheInfo.reserveCacheRegion(cacheLevel, cacheReservationSize));
cacheInfo.l3ReservationLimits.maxNumRegions = maxNumRegionsOrig;
}
TEST_F(DrmCacheInfoTest, givenCacheInfoWithReservedCacheRegionWhenGetCacheRegionIsCalledForReservedCacheRegionThenReturnTrue) {
CacheInfo cacheInfo(*drm->getIoctlHelper(), l2CacheParameters, l3CacheParameters);
constexpr auto cacheLevel{CacheLevel::level3};
size_t cacheReservationSize = cacheInfo.getMaxReservationCacheSize(cacheLevel);
EXPECT_EQ(CacheRegion::region1, cacheInfo.reserveCacheRegion(cacheLevel, cacheReservationSize));
EXPECT_TRUE(cacheInfo.getCacheRegion(cacheReservationSize, CacheRegion::region1));
EXPECT_EQ(CacheRegion::region1, cacheInfo.freeCacheRegion(CacheRegion::region1));
EXPECT_EQ(CacheRegion::region1, cacheInfo.freeCacheRegion(cacheLevel, CacheRegion::region1));
}
TEST(DrmCacheInfoTest, givenCacheInfoCreatedWhenGetCacheRegionIsCalledForReservableRegionsWithRegionSizesInverselyProportionalToNumCacheRegionsThenReturnTrue) {
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
TEST_F(DrmCacheInfoTest, givenCacheInfoCreatedWhenGetCacheRegionIsCalledForReservableRegionsWithRegionSizesInverselyProportionalToNumCacheRegionsThenReturnTrue) {
CacheInfo cacheInfo(*drm->getIoctlHelper(), l2CacheParameters, l3CacheParameters);
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
CacheInfo cacheInfo(*drm.getIoctlHelper(), l3CacheParameters);
size_t regionSize = cacheInfo.getMaxReservationCacheSize() / cacheInfo.getMaxReservationNumCacheRegions();
constexpr auto cacheLevel{CacheLevel::level3};
size_t regionSize = cacheInfo.getMaxReservationCacheSize(cacheLevel) / cacheInfo.getMaxReservationNumCacheRegions(cacheLevel);
EXPECT_TRUE(cacheInfo.getCacheRegion(regionSize, CacheRegion::region1));
EXPECT_TRUE(cacheInfo.getCacheRegion(regionSize, CacheRegion::region2));
EXPECT_EQ(CacheRegion::region2, cacheInfo.freeCacheRegion(CacheRegion::region2));
EXPECT_EQ(CacheRegion::region1, cacheInfo.freeCacheRegion(CacheRegion::region1));
EXPECT_EQ(CacheRegion::region2, cacheInfo.freeCacheRegion(cacheLevel, CacheRegion::region2));
EXPECT_EQ(CacheRegion::region1, cacheInfo.freeCacheRegion(cacheLevel, CacheRegion::region1));
}
TEST(DrmCacheInfoTest, givenCacheInfoWhenSpecificNumCacheWaysIsRequestedThenReserveAppropriateCacheSize) {
constexpr uint16_t maxNumCacheWays = 32;
TEST_F(DrmCacheInfoTest, givenCacheInfoWhenSpecificNumCacheWaysIsRequestedThenReserveAppropriateCacheSize) {
DebugManagerStateRestore restorer;
debugManager.flags.ClosNumCacheWays.set(maxNumCacheWays / 2);
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
MockCacheInfo cacheInfo(*drm->getIoctlHelper(), l2CacheParameters, l3CacheParameters);
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = maxNumCacheWays;
MockCacheInfo cacheInfo(*drm.getIoctlHelper(), l3CacheParameters);
size_t maxReservationCacheSize = cacheInfo.getMaxReservationCacheSize();
constexpr auto cacheLevel{CacheLevel::level3};
size_t maxReservationCacheSize = cacheInfo.getMaxReservationCacheSize(cacheLevel);
EXPECT_EQ(CacheRegion::region1, cacheInfo.reserveCacheRegion(maxReservationCacheSize));
EXPECT_EQ(CacheRegion::region1, cacheInfo.reserveCacheRegion(cacheLevel, maxReservationCacheSize));
EXPECT_TRUE(cacheInfo.isRegionReserved(CacheRegion::region1, maxReservationCacheSize));
auto expectedRegionSize = cacheInfo.reservedCacheRegionsSize[toUnderlying(CacheRegion::region1)];
EXPECT_EQ(maxReservationCacheSize / 2, expectedRegionSize);
EXPECT_EQ(CacheRegion::region1, cacheInfo.freeCacheRegion(CacheRegion::region1));
EXPECT_EQ(CacheRegion::region1, cacheInfo.freeCacheRegion(cacheLevel, CacheRegion::region1));
}
TEST(DrmCacheInfoTest, givenCacheInfoWhenNumCacheWaysIsExceededThenDontReserveCacheRegion) {
constexpr uint16_t maxNumCacheWays = 32;
TEST_F(DrmCacheInfoTest, givenCacheInfoWhenNumCacheWaysIsExceededThenDontReserveCacheRegion) {
MockCacheInfo cacheInfo(*drm->getIoctlHelper(), l2CacheParameters, l3CacheParameters);
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
constexpr auto cacheLevel{CacheLevel::level3};
size_t maxReservationCacheSize = cacheInfo.getMaxReservationCacheSize(cacheLevel);
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = maxNumCacheWays;
MockCacheInfo cacheInfo(*drm.getIoctlHelper(), l3CacheParameters);
size_t maxReservationCacheSize = cacheInfo.getMaxReservationCacheSize();
EXPECT_EQ(CacheRegion::region1, cacheInfo.reserveCacheRegion(maxReservationCacheSize));
EXPECT_EQ(CacheRegion::region1, cacheInfo.reserveCacheRegion(cacheLevel, maxReservationCacheSize));
EXPECT_TRUE(cacheInfo.isRegionReserved(CacheRegion::region1, maxReservationCacheSize));
EXPECT_EQ(CacheRegion::none, cacheInfo.reserveCacheRegion(maxReservationCacheSize));
EXPECT_EQ(CacheRegion::none, cacheInfo.reserveCacheRegion(cacheLevel, maxReservationCacheSize));
EXPECT_FALSE(cacheInfo.isRegionReserved(CacheRegion::region2, maxReservationCacheSize));
}
TEST(DrmCacheInfoTest, givenCacheInfoCreatedWhenFreeCacheRegionIsCalledForNonReservedRegionThenItFails) {
constexpr uint16_t maxNumCacheWays = 32;
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = maxNumCacheWays;
MockCacheInfo cacheInfo(*drm.getIoctlHelper(), l3CacheParameters);
TEST_F(DrmCacheInfoTest, givenCacheInfoCreatedWhenFreeCacheRegionIsCalledForNonReservedRegionThenItFails) {
MockCacheInfo cacheInfo(*drm->getIoctlHelper(), l2CacheParameters, l3CacheParameters);
constexpr auto cacheLevel{CacheLevel::level3};
cacheInfo.reservedCacheRegionsSize[toUnderlying(CacheRegion::region1)] = MemoryConstants::kiloByte;
EXPECT_EQ(CacheRegion::none, cacheInfo.freeCacheRegion(CacheRegion::region1));
EXPECT_EQ(CacheRegion::none, cacheInfo.freeCacheRegion(cacheLevel, CacheRegion::region1));
}
TEST_F(DrmCacheInfoTest, givenCacheInfoCreatedWhenPassingRegionIndexThenCorrectCacheLevelReturned) {
auto *cacheInfo{new MockCacheInfo(*drm->getIoctlHelper(), l2CacheParameters, l3CacheParameters)};
drm->cacheInfo.reset(cacheInfo);
EXPECT_EQ(CacheLevel::level3, cacheInfo->getLevelForRegion(CacheRegion::region1));
EXPECT_EQ(CacheLevel::level3, cacheInfo->getLevelForRegion(CacheRegion::region2));
EXPECT_EQ(CacheLevel::level2, cacheInfo->getLevelForRegion(CacheRegion::region3));
}
TEST_F(DrmCacheInfoTest, givenCacheInfoCreatedWhenAnyLevelLimitIsZeroThenNoRegionCanBeReserved) {
constexpr auto anyNonZeroValue{42U};
auto *cacheInfo{new MockCacheInfo(*drm->getIoctlHelper(), l2CacheParameters, l3CacheParameters)};
drm->cacheInfo.reset(cacheInfo);
l2CacheParameters.maxSize = 0U;
EXPECT_EQ(CacheRegion::none, cacheInfo->reserveCacheRegion(CacheLevel::level2, anyNonZeroValue));
EXPECT_FALSE(cacheInfo->isRegionReserved(CacheRegion::region3, anyNonZeroValue));
l2CacheParameters.maxSize = anyNonZeroValue;
l2CacheParameters.maxNumWays = 0U;
EXPECT_EQ(CacheRegion::none, cacheInfo->reserveCacheRegion(CacheLevel::level2, anyNonZeroValue));
EXPECT_FALSE(cacheInfo->isRegionReserved(CacheRegion::region3, anyNonZeroValue));
l2CacheParameters.maxNumWays = anyNonZeroValue;
l2CacheParameters.maxNumRegions = 0U;
EXPECT_EQ(CacheRegion::none, cacheInfo->reserveCacheRegion(CacheLevel::level2, anyNonZeroValue));
EXPECT_FALSE(cacheInfo->isRegionReserved(CacheRegion::region3, anyNonZeroValue));
}
TEST_F(DrmCacheInfoTest, givenCacheInfoCreatedWhenGetCacheRegionSucceedsToReserveL2CacheRegionThenReturnTrue) {
DebugManagerStateRestore restorer;
debugManager.flags.L2ClosNumCacheWays.set(2);
MockIoctlHelper ioctlHelper{*drm};
auto *cacheInfo{new MockCacheInfo(ioctlHelper, l2CacheParameters, l3CacheParameters)};
drm->cacheInfo.reset(cacheInfo);
constexpr auto cacheLevel{CacheLevel::level2};
size_t cacheReservationSize = cacheInfo->getMaxReservationCacheSize(cacheLevel);
ioctlHelper.closAllocResult = CacheRegion::region3;
ioctlHelper.closAllocWaysResult = l2CacheParameters.maxNumWays;
EXPECT_TRUE(cacheInfo->getCacheRegion(cacheReservationSize, CacheRegion::region3));
EXPECT_EQ(cacheInfo->reservedCacheRegionsSize[toUnderlying(CacheRegion::region3)], cacheReservationSize);
EXPECT_EQ(ioctlHelper.closAllocWaysCalled, 1U);
ioctlHelper.closFreeResult = CacheRegion::region3;
EXPECT_EQ(cacheInfo->freeCacheRegion(cacheLevel, CacheRegion::region3), CacheRegion::region3);
EXPECT_EQ(cacheInfo->reservedCacheRegionsSize[toUnderlying(CacheRegion::region3)], 0U);
EXPECT_EQ(cacheInfo->freeCacheRegion(cacheLevel, CacheRegion::region3), CacheRegion::none);
EXPECT_EQ(ioctlHelper.closAllocCalled, 1U);
EXPECT_EQ(ioctlHelper.closAllocWaysCalled, 2U);
EXPECT_EQ(ioctlHelper.closFreeCalled, 1U);
}

View File

@@ -4944,11 +4944,13 @@ TEST_F(DrmAllocationTests, givenDrmAllocationWhenDefaultCacheInfoIsAvailableThen
TEST_F(DrmAllocationTests, givenDrmAllocationWhenCacheRegionIsNotSetThenReturnFalse) {
const uint32_t rootDeviceIndex = 0u;
DrmMock drm(*executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]);
CacheReservationParameters l2CacheParameters{};
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
drm.cacheInfo.reset(new MockCacheInfo(*drm.getIoctlHelper(), l3CacheParameters));
drm.cacheInfo.reset(new MockCacheInfo(*drm.getIoctlHelper(), l2CacheParameters, l3CacheParameters));
MockDrmAllocation allocation(rootDeviceIndex, AllocationType::buffer, MemoryPool::localMemory);
@@ -4960,11 +4962,12 @@ TEST_F(DrmAllocationTests, givenDrmAllocationWhenCacheRegionIsSetSuccessfullyThe
DrmMock drm(*executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]);
drm.queryAndSetVmBindPatIndexProgrammingSupport();
CacheReservationParameters l2CacheParameters{};
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
drm.cacheInfo.reset(new MockCacheInfo(*drm.getIoctlHelper(), l3CacheParameters));
drm.cacheInfo.reset(new MockCacheInfo(*drm.getIoctlHelper(), l2CacheParameters, l3CacheParameters));
MockDrmAllocation allocation(rootDeviceIndex, AllocationType::buffer, MemoryPool::localMemory);
auto &productHelper = executionEnvironment->rootDeviceEnvironments[0]->getHelper<ProductHelper>();
@@ -4982,11 +4985,12 @@ TEST_F(DrmAllocationTests, givenDrmAllocationWhenCacheRegionIsSetSuccessfullyThe
DrmMock drm(*executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]);
drm.queryAndSetVmBindPatIndexProgrammingSupport();
CacheReservationParameters l2CacheParameters{};
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
drm.cacheInfo.reset(new MockCacheInfo(*drm.getIoctlHelper(), l3CacheParameters));
drm.cacheInfo.reset(new MockCacheInfo(*drm.getIoctlHelper(), l2CacheParameters, l3CacheParameters));
MockBufferObject bo(rootDeviceIndex, &drm, 3, 0, 0, 1);
MockDrmAllocation allocation(rootDeviceIndex, AllocationType::buffer, MemoryPool::localMemory);
@@ -5143,11 +5147,12 @@ TEST_F(DrmMemoryManagerTest, givenDrmAllocationWithHostPtrWhenItIsCreatedWithCac
mock->ioctlExpected.total = -1;
auto drm = static_cast<DrmMockCustom *>(executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->osInterface->getDriverModel()->as<Drm>());
CacheReservationParameters l2CacheParameters{};
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
drm->cacheInfo.reset(new MockCacheInfo(*drm->getIoctlHelper(), l3CacheParameters));
drm->cacheInfo.reset(new MockCacheInfo(*drm->getIoctlHelper(), l2CacheParameters, l3CacheParameters));
auto ptr = reinterpret_cast<void *>(0x1000);
auto size = MemoryConstants::pageSize;

View File

@@ -1294,11 +1294,12 @@ TEST_F(DrmMemoryOperationsHandlerBindTest, givenClosEnabledAndAllocationToBeCach
auto osContext = memoryManager->createAndRegisterOsContext(csr.get(), EngineDescriptorHelper::getDefaultDescriptor());
csr->setupContext(*osContext);
CacheReservationParameters l2CacheParameters{};
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 64 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
mock->cacheInfo.reset(new CacheInfo(*mock->getIoctlHelper(), l3CacheParameters));
mock->cacheInfo.reset(new CacheInfo(*mock->getIoctlHelper(), l2CacheParameters, l3CacheParameters));
auto &productHelper = executionEnvironment->rootDeviceEnvironments[0]->getHelper<ProductHelper>();