diff --git a/opencl/test/unit_test/os_interface/linux/hw_info_config_linux_tests.cpp b/opencl/test/unit_test/os_interface/linux/hw_info_config_linux_tests.cpp index 7c7646a86b..0c0d3901a5 100644 --- a/opencl/test/unit_test/os_interface/linux/hw_info_config_linux_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/hw_info_config_linux_tests.cpp @@ -301,8 +301,8 @@ TEST_F(HwInfoConfigTestLinuxDummy, givenInvalidTopologyDataWhenConfiguringThenRe drm->StoredSSVal = storedSSVal; drm->StoredEUVal = 0; - int sliceCount, subSliceCount, euCount; - EXPECT_FALSE(drm->queryTopology(outHwInfo, sliceCount, subSliceCount, euCount)); + Drm::QueryTopologyData topologyData = {}; + EXPECT_FALSE(drm->queryTopology(outHwInfo, topologyData)); } { @@ -311,8 +311,8 @@ TEST_F(HwInfoConfigTestLinuxDummy, givenInvalidTopologyDataWhenConfiguringThenRe drm->StoredSSVal = 0; drm->StoredEUVal = storedEUVal; - int sliceCount, subSliceCount, euCount; - EXPECT_FALSE(drm->queryTopology(outHwInfo, sliceCount, subSliceCount, euCount)); + Drm::QueryTopologyData topologyData = {}; + EXPECT_FALSE(drm->queryTopology(outHwInfo, topologyData)); } { @@ -321,8 +321,8 @@ TEST_F(HwInfoConfigTestLinuxDummy, givenInvalidTopologyDataWhenConfiguringThenRe drm->StoredSSVal = storedSSVal; drm->StoredEUVal = storedEUVal; - int sliceCount, subSliceCount, euCount; - EXPECT_FALSE(drm->queryTopology(outHwInfo, sliceCount, subSliceCount, euCount)); + Drm::QueryTopologyData topologyData = {}; + EXPECT_FALSE(drm->queryTopology(outHwInfo, topologyData)); } } diff --git a/shared/source/os_interface/linux/drm_neo.cpp b/shared/source/os_interface/linux/drm_neo.cpp index ad281fadec..31144a4639 100644 --- a/shared/source/os_interface/linux/drm_neo.cpp +++ b/shared/source/os_interface/linux/drm_neo.cpp @@ -307,33 +307,40 @@ int Drm::getErrno() { int Drm::setupHardwareInfo(DeviceDescriptor *device, bool setupFeatureTableAndWorkaroundTable) { HardwareInfo *hwInfo = const_cast(device->pHwInfo); int ret; - int sliceTotal; - int subSliceTotal; - int euTotal; - bool status = queryTopology(*hwInfo, sliceTotal, subSliceTotal, euTotal); + Drm::QueryTopologyData topologyData = {}; + + bool status = queryTopology(*hwInfo, topologyData); if (!status) { PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "WARNING: Topology query failed!\n"); - sliceTotal = hwInfo->gtSystemInfo.SliceCount; + topologyData.sliceCount = hwInfo->gtSystemInfo.SliceCount; - ret = getEuTotal(euTotal); + ret = getEuTotal(topologyData.euCount); if (ret != 0) { PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query EU total parameter!\n"); return ret; } - ret = getSubsliceTotal(subSliceTotal); + ret = getSubsliceTotal(topologyData.subSliceCount); if (ret != 0) { PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query subslice total parameter!\n"); return ret; } + + topologyData.maxEuCount = topologyData.euCount; + topologyData.maxSliceCount = topologyData.sliceCount; + topologyData.maxSubSliceCount = topologyData.subSliceCount; } - hwInfo->gtSystemInfo.SliceCount = static_cast(sliceTotal); - hwInfo->gtSystemInfo.SubSliceCount = static_cast(subSliceTotal); - hwInfo->gtSystemInfo.EUCount = static_cast(euTotal); + hwInfo->gtSystemInfo.SliceCount = static_cast(topologyData.sliceCount); + hwInfo->gtSystemInfo.SubSliceCount = static_cast(topologyData.subSliceCount); + hwInfo->gtSystemInfo.EUCount = static_cast(topologyData.euCount); + + hwInfo->gtSystemInfo.MaxSubSlicesSupported = topologyData.maxSubSliceCount; + hwInfo->gtSystemInfo.MaxDualSubSlicesSupported = topologyData.maxSubSliceCount; + hwInfo->gtSystemInfo.MaxSlicesSupported = topologyData.maxSliceCount; status = querySystemInfo(); if (!status) { diff --git a/shared/source/os_interface/linux/drm_neo.h b/shared/source/os_interface/linux/drm_neo.h index dfbaba0fb8..f4990d9ebc 100644 --- a/shared/source/os_interface/linux/drm_neo.h +++ b/shared/source/os_interface/linux/drm_neo.h @@ -65,6 +65,16 @@ class Drm { MaxSize }; + struct QueryTopologyData { + int sliceCount; + int subSliceCount; + int euCount; + + int maxSliceCount; + int maxSubSliceCount; + int maxEuCount; + }; + virtual ~Drm(); virtual int ioctl(unsigned long request, void *arg); @@ -104,7 +114,7 @@ class Drm { MOCKABLE_VIRTUAL bool querySystemInfo(); MOCKABLE_VIRTUAL bool queryEngineInfo(); MOCKABLE_VIRTUAL bool queryMemoryInfo(); - bool queryTopology(const HardwareInfo &hwInfo, int &sliceCount, int &subSliceCount, int &euCount); + bool queryTopology(const HardwareInfo &hwInfo, QueryTopologyData &data); bool createVirtualMemoryAddressSpace(uint32_t vmCount); void destroyVirtualMemoryAddressSpace(); uint32_t getVirtualMemoryAddressSpace(uint32_t vmId); diff --git a/shared/source/os_interface/linux/drm_query_extended.cpp b/shared/source/os_interface/linux/drm_query_extended.cpp index ff0e5fb486..7572594ed6 100644 --- a/shared/source/os_interface/linux/drm_query_extended.cpp +++ b/shared/source/os_interface/linux/drm_query_extended.cpp @@ -11,7 +11,7 @@ namespace NEO { -bool Drm::queryTopology(const HardwareInfo &hwInfo, int &sliceCount, int &subSliceCount, int &euCount) { +bool Drm::queryTopology(const HardwareInfo &hwInfo, QueryTopologyData &topologyData) { int32_t length; auto dataQuery = this->query(DRM_I915_QUERY_TOPOLOGY_INFO, DrmQueryItemFlags::topology, length); auto data = reinterpret_cast(dataQuery.get()); @@ -20,7 +20,11 @@ bool Drm::queryTopology(const HardwareInfo &hwInfo, int &sliceCount, int &subSli return false; } - return translateTopologyInfo(data, sliceCount, subSliceCount, euCount); + topologyData.maxSliceCount = data->max_slices; + topologyData.maxSubSliceCount = data->max_subslices; + topologyData.maxEuCount = data->max_eus_per_subslice; + + return translateTopologyInfo(data, topologyData.sliceCount, topologyData.subSliceCount, topologyData.euCount); } bool Drm::isDebugAttachAvailable() { diff --git a/shared/source/os_interface/linux/hw_info_config.cpp b/shared/source/os_interface/linux/hw_info_config.cpp index 9925625530..450dc4f6e9 100644 --- a/shared/source/os_interface/linux/hw_info_config.cpp +++ b/shared/source/os_interface/linux/hw_info_config.cpp @@ -90,37 +90,43 @@ int HwInfoConfig::configureHwInfo(const HardwareInfo *inHwInfo, HardwareInfo *ou } platform->usRevId = static_cast(val); - int sliceCount; - int subSliceCount; - int euCount; + Drm::QueryTopologyData topologyData = {}; - bool status = drm->queryTopology(*outHwInfo, sliceCount, subSliceCount, euCount); + bool status = drm->queryTopology(*outHwInfo, topologyData); if (!status) { PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "WARNING: Topology query failed!\n"); - sliceCount = gtSystemInfo->SliceCount; + topologyData.sliceCount = gtSystemInfo->SliceCount; - ret = drm->getEuTotal(euCount); + ret = drm->getEuTotal(topologyData.euCount); if (ret != 0) { PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query EU total parameter!\n"); *outHwInfo = {}; return ret; } - ret = drm->getSubsliceTotal(subSliceCount); + ret = drm->getSubsliceTotal(topologyData.subSliceCount); if (ret != 0) { PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query subslice total parameter!\n"); *outHwInfo = {}; return ret; } + + topologyData.maxEuCount = topologyData.euCount / topologyData.subSliceCount; + topologyData.maxSliceCount = topologyData.sliceCount; + topologyData.maxSubSliceCount = topologyData.subSliceCount; } - gtSystemInfo->SliceCount = static_cast(sliceCount); - gtSystemInfo->SubSliceCount = static_cast(subSliceCount); - gtSystemInfo->EUCount = static_cast(euCount); + gtSystemInfo->SliceCount = static_cast(topologyData.sliceCount); + gtSystemInfo->SubSliceCount = static_cast(topologyData.subSliceCount); + gtSystemInfo->EUCount = static_cast(topologyData.euCount); gtSystemInfo->ThreadCount = this->threadsPerEu * gtSystemInfo->EUCount; + gtSystemInfo->MaxEuPerSubSlice = topologyData.maxEuCount; + gtSystemInfo->MaxSubSlicesSupported = topologyData.maxSubSliceCount; + gtSystemInfo->MaxSlicesSupported = topologyData.maxSliceCount; + uint64_t gttSizeQuery = 0; featureTable->ftrSVM = true; diff --git a/shared/test/unit_test/os_interface/linux/drm_query_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_query_tests.cpp index ecbcc7a378..df87b0104f 100644 --- a/shared/test/unit_test/os_interface/linux/drm_query_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_query_tests.cpp @@ -7,9 +7,12 @@ #include "shared/source/helpers/file_io.h" #include "shared/source/helpers/hw_info.h" +#include "shared/source/os_interface/hw_info_config.h" +#include "shared/source/os_interface/linux/os_interface.h" #include "shared/test/common/helpers/default_hw_info.h" #include "opencl/test/unit_test/os_interface/linux/drm_mock.h" +#include "test.h" #include "gtest/gtest.h" @@ -43,3 +46,53 @@ TEST(DrmQueryTest, WhenCallingIsDebugAttachAvailableThenReturnValueIsFalse) { EXPECT_FALSE(drm.isDebugAttachAvailable()); } + +TEST(DrmQueryTest, GivenDrmWhenQueryingTopologyInfoCorrectMaxValuesAreSet) { + auto executionEnvironment = std::make_unique(); + executionEnvironment->prepareRootDeviceEnvironments(1); + + *executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo() = *NEO::defaultHwInfo.get(); + DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; + + Drm::QueryTopologyData topologyData = {}; + + EXPECT_TRUE(drm.queryTopology(*executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(), topologyData)); + + EXPECT_EQ(drm.StoredSVal, topologyData.sliceCount); + EXPECT_EQ(drm.StoredSSVal, topologyData.subSliceCount); + EXPECT_EQ(drm.StoredEUVal, topologyData.euCount); + + EXPECT_EQ(drm.StoredSVal, topologyData.maxSliceCount); + EXPECT_EQ(drm.StoredSSVal / drm.StoredSVal, topologyData.maxSubSliceCount); + EXPECT_EQ(drm.StoredEUVal / drm.StoredSSVal, topologyData.maxEuCount); +} + +using HwConfigTopologyQuery = ::testing::Test; + +HWTEST2_F(HwConfigTopologyQuery, WhenGettingTopologyFailsThenSetMaxValuesBasedOnEuAndSubsliceIoctlQueries, MatchAny) { + auto executionEnvironment = std::make_unique(); + executionEnvironment->prepareRootDeviceEnvironments(1); + + *executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo() = *NEO::defaultHwInfo.get(); + auto drm = new DrmMock(*executionEnvironment->rootDeviceEnvironments[0]); + + drm->setGtType(GTTYPE_GT1); + + auto osInterface = std::make_unique(); + osInterface->get()->setDrm(static_cast(drm)); + + drm->failRetTopology = true; + + auto hwInfo = *executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(); + HardwareInfo outHwInfo; + auto hwConfig = HwInfoConfigHw::get(); + int ret = hwConfig->configureHwInfo(&hwInfo, &outHwInfo, osInterface.get()); + EXPECT_NE(-1, ret); + + EXPECT_EQ(outHwInfo.gtSystemInfo.EUCount / outHwInfo.gtSystemInfo.SubSliceCount, outHwInfo.gtSystemInfo.MaxEuPerSubSlice); + EXPECT_EQ(outHwInfo.gtSystemInfo.SubSliceCount, outHwInfo.gtSystemInfo.MaxSubSlicesSupported); + EXPECT_EQ(hwInfo.gtSystemInfo.SliceCount, outHwInfo.gtSystemInfo.MaxSlicesSupported); + + EXPECT_EQ(static_cast(drm->StoredEUVal), outHwInfo.gtSystemInfo.EUCount); + EXPECT_EQ(static_cast(drm->StoredSSVal), outHwInfo.gtSystemInfo.SubSliceCount); +} \ No newline at end of file