diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.cpp b/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.cpp index 298dc49aaf..0b28072e28 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.cpp @@ -30,7 +30,7 @@ void DebugApiLinuxFixture::setUp(NEO::HardwareInfo *hwInfo) { mockDrm->storedSSVal = hwInfo->gtSystemInfo.SubSliceCount; mockDrm->storedEUVal = hwInfo->gtSystemInfo.EUCount; } - NEO::Drm::QueryTopologyData topologyData = {}; + NEO::DrmQueryTopologyData topologyData = {}; mockDrm->queryTopology(neoDevice->getHardwareInfo(), topologyData); auto &rootDeviceEnvironment = *neoDevice->executionEnvironment->rootDeviceEnvironments[0]; auto gtSystemInfo = &rootDeviceEnvironment.getMutableHardwareInfo()->gtSystemInfo; @@ -61,7 +61,7 @@ void DebugApiLinuxMultiDeviceFixture::setUp() { auto engineInfo = mockDrm->getEngineInfo(); ASSERT_NE(nullptr, engineInfo->getEngineInstance(1, hwInfo.capabilityTable.defaultEngineType)); - NEO::Drm::QueryTopologyData topologyData = {}; + NEO::DrmQueryTopologyData topologyData = {}; mockDrm->queryTopology(neoDevice->getHardwareInfo(), topologyData); auto &rootDeviceEnvironment = *neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0]; auto gtSystemInfo = &rootDeviceEnvironment.getMutableHardwareInfo()->gtSystemInfo; diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp b/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp index 405f5aaf76..f2c4d0524d 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp @@ -183,7 +183,7 @@ TEST(DebugSessionLinuxTest, WhenConvertingThreadIDsForDeviceWithSingleSliceThenS mockDrm->storedEUVal = hwInfo.gtSystemInfo.EUCount; mockDrm->disableSomeTopology = true; - NEO::Drm::QueryTopologyData topologyData = {}; + NEO::DrmQueryTopologyData topologyData = {}; mockDrm->queryTopology(neoDevice->getHardwareInfo(), topologyData); neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface); @@ -228,7 +228,7 @@ TEST(DebugSessionLinuxTest, WhenConvertingThreadIDsForDeviceWithMultipleSlicesTh mockDrm->storedEUVal = hwInfo.gtSystemInfo.EUCount; mockDrm->disableSomeTopology = true; - NEO::Drm::QueryTopologyData topologyData = {}; + NEO::DrmQueryTopologyData topologyData = {}; mockDrm->queryTopology(neoDevice->getHardwareInfo(), topologyData); neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface); @@ -271,7 +271,7 @@ TEST(DebugSessionLinuxTest, GivenDeviceWithSingleSliceWhenCallingAreRequestedThr mockDrm->storedSSVal = hwInfo.gtSystemInfo.SubSliceCount; mockDrm->storedEUVal = hwInfo.gtSystemInfo.EUCount; - NEO::Drm::QueryTopologyData topologyData = {}; + NEO::DrmQueryTopologyData topologyData = {}; mockDrm->queryTopology(neoDevice->getHardwareInfo(), topologyData); neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface); neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr(mockDrm)); diff --git a/shared/source/os_interface/linux/drm_neo.cpp b/shared/source/os_interface/linux/drm_neo.cpp index ef83c84155..676ac2bcb9 100644 --- a/shared/source/os_interface/linux/drm_neo.cpp +++ b/shared/source/os_interface/linux/drm_neo.cpp @@ -444,7 +444,7 @@ int Drm::setupHardwareInfo(const DeviceDescriptor *device, bool setupFeatureTabl ioctlHelper->setupIpVersion(); rootDeviceEnvironment.initReleaseHelper(); - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; bool status = queryTopology(*hwInfo, topologyData); @@ -681,73 +681,6 @@ void Drm::setNewResourceBoundToVM(BufferObject *bo, uint32_t vmHandleId) { } } -bool Drm::translateTopologyInfo(const QueryTopologyInfo *queryTopologyInfo, QueryTopologyData &data, TopologyMapping &mapping) { - int sliceCount = 0; - int subSliceCount = 0; - int euCount = 0; - int maxSliceCount = 0; - int maxSubSliceCountPerSlice = 0; - std::vector sliceIndices; - sliceIndices.reserve(maxSliceCount); - - for (int x = 0; x < queryTopologyInfo->maxSlices; x++) { - bool isSliceEnable = (queryTopologyInfo->data[x / 8] >> (x % 8)) & 1; - if (!isSliceEnable) { - continue; - } - sliceIndices.push_back(x); - sliceCount++; - - std::vector subSliceIndices; - subSliceIndices.reserve(queryTopologyInfo->maxSubslices); - - for (int y = 0; y < queryTopologyInfo->maxSubslices; y++) { - size_t yOffset = (queryTopologyInfo->subsliceOffset + x * queryTopologyInfo->subsliceStride + y / 8); - bool isSubSliceEnabled = (queryTopologyInfo->data[yOffset] >> (y % 8)) & 1; - if (!isSubSliceEnabled) { - continue; - } - subSliceCount++; - subSliceIndices.push_back(y); - - for (int z = 0; z < queryTopologyInfo->maxEusPerSubslice; z++) { - size_t zOffset = (queryTopologyInfo->euOffset + (x * queryTopologyInfo->maxSubslices + y) * queryTopologyInfo->euStride + z / 8); - bool isEUEnabled = (queryTopologyInfo->data[zOffset] >> (z % 8)) & 1; - if (!isEUEnabled) { - continue; - } - euCount++; - } - } - - if (subSliceIndices.size()) { - maxSubSliceCountPerSlice = std::max(maxSubSliceCountPerSlice, subSliceIndices[subSliceIndices.size() - 1] + 1); - } - - // single slice available - if (sliceCount == 1) { - mapping.subsliceIndices = std::move(subSliceIndices); - } - } - - if (sliceIndices.size()) { - maxSliceCount = sliceIndices[sliceIndices.size() - 1] + 1; - mapping.sliceIndices = std::move(sliceIndices); - } - - if (sliceCount != 1) { - mapping.subsliceIndices.clear(); - } - - data.sliceCount = sliceCount; - data.subSliceCount = subSliceCount; - data.euCount = euCount; - data.maxSliceCount = maxSliceCount; - data.maxSubSliceCount = maxSubSliceCountPerSlice; - - return (data.sliceCount && data.subSliceCount && data.euCount); -} - PhysicalDevicePciBusInfo Drm::getPciBusInfo() const { PhysicalDevicePciBusInfo pciBusInfo(PhysicalDevicePciBusInfo::invalidValue, PhysicalDevicePciBusInfo::invalidValue, PhysicalDevicePciBusInfo::invalidValue, PhysicalDevicePciBusInfo::invalidValue); @@ -1048,77 +981,10 @@ void Drm::setupIoctlHelper(const PRODUCT_FAMILY productFamily) { } } -bool Drm::queryTopology(const HardwareInfo &hwInfo, QueryTopologyData &topologyData) { - topologyData.sliceCount = 0; - topologyData.subSliceCount = 0; - topologyData.euCount = 0; +bool Drm::queryTopology(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData) { - int sliceCount = 0; - int subSliceCount = 0; - int euCount = 0; - - auto request = ioctlHelper->getDrmParamValue(DrmParam::QueryComputeSlices); - if (DebugManager.flags.UseNewQueryTopoIoctl.get() && this->engineInfo && hwInfo.gtSystemInfo.MultiTileArchInfo.TileCount > 0 && request != 0) { - bool success = true; - - for (uint32_t i = 0; i < hwInfo.gtSystemInfo.MultiTileArchInfo.TileCount; i++) { - auto classInstance = this->engineInfo->getEngineInstance(i, hwInfo.capabilityTable.defaultEngineType); - UNRECOVERABLE_IF(!classInstance); - - uint32_t flags = classInstance->engineClass; - flags |= (classInstance->engineInstance << 8); - - auto dataQuery = this->query(request, flags); - if (dataQuery.empty()) { - success = false; - break; - } - auto data = reinterpret_cast(dataQuery.data()); - - QueryTopologyData tileTopologyData = {}; - TopologyMapping mapping; - if (!translateTopologyInfo(data, tileTopologyData, mapping)) { - success = false; - break; - } - - // pick smallest config - sliceCount = (sliceCount == 0) ? tileTopologyData.sliceCount : std::min(sliceCount, tileTopologyData.sliceCount); - subSliceCount = (subSliceCount == 0) ? tileTopologyData.subSliceCount : std::min(subSliceCount, tileTopologyData.subSliceCount); - euCount = (euCount == 0) ? tileTopologyData.euCount : std::min(euCount, tileTopologyData.euCount); - - topologyData.maxSliceCount = std::max(topologyData.maxSliceCount, tileTopologyData.maxSliceCount); - topologyData.maxSubSliceCount = std::max(topologyData.maxSubSliceCount, tileTopologyData.maxSubSliceCount); - topologyData.maxEuCount = std::max(topologyData.maxEuCount, static_cast(data->maxEusPerSubslice)); - - this->topologyMap[i] = mapping; - } - - if (success) { - topologyData.sliceCount = sliceCount; - topologyData.subSliceCount = subSliceCount; - topologyData.euCount = euCount; - return true; - } - } - - // fallback to DRM_I915_QUERY_TOPOLOGY_INFO - - request = ioctlHelper->getDrmParamValue(DrmParam::QueryTopologyInfo); - auto dataQuery = this->query(request, 0); - if (dataQuery.empty()) { - return false; - } - auto data = reinterpret_cast(dataQuery.data()); - - TopologyMapping mapping; - auto retVal = translateTopologyInfo(data, topologyData, mapping); - topologyData.maxEuCount = data->maxEusPerSubslice; - - this->topologyMap.clear(); - this->topologyMap[0] = mapping; - - return retVal; + auto result = this->ioctlHelper->getTopologyDataAndMap(hwInfo, topologyData, topologyMap); + return result; } void Drm::queryPageFaultSupport() { diff --git a/shared/source/os_interface/linux/drm_neo.h b/shared/source/os_interface/linux/drm_neo.h index f4d39684e9..b12ff92834 100644 --- a/shared/source/os_interface/linux/drm_neo.h +++ b/shared/source/os_interface/linux/drm_neo.h @@ -70,16 +70,6 @@ class Drm : public DriverModel { static SubmissionStatus getSubmissionStatusFromReturnCode(int32_t retCode); - struct QueryTopologyData { - int sliceCount; - int subSliceCount; - int euCount; - - int maxSliceCount; - int maxSubSliceCount; - int maxEuCount; - }; - ~Drm() override; virtual int ioctl(DrmIoctl request, void *arg); @@ -123,7 +113,7 @@ class Drm : public DriverModel { MOCKABLE_VIRTUAL bool sysmanQueryEngineInfo(); MOCKABLE_VIRTUAL bool queryEngineInfo(bool isSysmanEnabled); MOCKABLE_VIRTUAL bool queryMemoryInfo(); - bool queryTopology(const HardwareInfo &hwInfo, QueryTopologyData &data); + bool queryTopology(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData); bool createVirtualMemoryAddressSpace(uint32_t vmCount); void destroyVirtualMemoryAddressSpace(); uint32_t getVirtualMemoryAddressSpace(uint32_t vmId) const; @@ -266,7 +256,6 @@ class Drm : public DriverModel { Drm(std::unique_ptr &&hwDeviceIdIn, RootDeviceEnvironment &rootDeviceEnvironment); int getQueueSliceCount(GemContextParamSseu *sseu); - bool translateTopologyInfo(const QueryTopologyInfo *queryTopologyInfo, QueryTopologyData &data, TopologyMapping &mapping); std::string generateUUID(); std::string generateElfUUID(const void *data); void printIoctlStatistics(); diff --git a/shared/source/os_interface/linux/drm_wrappers.h b/shared/source/os_interface/linux/drm_wrappers.h index f04d2a7d8f..9e2c76a906 100644 --- a/shared/source/os_interface/linux/drm_wrappers.h +++ b/shared/source/os_interface/linux/drm_wrappers.h @@ -85,6 +85,16 @@ struct QueryTopologyInfo { uint8_t data[]; }; +struct DrmQueryTopologyData { + int sliceCount = 0; + int subSliceCount = 0; + int euCount = 0; + + int maxSliceCount = 0; + int maxSubSliceCount = 0; + int maxEuCount = 0; +}; + struct MemoryClassInstance { uint16_t memoryClass; uint16_t memoryInstance; diff --git a/shared/source/os_interface/linux/ioctl_helper.cpp b/shared/source/os_interface/linux/ioctl_helper.cpp index c9b0dd7bc3..24b5bb49ac 100644 --- a/shared/source/os_interface/linux/ioctl_helper.cpp +++ b/shared/source/os_interface/linux/ioctl_helper.cpp @@ -405,6 +405,92 @@ std::unique_ptr IoctlHelper::createMemoryInfo() { return {}; } +bool IoctlHelper::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData, TopologyMap &topologyMap) { + + auto request = this->getDrmParamValue(DrmParam::QueryTopologyInfo); + auto dataQuery = drm.query(request, 0); + if (dataQuery.empty()) { + return false; + } + auto topologyInfo = reinterpret_cast(dataQuery.data()); + + TopologyMapping mapping; + auto retVal = this->translateTopologyInfo(topologyInfo, topologyData, mapping); + topologyData.maxEuCount = topologyInfo->maxEusPerSubslice; + + topologyMap.clear(); + topologyMap[0] = mapping; + + return retVal; +} + +bool IoctlHelper::translateTopologyInfo(const QueryTopologyInfo *queryTopologyInfo, DrmQueryTopologyData &topologyData, TopologyMapping &mapping) { + int sliceCount = 0; + int subSliceCount = 0; + int euCount = 0; + int maxSliceCount = 0; + int maxSubSliceCountPerSlice = 0; + std::vector sliceIndices; + sliceIndices.reserve(maxSliceCount); + + for (int x = 0; x < queryTopologyInfo->maxSlices; x++) { + bool isSliceEnable = (queryTopologyInfo->data[x / 8] >> (x % 8)) & 1; + if (!isSliceEnable) { + continue; + } + sliceIndices.push_back(x); + sliceCount++; + + std::vector subSliceIndices; + subSliceIndices.reserve(queryTopologyInfo->maxSubslices); + + for (int y = 0; y < queryTopologyInfo->maxSubslices; y++) { + size_t yOffset = (queryTopologyInfo->subsliceOffset + x * queryTopologyInfo->subsliceStride + y / 8); + bool isSubSliceEnabled = (queryTopologyInfo->data[yOffset] >> (y % 8)) & 1; + if (!isSubSliceEnabled) { + continue; + } + subSliceCount++; + subSliceIndices.push_back(y); + + for (int z = 0; z < queryTopologyInfo->maxEusPerSubslice; z++) { + size_t zOffset = (queryTopologyInfo->euOffset + (x * queryTopologyInfo->maxSubslices + y) * queryTopologyInfo->euStride + z / 8); + bool isEUEnabled = (queryTopologyInfo->data[zOffset] >> (z % 8)) & 1; + if (!isEUEnabled) { + continue; + } + euCount++; + } + } + + if (subSliceIndices.size()) { + maxSubSliceCountPerSlice = std::max(maxSubSliceCountPerSlice, subSliceIndices[subSliceIndices.size() - 1] + 1); + } + + // single slice available + if (sliceCount == 1) { + mapping.subsliceIndices = std::move(subSliceIndices); + } + } + + if (sliceIndices.size()) { + maxSliceCount = sliceIndices[sliceIndices.size() - 1] + 1; + mapping.sliceIndices = std::move(sliceIndices); + } + + if (sliceCount != 1) { + mapping.subsliceIndices.clear(); + } + + topologyData.sliceCount = sliceCount; + topologyData.subSliceCount = subSliceCount; + topologyData.euCount = euCount; + topologyData.maxSliceCount = maxSliceCount; + topologyData.maxSubSliceCount = maxSubSliceCountPerSlice; + + return (sliceCount && subSliceCount && euCount); +} + std::unique_ptr IoctlHelper::createEngineInfo(bool isSysmanEnabled) { auto request = getDrmParamValue(DrmParam::QueryEngineInfo); auto enginesQuery = drm.query(request, 0); diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index a01dda9b5d..5301b1d3fc 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -7,6 +7,7 @@ #pragma once #include "shared/source/command_stream/task_count_helper.h" +#include "shared/source/helpers/topology_map.h" #include "shared/source/os_interface/linux/drm_wrappers.h" #include "shared/source/utilities/stackvec.h" @@ -28,6 +29,8 @@ enum class PreferredLocation : int16_t; struct HardwareInfo; struct HardwareIpVersion; struct EngineInfo; +struct DrmQueryTopologyData; + class MemoryInfo; struct MemoryRegion { @@ -151,6 +154,8 @@ class IoctlHelper { uint32_t getFlagsForPrimeHandleToFd() const; virtual std::unique_ptr createMemoryInfo(); virtual std::unique_ptr createEngineInfo(bool isSysmanEnabled); + virtual bool getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData, TopologyMap &topologyMap); + bool translateTopologyInfo(const QueryTopologyInfo *queryTopologyInfo, DrmQueryTopologyData &topologyData, TopologyMapping &mapping); protected: Drm &drm; @@ -283,6 +288,7 @@ class IoctlHelperPrelim20 : public IoctlHelper { bool isWaitBeforeBindRequired(bool bind) const override; void *pciBarrierMmap() override; void setupIpVersion() override; + bool getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData, TopologyMap &topologyMap) override; protected: bool queryHwIpVersion(EngineClassInstance &engineInfo, HardwareIpVersion &ipVersion, int &ret); diff --git a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp index 0adfc5ceff..34f1dc720a 100644 --- a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp @@ -18,6 +18,7 @@ #include "shared/source/os_interface/linux/cache_info.h" #include "shared/source/os_interface/linux/drm_neo.h" #include "shared/source/os_interface/linux/drm_wrappers.h" +#include "shared/source/os_interface/linux/engine_info.h" #include "shared/source/os_interface/linux/i915_prelim.h" #include "shared/source/os_interface/linux/ioctl_helper.h" #include "shared/source/os_interface/linux/sys_calls.h" @@ -70,6 +71,69 @@ bool IoctlHelperPrelim20::isChunkingAvailable() { return chunkSupported; } +bool IoctlHelperPrelim20::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData, TopologyMap &topologyMap) { + + auto request = this->getDrmParamValue(DrmParam::QueryComputeSlices); + auto engineInfo = drm.getEngineInfo(); + auto nTiles = hwInfo.gtSystemInfo.MultiTileArchInfo.TileCount; + + auto useNewQuery = DebugManager.flags.UseNewQueryTopoIoctl.get() && + engineInfo && + (nTiles > 0); + + if (useNewQuery) { + + bool success = true; + + int sliceCount = 0; + int subSliceCount = 0; + int euCount = 0; + + for (auto i = 0u; i < nTiles; i++) { + auto classInstance = engineInfo->getEngineInstance(i, hwInfo.capabilityTable.defaultEngineType); + UNRECOVERABLE_IF(!classInstance); + + uint32_t flags = classInstance->engineClass; + flags |= (classInstance->engineInstance << 8); + + auto dataQuery = drm.query(request, flags); + if (dataQuery.empty()) { + success = false; + break; + } + + auto data = reinterpret_cast(dataQuery.data()); + DrmQueryTopologyData tileTopologyData = {}; + TopologyMapping mapping; + if (!this->translateTopologyInfo(data, tileTopologyData, mapping)) { + success = false; + break; + } + + // pick smallest config + sliceCount = (sliceCount == 0) ? tileTopologyData.sliceCount : std::min(sliceCount, tileTopologyData.sliceCount); + subSliceCount = (subSliceCount == 0) ? tileTopologyData.subSliceCount : std::min(subSliceCount, tileTopologyData.subSliceCount); + euCount = (euCount == 0) ? tileTopologyData.euCount : std::min(euCount, tileTopologyData.euCount); + + topologyData.maxSliceCount = std::max(topologyData.maxSliceCount, tileTopologyData.maxSliceCount); + topologyData.maxSubSliceCount = std::max(topologyData.maxSubSliceCount, tileTopologyData.maxSubSliceCount); + topologyData.maxEuCount = std::max(topologyData.maxEuCount, static_cast(data->maxEusPerSubslice)); + + topologyMap[i] = mapping; + } + + if (success) { + topologyData.sliceCount = sliceCount; + topologyData.subSliceCount = subSliceCount; + topologyData.euCount = euCount; + return true; + } + } + + // fallback to DRM_I915_QUERY_TOPOLOGY_INFO + return IoctlHelper::getTopologyDataAndMap(hwInfo, topologyData, topologyMap); +} + bool IoctlHelperPrelim20::isVmBindAvailable() { int vmBindSupported = 0; GetParam getParam{}; diff --git a/shared/source/os_interface/linux/product_helper_drm.cpp b/shared/source/os_interface/linux/product_helper_drm.cpp index e4d72c48c6..b6e89a04e7 100644 --- a/shared/source/os_interface/linux/product_helper_drm.cpp +++ b/shared/source/os_interface/linux/product_helper_drm.cpp @@ -73,7 +73,7 @@ int ProductHelper::configureHwInfoDrm(const HardwareInfo *inHwInfo, HardwareInfo auto gtSystemInfo = &outHwInfo->gtSystemInfo; auto featureTable = &outHwInfo->featureTable; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; bool status = drm->queryTopology(*outHwInfo, topologyData); 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 1ad5a94000..21d17b4f9d 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp @@ -26,6 +26,7 @@ #include "drm/i915_drm_prelim.h" #include "drm/xe_drm.h" +#include #include #define XE_FIND_INVALID_INSTANCE 16 @@ -56,9 +57,6 @@ int IoctlHelperXe::xeGetQuery(Query *data) { case static_cast(DrmParam::QueryHwconfigTable): queryData = &hwconfigFakei915; break; - case static_cast(DrmParam::QueryTopologyInfo): - queryData = &topologyFakei915; - break; default: xeLog("error: bad query 0x%x\n", queryItem->queryId); return -1; @@ -141,7 +139,6 @@ bool IoctlHelperXe::initialize() { DebugManager.flags.ForceUserptrAlignment.set(64); DebugManager.flags.UseVmBind.set(1); DebugManager.flags.EnableImmediateVmBindExt.set(1); - DebugManager.flags.UseNewQueryTopoIoctl.set(0); DebugManager.flags.RenderCompressedBuffersEnabled.set(0); struct drm_xe_device_query queryConfig = {}; @@ -194,50 +191,6 @@ bool IoctlHelperXe::initialize() { queryConfig.data = castToUint64(hwconfigFakei915.data()); IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - memset(&queryConfig, 0, sizeof(queryConfig)); - queryConfig.query = DRM_XE_DEVICE_QUERY_GT_TOPOLOGY; - IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - std::vector topology(queryConfig.size); - queryConfig.data = castToUint64(topology.data()); - IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - std::vector geomDss; - std::vector computeDss; - std::vector euDss; - uint32_t topologySize = queryConfig.size; - uint8_t *dataPtr = reinterpret_cast(topology.data()); - while (topologySize >= sizeof(struct drm_xe_query_topology_mask)) { - struct drm_xe_query_topology_mask *topo = reinterpret_cast(dataPtr); - uint32_t itemSize = sizeof(struct drm_xe_query_topology_mask) + topo->num_bytes; - std::vector *toFill = nullptr; - - switch (topo->type) { - case XE_TOPO_DSS_GEOMETRY: - toFill = &geomDss; - break; - case XE_TOPO_DSS_COMPUTE: - toFill = &computeDss; - break; - case XE_TOPO_EU_PER_DSS: - toFill = &euDss; - break; - default: - xeLog("Un handle GT Topo type: %d\n", topo->type); - break; - } - if (toFill != nullptr) { - for (uint32_t j = 0; j < topo->num_bytes; j++) - toFill->push_back(topo->mask[j]); - } - topologySize -= itemSize; - dataPtr += itemSize; - } - topologyFakei915 = xeRebuildi915Topology(&geomDss, &computeDss, &euDss); - if (topologyFakei915.size()) { - ret = true; - } else { - xeLog("can't get i915 topology\n", ""); - UNRECOVERABLE_IF(true); - } auto hwInfo = this->drm.getRootDeviceEnvironment().getMutableHardwareInfo(); hwInfo->platform.usDeviceID = chipsetId; hwInfo->platform.usRevId = revId; @@ -369,6 +322,120 @@ std::unique_ptr IoctlHelperXe::createMemoryInfo() { return std::make_unique(regionsContainer, drm); } +void IoctlHelperXe::getTopologyData(uint32_t nTiles, std::vector> geomDss[2], std::vector> computeDss[2], std::vector> euDss[2], DrmQueryTopologyData &topologyData, bool &isComputeDssEmpty) { + int subSliceCount = 0; + int euPerDss = 0; + + for (auto tileId = 0u; tileId < nTiles; tileId++) { + + int subSliceCountPerTile = 0; + + for (auto byte = 0u; byte < computeDss[tileId].size(); byte++) { + subSliceCountPerTile += computeDss[tileId][byte].count(); + } + + if (subSliceCountPerTile == 0) { + isComputeDssEmpty = true; + for (auto byte = 0u; byte < geomDss[tileId].size(); byte++) { + subSliceCountPerTile += geomDss[tileId][byte].count(); + } + } + + int euPerDssPerTile = 0; + for (auto byte = 0u; byte < euDss[tileId].size(); byte++) { + euPerDssPerTile += euDss[tileId][byte].count(); + } + + // pick smallest config + subSliceCount = (subSliceCount == 0) ? subSliceCountPerTile : std::min(subSliceCount, subSliceCountPerTile); + euPerDss = (euPerDss == 0) ? euPerDssPerTile : std::min(euPerDss, euPerDssPerTile); + + // pick max config + topologyData.maxSubSliceCount = std::max(topologyData.maxSubSliceCount, subSliceCountPerTile); + topologyData.maxEuCount = std::max(topologyData.maxEuCount, euPerDssPerTile * subSliceCountPerTile); + } + + topologyData.sliceCount = 1; + topologyData.subSliceCount = subSliceCount; + topologyData.euCount = subSliceCount * euPerDss; + topologyData.maxSliceCount = 1; +} + +void IoctlHelperXe::getTopologyMap(uint32_t nTiles, std::vector> dssInfo[2], TopologyMap &topologyMap) { + for (auto tileId = 0u; tileId < nTiles; tileId++) { + std::vector sliceIndices; + std::vector subSliceIndices; + + sliceIndices.push_back(0); + + for (auto byte = 0u; byte < dssInfo[tileId].size(); byte++) { + for (auto bit = 0u; bit < 8u; bit++) { + if (dssInfo[tileId][byte].test(bit)) { + auto subSliceIndex = byte * 8 + bit; + subSliceIndices.push_back(subSliceIndex); + } + } + } + + topologyMap[tileId].sliceIndices = std::move(sliceIndices); + topologyMap[tileId].subsliceIndices = std::move(subSliceIndices); + } +} + +bool IoctlHelperXe::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData, TopologyMap &topologyMap) { + + auto queryGtTopology = queryData(DRM_XE_DEVICE_QUERY_GT_TOPOLOGY); + + auto fillMask = [](std::vector> &vec, drm_xe_query_topology_mask *topo) { + for (uint32_t j = 0; j < topo->num_bytes; j++) { + vec.push_back(topo->mask[j]); + } + }; + + std::vector> geomDss[2]; + std::vector> computeDss[2]; + std::vector> euDss[2]; + auto topologySize = queryGtTopology.size(); + uint8_t *dataPtr = reinterpret_cast(queryGtTopology.data()); + + auto nTiles = 1u; + + while (topologySize >= sizeof(drm_xe_query_topology_mask)) { + drm_xe_query_topology_mask *topo = reinterpret_cast(dataPtr); + UNRECOVERABLE_IF(topo == nullptr); + + uint32_t tileId = topo->gt_id; + nTiles = std::max(tileId + 1, nTiles); + + switch (topo->type) { + case XE_TOPO_DSS_GEOMETRY: + fillMask(geomDss[tileId], topo); + break; + case XE_TOPO_DSS_COMPUTE: + fillMask(computeDss[tileId], topo); + break; + case XE_TOPO_EU_PER_DSS: + fillMask(euDss[tileId], topo); + break; + default: + xeLog("Unhandle GT Topo type: %d\n", topo->type); + return false; + } + + uint32_t itemSize = sizeof(drm_xe_query_topology_mask) + topo->num_bytes; + topologySize -= itemSize; + dataPtr += itemSize; + } + + bool isComputeDssEmpty = false; + getTopologyData(nTiles, geomDss, computeDss, euDss, topologyData, isComputeDssEmpty); + + auto &dssInfo = isComputeDssEmpty ? geomDss : computeDss; + getTopologyMap(nTiles, dssInfo, topologyMap); + + return true; +} + int IoctlHelperXe::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) { struct drm_xe_gem_create create = {}; uint32_t regionsSize = static_cast(memClassInstances.size()); @@ -1381,85 +1448,4 @@ bool IoctlHelperXe::isWaitBeforeBindRequired(bool bind) const { return true; } -static uint32_t getVectorGetMax(std::vector *data) { - uint32_t ret = 0; - for (uint32_t i = 0; i < static_cast(data->size()); i++) { - for (uint32_t j = 0; j < 8; j++) { - if ((*data)[i] & (1 << j)) { - ret = (j + 1 + (i * 8)); - } - } - } - return ret; -} - -static uint32_t isBitOn(std::vector *data, uint32_t n) { - if (n / 8 < static_cast(data->size())) { - return isBitSet((*data)[n / 8], n % 8); - } - return 0; -} - -std::vector IoctlHelperXe::xeRebuildi915Topology(std::vector *geomDss, - std::vector *computeDss, - std::vector *euDss) { - std::vector ret; - xeLog("GeomDss %ld %d\n", geomDss->size(), getVectorGetMax(geomDss)); - xeLog("ComputeDss %ld %d\n", computeDss->size(), getVectorGetMax(computeDss)); - xeLog("EuDss %ld %d\n", euDss->size(), getVectorGetMax(euDss)); - uint32_t maxEuPerDss = getVectorGetMax(euDss); - uint32_t maxSubslice = getVectorGetMax(geomDss); - std::vector *currentDss = geomDss; - if (!maxSubslice) { - maxSubslice = getVectorGetMax(computeDss); - currentDss = computeDss; - if (!maxSubslice) { - xeLog("incorrect number of slices !\n", ""); - return {}; - } - } - uint32_t ssStride = static_cast(Math::divideAndRoundUp(maxSubslice, 8)); - uint32_t euStride = static_cast(Math::divideAndRoundUp(maxEuPerDss, 8)); - uint32_t maxSlice = 1; - uint32_t sliceLength = 1; - uint32_t subsliceLength = maxSlice * ssStride; - uint32_t euLength = maxSlice * maxSubslice * euStride; - uint32_t totalLength = sizeof(struct drm_i915_query_topology_info) + sliceLength + subsliceLength + euLength; - - xeLog("maxSlice:%d maxSubslice:%d maxEuPerDss:%d euStride:%d ssStride:%d\n", - maxSlice, maxSubslice, maxEuPerDss, euStride, ssStride); - xeLog("subsliceLength:%d euLength:%d totalLength:%d total_eu:%d\n", - subsliceLength, euLength, totalLength, maxEuPerDss * maxSubslice); - - { - ret.resize(sizeof(struct drm_i915_query_topology_info)); - auto topology = reinterpret_cast(ret.data()); - topology->max_slices = maxSlice; - topology->max_subslices = maxSubslice; - topology->max_eus_per_subslice = maxEuPerDss; - topology->subslice_offset = sliceLength; - topology->subslice_stride = ssStride; - topology->eu_offset = sliceLength + subsliceLength; - topology->eu_stride = euStride; - } - ret.push_back(maxSlice); - for (uint32_t i = 0; i < ssStride; i++) { - ret.push_back((*currentDss)[i]); - } - for (uint32_t i = 0; i < maxSubslice; i++) { - if (isBitOn(currentDss, i)) { - for (uint32_t j = 0; j < euStride; j++) - ret.push_back((*euDss)[j]); - } else { - for (uint32_t j = 0; j < euStride; j++) - ret.push_back(0); - } - } - if (ret.size() != totalLength) { - xeLog("Error while rebuilding i915 topology %ld %d\n", ret.size(), totalLength); - return {}; - } - return ret; -} - } // 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 05fcb3190c..a7e11ab28c 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h @@ -92,7 +92,7 @@ class IoctlHelperXe : public IoctlHelper { std::string getIoctlString(DrmIoctl ioctlRequest) const override; int createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_t drmVmId, uint32_t deviceIndex) override; std::string getDrmParamString(DrmParam param) const override; - + bool getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData, TopologyMap &topologyMap) override; std::string getFileForMaxGpuFrequency() const override; std::string getFileForMaxGpuFrequencyOfSubDevice(int subDeviceId) const override; std::string getFileForMaxMemoryFrequencyOfSubDevice(int subDeviceId) const override; @@ -101,8 +101,8 @@ class IoctlHelperXe : public IoctlHelper { bool isWaitBeforeBindRequired(bool bind) const override; std::unique_ptr createEngineInfo(bool isSysmanEnabled) override; std::unique_ptr createMemoryInfo() override; - - std::vector xeRebuildi915Topology(std::vector *geomDss, std::vector *computeDss, std::vector *euDss); + void getTopologyData(uint32_t nTiles, std::vector> geomDss[2], std::vector> computeDss[2], std::vector> euDss[2], DrmQueryTopologyData &topologyData, bool &isComputeDssEmpty); + void getTopologyMap(uint32_t nTiles, std::vector> dssInfo[2], TopologyMap &topologyMap); private: template @@ -144,7 +144,6 @@ class IoctlHelperXe : public IoctlHelper { int instance = 0; uint32_t xeTimestampFrequency = 0; std::vector hwconfigFakei915; - std::vector topologyFakei915; std::vector contextParamEngine; std::vector allEngines; }; diff --git a/shared/test/common/libult/linux/drm_mock.h b/shared/test/common/libult/linux/drm_mock.h index 866381b0d4..2d15570be8 100644 --- a/shared/test/common/libult/linux/drm_mock.h +++ b/shared/test/common/libult/linux/drm_mock.h @@ -51,7 +51,6 @@ class DrmMock : public Drm { using Drm::setupIoctlHelper; using Drm::sliceCountChangeSupported; using Drm::systemInfo; - using Drm::translateTopologyInfo; using Drm::virtualMemoryIds; DrmMock(int fd, RootDeviceEnvironment &rootDeviceEnvironment); diff --git a/shared/test/unit_test/os_interface/linux/drm_query_topology_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_query_topology_prelim_tests.cpp index eaf7a94dfa..cd7f7208c2 100644 --- a/shared/test/unit_test/os_interface/linux/drm_query_topology_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_query_topology_prelim_tests.cpp @@ -25,7 +25,7 @@ TEST(DrmQueryTopologyTest, givenDrmWhenQueryTopologyCalledThenPassNoFlags) { auto executionEnvironment = std::make_unique(); DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; EXPECT_TRUE(drm.queryTopology(*drm.context.hwInfo, topologyData)); @@ -125,7 +125,7 @@ struct QueryTopologyTests : ::testing::Test { TEST_F(QueryTopologyTests, givenZeroTilesWhenQueryingThenFallbackToQueryTopology) { createDrm(0); - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData); @@ -144,7 +144,7 @@ TEST_F(QueryTopologyTests, givenNonZeroTilesWhenDebugFlagDisabledThenFallbackToQ DebugManager.flags.UseNewQueryTopoIoctl.set(false); createDrm(2); - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData); @@ -162,7 +162,7 @@ TEST_F(QueryTopologyTests, givenNonZeroTilesWhenDebugFlagDisabledThenFallbackToQ TEST_F(QueryTopologyTests, givenNonZeroTilesWhenQueryingThenUseOnlyNewIoctl) { createDrm(2); - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData); @@ -182,7 +182,7 @@ TEST_F(QueryTopologyTests, givenNonZeroTilesWithoutEngineInfoThenFallback) { drmMock->engineInfo.reset(); - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData); EXPECT_EQ(0u, drmMock->queryComputeSlicesCallCount); @@ -201,7 +201,7 @@ TEST_F(QueryTopologyTests, givenNonZeroTilesWhenFailOnNewQueryThenFallback) { drmMock->queryComputeSlicesEuCount = 0; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData); EXPECT_EQ(2u, drmMock->queryComputeSlicesCallCount); @@ -220,7 +220,7 @@ TEST_F(QueryTopologyTests, givenNonZeroTilesWhenIncorrectValuesQueriedThenFallba drmMock->failOnQuery = true; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData); EXPECT_EQ(1u, drmMock->queryComputeSlicesCallCount); @@ -239,7 +239,7 @@ TEST_F(QueryTopologyTests, givenAsymetricTilesWhenQueryingThenPickSmallerValue) drmMock->useSmallerValuesOnSecondCall = true; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData); EXPECT_EQ(drmMock->queryComputeSlicesSCount / 2, topologyData.sliceCount); @@ -256,7 +256,7 @@ TEST_F(QueryTopologyTests, givenAsymetricTilesWhenGettingSliceMappingsThenCorrec drmMock->useSmallerValuesOnSecondCall = true; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData); auto device0SliceMapping = drmMock->getSliceMappings(0); @@ -277,7 +277,7 @@ TEST_F(QueryTopologyTests, givenNonZeroTilesAndFallbackPathWhenGettingSliceMappi DebugManager.flags.UseNewQueryTopoIoctl.set(false); createDrm(2); - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData); @@ -300,7 +300,7 @@ TEST_F(QueryTopologyTests, givenNonZeroTilesAndFallbackPathWhenGettingSliceMappi TEST_F(QueryTopologyTests, givenDrmWhenGettingTopologyMapThenCorrectMapIsReturned) { createDrm(2); - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData); auto topologyMap = drmMock->getTopologyMap(); diff --git a/shared/test/unit_test/os_interface/linux/drm_query_topology_upstream_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_query_topology_upstream_tests.cpp index fc93b979ba..eced6a1136 100644 --- a/shared/test/unit_test/os_interface/linux/drm_query_topology_upstream_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_query_topology_upstream_tests.cpp @@ -18,7 +18,7 @@ TEST(DrmQueryTopologyTest, GivenDrmWhenQueryingTopologyInfoCorrectMaxValuesAreSe auto executionEnvironment = std::make_unique(); DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; EXPECT_TRUE(drm.queryTopology(*executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(), topologyData)); @@ -35,7 +35,7 @@ TEST(DrmQueryTopologyTest, givenDrmWhenGettingSliceMappingsThenCorrectMappingRet auto executionEnvironment = std::make_unique(); DrmMock drmMock{*executionEnvironment->rootDeviceEnvironments[0]}; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; EXPECT_TRUE(drmMock.queryTopology(*executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(), topologyData)); diff --git a/shared/test/unit_test/os_interface/linux/drm_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_tests.cpp index 00ff7dc5bc..f9dd24a819 100644 --- a/shared/test/unit_test/os_interface/linux/drm_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_tests.cpp @@ -1001,7 +1001,7 @@ TEST(DrmQueryTest, GivenLessAvailableSubSlicesThanMaxSubSlicesWhenQueryingTopolo DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; drm.disableSomeTopology = true; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drm.storedSVal = 4; drm.storedSSVal = drm.storedSVal * 7; drm.storedEUVal = drm.storedSSVal * 4; @@ -1022,7 +1022,7 @@ TEST(DrmQueryTest, givenDrmWhenGettingTopologyMapThenCorrectMapIsReturned) { *executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo() = *NEO::defaultHwInfo.get(); DrmMock drmMock{*executionEnvironment->rootDeviceEnvironments[0]}; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; EXPECT_TRUE(drmMock.queryTopology(*executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(), topologyData)); @@ -1041,7 +1041,7 @@ TEST(DrmQueryTest, GivenSingleSliceConfigWhenQueryingTopologyInfoThenSubsliceInd *executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo() = *NEO::defaultHwInfo.get(); DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drm.storedSVal = 1; drm.storedSSVal = drm.storedSVal * 7; drm.storedEUVal = drm.storedSSVal * 4; @@ -1073,7 +1073,7 @@ TEST(DrmQueryTest, GivenMultiSliceConfigWhenQueryingTopologyInfoThenSubsliceIndi *executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo() = *NEO::defaultHwInfo.get(); DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; drm.storedSVal = 2; drm.storedSSVal = drm.storedSVal * 7; drm.storedEUVal = drm.storedSSVal * 4; diff --git a/shared/test/unit_test/os_interface/linux/product_helper_linux_tests.cpp b/shared/test/unit_test/os_interface/linux/product_helper_linux_tests.cpp index b47ea269f8..3d351c8c24 100644 --- a/shared/test/unit_test/os_interface/linux/product_helper_linux_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/product_helper_linux_tests.cpp @@ -118,7 +118,7 @@ TEST_F(MockProductHelperTestLinux, givenInvalidTopologyDataWhenConfiguringThenRe drm->storedSSVal = storedSSVal; drm->storedEUVal = 0; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; EXPECT_FALSE(drm->queryTopology(outHwInfo, topologyData)); } @@ -128,7 +128,7 @@ TEST_F(MockProductHelperTestLinux, givenInvalidTopologyDataWhenConfiguringThenRe drm->storedSSVal = 0; drm->storedEUVal = storedEUVal; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; EXPECT_FALSE(drm->queryTopology(outHwInfo, topologyData)); } @@ -138,7 +138,7 @@ TEST_F(MockProductHelperTestLinux, givenInvalidTopologyDataWhenConfiguringThenRe drm->storedSSVal = storedSSVal; drm->storedEUVal = storedEUVal; - Drm::QueryTopologyData topologyData = {}; + DrmQueryTopologyData topologyData = {}; EXPECT_FALSE(drm->queryTopology(outHwInfo, topologyData)); } } 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 a5a0d01c9d..4368496542 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 @@ -341,73 +341,6 @@ TEST(IoctlHelperXeTest, whenGettingIoctlRequestValueThenPropertValueIsReturned) EXPECT_THROW(xeIoctlHelper->getIoctlRequestValue(DrmIoctl::DebuggerOpen), std::runtime_error); } -int verifTopology(std::vector *gen, std::vector *org) { - if (gen->size() == org->size()) { - if (equal(gen->begin(), gen->end(), org->begin())) { - return 1; - } - } - return 0; -} - -int testTopoDg1(IoctlHelperXe *xeioctl) { - std::vector geomDss = {0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - std::vector computeDss = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - std::vector euDss = {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - std::vector topologyFakei915 = { - 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, - 0x01, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - std::vector i915Topo = xeioctl->xeRebuildi915Topology(&geomDss, &computeDss, &euDss); - return verifTopology(&i915Topo, &topologyFakei915); -} - -int testTopoPvc(IoctlHelperXe *xeioctl) { - std::vector geomDss = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - std::vector computeDss = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - std::vector euDss = {0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - std::vector topologyFakei915 = { - 0x00, 0x00, 0x01, 0x00, 0x40, 0x00, 0x08, 0x00, - 0x01, 0x00, 0x08, 0x00, 0x09, 0x00, 0x01, 0x00, - 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff}; - - std::vector i915Topo = xeioctl->xeRebuildi915Topology(&geomDss, &computeDss, &euDss); - return verifTopology(&i915Topo, &topologyFakei915); -} - -int testTopoDg2(IoctlHelperXe *xeioctl) { - std::vector geomDss = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}; - std::vector computeDss = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}; - std::vector euDss = {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - std::vector topologyFakei915 = { - 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x04, 0x00, 0x05, 0x00, 0x02, 0x00, - 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff}; - - std::vector i915Topo = xeioctl->xeRebuildi915Topology(&geomDss, &computeDss, &euDss); - return verifTopology(&i915Topo, &topologyFakei915); -} - TEST(IoctlHelperXeTest, verifyPublicFunctions) { auto executionEnvironment = std::make_unique(); @@ -472,17 +405,6 @@ TEST(IoctlHelperXeTest, verifyPublicFunctions) { queryItem.queryId = xeIoctlHelper->getDrmParamValue(DrmParam::QueryTopologyInfo); mockXeIoctlHelper->ioctl(DrmIoctl::Query, &query); EXPECT_EQ(0, queryItem.length); - - EXPECT_EQ(1, testTopoDg1(mockXeIoctlHelper)); - EXPECT_EQ(1, testTopoDg2(mockXeIoctlHelper)); - EXPECT_EQ(1, testTopoPvc(mockXeIoctlHelper)); - - std::vector empty = {}; - std::vector verif1 = mockXeIoctlHelper->xeRebuildi915Topology(&empty, &empty, &empty); - EXPECT_EQ(0u, verif1.size()); - std::vector zero = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - std::vector verif2 = mockXeIoctlHelper->xeRebuildi915Topology(&zero, &zero, &zero); - EXPECT_EQ(0u, verif2.size()); } TEST(IoctlHelperXeTest, whenGettingFileNamesForFrequencyThenProperStringIsReturned) { @@ -642,6 +564,12 @@ class DrmMockXe : public DrmMockCustom { } deviceQuery->size = sizeof(queryGts); break; + case DRM_XE_DEVICE_QUERY_GT_TOPOLOGY: + if (deviceQuery->data) { + memcpy_s(reinterpret_cast(deviceQuery->data), deviceQuery->size, queryTopology.data(), queryTopology.size()); + } + deviceQuery->size = static_cast(queryTopology.size()); + break; }; ret = 0; } break; @@ -670,6 +598,26 @@ class DrmMockXe : public DrmMockCustom { } return ret; } + + void addMockedQueryTopologyData(uint16_t tileId, uint16_t maskType, uint32_t nBytes, const std::vector &mask) { + + ASSERT_EQ(nBytes, mask.size()); + + auto additionalSize = 8u + nBytes; + auto oldSize = queryTopology.size(); + auto newSize = oldSize + additionalSize; + queryTopology.resize(newSize, 0u); + + uint8_t *dataPtr = queryTopology.data() + oldSize; + + drm_xe_query_topology_mask *topo = reinterpret_cast(dataPtr); + topo->gt_id = tileId; + topo->type = maskType; + topo->num_bytes = nBytes; + + memcpy_s(reinterpret_cast(topo->mask), nBytes, mask.data(), nBytes); + } + int forceIoctlAnswer = 0; int setIoctlAnswer = 0; int gemVmBindReturn = 0; @@ -686,6 +634,7 @@ class DrmMockXe : public DrmMockCustom { uint64_t queryMemUsage[37]{}; // 1 qword for num regions and 12 qwords per region uint64_t queryGts[27]{}; // 1 qword for num gts and 13 qwords per gt + std::vector queryTopology; StackVec waitUserFenceInputs; StackVec vmBindInputs; @@ -845,6 +794,307 @@ TEST(IoctlHelperXeTest, whenCallingIoctlThenProperValueIsReturned) { EXPECT_THROW(mockXeIoctlHelper->ioctl(DrmIoctl::GemContextCreateExt, NULL), std::runtime_error); drm.reset(); } + +TEST(IoctlHelperXeTest, givenGeomDssWhenGetTopologyDataAndMapThenResultsAreCorrect) { + + auto executionEnvironment = std::make_unique(); + DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; + auto &hwInfo = *executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(); + auto xeIoctlHelper = std::make_unique(drm); + + uint16_t tileId = 0; + + drm.addMockedQueryTopologyData(tileId, XE_TOPO_DSS_GEOMETRY, 8, {0b11'1111, 0, 0, 0, 0, 0, 0, 0}); + drm.addMockedQueryTopologyData(tileId, XE_TOPO_DSS_COMPUTE, 8, {0, 0, 0, 0, 0, 0, 0, 0}); + drm.addMockedQueryTopologyData(tileId, XE_TOPO_EU_PER_DSS, 8, {0b1111'1111, 0b1111'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(1, topologyData.sliceCount); + EXPECT_EQ(1, topologyData.maxSliceCount); + + EXPECT_EQ(6, topologyData.subSliceCount); + EXPECT_EQ(6, topologyData.maxSubSliceCount); + + EXPECT_EQ(96, topologyData.euCount); + EXPECT_EQ(96, topologyData.maxEuCount); + + // verify topology map + std::vector expectedSliceIndices{0}; + ASSERT_EQ(expectedSliceIndices.size(), topologyMap[tileId].sliceIndices.size()); + ASSERT_TRUE(topologyMap[tileId].sliceIndices.size() > 0); + + for (auto i = 0u; i < expectedSliceIndices.size(); i++) { + EXPECT_EQ(expectedSliceIndices[i], topologyMap[tileId].sliceIndices[i]); + } + + std::vector expectedSubSliceIndices{0, 1, 2, 3, 4, 5}; + ASSERT_EQ(expectedSubSliceIndices.size(), topologyMap[tileId].subsliceIndices.size()); + ASSERT_TRUE(topologyMap[tileId].subsliceIndices.size() > 0); + + for (auto i = 0u; i < expectedSubSliceIndices.size(); i++) { + EXPECT_EQ(expectedSubSliceIndices[i], topologyMap[tileId].subsliceIndices[i]); + } +} + +TEST(IoctlHelperXeTest, givenComputeDssWhenGetTopologyDataAndMapThenResultsAreCorrect) { + + auto executionEnvironment = std::make_unique(); + DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; + auto &hwInfo = *executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(); + auto xeIoctlHelper = std::make_unique(drm); + + uint16_t tileId = 0; + drm.addMockedQueryTopologyData(tileId, XE_TOPO_DSS_GEOMETRY, 8, {0, 0, 0, 0, 0, 0, 0, 0}); + drm.addMockedQueryTopologyData(tileId, XE_TOPO_DSS_COMPUTE, 8, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}); + drm.addMockedQueryTopologyData(tileId, XE_TOPO_EU_PER_DSS, 8, {0b1111'1111, 0, 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(1, topologyData.sliceCount); + EXPECT_EQ(1, topologyData.maxSliceCount); + + EXPECT_EQ(64, topologyData.subSliceCount); + EXPECT_EQ(64, topologyData.maxSubSliceCount); + + EXPECT_EQ(512, topologyData.euCount); + EXPECT_EQ(512, topologyData.maxEuCount); + + // verify topology map + std::vector expectedSliceIndices = {0}; + ASSERT_EQ(expectedSliceIndices.size(), topologyMap[tileId].sliceIndices.size()); + ASSERT_TRUE(topologyMap[tileId].sliceIndices.size() > 0); + + for (auto i = 0u; i < expectedSliceIndices.size(); i++) { + EXPECT_EQ(expectedSliceIndices[i], topologyMap[tileId].sliceIndices[i]); + } + + std::vector expectedSubSliceIndices; + expectedSubSliceIndices.reserve(64u); + for (auto i = 0u; i < 64; i++) { + expectedSubSliceIndices.emplace_back(i); + } + + ASSERT_EQ(expectedSubSliceIndices.size(), topologyMap[tileId].subsliceIndices.size()); + ASSERT_TRUE(topologyMap[tileId].subsliceIndices.size() > 0); + + for (auto i = 0u; i < expectedSubSliceIndices.size(); i++) { + EXPECT_EQ(expectedSubSliceIndices[i], topologyMap[tileId].subsliceIndices[i]); + } +} + +TEST(IoctlHelperXeTest, given2TileAndComputeDssWhenGetTopologyDataAndMapThenResultsAreCorrect) { + + auto executionEnvironment = std::make_unique(); + DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; + auto &hwInfo = *executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(); + auto xeIoctlHelper = std::make_unique(drm); + + // symetric tiles + for (uint16_t tileId = 0; tileId < 2u; tileId++) { + drm.addMockedQueryTopologyData(tileId, XE_TOPO_DSS_GEOMETRY, 8, {0, 0, 0, 0, 0, 0, 0, 0}); + drm.addMockedQueryTopologyData(tileId, XE_TOPO_DSS_COMPUTE, 8, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}); + drm.addMockedQueryTopologyData(tileId, XE_TOPO_EU_PER_DSS, 4, {0b1111'1111, 0, 0, 0}); + } + + DrmQueryTopologyData topologyData{}; + TopologyMap topologyMap{}; + + auto result = xeIoctlHelper->getTopologyDataAndMap(hwInfo, topologyData, topologyMap); + ASSERT_TRUE(result); + + // verify topology data + EXPECT_EQ(1, topologyData.sliceCount); + EXPECT_EQ(1, topologyData.maxSliceCount); + + EXPECT_EQ(64, topologyData.subSliceCount); + EXPECT_EQ(64, topologyData.maxSubSliceCount); + + EXPECT_EQ(512, topologyData.euCount); + EXPECT_EQ(512, topologyData.maxEuCount); + + // verify topology map + for (auto tileId : {0u, 1u}) { + std::vector expectedSliceIndices{0}; + + ASSERT_EQ(expectedSliceIndices.size(), topologyMap[tileId].sliceIndices.size()); + ASSERT_TRUE(topologyMap[tileId].sliceIndices.size() > 0); + + for (auto i = 0u; i < expectedSliceIndices.size(); i++) { + EXPECT_EQ(expectedSliceIndices[i], topologyMap[tileId].sliceIndices[i]); + } + + std::vector expectedSubSliceIndices; + expectedSubSliceIndices.reserve(64u); + for (auto i = 0u; i < 64; i++) { + expectedSubSliceIndices.emplace_back(i); + } + + ASSERT_EQ(expectedSubSliceIndices.size(), topologyMap[tileId].subsliceIndices.size()); + ASSERT_TRUE(topologyMap[tileId].subsliceIndices.size() > 0); + + for (auto i = 0u; i < expectedSubSliceIndices.size(); i++) { + EXPECT_EQ(expectedSubSliceIndices[i], topologyMap[tileId].subsliceIndices[i]); + } + } +} + +TEST(IoctlHelperXeTest, given2TileWithDisabledDssOn1TileAndComputeDssWhenGetTopologyDataAndMapThenResultsAreCorrect) { + auto executionEnvironment = std::make_unique(); + DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; + auto &hwInfo = *executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(); + auto xeIoctlHelper = std::make_unique(drm); + + // half dss disabled on tile 0 + uint16_t tileId = 0; + drm.addMockedQueryTopologyData(tileId, XE_TOPO_DSS_GEOMETRY, 8, {0, 0, 0, 0, 0, 0, 0, 0}); + drm.addMockedQueryTopologyData(tileId, XE_TOPO_DSS_COMPUTE, 8, {0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0}); + drm.addMockedQueryTopologyData(tileId, XE_TOPO_EU_PER_DSS, 4, {0b1111'1111, 0, 0, 0}); + + tileId = 1; + drm.addMockedQueryTopologyData(tileId, XE_TOPO_DSS_GEOMETRY, 8, {0, 0, 0, 0, 0, 0, 0, 0}); + drm.addMockedQueryTopologyData(tileId, XE_TOPO_DSS_COMPUTE, 8, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}); + drm.addMockedQueryTopologyData(tileId, XE_TOPO_EU_PER_DSS, 4, {0b1111'1111, 0, 0, 0}); + + DrmQueryTopologyData topologyData{}; + TopologyMap topologyMap{}; + + auto result = xeIoctlHelper->getTopologyDataAndMap(hwInfo, topologyData, topologyMap); + ASSERT_TRUE(result); + + // verify topology data + EXPECT_EQ(1, topologyData.sliceCount); + EXPECT_EQ(1, topologyData.maxSliceCount); + + EXPECT_EQ(32, topologyData.subSliceCount); + EXPECT_EQ(64, topologyData.maxSubSliceCount); + + EXPECT_EQ(256, topologyData.euCount); + EXPECT_EQ(512, topologyData.maxEuCount); + + // verify topology map + constexpr uint32_t nTiles = 2; + std::vector expectedSubSliceIndices[nTiles]; + expectedSubSliceIndices[0].reserve(32u); + for (auto i = 0u; i < 32; i++) { + expectedSubSliceIndices[0].emplace_back(i); + } + + expectedSubSliceIndices[1].reserve(64u); + for (auto i = 0u; i < 64; i++) { + expectedSubSliceIndices[1].emplace_back(i); + } + + for (auto tileId : {0u, 1u}) { + std::vector expectedSliceIndices{0}; + + ASSERT_EQ(expectedSliceIndices.size(), topologyMap[tileId].sliceIndices.size()); + ASSERT_TRUE(topologyMap[tileId].sliceIndices.size() > 0); + + for (auto i = 0u; i < expectedSliceIndices.size(); i++) { + EXPECT_EQ(expectedSliceIndices[i], topologyMap[tileId].sliceIndices[i]); + } + + ASSERT_EQ(expectedSubSliceIndices[tileId].size(), topologyMap[tileId].subsliceIndices.size()); + ASSERT_TRUE(topologyMap[tileId].subsliceIndices.size() > 0); + + for (auto i = 0u; i < expectedSubSliceIndices[tileId].size(); i++) { + EXPECT_EQ(expectedSubSliceIndices[tileId][i], topologyMap[tileId].subsliceIndices[i]); + } + } +} + +TEST(IoctlHelperXeTest, given2TileWithDisabledEvenDssAndComputeDssWhenGetTopologyDataAndMapThenResultsAreCorrect) { + + auto executionEnvironment = std::make_unique(); + DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; + auto &hwInfo = *executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(); + auto xeIoctlHelper = std::make_unique(drm); + + for (uint16_t tileId = 0; tileId < 2u; tileId++) { + // even dss disabled + uint8_t data = 0b1010'1010; + + drm.addMockedQueryTopologyData(tileId, XE_TOPO_DSS_GEOMETRY, 8, {0, 0, 0, 0, 0, 0, 0, 0}); + drm.addMockedQueryTopologyData(tileId, XE_TOPO_DSS_COMPUTE, 8, {data, data, data, data, data, data, data, data}); + drm.addMockedQueryTopologyData(tileId, XE_TOPO_EU_PER_DSS, 4, {0b1111'1111, 0, 0, 0}); + } + + DrmQueryTopologyData topologyData{}; + TopologyMap topologyMap{}; + + auto result = xeIoctlHelper->getTopologyDataAndMap(hwInfo, topologyData, topologyMap); + ASSERT_TRUE(result); + + // verify topology data + EXPECT_EQ(1, topologyData.sliceCount); + EXPECT_EQ(1, topologyData.maxSliceCount); + + EXPECT_EQ(32, topologyData.subSliceCount); + EXPECT_EQ(32, topologyData.maxSubSliceCount); + + EXPECT_EQ(256, topologyData.euCount); + EXPECT_EQ(256, topologyData.maxEuCount); + + // verify topology map + + for (auto tileId : {0u, 1u}) { + std::vector expectedSliceIndices{0}; + + ASSERT_EQ(expectedSliceIndices.size(), topologyMap[tileId].sliceIndices.size()); + ASSERT_TRUE(topologyMap[tileId].sliceIndices.size() > 0); + + for (auto i = 0u; i < expectedSliceIndices.size(); i++) { + EXPECT_EQ(expectedSliceIndices[i], topologyMap[tileId].sliceIndices[i]); + } + + std::vector expectedSubSliceIndices; + expectedSubSliceIndices.reserve(32u); + for (auto i = 0u; i < 32; i++) { + auto dssIndex = i * 2 + 1; + expectedSubSliceIndices.emplace_back(dssIndex); + } + + ASSERT_EQ(expectedSubSliceIndices.size(), topologyMap[tileId].subsliceIndices.size()); + ASSERT_TRUE(topologyMap[tileId].subsliceIndices.size() > 0); + + for (auto i = 0u; i < expectedSubSliceIndices.size(); i++) { + EXPECT_EQ(expectedSubSliceIndices[i], topologyMap[tileId].subsliceIndices[i]); + } + } +} + +TEST(IoctlHelperXeTest, givenInvalidTypeFlagGetTopologyDataAndMapThenReturnFalse) { + + auto executionEnvironment = std::make_unique(); + DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; + auto &hwInfo = *executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(); + auto xeIoctlHelper = std::make_unique(drm); + + uint16_t tileId = 0; + + uint16_t incorrectFlagType = 128u; + drm.addMockedQueryTopologyData(tileId, incorrectFlagType, 8, {0b11'1111, 0, 0, 0, 0, 0, 0, 0}); + drm.addMockedQueryTopologyData(tileId, incorrectFlagType, 8, {0, 0, 0, 0, 0, 0, 0, 0}); + drm.addMockedQueryTopologyData(tileId, incorrectFlagType, 8, {0b1111'1111, 0b1111'1111, 0, 0, 0, 0, 0, 0}); + + DrmQueryTopologyData topologyData{}; + TopologyMap topologyMap{}; + + auto result = xeIoctlHelper->getTopologyDataAndMap(hwInfo, topologyData, topologyMap); + EXPECT_FALSE(result); +} + TEST(IoctlHelperXeTest, whenCreatingEngineInfoThenProperEnginesAreDiscovered) { DebugManagerStateRestore restorer; auto executionEnvironment = std::make_unique();