From 7d85b1aeb7f75fb5ac6135510f44ec3fccec2df2 Mon Sep 17 00:00:00 2001 From: shubham kumar Date: Mon, 5 May 2025 13:45:39 +0000 Subject: [PATCH] feature: add support for eustall uAPI Related-To: NEO-14347 Signed-off-by: shubham kumar --- .../os_interface/linux/xe/CMakeLists.txt | 2 +- .../linux/xe/ioctl_helper_xe_perf.cpp | 154 ++++++++- .../os_interface/linux/xe/CMakeLists.txt | 4 +- .../linux/xe/mock_drm_xe_perf.cpp | 61 ++++ .../os_interface/linux/xe/mock_drm_xe_perf.h | 27 ++ .../os_interface/linux/xe/CMakeLists.txt | 2 +- .../linux/xe/ioctl_helper_xe_perf_tests.cpp | 308 +++++++++++++----- 7 files changed, 464 insertions(+), 94 deletions(-) create mode 100644 shared/test/common/os_interface/linux/xe/mock_drm_xe_perf.cpp create mode 100644 shared/test/common/os_interface/linux/xe/mock_drm_xe_perf.h diff --git a/shared/source/os_interface/linux/xe/CMakeLists.txt b/shared/source/os_interface/linux/xe/CMakeLists.txt index 8f23a4e371..4caf7596a2 100644 --- a/shared/source/os_interface/linux/xe/CMakeLists.txt +++ b/shared/source/os_interface/linux/xe/CMakeLists.txt @@ -9,7 +9,7 @@ set(NEO_CORE_OS_INTERFACE_LINUX_XE ${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}create_ioctl_helper_xe.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_helper_xe.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_helper_xe.h - ${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}ioctl_helper_xe_perf.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_helper_xe_perf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/xedrm.h ${CMAKE_CURRENT_SOURCE_DIR}/xedrm_prelim.h ) diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe_perf.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe_perf.cpp index 1b82d10bf0..9f61f0f64c 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe_perf.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe_perf.cpp @@ -9,26 +9,168 @@ #include "shared/source/os_interface/linux/xe/ioctl_helper_xe.h" #include "shared/source/os_interface/linux/xe/xedrm.h" +#include + +#define RETURN_ME(X) return X + namespace NEO { +uint64_t getClosestSamplingRate(uint64_t requestedRate, uint64_t *samplingRates, uint64_t size) { + uint64_t samplingUnit = 0; + + for (uint64_t index = 0; index < size; index++) { + // Need to find the sampling rate which is closest to the requested rate + if (samplingRates[index] >= requestedRate) { + if (index == 0) { + // The requested sampling rate is smaller than all suported sampling rates or equal to the 1st sampling rate. Pick the smallest supported rate and exit. + samplingUnit = samplingRates[index]; + break; + } + uint64_t oneLowerIndex = index - 1; + uint64_t oneHigherIndex = index; + + uint64_t deltaWithOneLowerIndex = requestedRate - samplingRates[oneLowerIndex]; + uint64_t deltaWithOneHigherIndex = samplingRates[oneHigherIndex] - requestedRate; + + samplingUnit = deltaWithOneHigherIndex <= deltaWithOneLowerIndex ? samplingRates[oneHigherIndex] : samplingRates[oneLowerIndex]; + break; + } + } + + // Requested sampling rate is higher than the max supported rate. Select the highest sampling rate supported. + if (samplingUnit == 0) { + samplingUnit = samplingRates[size - 1]; + } + return samplingUnit; +} + bool IoctlHelperXe::perfOpenEuStallStream(uint32_t euStallFdParameter, uint32_t &samplingPeriodNs, uint64_t engineInstance, uint64_t notifyNReports, uint64_t gpuTimeStampfrequency, int32_t *stream) { - return false; + + // Query Sampling rates + drm_xe_query_eu_stall *euStallQueryData = nullptr; + drm_xe_device_query euStallDeviceQuery = {}; + euStallDeviceQuery.extensions = 0; + euStallDeviceQuery.query = DRM_XE_DEVICE_QUERY_EU_STALL; + euStallDeviceQuery.size = 0; + euStallDeviceQuery.data = 0; + + int ret = ioctl(DrmIoctl::perfQuery, &euStallDeviceQuery); + if (ret != 0 || euStallDeviceQuery.size == 0) { + PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get() && (ret != 0), stderr, + "%s failed errno = %d | ret = %d \n", "DRM_IOCTL_XE_DEVICE_QUERY", errno, ret); + return false; + } + + std::vector allocateMemory(euStallDeviceQuery.size); + euStallQueryData = reinterpret_cast(allocateMemory.data()); + + euStallDeviceQuery.data = reinterpret_cast(euStallQueryData); + ret = ioctl(DrmIoctl::perfQuery, &euStallDeviceQuery); + if (ret != 0 || euStallQueryData->num_sampling_rates == 0) { + PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get() && (ret != 0), stderr, + "%s failed errno = %d | ret = %d \n", "DRM_IOCTL_XE_DEVICE_QUERY", errno, ret); + return false; + } + + // Select sampling rate. + uint64_t gpuClockPeriodNs = CommonConstants::nsecPerSec / gpuTimeStampfrequency; + uint64_t numberOfClocks = samplingPeriodNs / gpuClockPeriodNs; + uint64_t samplingUnit = getClosestSamplingRate(numberOfClocks, reinterpret_cast(&euStallQueryData->sampling_rates), euStallQueryData->num_sampling_rates); + samplingPeriodNs = static_cast(samplingUnit) * static_cast(gpuClockPeriodNs); + + // Populate the EU stall properties. The array will have property type and value in successive index. + std::array properties; + properties[0] = drm_xe_eu_stall_property_id::DRM_XE_EU_STALL_PROP_SAMPLE_RATE; + properties[1] = samplingUnit; + properties[2] = drm_xe_eu_stall_property_id::DRM_XE_EU_STALL_PROP_WAIT_NUM_REPORTS; + properties[3] = notifyNReports; + properties[4] = drm_xe_eu_stall_property_id::DRM_XE_EU_STALL_PROP_GT_ID; + properties[5] = engineInstance; + + // Call perf open ioctl. + uint32_t numProperties = sizeof(properties) / (sizeof(properties[0]) * 2); + std::vector extensionProperty(numProperties); + drm_xe_observation_param observationParam = {}; + observationParam.extensions = 0; + observationParam.observation_type = drm_xe_observation_type::DRM_XE_OBSERVATION_TYPE_EU_STALL; + observationParam.observation_op = drm_xe_observation_op::DRM_XE_OBSERVATION_OP_STREAM_OPEN; + observationParam.param = reinterpret_cast(extensionProperty.data()); + + // Chain the properties for perfOpen ioctl. + drm_xe_ext_set_property *ext = extensionProperty.data(); + + for (uint32_t i = 0; i < numProperties; i++) { + ext->base.name = DRM_XE_EU_STALL_EXTENSION_SET_PROPERTY; + ext->property = static_cast(properties[i * 2]); + ext->value = properties[(i * 2) + 1]; + ext++; + } + + ext = extensionProperty.data(); + for (uint32_t j = 0; j < numProperties - 1; j++) { + ext[j].base.next_extension = reinterpret_cast(&ext[j + 1]); + } + + *stream = ioctl(DrmIoctl::perfOpen, &observationParam); + if (*stream < 0) { + PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get() && (*stream < 0), stderr, + "%s failed errno = %d | ret = %d \n", "DRM_IOCTL_XE_OBSERVATION", errno, *stream); + return false; + } + + auto flags = SysCalls::fcntl(*stream, F_GETFL); + if (flags == -1) { + PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "fcntl system call failed with return code %d\n", flags); + return false; + } + auto status = SysCalls::fcntl(*stream, F_SETFL, flags | O_CLOEXEC | O_NONBLOCK); + if (status != 0) { + PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "fcntl system call failed with return code %d\n", status); + return false; + } + + ret = ioctl(*stream, DrmIoctl::perfEnable, 0); + PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get() && (ret < 0), stderr, + "%s failed errno = %d | ret = %d \n", "DRM_XE_OBSERVATION_IOCTL_ENABLE", errno, ret); + return (ret == 0) ? true : false; } bool IoctlHelperXe::perfDisableEuStallStream(int32_t *stream) { - return false; + int disableStatus = ioctl(*stream, DrmIoctl::perfDisable, 0); + PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get() && (disableStatus < 0), stderr, + "DRM_XE_OBSERVATION_IOCTL_DISABLE failed errno = %d | ret = %d \n", errno, disableStatus); + + int closeStatus = NEO::SysCalls::close(*stream); + PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get() && (closeStatus < 0), stderr, + "close() failed errno = %d | ret = %d \n", errno, closeStatus); + *stream = -1; + + return ((closeStatus == 0) && (disableStatus == 0)) ? true : false; } unsigned int IoctlHelperXe::getIoctlRequestValuePerf(DrmIoctl ioctlRequest) const { - return 0; + switch (ioctlRequest) { + case DrmIoctl::perfOpen: + RETURN_ME(DRM_IOCTL_XE_OBSERVATION); + case DrmIoctl::perfEnable: + RETURN_ME(DRM_XE_OBSERVATION_IOCTL_ENABLE); + case DrmIoctl::perfDisable: + RETURN_ME(DRM_XE_OBSERVATION_IOCTL_DISABLE); + case DrmIoctl::perfQuery: + RETURN_ME(DRM_IOCTL_XE_DEVICE_QUERY); + + default: + return 0; + } } int IoctlHelperXe::perfOpenIoctl(DrmIoctl request, void *arg) { - return 0; + auto ret = IoctlHelper::ioctl(request, arg); + return ret; } bool IoctlHelperXe::isEuStallSupported() { - return false; + return true; } -} // namespace NEO +} // namespace NEO \ No newline at end of file diff --git a/shared/test/common/os_interface/linux/xe/CMakeLists.txt b/shared/test/common/os_interface/linux/xe/CMakeLists.txt index 760e8261c8..919c68d425 100644 --- a/shared/test/common/os_interface/linux/xe/CMakeLists.txt +++ b/shared/test/common/os_interface/linux/xe/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2024 Intel Corporation +# Copyright (C) 2024-2025 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -11,6 +11,8 @@ set(neo_libult_common_SRCS_LIB_ULT_LINUX_XE ${CMAKE_CURRENT_SOURCE_DIR}/mock_drm_xe.inl ${CMAKE_CURRENT_SOURCE_DIR}/mock_drm_xe_definitions.inl ${CMAKE_CURRENT_SOURCE_DIR}/xe_config_fixture.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock_drm_xe_perf.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_drm_xe_perf.h ) if(UNIX) diff --git a/shared/test/common/os_interface/linux/xe/mock_drm_xe_perf.cpp b/shared/test/common/os_interface/linux/xe/mock_drm_xe_perf.cpp new file mode 100644 index 0000000000..f4d5ce013a --- /dev/null +++ b/shared/test/common/os_interface/linux/xe/mock_drm_xe_perf.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2024-2025 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/test/common/os_interface/linux/xe/mock_drm_xe_perf.h" + +#include "shared/test/common/os_interface/linux/xe/mock_ioctl_helper_xe.h" + +std::unique_ptr DrmMockXePerf::create(RootDeviceEnvironment &rootDeviceEnvironment) { + auto drm = std::unique_ptr(new DrmMockXePerf{rootDeviceEnvironment}); + drm->initInstance(); + + drm->ioctlHelper = std::make_unique(*drm); + + return drm; +} + +int DrmMockXePerf::ioctl(DrmIoctl request, void *arg) { + int ret = -1; + ioctlCalled = true; + + if (forceIoctlAnswer) { + return setIoctlAnswer; + } + + switch (request) { + case DrmIoctl::perfQuery: { + perfQueryCallCount++; + if (failPerfQueryOnCall && (perfQueryCallCount >= failPerfQueryOnCall)) { + return -1; + } + drm_xe_device_query *euStallDeviceQuery = static_cast(arg); + uint64_t samplingRates[] = {251, 502}; + if (euStallDeviceQuery->size == 0) { + if (querySizeZero) { + euStallDeviceQuery->size = 0; + return 0; + } else { + uint32_t sizeNeeded = sizeof(drm_xe_query_eu_stall) + sizeof(samplingRates); + euStallDeviceQuery->size = sizeNeeded; + } + } else { + drm_xe_query_eu_stall *euStallQueryData = reinterpret_cast(euStallDeviceQuery->data); + if (numSamplingRateCountZero) { + euStallQueryData->num_sampling_rates = 0; + return 0; + } + euStallQueryData->num_sampling_rates = 2; + memcpy_s(reinterpret_cast(euStallQueryData->sampling_rates), sizeof(samplingRates), &samplingRates, sizeof(samplingRates)); + } + ret = 0; + } break; + default: + return DrmMockXe::ioctl(request, arg); + } + + return ret; +} diff --git a/shared/test/common/os_interface/linux/xe/mock_drm_xe_perf.h b/shared/test/common/os_interface/linux/xe/mock_drm_xe_perf.h new file mode 100644 index 0000000000..6d767f63b5 --- /dev/null +++ b/shared/test/common/os_interface/linux/xe/mock_drm_xe_perf.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024-2025 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/test/common/os_interface/linux/xe/mock_drm_xe.h" + +using NEO::XeDrm::DrmMockXe; + +struct DrmMockXePerf : public DrmMockXe { + static std::unique_ptr create(RootDeviceEnvironment &rootDeviceEnvironment); + + int ioctl(DrmIoctl request, void *arg) override; + + int32_t curFd = 0; + bool querySizeZero = false; + bool numSamplingRateCountZero = false; + uint32_t perfQueryCallCount = 0; + uint32_t failPerfQueryOnCall = 0; + + protected: + // Don't call directly, use the create() function + DrmMockXePerf(RootDeviceEnvironment &rootDeviceEnvironment) : DrmMockXe(rootDeviceEnvironment) {} +}; \ No newline at end of file diff --git a/shared/test/unit_test/os_interface/linux/xe/CMakeLists.txt b/shared/test/unit_test/os_interface/linux/xe/CMakeLists.txt index c472e7d636..b8937e7d93 100644 --- a/shared/test/unit_test/os_interface/linux/xe/CMakeLists.txt +++ b/shared/test/unit_test/os_interface/linux/xe/CMakeLists.txt @@ -8,7 +8,7 @@ set(NEO_CORE_OS_INTERFACE_TESTS_LINUX_XE ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_helper_xe_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ccs_mode_xe_tests.cpp - ${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/ioctl_helper_xe_perf_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_helper_xe_perf_tests.cpp ) if(NEO_ENABLE_XE_EU_DEBUG_SUPPORT) list(APPEND NEO_CORE_OS_INTERFACE_TESTS_LINUX_XE diff --git a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_perf_tests.cpp b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_perf_tests.cpp index bd10456f64..4c3916ece5 100644 --- a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_perf_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_perf_tests.cpp @@ -6,18 +6,237 @@ */ #include "shared/source/os_interface/linux/os_context_linux.h" -#include "shared/source/os_interface/linux/xe/ioctl_helper_xe.h" +#include "shared/source/os_interface/linux/sys_calls.h" #include "shared/test/common/helpers/engine_descriptor_helper.h" +#include "shared/test/common/helpers/variable_backup.h" #include "shared/test/common/mocks/linux/mock_drm_memory_manager.h" #include "shared/test/common/mocks/linux/mock_os_context_linux.h" +#include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h" #include "shared/test/common/os_interface/linux/xe/mock_drm_xe.h" +#include "shared/test/common/os_interface/linux/xe/mock_drm_xe_perf.h" +#include "shared/test/common/os_interface/linux/xe/mock_ioctl_helper_xe.h" #include "shared/test/common/os_interface/linux/xe/xe_config_fixture.h" #include "shared/test/common/test_macros/test.h" using namespace NEO; using IoctlHelperXeTest = Test; -TEST_F(IoctlHelperXeTest, whenCallingPerfOpenEuStallStreamThenFailueIsReturned) { +TEST_F(IoctlHelperXeTest, whenCallingGetIoctlRequestValuePerfThenCorrectValueisReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + xeIoctlHelper->initialize(); + + EXPECT_NE(nullptr, xeIoctlHelper); + EXPECT_EQ(DRM_IOCTL_XE_OBSERVATION, xeIoctlHelper->getIoctlRequestValuePerf(DrmIoctl::perfOpen)); + EXPECT_EQ(DRM_XE_OBSERVATION_IOCTL_ENABLE, xeIoctlHelper->getIoctlRequestValuePerf(DrmIoctl::perfEnable)); + EXPECT_EQ(DRM_XE_OBSERVATION_IOCTL_DISABLE, xeIoctlHelper->getIoctlRequestValuePerf(DrmIoctl::perfDisable)); + EXPECT_EQ(DRM_IOCTL_XE_DEVICE_QUERY, xeIoctlHelper->getIoctlRequestValuePerf(DrmIoctl::perfQuery)); + EXPECT_EQ(0u, xeIoctlHelper->getIoctlRequestValuePerf(DrmIoctl::version)); +} + +TEST_F(IoctlHelperXeTest, givenXeHelperWhenCallingPerfOpenEuStallStreamWithInvalidArgumentsThenFailureReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t invalidFd = -1; + xeIoctlHelper->failPerfOpen = true; + uint32_t samplingPeridNs = 10000u; + EXPECT_FALSE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeridNs, 1, 20u, 10000u, &invalidFd)); +} + +TEST_F(IoctlHelperXeTest, givenCalltoPerfOpenEuStallStreamWithInvalidStreamWithEnableSetToFailThenFailureReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t invalidFd = -1; + xeIoctlHelper->failPerfEnable = true; + uint32_t samplingPeridNs = 10000u; + EXPECT_FALSE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeridNs, 1, 20u, 10000u, &invalidFd)); +} + +TEST_F(IoctlHelperXeTest, givenCalltoPerfDisableEuStallStreamWithInvalidStreamThenFailureIsReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t invalidFd = -1; + xeIoctlHelper->failPerfDisable = true; + EXPECT_FALSE(xeIoctlHelper->perfDisableEuStallStream(&invalidFd)); +} + +TEST_F(IoctlHelperXeTest, givenCalltoPerfOpenEuStallStreamWithValidStreamAndPerfEnableFailsThenFailureIsReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t validFd = -1; + uint32_t samplingPeriodNs = 10000u; + xeIoctlHelper->failPerfEnable = true; + EXPECT_FALSE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeriodNs, 1, 20u, 10000u, &validFd)); +} + +TEST_F(IoctlHelperXeTest, whenCallingPerfOpenEuStallStreamThenCloseThenTrueIsReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t validFd = -1; + uint32_t samplingPeriodNs = 50000000u; + EXPECT_TRUE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeriodNs, 1, 20u, 10000u, &validFd)); + EXPECT_TRUE(xeIoctlHelper->perfDisableEuStallStream(&validFd)); +} + +TEST_F(IoctlHelperXeTest, whenCallingPerfOpenEuStallStreamThenCloseWithSmallestSamplingRateValueThenTrueIsReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t validFd = -1; + uint32_t samplingPeriodNs = 10u; + EXPECT_TRUE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeriodNs, 1, 20u, 10000u, &validFd)); + EXPECT_TRUE(xeIoctlHelper->perfDisableEuStallStream(&validFd)); +} + +TEST_F(IoctlHelperXeTest, whenCallingPerfOpenEuStallStreamThenCloseWithLargestSamplingRateValueThenTrueIsReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t validFd = -1; + uint32_t samplingPeriodNs = 1000000000u; + EXPECT_TRUE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeriodNs, 1, 20u, 10000u, &validFd)); + EXPECT_TRUE(xeIoctlHelper->perfDisableEuStallStream(&validFd)); +} + +TEST_F(IoctlHelperXeTest, whenCallingPerfOpenEuStallStreamThenCloseWithDifferentSampligRatesToCoverIfBranchThenTrueIsReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t validFd = -1; + uint32_t samplingPeriodNs = 25200000u; + EXPECT_TRUE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeriodNs, 1, 20u, 10000u, &validFd)); + EXPECT_TRUE(xeIoctlHelper->perfDisableEuStallStream(&validFd)); +} + +TEST_F(IoctlHelperXeTest, givenXeHelperWhenCallingPerfOpenEuStallStreamAndQuerySizeIsZeroThenFailureReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t validFd = -1; + uint32_t samplingPeridNs = 10000u; + drm->querySizeZero = true; + EXPECT_FALSE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeridNs, 1, 20u, 10000u, &validFd)); +} + +TEST_F(IoctlHelperXeTest, givenXeHelperWhenCallingPerfOpenEuStallStreamAndNumSamplingRatesIsZeroThenFailureReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t validFd = -1; + uint32_t samplingPeridNs = 10000u; + drm->numSamplingRateCountZero = true; + EXPECT_FALSE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeridNs, 1, 20u, 10000u, &validFd)); +} + +TEST_F(IoctlHelperXeTest, givenXeHelperWhenCallingPerfOpenEuStallStreamAndIoctlFailsThenFailureReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t validFd = -1; + uint32_t samplingPeridNs = 10000u; + drm->failPerfQueryOnCall = 2; + EXPECT_FALSE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeridNs, 1, 20u, 10000u, &validFd)); +} + +TEST_F(IoctlHelperXeTest, givenXeHelperWhenCallingPerfOpenEuStallStreamAndQueryIoctlFailsThenFailureReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t validFd = -1; + uint32_t samplingPeridNs = 10000u; + xeIoctlHelper->failPerfQuery = true; + EXPECT_FALSE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeridNs, 1, 20u, 10000u, &validFd)); +} + +TEST_F(IoctlHelperXeTest, givenXeHelperWhenCallingPerfOpenEuStallStreamAndOpenIoctlFailsThenFailureReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + int32_t validFd = -1; + uint32_t samplingPeridNs = 10000u; + xeIoctlHelper->failPerfOpen = true; + EXPECT_FALSE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeridNs, 1, 20u, 10000u, &validFd)); +} + +TEST_F(IoctlHelperXeTest, givenCalltoPerfDisableEuStallStreamWithValidStreamButCloseFailsThenFailureReturned) { + VariableBackup mockClose(&NEO::SysCalls::sysCallsClose, [](int fileDescriptor) -> int { + return -1; + }); + + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + NEO::SysCalls::closeFuncCalled = 0; + NEO::SysCalls::closeFuncRetVal = -1; + int32_t invalidFd = 10; + EXPECT_FALSE(xeIoctlHelper->perfDisableEuStallStream(&invalidFd)); + EXPECT_EQ(1u, NEO::SysCalls::closeFuncCalled); + EXPECT_EQ(10, NEO::SysCalls::closeFuncArgPassed); + NEO::SysCalls::closeFuncCalled = 0; + NEO::SysCalls::closeFuncArgPassed = 0; + NEO::SysCalls::closeFuncRetVal = 0; +} + +TEST_F(IoctlHelperXeTest, givenCalltoPerfOpenEuStallStreamWithValidStreamButFcntlFailsThenFailureReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXePerf::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + + xeIoctlHelper->initialize(); + SysCalls::failFcntl = true; + int32_t validFd = -1; + uint32_t samplingPeridNs = 10000u; + EXPECT_FALSE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeridNs, 1, 20u, 10000u, &validFd)); + + SysCalls::failFcntl = false; + SysCalls::failFcntl1 = true; + EXPECT_FALSE(xeIoctlHelper->perfOpenEuStallStream(0u, samplingPeridNs, 1, 20u, 10000u, &validFd)); + SysCalls::failFcntl1 = false; +} + +TEST_F(IoctlHelperXeTest, whenCallingIsEuStallSupportedThenFalseIsReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = std::make_unique(*drm); + EXPECT_NE(nullptr, xeIoctlHelper); + EXPECT_TRUE(xeIoctlHelper.get()->isEuStallSupported()); +} + +TEST_F(IoctlHelperXeTest, whenCallingPerfOpenEuStallStreamWithNoIoctlSupportThenFailueIsReturned) { auto executionEnvironment = std::make_unique(); auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); auto xeIoctlHelper = std::make_unique(*drm); @@ -27,92 +246,11 @@ TEST_F(IoctlHelperXeTest, whenCallingPerfOpenEuStallStreamThenFailueIsReturned) EXPECT_FALSE(xeIoctlHelper.get()->perfOpenEuStallStream(0u, samplingPeriodNs, 1, 20u, 10000u, &invalidFd)); } -TEST_F(IoctlHelperXeTest, whenCallingPerfDisableEuStallStreamThenFailueIsReturned) { +TEST_F(IoctlHelperXeTest, whenCallingPerfDisableEuStallStreamWithNoIoctlSupportThenFailueIsReturned) { auto executionEnvironment = std::make_unique(); auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); auto xeIoctlHelper = std::make_unique(*drm); EXPECT_NE(nullptr, xeIoctlHelper); int32_t invalidFd = -1; EXPECT_FALSE(xeIoctlHelper.get()->perfDisableEuStallStream(&invalidFd)); -} - -TEST_F(IoctlHelperXeTest, whenCallingGetIoctlRequestValuePerfOpenThenZeroisReturned) { - auto executionEnvironment = std::make_unique(); - auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); - auto xeIoctlHelper = std::make_unique(*drm); - EXPECT_NE(nullptr, xeIoctlHelper); - EXPECT_EQ(0u, xeIoctlHelper.get()->getIoctlRequestValuePerf(DrmIoctl::perfOpen)); -} - -TEST_F(IoctlHelperXeTest, whenCallingGetIoctlRequestValuePerfEnableThenZeroisReturned) { - auto executionEnvironment = std::make_unique(); - auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); - auto xeIoctlHelper = std::make_unique(*drm); - EXPECT_NE(nullptr, xeIoctlHelper); - EXPECT_EQ(0u, xeIoctlHelper.get()->getIoctlRequestValuePerf(DrmIoctl::perfEnable)); -} - -TEST_F(IoctlHelperXeTest, whenCallingGetIoctlRequestValuePerfDisableThenZeroisReturned) { - auto executionEnvironment = std::make_unique(); - auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); - auto xeIoctlHelper = std::make_unique(*drm); - EXPECT_NE(nullptr, xeIoctlHelper); - EXPECT_EQ(0u, xeIoctlHelper.get()->getIoctlRequestValuePerf(DrmIoctl::perfDisable)); -} - -TEST_F(IoctlHelperXeTest, whenCallingGetIoctlRequestValuePerfQueryThenZeroisReturned) { - auto executionEnvironment = std::make_unique(); - auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); - auto xeIoctlHelper = std::make_unique(*drm); - EXPECT_NE(nullptr, xeIoctlHelper); - EXPECT_EQ(0u, xeIoctlHelper.get()->getIoctlRequestValuePerf(DrmIoctl::perfQuery)); -} - -TEST_F(IoctlHelperXeTest, whenCallingPerfOpenIoctlWithInvalidValuesThenZeroisReturned) { - auto executionEnvironment = std::make_unique(); - auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); - auto xeIoctlHelper = std::make_unique(*drm); - EXPECT_NE(nullptr, xeIoctlHelper); - EXPECT_EQ(0, xeIoctlHelper.get()->perfOpenIoctl(DrmIoctl::perfOpen, nullptr)); -} - -TEST_F(IoctlHelperXeTest, whenCallingGetIoctlRequestValueWithInvalidValueThenErrorReturned) { - auto executionEnvironment = std::make_unique(); - auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); - auto xeIoctlHelper = std::make_unique(*drm); - EXPECT_NE(nullptr, xeIoctlHelper); - EXPECT_EQ(0u, xeIoctlHelper.get()->getIoctlRequestValuePerf(DrmIoctl::version)); -} - -TEST_F(IoctlHelperXeTest, whenCallingPerfOpenIoctlThenProperValueIsReturned) { - auto executionEnvironment = std::make_unique(); - auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); - auto xeIoctlHelper = std::make_unique(*drm); - EXPECT_NE(nullptr, xeIoctlHelper); - EXPECT_EQ(0, xeIoctlHelper.get()->ioctl(DrmIoctl::perfOpen, nullptr)); -} - -TEST_F(IoctlHelperXeTest, whenCallingPerfQueryIoctlThenProperValueIsReturned) { - auto executionEnvironment = std::make_unique(); - auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); - auto xeIoctlHelper = std::make_unique(*drm); - EXPECT_NE(nullptr, xeIoctlHelper); - EXPECT_EQ(0, xeIoctlHelper.get()->ioctl(DrmIoctl::perfQuery, nullptr)); -} - -TEST_F(IoctlHelperXeTest, whenCallingPerfDisableIoctlThenProperValueIsReturned) { - auto executionEnvironment = std::make_unique(); - auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); - auto xeIoctlHelper = std::make_unique(*drm); - EXPECT_NE(nullptr, xeIoctlHelper); - int32_t invalidFd = -1; - EXPECT_EQ(-1, xeIoctlHelper.get()->ioctl(invalidFd, DrmIoctl::perfDisable, nullptr)); -} - -TEST_F(IoctlHelperXeTest, whenCallingIsEuStallSupportedThenFalseIsReturned) { - auto executionEnvironment = std::make_unique(); - auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); - auto xeIoctlHelper = std::make_unique(*drm); - EXPECT_NE(nullptr, xeIoctlHelper); - EXPECT_FALSE(xeIoctlHelper.get()->isEuStallSupported()); -} +} \ No newline at end of file