diff --git a/opencl/test/unit_test/os_interface/linux/drm_mock.h b/opencl/test/unit_test/os_interface/linux/drm_mock.h index cfa1945358..0ef40d7d1e 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_mock.h +++ b/opencl/test/unit_test/os_interface/linux/drm_mock.h @@ -45,6 +45,7 @@ class DrmMock : public Drm { using Drm::requirePerContextVM; using Drm::sliceCountChangeSupported; using Drm::systemInfo; + using Drm::translateTopologyInfo; using Drm::virtualMemoryIds; DrmMock(int fd, RootDeviceEnvironment &rootDeviceEnvironment) : Drm(std::make_unique(fd, ""), rootDeviceEnvironment) { diff --git a/opencl/test/unit_test/os_interface/linux/drm_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_tests.cpp index e24aa45d42..05a7d29247 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_tests.cpp @@ -595,3 +595,27 @@ TEST(DrmTest, givenProgramDebuggingAndContextDebugAvailableWhenCreatingContextFo EXPECT_EQ(static_cast(-1), drmMock.passedContextDebugId); } + +TEST(DrmQueryTest, GivenDrmWhenSetupHardwareInfoCalledThenCorrectMaxValuesInGtSystemInfoAreSet) { + auto executionEnvironment = std::make_unique(); + executionEnvironment->prepareRootDeviceEnvironments(1); + + *executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo() = *NEO::defaultHwInfo.get(); + auto hwInfo = executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo(); + DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; + + drm.failRetTopology = true; + + drm.StoredEUVal = 48; + drm.StoredSSVal = 6; + hwInfo->gtSystemInfo.SliceCount = 2; + + auto setupHardwareInfo = [](HardwareInfo *, bool) {}; + DeviceDescriptor device = {0, hwInfo, setupHardwareInfo, GTTYPE_UNDEFINED}; + + drm.setupHardwareInfo(&device, false); + + EXPECT_EQ(hwInfo->gtSystemInfo.SliceCount, hwInfo->gtSystemInfo.MaxSlicesSupported); + EXPECT_EQ(6u, hwInfo->gtSystemInfo.MaxSubSlicesSupported); + EXPECT_EQ(8u, hwInfo->gtSystemInfo.MaxEuPerSubSlice); +} 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..94265d7540 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)); } } @@ -552,3 +552,52 @@ TEST(HwInfoConfigLinuxTest, whenAdjustPlatformForProductFamilyCalledThenDoNothin EXPECT_EQ(GFXCORE_FAMILY::IGFX_UNKNOWN_CORE, localHwInfo.platform.eRenderCoreFamily); EXPECT_EQ(GFXCORE_FAMILY::IGFX_UNKNOWN_CORE, localHwInfo.platform.eDisplayCoreFamily); } + +using HwConfigLinux = ::testing::Test; + +HWTEST2_F(HwConfigLinux, GivenDifferentValuesFromTopologyQueryWhenConfiguringHwInfoThenMaxValuesAreSetInGtSystemInfo, 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)); + + auto hwInfo = *executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(); + HardwareInfo outHwInfo; + auto hwConfig = HwInfoConfigHw::get(); + + hwInfo.gtSystemInfo.MaxSubSlicesSupported = drm->StoredSSVal * 2; + hwInfo.gtSystemInfo.MaxDualSubSlicesSupported = drm->StoredSSVal * 2; + hwInfo.gtSystemInfo.MaxEuPerSubSlice = 16; + hwInfo.gtSystemInfo.MaxSlicesSupported = drm->StoredSVal * 4; + + int ret = hwConfig->configureHwInfo(&hwInfo, &outHwInfo, osInterface.get()); + EXPECT_EQ(0, ret); + + EXPECT_EQ(static_cast(drm->StoredSSVal * 2), outHwInfo.gtSystemInfo.MaxSubSlicesSupported); + EXPECT_EQ(static_cast(drm->StoredSSVal * 2), outHwInfo.gtSystemInfo.MaxDualSubSlicesSupported); + EXPECT_EQ(16u, outHwInfo.gtSystemInfo.MaxEuPerSubSlice); + EXPECT_EQ(static_cast(drm->StoredSVal * 4), outHwInfo.gtSystemInfo.MaxSlicesSupported); + + drm->StoredSVal = 3; + drm->StoredSSVal = 12; + drm->StoredEUVal = 12 * 8; + + hwInfo.gtSystemInfo.MaxSubSlicesSupported = drm->StoredSSVal / 2; + hwInfo.gtSystemInfo.MaxDualSubSlicesSupported = drm->StoredSSVal / 2; + hwInfo.gtSystemInfo.MaxEuPerSubSlice = 1; + hwInfo.gtSystemInfo.MaxSlicesSupported = drm->StoredSVal / 2; + + ret = hwConfig->configureHwInfo(&hwInfo, &outHwInfo, osInterface.get()); + EXPECT_EQ(0, ret); + + EXPECT_EQ(12u, outHwInfo.gtSystemInfo.MaxSubSlicesSupported); + EXPECT_EQ(static_cast(drm->StoredEUVal / drm->StoredSSVal), outHwInfo.gtSystemInfo.MaxEuPerSubSlice); + EXPECT_EQ(static_cast(drm->StoredSVal), outHwInfo.gtSystemInfo.MaxSlicesSupported); + + EXPECT_EQ(hwInfo.gtSystemInfo.MaxDualSubSlicesSupported, outHwInfo.gtSystemInfo.MaxDualSubSlicesSupported); +} diff --git a/shared/source/os_interface/linux/drm_neo.cpp b/shared/source/os_interface/linux/drm_neo.cpp index 518dfcaf37..a27b5e8f69 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.subSliceCount; + topologyData.maxSliceCount = topologyData.sliceCount; + topologyData.maxSubSliceCount = topologyData.subSliceCount / topologyData.sliceCount; } - 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.MaxEuPerSubSlice = topologyData.maxEuCount; + hwInfo->gtSystemInfo.MaxSubSlicesSupported = topologyData.maxSubSliceCount * topologyData.maxSliceCount; + hwInfo->gtSystemInfo.MaxSlicesSupported = topologyData.maxSliceCount; status = querySystemInfo(); if (!status) { @@ -514,16 +521,20 @@ uint32_t Drm::getVirtualMemoryAddressSpace(uint32_t vmId) { return 0; } -bool Drm::translateTopologyInfo(const drm_i915_query_topology_info *queryTopologyInfo, int &sliceCount, int &subSliceCount, int &euCount) { +bool Drm::translateTopologyInfo(const drm_i915_query_topology_info *queryTopologyInfo, int &sliceCount, int &subSliceCount, int &euCount, int &maxSliceCount) { sliceCount = 0; subSliceCount = 0; euCount = 0; + maxSliceCount = queryTopologyInfo->max_slices; + std::vector sliceIndices; + sliceIndices.reserve(maxSliceCount); for (int x = 0; x < queryTopologyInfo->max_slices; x++) { bool isSliceEnable = (queryTopologyInfo->data[x / 8] >> (x % 8)) & 1; if (!isSliceEnable) { continue; } + sliceIndices.push_back(x); sliceCount++; for (int y = 0; y < queryTopologyInfo->max_subslices; y++) { size_t yOffset = (queryTopologyInfo->subslice_offset + x * queryTopologyInfo->subslice_stride + y / 8); @@ -543,6 +554,9 @@ bool Drm::translateTopologyInfo(const drm_i915_query_topology_info *queryTopolog } } + if (sliceIndices.size()) { + maxSliceCount = sliceIndices[sliceIndices.size() - 1] + 1; + } return (sliceCount && subSliceCount && euCount); } diff --git a/shared/source/os_interface/linux/drm_neo.h b/shared/source/os_interface/linux/drm_neo.h index 3bf0e252cb..c709c28687 100644 --- a/shared/source/os_interface/linux/drm_neo.h +++ b/shared/source/os_interface/linux/drm_neo.h @@ -66,6 +66,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); @@ -106,7 +116,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); @@ -182,7 +192,7 @@ class Drm { protected: int getQueueSliceCount(drm_i915_gem_context_param_sseu *sseu); - bool translateTopologyInfo(const drm_i915_query_topology_info *queryTopologyInfo, int &sliceCount, int &subSliceCount, int &euCount); + bool translateTopologyInfo(const drm_i915_query_topology_info *queryTopologyInfo, int &sliceCount, int &subSliceCount, int &euCount, int &maxSliceCount); std::string generateUUID(); std::string generateElfUUID(const void *data); bool sliceCountChangeSupported = false; diff --git a/shared/source/os_interface/linux/drm_query_extended.cpp b/shared/source/os_interface/linux/drm_query_extended.cpp index ff0e5fb486..e65094a7ba 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,10 @@ 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, topologyData.maxSliceCount); } 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..2c81c34f99 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 / topologyData.sliceCount; } - 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 = std::max(static_cast(topologyData.maxEuCount), gtSystemInfo->MaxEuPerSubSlice); + gtSystemInfo->MaxSubSlicesSupported = std::max(static_cast(topologyData.maxSubSliceCount * topologyData.maxSliceCount), gtSystemInfo->MaxSubSlicesSupported); + gtSystemInfo->MaxSlicesSupported = std::max(static_cast(topologyData.maxSliceCount), gtSystemInfo->MaxSlicesSupported); + 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..3a53a822f9 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,58 @@ 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; + + hwInfo.gtSystemInfo.MaxSlicesSupported = 0; + hwInfo.gtSystemInfo.MaxSubSlicesSupported = 0; + hwInfo.gtSystemInfo.MaxEuPerSubSlice = 0; + + 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