From bc5237ca8aafa8daa6a16c98643bb4adcc9a241c Mon Sep 17 00:00:00 2001 From: Mateusz Jablonski Date: Tue, 10 Sep 2024 16:30:25 +0000 Subject: [PATCH] feature: add support for query l3 bank count in xe-prelim Related-To: NEO-11125 Signed-off-by: Mateusz Jablonski --- .../os_interface/linux/xe/ioctl_helper_xe.cpp | 19 +++++++++-- .../os_interface/linux/xe/ioctl_helper_xe.h | 3 +- .../linux/xe/ioctl_helper_xe_prelim.cpp | 4 +++ .../linux/xe/ioctl_helper_xe_prelim.h | 1 + .../linux/xe/mock_ioctl_helper_xe.h | 10 ++++++ .../linux/xe/ioctl_helper_xe_prelim_tests.cpp | 11 ++++++ .../linux/xe/ioctl_helper_xe_tests.cpp | 34 +++++++++++++++++++ 7 files changed, 79 insertions(+), 3 deletions(-) diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp index 2f10043198..a158bb7cbb 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp @@ -443,9 +443,10 @@ bool IoctlHelperXe::setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime) { } void IoctlHelperXe::getTopologyData(size_t nTiles, std::vector> *geomDss, std::vector> *computeDss, - std::vector> *euDss, DrmQueryTopologyData &topologyData, bool &isComputeDssEmpty) { + std::vector> *euDss, std::vector> *l3BanksMask, DrmQueryTopologyData &topologyData, bool &isComputeDssEmpty) { int subSliceCount = 0; int euPerDss = 0; + int l3Banks = 0; for (auto tileId = 0u; tileId < nTiles; tileId++) { @@ -467,9 +468,15 @@ void IoctlHelperXe::getTopologyData(size_t nTiles, std::vector> * euPerDssPerTile += euDss[tileId][byte].count(); } + int l3BanksPerTile = 0; + for (auto byte = 0u; byte < l3BanksMask[tileId].size(); byte++) { + l3BanksPerTile += l3BanksMask[tileId][byte].count(); + } + // pick smallest config subSliceCount = (subSliceCount == 0) ? subSliceCountPerTile : std::min(subSliceCount, subSliceCountPerTile); euPerDss = (euPerDss == 0) ? euPerDssPerTile : std::min(euPerDss, euPerDssPerTile); + l3Banks = (l3Banks == 0) ? l3BanksPerTile : std::min(l3Banks, l3BanksPerTile); // pick max config topologyData.maxSubSlicesPerSlice = std::max(topologyData.maxSubSlicesPerSlice, subSliceCountPerTile); @@ -480,6 +487,7 @@ void IoctlHelperXe::getTopologyData(size_t nTiles, std::vector> * topologyData.subSliceCount = subSliceCount; topologyData.euCount = subSliceCount * euPerDss; topologyData.maxSlices = 1; + topologyData.numL3Banks = l3Banks; } void IoctlHelperXe::getTopologyMap(size_t nTiles, std::vector> *dssInfo, TopologyMap &topologyMap) { @@ -516,6 +524,7 @@ bool IoctlHelperXe::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTo StackVec>, 2> geomDss; StackVec>, 2> computeDss; StackVec>, 2> euDss; + StackVec>, 2> l3Banks; auto topologySize = queryGtTopology.size(); auto dataPtr = queryGtTopology.data(); @@ -524,6 +533,7 @@ bool IoctlHelperXe::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTo geomDss.resize(numTiles); computeDss.resize(numTiles); euDss.resize(numTiles); + l3Banks.resize(numTiles); bool receivedDssInfo = false; while (topologySize >= sizeof(drm_xe_query_topology_mask)) { drm_xe_query_topology_mask *topo = reinterpret_cast(dataPtr); @@ -545,6 +555,8 @@ bool IoctlHelperXe::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTo default: if (isEuPerDssTopologyType(topo->type)) { fillMask(euDss[tileId], topo); + } else if (isL3BankTopologyType(topo->type)) { + fillMask(l3Banks[tileId], topo); } else { xeLog("Unhandle GT Topo type: %d\n", topo->type); } @@ -557,7 +569,7 @@ bool IoctlHelperXe::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTo } bool isComputeDssEmpty = false; - getTopologyData(numTiles, geomDss.begin(), computeDss.begin(), euDss.begin(), topologyData, isComputeDssEmpty); + getTopologyData(numTiles, geomDss.begin(), computeDss.begin(), euDss.begin(), l3Banks.begin(), topologyData, isComputeDssEmpty); auto &dssInfo = isComputeDssEmpty ? geomDss : computeDss; getTopologyMap(numTiles, dssInfo.begin(), topologyMap); @@ -1723,4 +1735,7 @@ void IoctlHelperXe::querySupportedFeatures() { bool IoctlHelperXe::isEuPerDssTopologyType(uint16_t topologyType) const { return topologyType == DRM_XE_TOPO_EU_PER_DSS; } +bool IoctlHelperXe::isL3BankTopologyType(uint16_t topologyType) const { + return false; +} } // namespace NEO diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h index baa8ae357c..3711f68a3e 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h @@ -113,7 +113,7 @@ class IoctlHelperXe : public IoctlHelper { std::unique_ptr createMemoryInfo() override; size_t getLocalMemoryRegionsSize(const MemoryInfo *memoryInfo, uint32_t subDevicesCount, uint32_t deviceBitfield) const override; void setupIpVersion() override; - void getTopologyData(size_t nTiles, std::vector> *geomDss, std::vector> *computeDss, std::vector> *euDss, DrmQueryTopologyData &topologyData, bool &isComputeDssEmpty); + void getTopologyData(size_t nTiles, std::vector> *geomDss, std::vector> *computeDss, std::vector> *euDss, std::vector> *l3BanksMask, DrmQueryTopologyData &topologyData, bool &isComputeDssEmpty); void getTopologyMap(size_t nTiles, std::vector> *dssInfo, TopologyMap &topologyMap); bool setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime) override; @@ -134,6 +134,7 @@ class IoctlHelperXe : public IoctlHelper { bool resourceRegistrationEnabled() override { return true; } bool isPreemptionSupported() override { return true; } virtual bool isEuPerDssTopologyType(uint16_t topologyType) const; + virtual bool isL3BankTopologyType(uint16_t topologyType) const; protected: static constexpr uint32_t maxContextSetProperties = 4; diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe_prelim.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe_prelim.cpp index c1623bb486..9c46dd5e1e 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe_prelim.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe_prelim.cpp @@ -15,4 +15,8 @@ bool IoctlHelperXePrelim::isEuPerDssTopologyType(uint16_t topologyType) const { return topologyType == DRM_XE_TOPO_EU_PER_DSS || topologyType == DRM_XE_TOPO_SIMD16_EU_PER_DSS; } + +bool IoctlHelperXePrelim::isL3BankTopologyType(uint16_t topologyType) const { + return topologyType == DRM_XE_TOPO_L3_BANK; +} } // namespace NEO diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe_prelim.h b/shared/source/os_interface/linux/xe/ioctl_helper_xe_prelim.h index 2a8243c784..3e37c3afe2 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe_prelim.h +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe_prelim.h @@ -14,6 +14,7 @@ class IoctlHelperXePrelim : public IoctlHelperXe { public: using IoctlHelperXe::IoctlHelperXe; bool isEuPerDssTopologyType(uint16_t topologyType) const override; + bool isL3BankTopologyType(uint16_t topologyType) const override; }; } // namespace NEO diff --git a/shared/test/common/os_interface/linux/xe/mock_ioctl_helper_xe.h b/shared/test/common/os_interface/linux/xe/mock_ioctl_helper_xe.h index 6bb5365369..d4924937af 100644 --- a/shared/test/common/os_interface/linux/xe/mock_ioctl_helper_xe.h +++ b/shared/test/common/os_interface/linux/xe/mock_ioctl_helper_xe.h @@ -12,6 +12,8 @@ using namespace NEO; struct MockIoctlHelperXe : IoctlHelperXe { + static const uint16_t mockL3BankTopologyType = 0x100; + using IoctlHelperXe::bindInfo; using IoctlHelperXe::contextParamEngine; using IoctlHelperXe::defaultEngine; @@ -54,6 +56,14 @@ struct MockIoctlHelperXe : IoctlHelperXe { } return IoctlHelperXe::ioctl(fd, request, arg); } + bool isL3BankTopologyType(uint16_t topologyType) const override { + if (isL3BankTopologyTypeCallBase) { + return IoctlHelperXe::isL3BankTopologyType(topologyType); + } + return topologyType == mockL3BankTopologyType; + } + + bool isL3BankTopologyTypeCallBase = true; bool failPerfDisable = false; bool failPerfEnable = false; bool failPerfOpen = false; diff --git a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_prelim_tests.cpp index a2a74bc667..fcac155c18 100644 --- a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_prelim_tests.cpp @@ -22,3 +22,14 @@ TEST(IoctlHelperXePrelimTest, givenSimd16EuPerDssTypeWhenCheckingIfTopologyIsEuP EXPECT_FALSE(ioctlHelper.isEuPerDssTopologyType(DRM_XE_TOPO_DSS_GEOMETRY)); EXPECT_FALSE(ioctlHelper.isEuPerDssTopologyType(DRM_XE_TOPO_DSS_COMPUTE)); } + +TEST(IoctlHelperXePrelimTest, givenL3BankTypeWhenCheckingIfTopologyIsL3BankTypeThenSuccessIsReturned) { + MockExecutionEnvironment executionEnvironment{}; + std::unique_ptr drm{Drm::create(std::make_unique(0, ""), *executionEnvironment.rootDeviceEnvironments[0])}; + IoctlHelperXePrelim ioctlHelper{*drm}; + EXPECT_TRUE(ioctlHelper.isL3BankTopologyType(DRM_XE_TOPO_L3_BANK)); + EXPECT_FALSE(ioctlHelper.isL3BankTopologyType(DRM_XE_TOPO_EU_PER_DSS)); + EXPECT_FALSE(ioctlHelper.isL3BankTopologyType(DRM_XE_TOPO_DSS_GEOMETRY)); + EXPECT_FALSE(ioctlHelper.isL3BankTopologyType(DRM_XE_TOPO_DSS_COMPUTE)); + EXPECT_FALSE(ioctlHelper.isL3BankTopologyType(DRM_XE_TOPO_SIMD16_EU_PER_DSS)); +} diff --git a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp index 1970bd7373..9a5dac0e88 100644 --- a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp @@ -2406,6 +2406,15 @@ TEST(IoctlHelperXeTest, givenCorrectEuPerDssTypeWhenCheckingIfTopologyIsEuPerDss EXPECT_FALSE(ioctlHelper.isEuPerDssTopologyType(DRM_XE_TOPO_DSS_COMPUTE)); } +TEST(IoctlHelperXeTest, whenCheckingIfTopologyIsL3BankThenFalseIsReturned) { + MockExecutionEnvironment executionEnvironment{}; + std::unique_ptr drm{Drm::create(std::make_unique(0, ""), *executionEnvironment.rootDeviceEnvironments[0])}; + IoctlHelperXe ioctlHelper{*drm}; + EXPECT_FALSE(ioctlHelper.isL3BankTopologyType(DRM_XE_TOPO_EU_PER_DSS)); + EXPECT_FALSE(ioctlHelper.isL3BankTopologyType(DRM_XE_TOPO_DSS_GEOMETRY)); + EXPECT_FALSE(ioctlHelper.isL3BankTopologyType(DRM_XE_TOPO_DSS_COMPUTE)); +} + TEST(IoctlHelperXeTest, givenIoctlHelperWhenSettingExtContextThenCallExternalIoctlFunction) { MockExecutionEnvironment executionEnvironment{}; std::unique_ptr drm{Drm::create(std::make_unique(0, ""), *executionEnvironment.rootDeviceEnvironments[0])}; @@ -2430,3 +2439,28 @@ TEST(IoctlHelperXeTest, givenIoctlHelperWhenSettingExtContextThenCallExternalIoc EXPECT_TRUE(ioctlHelper.ioctl(DrmIoctl::getResetStats, &resetStats)); EXPECT_FALSE(ioctlCalled); } +TEST(IoctlHelperXeTest, givenL3BankWhenGetTopologyDataAndMapThenResultsAreCorrect) { + + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + xeIoctlHelper->isL3BankTopologyTypeCallBase = false; + auto &hwInfo = *executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(); + + xeIoctlHelper->initialize(); + + for (auto gtId = 0u; gtId < 4u; gtId++) { + drm->addMockedQueryTopologyData(gtId, DRM_XE_TOPO_DSS_GEOMETRY, 8, {0b11'1111, 0, 0, 0, 0, 0, 0, 0}); + drm->addMockedQueryTopologyData(gtId, DRM_XE_TOPO_DSS_COMPUTE, 8, {0, 0, 0, 0, 0, 0, 0, 0}); + drm->addMockedQueryTopologyData(gtId, DRM_XE_TOPO_EU_PER_DSS, 8, {0b1111'1111, 0b1111'1111, 0, 0, 0, 0, 0, 0}); + drm->addMockedQueryTopologyData(gtId, MockIoctlHelperXe::mockL3BankTopologyType, 8, {0b1111'0011, 0b1001'1111, 0, 0, 0, 0, 0, 0}); + } + DrmQueryTopologyData topologyData{}; + TopologyMap topologyMap{}; + + auto result = xeIoctlHelper->getTopologyDataAndMap(hwInfo, topologyData, topologyMap); + ASSERT_TRUE(result); + + // verify topology data + EXPECT_EQ(12, topologyData.numL3Banks); +}