From e287174211cb698146e236f7383df3a3e6240927 Mon Sep 17 00:00:00 2001 From: shubham kumar Date: Tue, 11 Mar 2025 18:21:47 +0000 Subject: [PATCH] feature: Add EU stall support for xe2/xe3 core Related-To: NEO-13777 Signed-off-by: shubham kumar --- .../linux/os_metric_ip_sampling_imp_linux.cpp | 6 +++++- ...est_metric_ip_sampling_linux_pvc_prelim.cpp | 2 ++ .../source/os_interface/linux/drm_wrappers.h | 1 + .../os_interface/linux/xe/ioctl_helper_xe.cpp | 2 ++ .../os_interface/linux/sys_calls_linux_ult.cpp | 11 +++++++++++ .../os_interface/linux/sys_calls_linux_ult.h | 2 ++ .../linux/xe/mock_ioctl_helper_xe.h | 18 +++++++++++++++--- .../linux/xe/ioctl_helper_xe_perf_tests.cpp | 16 ++++++++++++++++ 8 files changed, 54 insertions(+), 4 deletions(-) diff --git a/level_zero/tools/source/metrics/linux/os_metric_ip_sampling_imp_linux.cpp b/level_zero/tools/source/metrics/linux/os_metric_ip_sampling_imp_linux.cpp index 67d94063c9..18e4f5db67 100644 --- a/level_zero/tools/source/metrics/linux/os_metric_ip_sampling_imp_linux.cpp +++ b/level_zero/tools/source/metrics/linux/os_metric_ip_sampling_imp_linux.cpp @@ -47,6 +47,7 @@ MetricIpSamplingLinuxImp::MetricIpSamplingLinuxImp(Device &device) : device(devi ze_result_t MetricIpSamplingLinuxImp::startMeasurement(uint32_t ¬ifyEveryNReports, uint32_t &samplingPeriodNs) { const auto drm = device.getOsInterface()->getDriverModel()->as(); + // gpuTimeStampfrequency will be in Hertz uint64_t gpuTimeStampfrequency = 0; ze_result_t ret = getMetricsTimerResolution(gpuTimeStampfrequency); if (ret != ZE_RESULT_SUCCESS) { @@ -66,7 +67,7 @@ ze_result_t MetricIpSamplingLinuxImp::startMeasurement(uint32_t ¬ifyEveryNRep return ZE_RESULT_ERROR_UNKNOWN; } - notifyEveryNReports = std::max(notifyEveryNReports, 1u); + notifyEveryNReports = std::clamp(notifyEveryNReports, 1u, getRequiredBufferSize(notifyEveryNReports)); if (!ioctlHelper->perfOpenEuStallStream(euStallFdParameter, samplingPeriodNs, classInstance->engineInstance, notifyEveryNReports, gpuTimeStampfrequency, &stream)) { return ZE_RESULT_ERROR_UNKNOWN; } @@ -99,6 +100,9 @@ ze_result_t MetricIpSamplingLinuxImp::readData(uint8_t *pRawData, size_t *pRawDa // If read needs to try again, do not return error if (errno == EINTR || errno == EAGAIN || errno == EBUSY) { return ZE_RESULT_SUCCESS; + } else if (errno == EIO) { + // on i915 EIO is not returned by KMD for any error conditions. Hence we can use this safetly for both xe and i915. + return ZE_RESULT_WARNING_DROPPED_DATA; } return ZE_RESULT_ERROR_UNKNOWN; diff --git a/level_zero/tools/test/unit_tests/sources/metrics/linux/test_metric_ip_sampling_linux_pvc_prelim.cpp b/level_zero/tools/test/unit_tests/sources/metrics/linux/test_metric_ip_sampling_linux_pvc_prelim.cpp index b964d5cf85..ac02c21475 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/linux/test_metric_ip_sampling_linux_pvc_prelim.cpp +++ b/level_zero/tools/test/unit_tests/sources/metrics/linux/test_metric_ip_sampling_linux_pvc_prelim.cpp @@ -255,6 +255,8 @@ HWTEST2_F(MetricIpSamplingLinuxTestPrelim, givenReadFailsWithRetryErrorNumberWhe EXPECT_EQ(metricIpSamplingOsInterface->readData(&pRawData, &pRawDataSize), ZE_RESULT_SUCCESS); errno = EAGAIN; EXPECT_EQ(metricIpSamplingOsInterface->readData(&pRawData, &pRawDataSize), ZE_RESULT_SUCCESS); + errno = EIO; + EXPECT_EQ(metricIpSamplingOsInterface->readData(&pRawData, &pRawDataSize), ZE_RESULT_WARNING_DROPPED_DATA); } HWTEST2_F(MetricIpSamplingLinuxTestPrelim, WhenGetRequiredBufferSizeIsCalledThenCorrectSizeIsReturned, IsPVC) { diff --git a/shared/source/os_interface/linux/drm_wrappers.h b/shared/source/os_interface/linux/drm_wrappers.h index e5cd92b129..ce5c7a0d14 100644 --- a/shared/source/os_interface/linux/drm_wrappers.h +++ b/shared/source/os_interface/linux/drm_wrappers.h @@ -293,6 +293,7 @@ enum class DrmIoctl { perfOpen, perfEnable, perfDisable, + perfQuery, primaryContextExport, primaryContextImport }; 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 58ad633609..d482441109 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp @@ -1284,6 +1284,7 @@ int IoctlHelperXe::ioctl(DrmIoctl request, void *arg) { case DrmIoctl::metadataDestroy: { ret = debuggerMetadataDestroyIoctl(request, arg); } break; + case DrmIoctl::perfQuery: case DrmIoctl::perfOpen: { ret = perfOpenIoctl(request, arg); } break; @@ -1706,6 +1707,7 @@ unsigned int IoctlHelperXe::getIoctlRequestValue(DrmIoctl ioctlRequest) const { case DrmIoctl::perfOpen: case DrmIoctl::perfEnable: case DrmIoctl::perfDisable: + case DrmIoctl::perfQuery: return getIoctlRequestValuePerf(ioctlRequest); default: UNRECOVERABLE_IF(true); diff --git a/shared/test/common/os_interface/linux/sys_calls_linux_ult.cpp b/shared/test/common/os_interface/linux/sys_calls_linux_ult.cpp index 6244813413..acddc8a071 100644 --- a/shared/test/common/os_interface/linux/sys_calls_linux_ult.cpp +++ b/shared/test/common/os_interface/linux/sys_calls_linux_ult.cpp @@ -71,6 +71,8 @@ int fsyncArgPassed = 0; int fsyncRetVal = 0; uint32_t mkfifoFuncCalled = 0; bool failMkfifo = 0; +bool failFcntl = false; +bool failFcntl1 = false; std::vector mmapVector(64); std::vector mmapCapturedExtendedPointers(64); @@ -383,13 +385,22 @@ int pipe(int pipeFd[2]) { } int fcntl(int fd, int cmd) { + if (failFcntl) { + return -1; + } + if (cmd == F_GETFL) { getFileDescriptorFlagsCalled++; return O_RDWR; } return 0; } + int fcntl(int fd, int cmd, int arg) { + if (failFcntl1) { + return -1; + } + if (cmd == F_SETFL) { setFileDescriptorFlagsCalled++; passedFileDescriptorFlagsToSet = arg; diff --git a/shared/test/common/os_interface/linux/sys_calls_linux_ult.h b/shared/test/common/os_interface/linux/sys_calls_linux_ult.h index e8c2dbd69c..1f70d1cdfd 100644 --- a/shared/test/common/os_interface/linux/sys_calls_linux_ult.h +++ b/shared/test/common/os_interface/linux/sys_calls_linux_ult.h @@ -79,6 +79,8 @@ extern uint32_t readFuncCalled; extern uint32_t writeFuncCalled; extern uint32_t mkfifoFuncCalled; extern bool failMkfifo; +extern bool failFcntl; +extern bool failFcntl1; extern std::vector mmapVector; extern std::vector mmapCapturedExtendedPointers; diff --git a/shared/test/common/os_interface/linux/xe/mock_ioctl_helper_xe.h b/shared/test/common/os_interface/linux/xe/mock_ioctl_helper_xe.h index 65a02b433b..7c065296bc 100644 --- a/shared/test/common/os_interface/linux/xe/mock_ioctl_helper_xe.h +++ b/shared/test/common/os_interface/linux/xe/mock_ioctl_helper_xe.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -35,8 +35,19 @@ struct MockIoctlHelperXe : IoctlHelperXe { using IoctlHelperXe::xeShowBindTable; int perfOpenIoctl(DrmIoctl request, void *arg) override { - if (failPerfOpen) { - return -1; + switch (request) { + case DrmIoctl::perfQuery: + if (failPerfQuery) { + return -1; + } + break; + case DrmIoctl::perfOpen: + if (failPerfOpen) { + return -1; + } + break; + default: + break; } return IoctlHelperXe::perfOpenIoctl(request, arg); } @@ -60,4 +71,5 @@ struct MockIoctlHelperXe : IoctlHelperXe { bool failPerfDisable = false; bool failPerfEnable = false; bool failPerfOpen = false; + bool failPerfQuery = false; }; 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 acd56bf21c..bd10456f64 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 @@ -60,6 +60,14 @@ TEST_F(IoctlHelperXeTest, whenCallingGetIoctlRequestValuePerfDisableThenZeroisRe 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]); @@ -84,6 +92,14 @@ TEST_F(IoctlHelperXeTest, whenCallingPerfOpenIoctlThenProperValueIsReturned) { 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]);