refactor: prepare CLOS logic for extension

Prepare cache setup and reservation logic to be extended w.r.t other
cache-levels.

Conceptually this change is like adding a switch-statement, in several
places, in which existing code makes a single (and only) case. This is
caused by splitting larger development to ease the review. Further cases
will be added in following steps. Such approach sometimes creates code
which may seem redundant but it is meant to simplify plugging following
extensions in an easy way.

Related-To: NEO-12837
Signed-off-by: Maciej Bielski <maciej.bielski@intel.com>
This commit is contained in:
Maciej Bielski 2025-02-13 17:01:04 +00:00 committed by Compute-Runtime-Automation
parent 9f3a95b7d6
commit 6924a48ca6
29 changed files with 256 additions and 114 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -23,7 +23,7 @@ class CacheReservation {
virtual bool reserveCache(size_t cacheLevel, size_t cacheReservationSize) = 0;
virtual bool setCacheAdvice(void *ptr, size_t regionSize, ze_cache_ext_region_t cacheRegion) = 0;
virtual size_t getMaxCacheReservationSize() = 0;
virtual size_t getMaxCacheReservationSize(size_t cacheLevel) = 0;
};
} // namespace L0

View File

@ -22,14 +22,24 @@ std::unique_ptr<CacheReservation> CacheReservation::create(Device &device) {
}
bool CacheReservationImpl::reserveCache(size_t cacheLevel, size_t cacheReservationSize) {
auto drm = device.getOsInterface()->getDriverModel()->as<NEO::Drm>();
switch (cacheLevel) {
case 3U:
return reserveCacheForLevel(3U, cacheReservationSize, reservedL3CacheRegion, reservedL3CacheSize);
default:
return false;
}
auto cacheInfo = drm->getL3CacheInfo();
return true;
}
bool CacheReservationImpl::reserveCacheForLevel(size_t 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(this->reservedL3CacheRegion);
this->reservedL3CacheRegion = NEO::CacheRegion::none;
this->reservedL3CacheSize = 0;
cacheInfo->freeCacheRegion(reservedCacheRegion);
reservedCacheRegion = NEO::CacheRegion::none;
reservedCacheSize = 0;
return true;
}
@ -38,8 +48,8 @@ bool CacheReservationImpl::reserveCache(size_t cacheLevel, size_t cacheReservati
return false;
}
this->reservedL3CacheRegion = cacheRegion;
this->reservedL3CacheSize = cacheReservationSize;
reservedCacheRegion = cacheRegion;
reservedCacheSize = cacheReservationSize;
return true;
}
@ -66,10 +76,15 @@ bool CacheReservationImpl::setCacheAdvice(void *ptr, [[maybe_unused]] size_t reg
return drmAllocation->setCacheAdvice(drm, cacheRegionSize, cacheRegionIdx, !drmAllocation->isAllocatedInLocalMemoryPool());
}
size_t CacheReservationImpl::getMaxCacheReservationSize() {
size_t CacheReservationImpl::getMaxCacheReservationSize(size_t cacheLevel) {
if (cacheLevel != 3U) {
return 0U;
}
auto drm = device.getOsInterface()->getDriverModel()->as<NEO::Drm>();
auto cacheInfo = drm->getL3CacheInfo();
auto cacheInfo = drm->getCacheInfo();
DEBUG_BREAK_IF(cacheInfo == nullptr);
return cacheInfo->getMaxReservationCacheSize();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2024 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -20,9 +20,10 @@ class CacheReservationImpl : public CacheReservation {
bool reserveCache(size_t cacheLevel, size_t cacheReservationSize) override;
bool setCacheAdvice(void *ptr, size_t regionSize, ze_cache_ext_region_t cacheRegion) override;
size_t getMaxCacheReservationSize() override;
size_t getMaxCacheReservationSize(size_t cacheLevel) override;
protected:
bool reserveCacheForLevel(size_t cacheLevel, size_t cacheReservationSize, NEO::CacheRegion &reservedCacheRegion, size_t &reservedCacheSize);
Device &device;
NEO::CacheRegion reservedL3CacheRegion = NEO::CacheRegion::none;
size_t reservedL3CacheSize = 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2024 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -21,7 +21,7 @@ bool CacheReservationImpl::setCacheAdvice(void *ptr, size_t regionSize, ze_cache
return false;
}
size_t CacheReservationImpl::getMaxCacheReservationSize() {
size_t CacheReservationImpl::getMaxCacheReservationSize(size_t cacheLevel) {
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2024 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -17,7 +17,7 @@ class CacheReservationImpl : public CacheReservation {
bool reserveCache(size_t cacheLevel, size_t cacheReservationSize) override;
bool setCacheAdvice(void *ptr, size_t regionSize, ze_cache_ext_region_t cacheRegion) override;
size_t getMaxCacheReservationSize() override;
size_t getMaxCacheReservationSize(size_t cacheLevel) override;
};
} // namespace L0

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -21,7 +21,7 @@ bool CacheReservationImpl::setCacheAdvice(void *ptr, size_t regionSize, ze_cache
return false;
}
size_t CacheReservationImpl::getMaxCacheReservationSize() {
size_t CacheReservationImpl::getMaxCacheReservationSize(size_t cacheLevel) {
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -17,7 +17,7 @@ class CacheReservationImpl : public CacheReservation {
bool reserveCache(size_t cacheLevel, size_t cacheReservationSize) override;
bool setCacheAdvice(void *ptr, size_t regionSize, ze_cache_ext_region_t cacheRegion) override;
size_t getMaxCacheReservationSize() override;
size_t getMaxCacheReservationSize(size_t cacheLevel) override;
};
} // namespace L0

View File

@ -1239,8 +1239,9 @@ ze_result_t DeviceImp::getCacheProperties(uint32_t *pCount, ze_device_cache_prop
if (pCacheProperties->pNext) {
auto extendedProperties = reinterpret_cast<ze_device_cache_properties_t *>(pCacheProperties->pNext);
if (extendedProperties->stype == ZE_STRUCTURE_TYPE_CACHE_RESERVATION_EXT_DESC) {
constexpr size_t cacheLevel{3U};
auto cacheReservationProperties = reinterpret_cast<ze_cache_reservation_ext_desc_t *>(extendedProperties);
cacheReservationProperties->maxCacheReservationSize = cacheReservation->getMaxCacheReservationSize();
cacheReservationProperties->maxCacheReservationSize = cacheReservation->getMaxCacheReservationSize(cacheLevel);
} else {
return ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}
@ -1255,12 +1256,16 @@ ze_result_t DeviceImp::reserveCache(size_t cacheLevel, size_t cacheReservationSi
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
if (cacheReservation->getMaxCacheReservationSize() == 0) {
if (cacheLevel == 0U) {
cacheLevel = 3U;
}
if (cacheLevel != 3U) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
if (cacheLevel == 0) {
cacheLevel = 3;
if (cacheReservation->getMaxCacheReservationSize(cacheLevel) == 0U) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
auto result = cacheReservation->reserveCache(cacheLevel, cacheReservationSize);
@ -1277,12 +1282,22 @@ ze_result_t DeviceImp::setCacheAdvice(void *ptr, size_t regionSize, ze_cache_ext
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
if (cacheReservation->getMaxCacheReservationSize() == 0) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
if (cacheRegion == ze_cache_ext_region_t::ZE_CACHE_EXT_REGION_DEFAULT) {
cacheRegion = ze_cache_ext_region_t::ZE_CACHE_EXT_REGION_NON_RESERVED;
}
if (cacheRegion == ze_cache_ext_region_t::ZE_CACHE_EXT_REGION_ZE_CACHE_REGION_DEFAULT) {
cacheRegion = ze_cache_ext_region_t::ZE_CACHE_EXT_REGION_ZE_CACHE_NON_RESERVED_REGION;
const auto cacheLevel{[cacheRegion]() {
switch (cacheRegion) {
case ze_cache_ext_region_t::ZE_CACHE_EXT_REGION_RESERVED:
case ze_cache_ext_region_t::ZE_CACHE_EXT_REGION_NON_RESERVED:
return 3U;
default:
UNRECOVERABLE_IF(true);
}
}()};
if (cacheReservation->getMaxCacheReservationSize(cacheLevel) == 0) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
auto result = cacheReservation->setCacheAdvice(ptr, regionSize, cacheRegion);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2024 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -49,7 +49,11 @@ class CacheReservationFixture : public DeviceFixture {
mockDrm->ioctlHelper = IoctlHelper::getI915Helper(productFamily, "2.0", *mockDrm);
mockDrm->ioctlHelper->initialize();
mockDrm->l3CacheInfo.reset(new MockCacheInfo(*mockDrm->ioctlHelper, 1024, 1, 32));
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 1024;
l3CacheParameters.maxNumRegions = 1;
l3CacheParameters.maxNumWays = 32;
mockDrm->cacheInfo.reset(new MockCacheInfo(*mockDrm->ioctlHelper, l3CacheParameters));
rootDeviceEnvironment.osInterface.reset(new NEO::OSInterface);
rootDeviceEnvironment.osInterface->setDriverModel(std::unique_ptr<DriverModel>(mockDrm));
rootDeviceEnvironment.initGmm();
@ -67,14 +71,19 @@ class CacheReservationFixture : public DeviceFixture {
using CacheReservationTest = Test<CacheReservationFixture>;
HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingReserveCacheWithZeroSizeThenRemovePriorReservation, IsCacheReservationSupported) {
size_t cacheLevel = 3;
size_t cacheReservationSize = 0;
HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingReserveCacheThenReservationIsAcquiredAndReleasedAppropriately, IsCacheReservationSupported) {
constexpr size_t cacheLevel{3U};
constexpr size_t cacheReservationSize{128U};
auto result = cache->reserveCache(cacheLevel, cacheReservationSize);
EXPECT_TRUE(result);
auto result1 = cache->reserveCache(cacheLevel, cacheReservationSize);
EXPECT_TRUE(result1);
auto cacheImpl = static_cast<MockCacheReservationImpl *>(cache);
EXPECT_EQ(CacheRegion::region1, cacheImpl->reservedL3CacheRegion);
EXPECT_EQ(cacheReservationSize, cacheImpl->reservedL3CacheSize);
auto result2 = cache->reserveCache(cacheLevel, 0U);
EXPECT_TRUE(result2);
EXPECT_EQ(CacheRegion::none, cacheImpl->reservedL3CacheRegion);
EXPECT_EQ(0u, cacheImpl->reservedL3CacheSize);
}
@ -82,7 +91,7 @@ HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingReserve
HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingReserveCacheWithInvalidSizeThenDontReserveCacheRegion, IsCacheReservationSupported) {
size_t cacheLevel = 3;
size_t cacheReservationSize = 2048;
ASSERT_GT(cacheReservationSize, mockDrm->getL3CacheInfo()->getMaxReservationCacheSize());
ASSERT_GT(cacheReservationSize, mockDrm->getCacheInfo()->getMaxReservationCacheSize());
auto result = cache->reserveCache(cacheLevel, cacheReservationSize);
EXPECT_FALSE(result);
@ -92,17 +101,16 @@ HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingReserve
EXPECT_EQ(0u, cacheImpl->reservedL3CacheSize);
}
HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingReserveCacheWithValidSizeThenReserveCacheRegionWithGivenSize, IsCacheReservationSupported) {
size_t cacheLevel = 3;
size_t cacheReservationSize = 1024;
ASSERT_LE(cacheReservationSize, mockDrm->getL3CacheInfo()->getMaxReservationCacheSize());
HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingReserveCacheWithInvalidCacheLevelThenDontReserveCacheRegion, IsCacheReservationSupported) {
constexpr size_t cacheLevel{1U};
constexpr size_t cacheReservationSize{128U};
auto result = cache->reserveCache(cacheLevel, cacheReservationSize);
EXPECT_TRUE(result);
EXPECT_FALSE(result);
auto cacheImpl = static_cast<MockCacheReservationImpl *>(cache);
EXPECT_NE(CacheRegion::none, cacheImpl->reservedL3CacheRegion);
EXPECT_EQ(1024u, cacheImpl->reservedL3CacheSize);
EXPECT_EQ(CacheRegion::none, cacheImpl->reservedL3CacheRegion);
EXPECT_EQ(0U, cacheImpl->reservedL3CacheSize);
}
HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingSetCacheAdviceWithInvalidPointerThenReturnFalse, IsCacheReservationSupported) {
@ -225,8 +233,13 @@ HWTEST2_F(CacheReservationTest, GivenCacheReservationSupportedWhenCallingSetCach
}
}
HWTEST2_F(CacheReservationTest, GivenCacheReservationCreatedWhenCallingGetMaxCacheReservationSizeThenReturnZero, IsCacheReservationSupported) {
EXPECT_EQ(mockDrm->getL3CacheInfo()->getMaxReservationCacheSize(), cache->getMaxCacheReservationSize());
HWTEST2_F(CacheReservationTest, GivenCacheReservationWhenCallingGetMaxCacheReservationSizeThenAppropriateValueReturned, IsCacheReservationSupported) {
auto cacheLevel{3U};
EXPECT_EQ(mockDrm->getCacheInfo()->getMaxReservationCacheSize(), cache->getMaxCacheReservationSize(cacheLevel));
cacheLevel = 2U;
EXPECT_EQ(0U, cache->getMaxCacheReservationSize(cacheLevel));
cacheLevel = 1U;
EXPECT_EQ(0U, cache->getMaxCacheReservationSize(cacheLevel));
}
} // namespace ult

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2022 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -49,7 +49,8 @@ TEST_F(CacheReservationTest, GivenCacheReservationCreatedWhenCallingSetCacheAdvi
}
TEST_F(CacheReservationTest, GivenCacheReservationCreatedWhenCallingGetMaxCacheReservationSizeThenReturnZero) {
EXPECT_EQ(0u, cache->getMaxCacheReservationSize());
constexpr auto cacheLevel{3U};
EXPECT_EQ(0u, cache->getMaxCacheReservationSize(cacheLevel));
}
} // namespace ult

View File

@ -160,7 +160,7 @@ class MockCacheReservation : public CacheReservation {
receivedCacheRegion = cacheRegion;
return isInitialized;
}
size_t getMaxCacheReservationSize() override {
size_t getMaxCacheReservationSize(size_t cacheLevel) override {
return maxCacheReservationSize;
}

View File

@ -48,5 +48,30 @@ TEST_F(DrmDeviceTests, whenMemoryAccessPropertiesQueriedThenConcurrentDeviceShar
delete proxyMemoryManager;
}
TEST_F(DrmDeviceTests, givenDriverModelIsNotDrmWhenUsingTheApiThenUnsupportedFeatureErrorIsReturned) {
constexpr auto rootDeviceIndex{0U};
execEnv->rootDeviceEnvironments[rootDeviceIndex]->osInterface.reset(new NEO::OSInterface);
auto drm{new DrmMock{*execEnv->rootDeviceEnvironments[rootDeviceIndex]}};
drm->getDriverModelTypeCallBase = false;
drm->getDriverModelTypeResult = DriverModelType::unknown;
execEnv->rootDeviceEnvironments[rootDeviceIndex]->osInterface->setDriverModel(std::unique_ptr<DriverModel>{drm});
EXPECT_NE(nullptr, neoDevice->getRootDeviceEnvironment().osInterface.get());
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, device->reserveCache(3, 0));
}
TEST_F(DrmDeviceTests, givenCacheLevelUnsupportedViaCacheReservationApiWhenUsingTheApiThenUnsupportedFeatureErrorIsReturned) {
constexpr auto rootDeviceIndex{0U};
execEnv->rootDeviceEnvironments[rootDeviceIndex]->osInterface.reset(new NEO::OSInterface);
auto drm{new DrmMock{*execEnv->rootDeviceEnvironments[rootDeviceIndex]}};
execEnv->rootDeviceEnvironments[rootDeviceIndex]->osInterface->setDriverModel(std::unique_ptr<DriverModel>{drm});
EXPECT_NE(nullptr, neoDevice->getRootDeviceEnvironment().osInterface.get());
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, device->reserveCache(1, 0));
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, device->reserveCache(2, 0));
}
} // namespace ult
} // namespace L0

View File

@ -13,6 +13,7 @@
#include "shared/source/helpers/gfx_core_helper.h"
#include "shared/source/helpers/preamble.h"
#include "shared/source/helpers/ray_tracing_helper.h"
#include "shared/source/os_interface/linux/hw_device_id.h"
#include "shared/source/os_interface/os_inc_base.h"
#include "shared/source/os_interface/os_interface.h"
#include "shared/source/os_interface/product_helper.h"

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Intel Corporation
* Copyright (C) 2022-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -32,7 +32,12 @@ struct BuffersWithClMemCacheClosTests : public DrmMemoryManagerLocalMemoryPrelim
auto memoryInfo = new MockExtendedMemoryInfo(*mock);
mock->memoryInfo.reset(memoryInfo);
mock->l3CacheInfo.reset(new MockCacheInfo(*mock->getIoctlHelper(), 1024, 2, 32));
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 1024;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
mock->cacheInfo.reset(new MockCacheInfo(*mock->getIoctlHelper(), l3CacheParameters));
auto &multiTileArchInfo = executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->getMutableHardwareInfo()->gtSystemInfo.MultiTileArchInfo;
multiTileArchInfo.TileCount = (memoryInfo->getDrmRegionInfos().size() - 1);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Intel Corporation
* Copyright (C) 2022-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -27,10 +27,12 @@ CacheInfo::~CacheInfo() {
}
CacheRegion CacheInfo::reserveRegion(size_t cacheReservationSize) {
uint16_t numWays = (maxReservationNumWays * cacheReservationSize) / maxReservationCacheSize;
auto &limits{l3ReservationLimits};
uint16_t numWays = (limits.maxNumWays * cacheReservationSize) / limits.maxSize;
if (debugManager.flags.ClosNumCacheWays.get() != -1) {
numWays = debugManager.flags.ClosNumCacheWays.get();
cacheReservationSize = (numWays * maxReservationCacheSize) / maxReservationNumWays;
cacheReservationSize = (numWays * limits.maxSize) / limits.maxNumWays;
}
auto regionIndex = cacheReserve.reserveCache(CacheLevel::level3, numWays);
if (regionIndex == CacheRegion::none) {
@ -52,10 +54,12 @@ CacheRegion CacheInfo::freeRegion(CacheRegion regionIndex) {
}
bool CacheInfo::isRegionReserved(CacheRegion regionIndex, [[maybe_unused]] size_t expectedRegionSize) const {
auto &limits{l3ReservationLimits};
if (regionIndex < CacheRegion::count && reservedCacheRegionsSize[toUnderlying(regionIndex)]) {
if (debugManager.flags.ClosNumCacheWays.get() != -1) {
auto numWays = debugManager.flags.ClosNumCacheWays.get();
expectedRegionSize = (numWays * maxReservationCacheSize) / maxReservationNumWays;
expectedRegionSize = (numWays * limits.maxSize) / limits.maxNumWays;
}
DEBUG_BREAK_IF(expectedRegionSize != reservedCacheRegionsSize[toUnderlying(regionIndex)]);
return true;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2024 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -19,11 +19,15 @@ namespace NEO {
class IoctlHelper;
struct CacheReservationParameters {
size_t maxSize{0U};
uint32_t maxNumRegions{0U};
uint16_t maxNumWays{0U};
};
struct CacheInfo {
CacheInfo(IoctlHelper &ioctlHelper, size_t maxReservationCacheSize, uint32_t maxReservationNumCacheRegions, uint16_t maxReservationNumWays)
: maxReservationCacheSize(maxReservationCacheSize),
maxReservationNumCacheRegions(maxReservationNumCacheRegions),
maxReservationNumWays(maxReservationNumWays),
CacheInfo(IoctlHelper &ioctlHelper, const CacheReservationParameters l3Limits)
: l3ReservationLimits{l3Limits},
cacheReserve{ioctlHelper} {
reservedCacheRegionsSize.fill(0UL);
@ -35,15 +39,18 @@ struct CacheInfo {
CacheInfo &operator=(const CacheInfo &) = delete;
size_t getMaxReservationCacheSize() const {
return maxReservationCacheSize;
const auto &limits{l3ReservationLimits};
return limits.maxSize;
}
size_t getMaxReservationNumCacheRegions() const {
return maxReservationNumCacheRegions;
const auto &limits{l3ReservationLimits};
return limits.maxNumRegions;
}
size_t getMaxReservationNumWays() const {
return maxReservationNumWays;
const auto &limits{l3ReservationLimits};
return limits.maxNumWays;
}
CacheRegion reserveCacheRegion(size_t cacheReservationSize) {
@ -68,9 +75,7 @@ struct CacheInfo {
bool getRegion(size_t regionSize, CacheRegion regionIndex);
protected:
size_t maxReservationCacheSize;
uint32_t maxReservationNumCacheRegions;
uint16_t maxReservationNumWays;
CacheReservationParameters l3ReservationLimits;
ClosCacheReservation cacheReserve;
std::array<size_t, toUnderlying(CacheRegion::count)> reservedCacheRegionsSize;
SpinLock mtx;

View File

@ -161,7 +161,7 @@ bool DrmAllocation::setCacheRegion(Drm *drm, CacheRegion regionIndex) {
return true;
}
auto cacheInfo = drm->getL3CacheInfo();
auto cacheInfo = drm->getCacheInfo();
if (cacheInfo == nullptr) {
return false;
}
@ -175,7 +175,7 @@ bool DrmAllocation::setCacheRegion(Drm *drm, CacheRegion regionIndex) {
}
bool DrmAllocation::setCacheAdvice(Drm *drm, size_t regionSize, CacheRegion regionIndex, bool isSystemMemoryPool) {
if (!drm->getL3CacheInfo()->getCacheRegion(regionSize, regionIndex)) {
if (!drm->getCacheInfo()->getCacheRegion(regionSize, regionIndex)) {
return false;
}

View File

@ -1017,24 +1017,25 @@ void Drm::setupSystemInfo(HardwareInfo *hwInfo, SystemInfo *sysInfo) {
void Drm::setupCacheInfo(const HardwareInfo &hwInfo) {
auto &productHelper = rootDeviceEnvironment.getHelper<ProductHelper>();
if (debugManager.flags.ClosEnabled.get() == 0 || productHelper.getNumCacheRegions() == 0) {
this->l3CacheInfo.reset(new CacheInfo{*ioctlHelper, 0, 0, 0});
return;
}
auto getL3CacheReservationLimits{[&hwInfo, &productHelper]() {
CacheReservationParameters out{};
if (debugManager.flags.ClosEnabled.get() == 0 || productHelper.getNumCacheRegions() == 0) {
return out;
}
auto allocateL3CacheInfo{[&productHelper, &hwInfo, &ioctlHelper = *(this->ioctlHelper)]() {
constexpr uint16_t maxNumWays = 32;
constexpr uint16_t totalMaxNumWays = 32;
constexpr uint16_t globalReservationLimit = 16;
constexpr uint16_t clientReservationLimit = 8;
constexpr uint16_t maxReservationNumWays = std::min(globalReservationLimit, clientReservationLimit);
const size_t totalCacheSize = hwInfo.gtSystemInfo.L3CacheSizeInKb * MemoryConstants::kiloByte;
const size_t maxReservationCacheSize = (totalCacheSize * maxReservationNumWays) / maxNumWays;
const uint32_t maxReservationNumCacheRegions = productHelper.getNumCacheRegions() - 1;
return new CacheInfo(ioctlHelper, maxReservationCacheSize, maxReservationNumCacheRegions, maxReservationNumWays);
out.maxNumWays = std::min(globalReservationLimit, clientReservationLimit);
out.maxSize = (totalCacheSize * out.maxNumWays) / totalMaxNumWays;
out.maxNumRegions = productHelper.getNumCacheRegions() - 1;
return out;
}};
this->l3CacheInfo.reset(allocateL3CacheInfo());
this->cacheInfo.reset(new CacheInfo(*ioctlHelper, getL3CacheReservationLimits()));
}
void Drm::getPrelimVersion(std::string &prelimVersion) {

View File

@ -190,8 +190,8 @@ class Drm : public DriverModel {
return systemInfo.get();
}
CacheInfo *getL3CacheInfo() const {
return l3CacheInfo.get();
CacheInfo *getCacheInfo() const {
return cacheInfo.get();
}
MemoryInfo *getMemoryInfo() const {
@ -334,7 +334,7 @@ class Drm : public DriverModel {
std::unique_ptr<HwDeviceIdDrm> hwDeviceId;
std::unique_ptr<IoctlHelper> ioctlHelper;
std::unique_ptr<SystemInfo> systemInfo;
std::unique_ptr<CacheInfo> l3CacheInfo;
std::unique_ptr<CacheInfo> cacheInfo;
std::unique_ptr<EngineInfo> engineInfo;
std::unique_ptr<MemoryInfo> memoryInfo;

View File

@ -12,6 +12,7 @@
#include "shared/test/common/helpers/default_hw_info.h"
#include "shared/test/common/mocks/linux/mock_drm_wrappers.h"
#include "shared/test/common/os_interface/linux/device_command_stream_fixture.h"
#include "shared/test/common/test_macros/mock_method_macros.h"
#include <cstdio>
#include <fstream>
@ -24,8 +25,10 @@ using namespace NEO;
class DrmMock : public Drm {
public:
using BaseClass = Drm;
using Drm::adapterBDF;
using Drm::bindAvailable;
using Drm::cacheInfo;
using Drm::checkQueueSliceSupport;
using Drm::chunkingAvailable;
using Drm::chunkingMode;
@ -40,7 +43,6 @@ class DrmMock : public Drm {
using Drm::getQueueSliceCount;
using Drm::ioctlHelper;
using Drm::isSharedSystemAllocEnabled;
using Drm::l3CacheInfo;
using Drm::memoryInfo;
using Drm::memoryInfoQueried;
using Drm::minimalChunkingSize;
@ -190,6 +192,8 @@ class DrmMock : public Drm {
return mockProcessCount;
}
ADDMETHOD_CONST(getDriverModelType, DriverModelType, true, DriverModelType::drm, (), ());
static const int mockFd = 33;
bool failRetTopology = false;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Intel Corporation
* Copyright (C) 2022-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -27,7 +27,7 @@ class DrmQueryMock : public DrmMock {
DrmMockPrelimContext context{
nullptr,
rootDeviceEnvironment,
getL3CacheInfo(),
getCacheInfo(),
failRetTopology,
supportedCopyEnginesMask,
contextDebugSupported,

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2024 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -110,11 +110,11 @@ struct DrmMockCustom : public Drm {
static std::unique_ptr<DrmMockCustom> create(std::unique_ptr<HwDeviceIdDrm> &&hwDeviceId, RootDeviceEnvironment &rootDeviceEnvironment);
using Drm::bindAvailable;
using Drm::cacheInfo;
using Drm::checkToDisableScratchPage;
using Drm::completionFenceSupported;
using Drm::disableScratch;
using Drm::ioctlHelper;
using Drm::l3CacheInfo;
using Drm::memoryInfo;
using Drm::pageFaultSupported;
using Drm::queryTopology;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Intel Corporation
* Copyright (C) 2022-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -12,8 +12,8 @@
#include "shared/test/common/os_interface/linux/device_command_stream_fixture_context.h"
struct DrmMockCustomPrelim : public DrmMockCustom {
using Drm::cacheInfo;
using Drm::ioctlHelper;
using Drm::l3CacheInfo;
using Drm::memoryInfo;
static auto create(RootDeviceEnvironment &rootDeviceEnvironment) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2024 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -19,8 +19,8 @@ struct MockCacheInfo : public CacheInfo {
using CacheInfo::reservedCacheRegionsSize;
using CacheInfo::reserveRegion;
MockCacheInfo(IoctlHelper &ioctlHelper, size_t maxReservationCacheSize, uint32_t maxReservationNumCacheRegions, uint16_t maxReservationNumWays)
: CacheInfo(ioctlHelper, maxReservationCacheSize, maxReservationNumCacheRegions, maxReservationNumWays) {}
MockCacheInfo(IoctlHelper &ioctlHelper, CacheReservationParameters l3CacheReservationLimits)
: CacheInfo(ioctlHelper, l3CacheReservationLimits) {}
~MockCacheInfo() override = default;
@ -28,7 +28,7 @@ struct MockCacheInfo : public CacheInfo {
if (regionIndex >= CacheRegion::count) {
return false;
}
if (regionSize > (maxReservationCacheSize / maxReservationNumCacheRegions)) {
if (regionSize > (l3ReservationLimits.maxSize / l3ReservationLimits.maxNumRegions)) {
return false;
}
return true;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2023-2024 Intel Corporation
* Copyright (C) 2023-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -124,7 +124,7 @@ int DrmMockExtended::handleRemainingRequests(DrmIoctl request, void *arg) {
if (cacheReserveArg->clos_index > closIndex) {
return EINVAL;
}
auto cacheInfo = this->getL3CacheInfo();
auto cacheInfo = this->getCacheInfo();
auto maxReservationNumWays = cacheInfo ? cacheInfo->getMaxReservationNumWays() : maxNumWays;
if (cacheReserveArg->num_ways > maxReservationNumWays) {
return EINVAL;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2023-2024 Intel Corporation
* Copyright (C) 2023-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -25,9 +25,9 @@ using namespace NEO;
class DrmMockExtended : public DrmMock {
public:
using Drm::cacheInfo;
using Drm::engineInfo;
using Drm::ioctlHelper;
using Drm::l3CacheInfo;
using Drm::memoryInfo;
using Drm::pageFaultSupported;
using Drm::rootDeviceEnvironment;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Intel Corporation
* Copyright (C) 2022-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -26,7 +26,7 @@ TEST(DrmCacheInfoTest, givenCacheRegionsExistsWhenCallingSetUpCacheInfoThenCache
drm.setupCacheInfo(*defaultHwInfo.get());
auto cacheInfo = drm.getL3CacheInfo();
auto cacheInfo = drm.getCacheInfo();
EXPECT_NE(nullptr, cacheInfo);
if (productHelper.getNumCacheRegions() == 0) {
@ -56,8 +56,8 @@ TEST(DrmCacheInfoTest, givenDebugFlagSetWhenCallingSetUpCacheInfoThenCacheInfoIs
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
drm.setupCacheInfo(*defaultHwInfo.get());
EXPECT_NE(nullptr, drm.getL3CacheInfo());
auto cacheInfo = drm.getL3CacheInfo();
EXPECT_NE(nullptr, drm.getCacheInfo());
auto cacheInfo = drm.getCacheInfo();
EXPECT_EQ(0u, cacheInfo->getMaxReservationCacheSize());
EXPECT_EQ(0u, cacheInfo->getMaxReservationNumCacheRegions());
@ -68,7 +68,11 @@ TEST(DrmCacheInfoTest, givenCacheInfoCreatedWhenGetCacheRegionSucceedsToReserveC
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
CacheInfo cacheInfo(*drm.getIoctlHelper(), 32 * MemoryConstants::kiloByte, 2, 32);
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
CacheInfo cacheInfo(*drm.getIoctlHelper(), l3CacheParameters);
size_t cacheReservationSize = cacheInfo.getMaxReservationCacheSize();
EXPECT_TRUE(cacheInfo.getCacheRegion(cacheReservationSize, CacheRegion::region1));
@ -80,7 +84,11 @@ TEST(DrmCacheInfoTest, givenCacheInfoCreatedWhenGetCacheRegionFailsToReserveCach
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
CacheInfo cacheInfo(*drm.getIoctlHelper(), 32 * MemoryConstants::kiloByte, 2, 32);
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
CacheInfo cacheInfo(*drm.getIoctlHelper(), l3CacheParameters);
size_t cacheReservationSize = cacheInfo.getMaxReservationCacheSize();
drm.context.closIndex = 0xFFFF;
@ -93,7 +101,11 @@ TEST(DrmCacheInfoTest, givenCacheInfoWithReservedCacheRegionWhenGetCacheRegionIs
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
CacheInfo cacheInfo(*drm.getIoctlHelper(), 32 * MemoryConstants::kiloByte, 2, 32);
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
CacheInfo cacheInfo(*drm.getIoctlHelper(), l3CacheParameters);
size_t cacheReservationSize = cacheInfo.getMaxReservationCacheSize();
EXPECT_EQ(CacheRegion::region1, cacheInfo.reserveCacheRegion(cacheReservationSize));
@ -107,7 +119,11 @@ TEST(DrmCacheInfoTest, givenCacheInfoCreatedWhenGetCacheRegionIsCalledForReserva
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
CacheInfo cacheInfo(*drm.getIoctlHelper(), 32 * MemoryConstants::kiloByte, 2, 32);
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();
EXPECT_TRUE(cacheInfo.getCacheRegion(regionSize, CacheRegion::region1));
@ -126,7 +142,11 @@ TEST(DrmCacheInfoTest, givenCacheInfoWhenSpecificNumCacheWaysIsRequestedThenRese
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
MockCacheInfo cacheInfo(*drm.getIoctlHelper(), 32 * MemoryConstants::kiloByte, 2, maxNumCacheWays);
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));
@ -144,7 +164,11 @@ TEST(DrmCacheInfoTest, givenCacheInfoWhenNumCacheWaysIsExceededThenDontReserveCa
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
MockCacheInfo cacheInfo(*drm.getIoctlHelper(), 32 * MemoryConstants::kiloByte, 2, maxNumCacheWays);
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));
@ -155,10 +179,15 @@ TEST(DrmCacheInfoTest, givenCacheInfoWhenNumCacheWaysIsExceededThenDontReserveCa
}
TEST(DrmCacheInfoTest, givenCacheInfoCreatedWhenFreeCacheRegionIsCalledForNonReservedRegionThenItFails) {
constexpr uint16_t maxNumCacheWays = 32;
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
DrmQueryMock drm(*executionEnvironment->rootDeviceEnvironments[0]);
MockCacheInfo cacheInfo(*drm.getIoctlHelper(), 32 * MemoryConstants::kiloByte, 2, 32);
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = maxNumCacheWays;
MockCacheInfo cacheInfo(*drm.getIoctlHelper(), l3CacheParameters);
cacheInfo.reservedCacheRegionsSize[toUnderlying(CacheRegion::region1)] = MemoryConstants::kiloByte;
EXPECT_EQ(CacheRegion::none, cacheInfo.freeCacheRegion(CacheRegion::region1));

View File

@ -4944,7 +4944,11 @@ TEST_F(DrmAllocationTests, givenDrmAllocationWhenDefaultCacheInfoIsAvailableThen
TEST_F(DrmAllocationTests, givenDrmAllocationWhenCacheRegionIsNotSetThenReturnFalse) {
const uint32_t rootDeviceIndex = 0u;
DrmMock drm(*executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]);
drm.l3CacheInfo.reset(new MockCacheInfo(*drm.getIoctlHelper(), 32 * MemoryConstants::kiloByte, 2, 32));
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
drm.cacheInfo.reset(new MockCacheInfo(*drm.getIoctlHelper(), l3CacheParameters));
MockDrmAllocation allocation(rootDeviceIndex, AllocationType::buffer, MemoryPool::localMemory);
@ -4955,7 +4959,12 @@ TEST_F(DrmAllocationTests, givenDrmAllocationWhenCacheRegionIsSetSuccessfullyThe
const uint32_t rootDeviceIndex = 0u;
DrmMock drm(*executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]);
drm.queryAndSetVmBindPatIndexProgrammingSupport();
drm.l3CacheInfo.reset(new MockCacheInfo(*drm.getIoctlHelper(), 32 * MemoryConstants::kiloByte, 2, 32));
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
drm.cacheInfo.reset(new MockCacheInfo(*drm.getIoctlHelper(), l3CacheParameters));
MockDrmAllocation allocation(rootDeviceIndex, AllocationType::buffer, MemoryPool::localMemory);
auto &productHelper = executionEnvironment->rootDeviceEnvironments[0]->getHelper<ProductHelper>();
@ -4972,7 +4981,12 @@ TEST_F(DrmAllocationTests, givenDrmAllocationWhenCacheRegionIsSetSuccessfullyThe
const uint32_t rootDeviceIndex = 0u;
DrmMock drm(*executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]);
drm.queryAndSetVmBindPatIndexProgrammingSupport();
drm.l3CacheInfo.reset(new MockCacheInfo(*drm.getIoctlHelper(), 32 * MemoryConstants::kiloByte, 2, 32));
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
drm.cacheInfo.reset(new MockCacheInfo(*drm.getIoctlHelper(), l3CacheParameters));
MockBufferObject bo(rootDeviceIndex, &drm, 3, 0, 0, 1);
MockDrmAllocation allocation(rootDeviceIndex, AllocationType::buffer, MemoryPool::localMemory);
@ -5128,7 +5142,12 @@ TEST_F(DrmMemoryManagerTest, givenDrmAllocationWithHostPtrWhenItIsCreatedWithCac
}
mock->ioctlExpected.total = -1;
auto drm = static_cast<DrmMockCustom *>(executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->osInterface->getDriverModel()->as<Drm>());
drm->l3CacheInfo.reset(new MockCacheInfo(*drm->getIoctlHelper(), 32 * MemoryConstants::kiloByte, 2, 32));
CacheReservationParameters l3CacheParameters{};
l3CacheParameters.maxSize = 32 * MemoryConstants::kiloByte;
l3CacheParameters.maxNumRegions = 2;
l3CacheParameters.maxNumWays = 32;
drm->cacheInfo.reset(new MockCacheInfo(*drm->getIoctlHelper(), l3CacheParameters));
auto ptr = reinterpret_cast<void *>(0x1000);
auto size = MemoryConstants::pageSize;
@ -6264,7 +6283,7 @@ TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenUAllocat
allocData.cacheRegion = 0xFFFF;
auto &drm = static_cast<DrmMockCustom &>(memoryManager->getDrm(0));
drm.l3CacheInfo.reset(nullptr);
drm.cacheInfo.reset(nullptr);
auto allocation = memoryManager->allocatePhysicalLocalDeviceMemory(allocData, status);
EXPECT_EQ(nullptr, allocation);

View File

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