From 83b4edddf0b5df0b85e321d6b7934f6b4f1e1623 Mon Sep 17 00:00:00 2001 From: Joshua Santosh Ranjan Date: Fri, 30 Sep 2022 12:57:38 +0000 Subject: [PATCH] Update Fabric Latency to Edge Properties Related-To: LOCI-3464 Signed-off-by: Joshua Santosh Ranjan --- .../source/fabric/linux/fabric_device_iaf.cpp | 21 ++- .../sources/fabric/linux/test_fabric_iaf.cpp | 132 ++++++++++++++++-- .../source/os_interface/linux/ioctl_helper.h | 3 + .../linux/ioctl_helper_prelim.cpp | 28 ++++ .../linux/ioctl_helper_upstream.cpp | 4 + .../linux/ioctl_helper_tests_prelim.cpp | 56 ++++++++ .../linux/ioctl_helper_tests_upstream.cpp | 8 ++ 7 files changed, 235 insertions(+), 17 deletions(-) diff --git a/level_zero/core/source/fabric/linux/fabric_device_iaf.cpp b/level_zero/core/source/fabric/linux/fabric_device_iaf.cpp index 34678d25bf..c7ab691e06 100644 --- a/level_zero/core/source/fabric/linux/fabric_device_iaf.cpp +++ b/level_zero/core/source/fabric/linux/fabric_device_iaf.cpp @@ -80,8 +80,8 @@ bool FabricDeviceIaf::getEdgeProperty(FabricVertex *neighborVertex, ze_fabric_ed memcpy_s(edgeProperty.model, ZE_MAX_FABRIC_EDGE_MODEL_EXP_SIZE, "XeLink", 7); edgeProperty.bandwidth = accumulatedBandwidth; edgeProperty.bandwidthUnit = ZE_BANDWIDTH_UNIT_BYTES_PER_NANOSEC; - edgeProperty.latency = 0; - edgeProperty.latencyUnit = ZE_LATENCY_UNIT_UNKNOWN; + edgeProperty.latency = subDeviceEdgeProperties[0].latency; + edgeProperty.latencyUnit = subDeviceEdgeProperties[0].latencyUnit; edgeProperty.duplexity = ZE_FABRIC_EDGE_EXP_DUPLEXITY_FULL_DUPLEX; isConnected = true; @@ -211,14 +211,23 @@ bool FabricSubDeviceIaf::getEdgeProperty(FabricSubDeviceIaf *pNeighbourInterface // Considering the neighboring port is attached on a subdevice, fabricId and attachId could be used from // any of the connection - memcpy_s(&uuid.id[8], 4, &pNeighbourInterface->connections[0].currentid.fabricId, 4); + auto neighbourFabricId = pNeighbourInterface->connections[0].currentid.fabricId; + memcpy_s(&uuid.id[8], 4, &neighbourFabricId, 4); memcpy_s(&uuid.id[12], 1, &pNeighbourInterface->connections[0].currentid.attachId, 1); memcpy_s(edgeProperty.model, ZE_MAX_FABRIC_EDGE_MODEL_EXP_SIZE, "XeLink", 7); edgeProperty.bandwidth = accumulatedBandwidth; edgeProperty.bandwidthUnit = ZE_BANDWIDTH_UNIT_BYTES_PER_NANOSEC; - edgeProperty.latency = 0; + + auto &osInterface = device->getNEODevice()->getRootDeviceEnvironment().osInterface; + auto pDrm = osInterface->getDriverModel()->as(); + + edgeProperty.latency = std::numeric_limits::max(); edgeProperty.latencyUnit = ZE_LATENCY_UNIT_UNKNOWN; + if (pDrm->getIoctlHelper()->getFabricLatency(neighbourFabricId, edgeProperty.latency) == true) { + edgeProperty.latencyUnit = ZE_LATENCY_UNIT_HOP; + } + edgeProperty.duplexity = ZE_FABRIC_EDGE_EXP_DUPLEXITY_FULL_DUPLEX; isConnected = true; } @@ -268,8 +277,8 @@ bool FabricSubDeviceIaf::getEdgeProperty(FabricVertex *neighborVertex, memcpy_s(edgeProperty.model, ZE_MAX_FABRIC_EDGE_MODEL_EXP_SIZE, "XeLink", 7); edgeProperty.bandwidth = accumulatedBandwidth; edgeProperty.bandwidthUnit = ZE_BANDWIDTH_UNIT_BYTES_PER_NANOSEC; - edgeProperty.latency = 0; - edgeProperty.latencyUnit = ZE_LATENCY_UNIT_UNKNOWN; + edgeProperty.latency = subEdgeProperties[0].latency; + edgeProperty.latencyUnit = subEdgeProperties[0].latencyUnit; edgeProperty.duplexity = ZE_FABRIC_EDGE_EXP_DUPLEXITY_FULL_DUPLEX; isConnected = true; diff --git a/level_zero/core/test/unit_tests/sources/fabric/linux/test_fabric_iaf.cpp b/level_zero/core/test/unit_tests/sources/fabric/linux/test_fabric_iaf.cpp index ce2c9732bb..f3d5a4e6b7 100644 --- a/level_zero/core/test/unit_tests/sources/fabric/linux/test_fabric_iaf.cpp +++ b/level_zero/core/test/unit_tests/sources/fabric/linux/test_fabric_iaf.cpp @@ -231,9 +231,31 @@ TEST_F(TestFabricIaf, GivenIafFabricAvailableWhenGetPortsReturnsErrorThenReturnE delete subDeviceFabric; } +class MockIoctlHelperIafTest : public NEO::IoctlHelperPrelim20 { + public: + using IoctlHelperPrelim20::IoctlHelperPrelim20; + bool getFabricLatency(uint32_t fabricId, uint32_t &latency) override { + latency = 1; + return mockFabricLatencyReturn; + } + + bool mockFabricLatencyReturn = true; +}; + using FabricIafEdgeFixture = Test; TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenCreatingEdgesThenEdgesCreatedAreCorrect) { + // Setup OsInterface for Devices + for (auto &device : driverHandle->devices) { + auto executionEnvironment = device->getNEODevice()->getExecutionEnvironment(); + auto &rootDeviceEnvironment = executionEnvironment->rootDeviceEnvironments[device->getRootDeviceIndex()]; + auto osInterface = new OSInterface(); + auto drmMock = new DrmMockResources(*rootDeviceEnvironment); + drmMock->ioctlHelper.reset(new MockIoctlHelperIafTest(*drmMock)); + rootDeviceEnvironment->osInterface.reset(osInterface); + executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr(drmMock)); + } + // IAF port connection configuration // Device | SubDevice | Port -- Connected to -- Device | SubDevice | Port // 0 0 1 1 0 2 @@ -410,9 +432,9 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenCreatingEdgesT EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetPropertiesExp(edges[0], &edgeProperties)); EXPECT_EQ(edgeProperties.bandwidth, 4u); EXPECT_EQ(edgeProperties.bandwidthUnit, ZE_BANDWIDTH_UNIT_BYTES_PER_NANOSEC); - EXPECT_EQ(edgeProperties.latency, 0u); - EXPECT_EQ(edgeProperties.latencyUnit, ZE_LATENCY_UNIT_UNKNOWN); - EXPECT_EQ(strcmp(edgeProperties.model, "XeLink"), 0); + EXPECT_EQ(edgeProperties.latency, 1u); + EXPECT_EQ(edgeProperties.latencyUnit, ZE_LATENCY_UNIT_HOP); + EXPECT_STREQ(edgeProperties.model, "XeLink"); EXPECT_EQ(edgeProperties.duplexity, ZE_FABRIC_EDGE_EXP_DUPLEXITY_FULL_DUPLEX); // Root to Sub-Devices Connection @@ -424,7 +446,9 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenCreatingEdgesT EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex0->toHandle(), fabricVertex1->subVertices[0], &count, edges.data())); EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetPropertiesExp(edges[0], &edgeProperties)); EXPECT_EQ(edgeProperties.bandwidth, 2u); - EXPECT_EQ(strcmp(edgeProperties.model, "XeLink"), 0); + EXPECT_EQ(edgeProperties.latency, 1u); + EXPECT_EQ(edgeProperties.latencyUnit, ZE_LATENCY_UNIT_HOP); + EXPECT_STREQ(edgeProperties.model, "XeLink"); count = 0; EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex0->toHandle(), fabricVertex1->subVertices[1], &count, nullptr)); @@ -433,7 +457,9 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenCreatingEdgesT EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex0->toHandle(), fabricVertex1->subVertices[1], &count, edges.data())); EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetPropertiesExp(edges[0], &edgeProperties)); EXPECT_EQ(edgeProperties.bandwidth, 2u); - EXPECT_EQ(strcmp(edgeProperties.model, "XeLink"), 0); + EXPECT_EQ(edgeProperties.latency, 1u); + EXPECT_EQ(edgeProperties.latencyUnit, ZE_LATENCY_UNIT_HOP); + EXPECT_STREQ(edgeProperties.model, "XeLink"); // Sub-Devices to Root Connection count = 0; @@ -443,7 +469,9 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenCreatingEdgesT EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex0->subVertices[0], fabricVertex1->toHandle(), &count, edges.data())); EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetPropertiesExp(edges[0], &edgeProperties)); EXPECT_EQ(edgeProperties.bandwidth, 2u); - EXPECT_EQ(strcmp(edgeProperties.model, "XeLink"), 0); + EXPECT_EQ(edgeProperties.latency, 1u); + EXPECT_EQ(edgeProperties.latencyUnit, ZE_LATENCY_UNIT_HOP); + EXPECT_STREQ(edgeProperties.model, "XeLink"); count = 0; EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex0->subVertices[1], fabricVertex1->toHandle(), &count, nullptr)); @@ -452,7 +480,7 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenCreatingEdgesT EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex0->subVertices[1], fabricVertex1->toHandle(), &count, edges.data())); EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetPropertiesExp(edges[0], &edgeProperties)); EXPECT_EQ(edgeProperties.bandwidth, 2u); - EXPECT_EQ(strcmp(edgeProperties.model, "XeLink"), 0); + EXPECT_STREQ(edgeProperties.model, "XeLink"); // Sub-Devices to Sub-Devices Connection count = 0; @@ -465,7 +493,7 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenCreatingEdgesT EXPECT_EQ(edgeProperties.bandwidthUnit, ZE_BANDWIDTH_UNIT_UNKNOWN); EXPECT_EQ(edgeProperties.latency, 0u); EXPECT_EQ(edgeProperties.latencyUnit, ZE_LATENCY_UNIT_UNKNOWN); - EXPECT_EQ(strcmp(edgeProperties.model, "MDFI"), 0); + EXPECT_STREQ(edgeProperties.model, "MDFI"); EXPECT_EQ(edgeProperties.duplexity, ZE_FABRIC_EDGE_EXP_DUPLEXITY_FULL_DUPLEX); count = 0; @@ -474,7 +502,7 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenCreatingEdgesT edges.clear(); EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex1->subVertices[0], fabricVertex1->subVertices[1], &count, edges.data())); EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetPropertiesExp(edges[0], &edgeProperties)); - EXPECT_EQ(strcmp(edgeProperties.model, "MDFI"), 0); + EXPECT_STREQ(edgeProperties.model, "MDFI"); count = 0; EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex1->subVertices[0], fabricVertex0->subVertices[0], &count, nullptr)); @@ -483,7 +511,9 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenCreatingEdgesT EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex1->subVertices[0], fabricVertex0->subVertices[0], &count, edges.data())); EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetPropertiesExp(edges[0], &edgeProperties)); EXPECT_EQ(edgeProperties.bandwidth, 2u); - EXPECT_EQ(strcmp(edgeProperties.model, "XeLink"), 0); + EXPECT_STREQ(edgeProperties.model, "XeLink"); + EXPECT_EQ(edgeProperties.latency, 1u); + EXPECT_EQ(edgeProperties.latencyUnit, ZE_LATENCY_UNIT_HOP); count = 0; EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex1->subVertices[1], fabricVertex0->subVertices[1], &count, nullptr)); @@ -492,7 +522,87 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenCreatingEdgesT EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex1->subVertices[1], fabricVertex0->subVertices[1], &count, edges.data())); EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetPropertiesExp(edges[0], &edgeProperties)); EXPECT_EQ(edgeProperties.bandwidth, 2u); - EXPECT_EQ(strcmp(edgeProperties.model, "XeLink"), 0); + EXPECT_STREQ(edgeProperties.model, "XeLink"); +} + +TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenLatencyRequestIoctlFailsThenEdgeLatencyPropertiesAreUnknown) { + + // Setup OsInterface for Devices + for (auto &device : driverHandle->devices) { + auto executionEnvironment = device->getNEODevice()->getExecutionEnvironment(); + auto &rootDeviceEnvironment = executionEnvironment->rootDeviceEnvironments[device->getRootDeviceIndex()]; + auto osInterface = new OSInterface(); + auto drmMock = new DrmMockResources(*rootDeviceEnvironment); + auto mockIoctlHelper = new MockIoctlHelperIafTest(*drmMock); + mockIoctlHelper->mockFabricLatencyReturn = false; + drmMock->ioctlHelper.reset(mockIoctlHelper); + rootDeviceEnvironment->osInterface.reset(osInterface); + executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr(drmMock)); + } + + // IAF port connection configuration + // Device | SubDevice | Port -- Connected to -- Device | SubDevice | Port + // 0 0 1 1 0 2 + + std::vector connection_00_10; + { + FabricPortConnection connection; + connection.currentid = IafPortId(0, 0, 1); + connection.neighbourPortNumber = 2; + connection.neighbourGuid = 0xABC; + connection.bandwidthInBytesPerNanoSecond = 1; + connection.isDuplex = true; + connection_00_10.push_back(connection); + } + + std::vector connection_10_00; + { + FabricPortConnection connection; + connection.currentid = IafPortId(1, 0, 2); + connection.neighbourPortNumber = 1; + connection.neighbourGuid = 0xA; + connection.bandwidthInBytesPerNanoSecond = 1; + connection.isDuplex = true; + connection_10_00.push_back(connection); + } + + auto &fabricVertex0 = driverHandle->fabricVertices[0]; + { + auto fabricDeviceIaf = static_cast(fabricVertex0->pFabricDeviceInterfaces[FabricDeviceInterface::Type::Iaf].get()); + auto &fabricSubDeviceIaf0 = fabricDeviceIaf->subDeviceIafs[0]; + fabricSubDeviceIaf0->connections.clear(); + fabricSubDeviceIaf0->connections = connection_00_10; + fabricSubDeviceIaf0->guid = 0xA; + } + + auto fabricVertex1 = static_cast(driverHandle->fabricVertices[1]); + { + auto fabricDeviceIaf = static_cast(fabricVertex1->pFabricDeviceInterfaces[FabricDeviceInterface::Type::Iaf].get()); + auto &fabricSubDeviceIaf0 = fabricDeviceIaf->subDeviceIafs[0]; + fabricSubDeviceIaf0->connections.clear(); + fabricSubDeviceIaf0->connections = connection_10_00; + fabricSubDeviceIaf0->guid = 0xABC; + } + + for (auto &edge : driverHandle->fabricEdges) { + delete edge; + } + driverHandle->fabricEdges.clear(); + FabricEdge::createEdgesFromVertices(driverHandle->fabricVertices, driverHandle->fabricEdges); + uint32_t count = 0; + std::vector edges(30); + + // Root to Root Connection + EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex1->toHandle(), fabricVertex0->toHandle(), &count, nullptr)); + EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(fabricVertex1->toHandle(), fabricVertex0->toHandle(), &count, edges.data())); + ze_fabric_vertex_handle_t vertexA = nullptr, vertexB = nullptr; + EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetVerticesExp(edges[0], &vertexA, &vertexB)); + ze_fabric_edge_exp_properties_t edgeProperties = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetPropertiesExp(edges[0], &edgeProperties)); + EXPECT_EQ(edgeProperties.bandwidthUnit, ZE_BANDWIDTH_UNIT_BYTES_PER_NANOSEC); + EXPECT_EQ(edgeProperties.latencyUnit, ZE_LATENCY_UNIT_UNKNOWN); + EXPECT_STREQ(edgeProperties.model, "XeLink"); + EXPECT_EQ(edgeProperties.duplexity, ZE_FABRIC_EDGE_EXP_DUPLEXITY_FULL_DUPLEX); } } // namespace ult diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index bd8df3bc9c..c6c71aa1b0 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -134,6 +134,7 @@ class IoctlHelper { virtual std::string getFileForMaxGpuFrequency() const; virtual std::string getFileForMaxGpuFrequencyOfSubDevice(int subDeviceId) const; virtual std::string getFileForMaxMemoryFrequencyOfSubDevice(int subDeviceId) const; + virtual bool getFabricLatency(uint32_t fabricId, uint32_t &latency) = 0; uint32_t getFlagsForPrimeHandleToFd() const; @@ -190,6 +191,7 @@ class IoctlHelperUpstream : public IoctlHelper { int getDrmParamValue(DrmParam drmParam) const override; std::string getDrmParamString(DrmParam param) const override; std::string getIoctlString(DrmIoctl ioctlRequest) const override; + bool getFabricLatency(uint32_t fabricId, uint32_t &latency) override; }; template @@ -256,6 +258,7 @@ class IoctlHelperPrelim20 : public IoctlHelper { std::string getDrmParamString(DrmParam param) const override; std::string getIoctlString(DrmIoctl ioctlRequest) const override; bool checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest) const override; + bool getFabricLatency(uint32_t fabricId, uint32_t &latency) override; }; } // namespace NEO diff --git a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp index 1d942594be..f7c0c771b1 100644 --- a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp @@ -655,6 +655,34 @@ bool IoctlHelperPrelim20::checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctl return IoctlHelper::checkIfIoctlReinvokeRequired(error, ioctlRequest); } +bool IoctlHelperPrelim20::getFabricLatency(uint32_t fabricId, uint32_t &latency) { + Query query = {}; + QueryItem queryItem = {}; + PrelimI915::prelim_drm_i915_query_fabric_info info = {}; + info.fabric_id = fabricId; + + queryItem.queryId = PRELIM_DRM_I915_QUERY_FABRIC_INFO; + queryItem.length = static_cast(sizeof(info)); + queryItem.dataPtr = reinterpret_cast(&info); + queryItem.flags = 0; + + query.itemsPtr = reinterpret_cast(&queryItem); + query.numItems = 1; + auto ret = IoctlHelper::ioctl(DrmIoctl::Query, &query); + if (ret != 0) { + return false; + } + + if (info.latency < 10) { + return false; + } + + // Latency is in tenths of path length. 10 == 1 fabric link between src and dst + // 1 link = zero hops + latency = (info.latency / 10) - 1; + return true; +} + static_assert(sizeof(MemoryClassInstance) == sizeof(prelim_drm_i915_gem_memory_class_instance)); static_assert(offsetof(MemoryClassInstance, memoryClass) == offsetof(prelim_drm_i915_gem_memory_class_instance, memory_class)); static_assert(offsetof(MemoryClassInstance, memoryInstance) == offsetof(prelim_drm_i915_gem_memory_class_instance, memory_instance)); diff --git a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp index 32bb91e993..fb5dc37365 100644 --- a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp @@ -235,4 +235,8 @@ std::string IoctlHelperUpstream::getIoctlString(DrmIoctl ioctlRequest) const { return getIoctlStringBase(ioctlRequest); } } + +bool IoctlHelperUpstream::getFabricLatency(uint32_t fabricId, uint32_t &latency) { + return false; +} } // namespace NEO diff --git a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp index b95b37145a..4c255c95f4 100644 --- a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp +++ b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp @@ -10,6 +10,7 @@ #include "shared/source/os_interface/linux/i915_prelim.h" #include "shared/source/os_interface/linux/ioctl_helper.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" +#include "shared/test/common/libult/linux/drm_mock.h" #include "shared/test/common/mocks/mock_execution_environment.h" #include "shared/test/common/test_macros/test.h" @@ -348,3 +349,58 @@ TEST_F(IoctlPrelimHelperTests, givenPrelimWhenGettingEuStallPropertiesThenCorrec TEST_F(IoctlPrelimHelperTests, givenPrelimWhenGettingEuStallFdParameterThenCorrectIoctlValueIsReturned) { EXPECT_EQ(static_cast(PRELIM_I915_PERF_FLAG_FD_EU_STALL), ioctlHelper.getEuStallFdParameter()); } + +class DrmMockIoctl : public DrmMock { + public: + DrmMockIoctl(RootDeviceEnvironment &rootDeviceEnvironment) : DrmMock(rootDeviceEnvironment) { + rootDeviceEnvironment.setHwInfo(defaultHwInfo.get()); + } + int handleRemainingRequests(DrmIoctl request, void *arg) override { + if (request == DrmIoctl::Query) { + + Query *query = static_cast(arg); + QueryItem *queryItem = reinterpret_cast(query->itemsPtr); + PrelimI915::prelim_drm_i915_query_fabric_info *info = + reinterpret_cast(queryItem->dataPtr); + + info->latency = mockLatency; + return mockIoctlReturn; + } + return 0; + } + int mockIoctlReturn = 0; + uint32_t mockLatency = 10; +}; + +TEST(IoctlPrelimHelperFabricLatencyTest, givenPrelimWhenGettingFabricLatencyThenSuccessIsReturned) { + + MockExecutionEnvironment executionEnvironment{}; + std::unique_ptr drm = std::make_unique(*executionEnvironment.rootDeviceEnvironments[0]); + IoctlHelperPrelim20 ioctlHelper{*drm}; + + uint32_t latency = 0, fabricId = 0; + EXPECT_TRUE(ioctlHelper.getFabricLatency(fabricId, latency)); +} + +TEST(IoctlPrelimHelperFabricLatencyTest, givenPrelimWhenGettingFabricLatencyAndIoctlFailsThenErrorIsReturned) { + + MockExecutionEnvironment executionEnvironment{}; + std::unique_ptr drm = std::make_unique(*executionEnvironment.rootDeviceEnvironments[0]); + IoctlHelperPrelim20 ioctlHelper{*drm}; + + uint32_t latency = 0, fabricId = 0; + drm->mockIoctlReturn = 1; + EXPECT_FALSE(ioctlHelper.getFabricLatency(fabricId, latency)); +} + +TEST(IoctlPrelimHelperFabricLatencyTest, givenPrelimWhenGettingFabricLatencyAndIoctlSetsZeroForLatencyThenErrorIsReturned) { + + MockExecutionEnvironment executionEnvironment{}; + std::unique_ptr drm = std::make_unique(*executionEnvironment.rootDeviceEnvironments[0]); + IoctlHelperPrelim20 ioctlHelper{*drm}; + + uint32_t latency = 0, fabricId = 0; + drm->mockIoctlReturn = 0; + drm->mockLatency = 0; + EXPECT_FALSE(ioctlHelper.getFabricLatency(fabricId, latency)); +} diff --git a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp index 03c81d55b7..cb42ed405e 100644 --- a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp +++ b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp @@ -477,3 +477,11 @@ TEST(IoctlHelperTestsUpstream, givenUpstreamWhenInitializingThenTrueIsReturned) IoctlHelperUpstream ioctlHelper{*drm}; EXPECT_EQ(true, ioctlHelper.initialize()); } + +TEST(IoctlHelperTestsUpstream, givenUpstreamWhenGettingFabricLatencyThenFalseIsReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + IoctlHelperUpstream ioctlHelper{*drm}; + uint32_t fabricId = 0, latency = 0; + EXPECT_FALSE(ioctlHelper.getFabricLatency(fabricId, latency)); +}