From 282922693755c9c7b1d7fdd6f44f07c2ddf72c5b Mon Sep 17 00:00:00 2001 From: Zbigniew Zdanowicz Date: Mon, 31 May 2021 16:58:10 +0000 Subject: [PATCH] Improve query PCI info Signed-off-by: Zbigniew Zdanowicz --- opencl/source/dll/linux/drm_neo_create.cpp | 3 + .../linux/os_interface_linux_tests.cpp | 1 + .../os_interface/linux/drm_neo_create.cpp | 2 + .../os_interface/linux/drm_tests.cpp | 31 +++++++ .../os_interface/windows/gdi_dll_fixture.h | 3 + .../os_interface/windows/wddm20_tests.cpp | 72 +++------------- shared/source/os_interface/linux/drm_neo.cpp | 24 ++---- shared/source/os_interface/linux/drm_neo.h | 83 ++++++++++--------- .../source/os_interface/windows/wddm/wddm.cpp | 18 +--- shared/test/common/mock_gdi/gdi32_mock.def | 1 + shared/test/common/mock_gdi/mock_gdi.cpp | 9 +- shared/test/common/mock_gdi/mock_gdi.h | 1 + 12 files changed, 120 insertions(+), 128 deletions(-) diff --git a/opencl/source/dll/linux/drm_neo_create.cpp b/opencl/source/dll/linux/drm_neo_create.cpp index e904f2dded..209f56a50e 100644 --- a/opencl/source/dll/linux/drm_neo_create.cpp +++ b/opencl/source/dll/linux/drm_neo_create.cpp @@ -123,6 +123,9 @@ Drm *Drm::create(std::unique_ptr hwDeviceId, RootDeviceEnvironmen printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "INFO: Device doesn't support GEM Virtual Memory\n"); } } + + drmObject->queryAdapterBDF(); + return drmObject.release(); } diff --git a/opencl/test/unit_test/linux/os_interface_linux_tests.cpp b/opencl/test/unit_test/linux/os_interface_linux_tests.cpp index 25d1fd0b94..42f506f573 100644 --- a/opencl/test/unit_test/linux/os_interface_linux_tests.cpp +++ b/opencl/test/unit_test/linux/os_interface_linux_tests.cpp @@ -26,6 +26,7 @@ TEST(OsInterfaceTest, whenOsInterfaceSetupsGmmInputArgsThenFileDescriptorIsSetWi auto drm = new DrmMock(fakeFd, *rootDeviceEnvironment); drm->setPciPath("01:23.4"); + EXPECT_EQ(0, drm->queryAdapterBDF()); osInterface->setDriverModel(std::unique_ptr(drm)); diff --git a/opencl/test/unit_test/os_interface/linux/drm_neo_create.cpp b/opencl/test/unit_test/os_interface/linux/drm_neo_create.cpp index f39885c0db..4b94654a34 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_neo_create.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_neo_create.cpp @@ -40,6 +40,8 @@ Drm *Drm::create(std::unique_ptr hwDeviceId, RootDeviceEnvironmen const HardwareInfo *hwInfo = rootDeviceEnvironment.getHardwareInfo(); + drm->queryAdapterBDF(); + drm->queryMemoryInfo(); if (drm->isVmBindAvailable() && rootDeviceEnvironment.executionEnvironment.isDebuggingEnabled()) { 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 b31546cd35..af120e904d 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_tests.cpp @@ -45,21 +45,52 @@ TEST(DrmTest, GivenValidPciPathWhenGettingAdapterBdfThenCorrectValuesAreReturned { drm.setPciPath("ab:cd.e"); + EXPECT_EQ(0, drm.queryAdapterBDF()); auto adapterBdf = drm.getAdapterBDF(); EXPECT_EQ(0xabu, adapterBdf.Bus); EXPECT_EQ(0xcdu, adapterBdf.Device); EXPECT_EQ(0xeu, adapterBdf.Function); + + auto pciInfo = drm.getPciBusInfo(); + EXPECT_EQ(0x0u, pciInfo.pciDomain); + EXPECT_EQ(0xabu, pciInfo.pciBus); + EXPECT_EQ(0xcdu, pciInfo.pciDevice); + EXPECT_EQ(0xeu, pciInfo.pciFunction); } { drm.setPciPath("01:23.4"); + EXPECT_EQ(0, drm.queryAdapterBDF()); auto adapterBdf = drm.getAdapterBDF(); EXPECT_EQ(0x1u, adapterBdf.Bus); EXPECT_EQ(0x23u, adapterBdf.Device); EXPECT_EQ(0x4u, adapterBdf.Function); + + auto pciInfo = drm.getPciBusInfo(); + EXPECT_EQ(0x0u, pciInfo.pciDomain); + EXPECT_EQ(0x1u, pciInfo.pciBus); + EXPECT_EQ(0x23u, pciInfo.pciDevice); + EXPECT_EQ(0x4u, pciInfo.pciFunction); } } +TEST(DrmTest, GivenInvalidPciPathWhenGettingAdapterBdfThenInvalidPciInfoIsReturned) { + auto executionEnvironment = std::make_unique(); + executionEnvironment->prepareRootDeviceEnvironments(1); + DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; + + drm.setPciPath("invalidPci"); + EXPECT_EQ(1, drm.queryAdapterBDF()); + auto adapterBdf = drm.getAdapterBDF(); + EXPECT_EQ(std::numeric_limits::max(), adapterBdf.Data); + + auto pciInfo = drm.getPciBusInfo(); + EXPECT_EQ(PhysicalDevicePciBusInfo::InvalidValue, pciInfo.pciDomain); + EXPECT_EQ(PhysicalDevicePciBusInfo::InvalidValue, pciInfo.pciBus); + EXPECT_EQ(PhysicalDevicePciBusInfo::InvalidValue, pciInfo.pciDevice); + EXPECT_EQ(PhysicalDevicePciBusInfo::InvalidValue, pciInfo.pciFunction); +} + TEST(DrmTest, GivenInvalidPciPathWhenFrequencyIsQueriedThenReturnError) { auto executionEnvironment = std::make_unique(); executionEnvironment->prepareRootDeviceEnvironments(1); diff --git a/opencl/test/unit_test/os_interface/windows/gdi_dll_fixture.h b/opencl/test/unit_test/os_interface/windows/gdi_dll_fixture.h index 46d22e4bc8..b68c12ddab 100644 --- a/opencl/test/unit_test/os_interface/windows/gdi_dll_fixture.h +++ b/opencl/test/unit_test/os_interface/windows/gdi_dll_fixture.h @@ -51,6 +51,8 @@ struct GdiDllFixture { reinterpret_cast(mockGdiDll->getProcAddress("getRegisterTrimNotificationFailCall")); getLastPriorityFcn = reinterpret_cast(mockGdiDll->getProcAddress("getLastPriority")); + setAdapterBDFFcn = + reinterpret_cast(mockGdiDll->getProcAddress("setAdapterBDF")); setMockLastDestroyedResHandleFcn((D3DKMT_HANDLE)0); *getDestroySynchronizationObjectDataFcn() = {}; *getCreateSynchronizationObject2FailCallFcn() = false; @@ -89,4 +91,5 @@ struct GdiDllFixture { decltype(&getCreateSynchronizationObject2FailCall) getCreateSynchronizationObject2FailCallFcn = nullptr; decltype(&getRegisterTrimNotificationFailCall) getRegisterTrimNotificationFailCallFcn = nullptr; decltype(&getLastPriority) getLastPriorityFcn = nullptr; + decltype(&setAdapterBDF) setAdapterBDFFcn = nullptr; }; diff --git a/opencl/test/unit_test/os_interface/windows/wddm20_tests.cpp b/opencl/test/unit_test/os_interface/windows/wddm20_tests.cpp index 7ec551c657..f9944aceb5 100644 --- a/opencl/test/unit_test/os_interface/windows/wddm20_tests.cpp +++ b/opencl/test/unit_test/os_interface/windows/wddm20_tests.cpp @@ -1555,80 +1555,32 @@ TEST_F(WddmTestWithMockGdiDll, givenValidInputwhenSettingAllocationPriorityThenT EXPECT_EQ(DXGI_RESOURCE_PRIORITY_NORMAL, getLastPriorityFcn()); } -struct GdiWithMockedQueryAdapterInfoFunc : public MockGdi { - GdiWithMockedQueryAdapterInfoFunc() : MockGdi() { - queryAdapterInfo = mockQueryAdapterInfo; - GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCalled = 0u; - } - static NTSTATUS __stdcall mockQueryAdapterInfo(IN CONST D3DKMT_QUERYADAPTERINFO *adapterInfo) { - ++queryAdapterInfoCalled; +TEST_F(WddmTestWithMockGdiDll, givenQueryAdapterInfoCallReturnsSuccesThenPciBusInfoIsValid) { + ADAPTER_BDF queryAdapterBDF{}; + queryAdapterBDF.Bus = 1; + queryAdapterBDF.Device = 2; + queryAdapterBDF.Function = 3; + setAdapterBDFFcn(queryAdapterBDF); - if (queryAdapterInfoCallAlwaysReturnsUnsuccessful) { - return STATUS_UNSUCCESSFUL; - } - - if (adapterInfo->Type != KMTQAITYPE_ADAPTERADDRESS) { - return STATUS_NOT_IMPLEMENTED; - } - - if (adapterInfo->PrivateDriverDataSize != sizeof(D3DKMT_ADAPTERADDRESS)) { - return STATUS_INFO_LENGTH_MISMATCH; - } - - D3DKMT_ADAPTERADDRESS *adapterAddress = static_cast(adapterInfo->pPrivateDriverData); - adapterAddress->BusNumber = 1; - adapterAddress->DeviceNumber = 2; - adapterAddress->FunctionNumber = 3; - - return STATUS_SUCCESS; - } - static uint32_t queryAdapterInfoCalled; - static bool queryAdapterInfoCallAlwaysReturnsUnsuccessful; -}; - -uint32_t GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCalled; -bool GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCallAlwaysReturnsUnsuccessful; - -TEST(VerifyPciBusInfo, givenQueryAdapterInfoCallReturnsSuccesThenPciBusInfoIsValid) { - GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCallAlwaysReturnsUnsuccessful = false; - - auto osEnv = std::make_unique(); - osEnv->gdi = std::make_unique(); - - MockExecutionEnvironment executionEnvironment; - executionEnvironment.osEnvironment = std::move(osEnv); - - RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment); - - std::unique_ptr wddm(Wddm::createWddm(nullptr, rootDeviceEnvironment)); + EXPECT_TRUE(wddm->queryAdapterInfo()); auto pciBusInfo = wddm->getPciBusInfo(); - EXPECT_EQ(GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCalled, 1u); - EXPECT_EQ(pciBusInfo.pciDomain, 0u); EXPECT_EQ(pciBusInfo.pciBus, 1u); EXPECT_EQ(pciBusInfo.pciDevice, 2u); EXPECT_EQ(pciBusInfo.pciFunction, 3u); } -TEST(VerifyPciBusInfo, givenQueryAdapterInfoCallReturnsErrorThenPciBusInfoIsNotValid) { - GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCallAlwaysReturnsUnsuccessful = true; +TEST_F(WddmTestWithMockGdiDll, givenQueryAdapterInfoCallReturnsInvalidAdapterBDFThenPciBusInfoIsNotValid) { + ADAPTER_BDF queryAdapterBDF{}; + queryAdapterBDF.Data = std::numeric_limits::max(); + setAdapterBDFFcn(queryAdapterBDF); - auto osEnv = std::make_unique(); - osEnv->gdi = std::make_unique(); - - MockExecutionEnvironment executionEnvironment; - executionEnvironment.osEnvironment = std::move(osEnv); - - RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment); - - std::unique_ptr wddm(Wddm::createWddm(nullptr, rootDeviceEnvironment)); + EXPECT_TRUE(wddm->queryAdapterInfo()); auto pciBusInfo = wddm->getPciBusInfo(); - EXPECT_EQ(GdiWithMockedQueryAdapterInfoFunc::queryAdapterInfoCalled, 1u); - EXPECT_EQ(pciBusInfo.pciDomain, PhysicalDevicePciBusInfo::InvalidValue); EXPECT_EQ(pciBusInfo.pciBus, PhysicalDevicePciBusInfo::InvalidValue); EXPECT_EQ(pciBusInfo.pciDevice, PhysicalDevicePciBusInfo::InvalidValue); diff --git a/shared/source/os_interface/linux/drm_neo.cpp b/shared/source/os_interface/linux/drm_neo.cpp index e559bb1941..1231e11e84 100644 --- a/shared/source/os_interface/linux/drm_neo.cpp +++ b/shared/source/os_interface/linux/drm_neo.cpp @@ -702,15 +702,12 @@ bool Drm::translateTopologyInfo(const drm_i915_query_topology_info *queryTopolog PhysicalDevicePciBusInfo Drm::getPciBusInfo() const { PhysicalDevicePciBusInfo pciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue); - UNRECOVERABLE_IF(hwDeviceId == nullptr); - - const int pciBusInfoTokensNum = 3; - pciBusInfo.pciDomain = 0; - - if (std::sscanf(hwDeviceId->getPciPath(), "%02x:%02x.%01x", &(pciBusInfo.pciBus), &(pciBusInfo.pciDevice), &(pciBusInfo.pciFunction)) != pciBusInfoTokensNum) { - pciBusInfo.pciDomain = pciBusInfo.pciBus = pciBusInfo.pciDevice = pciBusInfo.pciFunction = PhysicalDevicePciBusInfo::InvalidValue; + if (adapterBDF.Data != std::numeric_limits::max()) { + pciBusInfo.pciDomain = 0; + pciBusInfo.pciBus = adapterBDF.Bus; + pciBusInfo.pciDevice = adapterBDF.Device; + pciBusInfo.pciFunction = adapterBDF.Function; } - return pciBusInfo; } @@ -719,21 +716,18 @@ Drm::~Drm() { this->printIoctlStatistics(); } -ADAPTER_BDF Drm::getAdapterBDF() const { - - ADAPTER_BDF adapterBDF{}; +int Drm::queryAdapterBDF() { constexpr int pciBusInfoTokensNum = 3; - uint32_t bus, device, function; if (std::sscanf(hwDeviceId->getPciPath(), "%02x:%02x.%01x", &bus, &device, &function) != pciBusInfoTokensNum) { - return {}; + adapterBDF.Data = std::numeric_limits::max(); + return 1; } adapterBDF.Bus = bus; adapterBDF.Function = function; adapterBDF.Device = device; - - return adapterBDF; + return 0; } void Drm::setGmmInputArgs(void *args) { diff --git a/shared/source/os_interface/linux/drm_neo.h b/shared/source/os_interface/linux/drm_neo.h index 45bff06b07..a54237832f 100644 --- a/shared/source/os_interface/linux/drm_neo.h +++ b/shared/source/os_interface/linux/drm_neo.h @@ -103,7 +103,10 @@ class Drm : public DriverModel { MOCKABLE_VIRTUAL void checkPreemptionSupport(); inline int getFileDescriptor() const { return hwDeviceId->getFileDescriptor(); } - ADAPTER_BDF getAdapterBDF() const; + ADAPTER_BDF getAdapterBDF() const { + return adapterBDF; + } + int queryAdapterBDF(); int createDrmVirtualMemory(uint32_t &drmVmId); void destroyDrmVirtualMemory(uint32_t drmVmId); uint32_t createDrmContext(uint32_t drmVmId, bool isSpecialContextRequested); @@ -212,48 +215,18 @@ class Drm : public DriverModel { struct TopologyMapping { std::vector sliceIndices; }; + + Drm(std::unique_ptr hwDeviceIdIn, RootDeviceEnvironment &rootDeviceEnvironment); + int getQueueSliceCount(drm_i915_gem_context_param_sseu *sseu); bool translateTopologyInfo(const drm_i915_query_topology_info *queryTopologyInfo, QueryTopologyData &data, TopologyMapping &mapping); std::string generateUUID(); std::string generateElfUUID(const void *data); - bool sliceCountChangeSupported = false; - drm_i915_gem_context_param_sseu sseu{}; - bool preemptionSupported = false; - bool nonPersistentContextsSupported = false; - bool requirePerContextVM = false; - bool bindAvailable = false; - bool directSubmissionActive = false; - bool contextDebugSupported = false; - bool newResourceBound = false; - std::once_flag checkBindOnce; - std::unique_ptr hwDeviceId; - int deviceId = 0; - int revisionId = 0; - GTTYPE eGtType = GTTYPE_UNDEFINED; - RootDeviceEnvironment &rootDeviceEnvironment; - uint64_t uuid = 0; - - Drm(std::unique_ptr hwDeviceIdIn, RootDeviceEnvironment &rootDeviceEnvironment); - std::unique_ptr systemInfo; - std::unique_ptr cacheInfo; - std::unique_ptr engineInfo; - std::unique_ptr memoryInfo; - std::vector virtualMemoryIds; - - std::array pagingFence; - std::array fenceVal; - - std::unordered_map topologyMap; - - std::string getSysFsPciPath(); - std::unique_ptr query(uint32_t queryId, uint32_t queryItemFlags, int32_t &length); - - StackVec classHandles; - - std::unordered_map> ioctlStatistics; - void printIoctlStatistics(); std::string ioctlToString(unsigned long request); std::string ioctlToStringImpl(unsigned long request); + std::string getSysFsPciPath(); + std::unique_ptr query(uint32_t queryId, uint32_t queryItemFlags, int32_t &length); + void printIoctlStatistics(); #pragma pack(1) struct PCIConfig { @@ -282,6 +255,42 @@ class Drm : public DriverModel { uint8_t MaxLatency; }; #pragma pack() + + drm_i915_gem_context_param_sseu sseu{}; + ADAPTER_BDF adapterBDF{}; + + std::unordered_map topologyMap; + std::unordered_map> ioctlStatistics; + + std::array pagingFence; + std::array fenceVal; + StackVec classHandles; + std::vector virtualMemoryIds; + + std::unique_ptr hwDeviceId; + std::unique_ptr systemInfo; + std::unique_ptr cacheInfo; + std::unique_ptr engineInfo; + std::unique_ptr memoryInfo; + + std::once_flag checkBindOnce; + + RootDeviceEnvironment &rootDeviceEnvironment; + uint64_t uuid = 0; + + int deviceId = 0; + int revisionId = 0; + GTTYPE eGtType = GTTYPE_UNDEFINED; + + bool sliceCountChangeSupported = false; + bool preemptionSupported = false; + bool nonPersistentContextsSupported = false; + bool requirePerContextVM = false; + bool bindAvailable = false; + bool directSubmissionActive = false; + bool contextDebugSupported = false; + bool newResourceBound = false; + private: int getParamIoctl(int param, int *dstValue); }; diff --git a/shared/source/os_interface/windows/wddm/wddm.cpp b/shared/source/os_interface/windows/wddm/wddm.cpp index 3420e61bfd..5f0173479c 100644 --- a/shared/source/os_interface/windows/wddm/wddm.cpp +++ b/shared/source/os_interface/windows/wddm/wddm.cpp @@ -1077,22 +1077,10 @@ void Wddm::createPagingFenceLogger() { } PhysicalDevicePciBusInfo Wddm::getPciBusInfo() const { - D3DKMT_ADAPTERADDRESS adapterAddress; - D3DKMT_QUERYADAPTERINFO queryAdapterInfo; - - queryAdapterInfo.hAdapter = getAdapter(); - queryAdapterInfo.Type = KMTQAITYPE_ADAPTERADDRESS; - queryAdapterInfo.pPrivateDriverData = &adapterAddress; - queryAdapterInfo.PrivateDriverDataSize = sizeof(adapterAddress); - - auto gdi = getGdi(); - UNRECOVERABLE_IF(gdi == nullptr); - - if (gdi->queryAdapterInfo(&queryAdapterInfo) == STATUS_SUCCESS) { - return PhysicalDevicePciBusInfo(0, adapterAddress.BusNumber, adapterAddress.DeviceNumber, adapterAddress.FunctionNumber); + if (adapterBDF.Data == std::numeric_limits::max()) { + return PhysicalDevicePciBusInfo(PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue, PhysicalDevicePciBusInfo::InvalidValue); } - - return PhysicalDevicePciBusInfo::invalid(); + return PhysicalDevicePciBusInfo(0, adapterBDF.Bus, adapterBDF.Device, adapterBDF.Function); } } // namespace NEO diff --git a/shared/test/common/mock_gdi/gdi32_mock.def b/shared/test/common/mock_gdi/gdi32_mock.def index bd8968ee66..f6e9fc5abe 100644 --- a/shared/test/common/mock_gdi/gdi32_mock.def +++ b/shared/test/common/mock_gdi/gdi32_mock.def @@ -75,3 +75,4 @@ getMonitorFenceCpuFenceAddress getCreateSynchronizationObject2FailCall getRegisterTrimNotificationFailCall getLastPriority +setAdapterBDF diff --git a/shared/test/common/mock_gdi/mock_gdi.cpp b/shared/test/common/mock_gdi/mock_gdi.cpp index baf1d4d470..bfc4155c8e 100644 --- a/shared/test/common/mock_gdi/mock_gdi.cpp +++ b/shared/test/common/mock_gdi/mock_gdi.cpp @@ -16,6 +16,7 @@ uint32_t gMapGpuVaFailConfigCount = 0; uint32_t gMapGpuVaFailConfigMax = 0; uint64_t gGpuAddressSpace = 0ull; uint32_t gLastPriority = 0ull; +ADAPTER_BDF gAdapterBDF{}; #ifdef __cplusplus // If used by C++ code, extern "C" { // we need to export the C interface @@ -313,6 +314,8 @@ NTSTATUS __stdcall D3DKMTQueryAdapterInfo(IN CONST D3DKMT_QUERYADAPTERINFO *quer adapterInfo->GfxPartition.Heap32[2].Limit = gAdapterInfo.GfxPartition.Heap32[2].Limit; adapterInfo->GfxPartition.Heap32[3].Base = gAdapterInfo.GfxPartition.Heap32[3].Base; adapterInfo->GfxPartition.Heap32[3].Limit = gAdapterInfo.GfxPartition.Heap32[3].Limit; + + adapterInfo->stAdapterBDF.Data = gAdapterBDF.Data; return STATUS_SUCCESS; } return STATUS_INVALID_PARAMETER; @@ -554,4 +557,8 @@ bool *getRegisterTrimNotificationFailCall() { uint32_t getLastPriority() { return gLastPriority; -} \ No newline at end of file +} + +void setAdapterBDF(ADAPTER_BDF &adapterBDF) { + gAdapterBDF = adapterBDF; +} diff --git a/shared/test/common/mock_gdi/mock_gdi.h b/shared/test/common/mock_gdi/mock_gdi.h index 8c3a428a7a..f626338c3a 100644 --- a/shared/test/common/mock_gdi/mock_gdi.h +++ b/shared/test/common/mock_gdi/mock_gdi.h @@ -80,3 +80,4 @@ VOID *getMonitorFenceCpuFenceAddress(); bool *getCreateSynchronizationObject2FailCall(); bool *getRegisterTrimNotificationFailCall(); uint32_t getLastPriority(); +void setAdapterBDF(ADAPTER_BDF &adapterBDF);