fix: only call std::clamp for valid values in startMeasurement

Related-To: NEO-16286
Signed-off-by: Jack Myers <jack.myers@intel.com>
This commit is contained in:
Jack Myers
2025-10-06 21:24:55 +00:00
committed by Compute-Runtime-Automation
parent f31c3fdd03
commit fd2c7fdc1a
4 changed files with 63 additions and 19 deletions

View File

@@ -5,6 +5,8 @@
*
*/
#include "os_metric_ip_sampling_imp_linux.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/os_interface/linux/drm_neo.h"
#include "shared/source/os_interface/linux/engine_info.h"
@@ -19,27 +21,10 @@
#include "level_zero/tools/source/metrics/os_interface_metric.h"
#include <algorithm>
#include <cstdint>
namespace L0 {
class MetricIpSamplingLinuxImp : public MetricIpSamplingOsInterface {
public:
MetricIpSamplingLinuxImp(Device &device);
~MetricIpSamplingLinuxImp() override = default;
ze_result_t startMeasurement(uint32_t &notifyEveryNReports, uint32_t &samplingPeriodNs) override;
ze_result_t stopMeasurement() override;
ze_result_t readData(uint8_t *pRawData, size_t *pRawDataSize) override;
uint32_t getRequiredBufferSize(const uint32_t maxReportCount) override;
uint32_t getUnitReportSize() override;
bool isNReportsAvailable() override;
bool isDependencyAvailable() override;
ze_result_t getMetricsTimerResolution(uint64_t &timerResolution) override;
private:
int32_t stream = -1;
Device &device;
};
MetricIpSamplingLinuxImp::MetricIpSamplingLinuxImp(Device &device) : device(device) {}
ze_result_t MetricIpSamplingLinuxImp::startMeasurement(uint32_t &notifyEveryNReports, uint32_t &samplingPeriodNs) {
@@ -65,7 +50,7 @@ ze_result_t MetricIpSamplingLinuxImp::startMeasurement(uint32_t &notifyEveryNRep
return ZE_RESULT_ERROR_UNKNOWN;
}
notifyEveryNReports = std::clamp(notifyEveryNReports, 1u, getRequiredBufferSize(notifyEveryNReports));
notifyEveryNReports = clampNReports(notifyEveryNReports);
if (!ioctlHelper->perfOpenEuStallStream(euStallFdParameter, samplingPeriodNs, classInstance->engineInstance, notifyEveryNReports, gpuTimeStampfrequency, &stream)) {
return ZE_RESULT_ERROR_UNKNOWN;
}
@@ -73,6 +58,15 @@ ze_result_t MetricIpSamplingLinuxImp::startMeasurement(uint32_t &notifyEveryNRep
return ZE_RESULT_SUCCESS;
}
uint32_t MetricIpSamplingLinuxImp::clampNReports(uint32_t notifyEveryNReports) {
auto reqBufSize = getRequiredBufferSize(notifyEveryNReports);
if (reqBufSize > 1u) {
return std::clamp(notifyEveryNReports, 1u, reqBufSize);
}
return std::min(notifyEveryNReports, reqBufSize);
}
ze_result_t MetricIpSamplingLinuxImp::stopMeasurement() {
const auto drm = device.getOsInterface()->getDriverModel()->as<NEO::Drm>();
auto ioctlHelper = drm->getIoctlHelper();

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/tools/source/metrics/os_interface_metric.h"
namespace L0 {
class MetricIpSamplingLinuxImp : public MetricIpSamplingOsInterface {
public:
MetricIpSamplingLinuxImp(Device &device);
~MetricIpSamplingLinuxImp() override = default;
ze_result_t startMeasurement(uint32_t &notifyEveryNReports, uint32_t &samplingPeriodNs) override;
ze_result_t stopMeasurement() override;
ze_result_t readData(uint8_t *pRawData, size_t *pRawDataSize) override;
uint32_t getRequiredBufferSize(const uint32_t maxReportCount) override;
uint32_t clampNReports(uint32_t notifyEveryNReports);
uint32_t getUnitReportSize() override;
bool isNReportsAvailable() override;
bool isDependencyAvailable() override;
ze_result_t getMetricsTimerResolution(uint64_t &timerResolution) override;
private:
int32_t stream = -1;
Device &device;
};
} // namespace L0

View File

@@ -12,6 +12,7 @@
#include <level_zero/zet_api.h>
#include <memory>
#include <sys/types.h>
namespace L0 {

View File

@@ -19,6 +19,7 @@
#include "shared/test/common/test_macros/hw_test.h"
#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h"
#include "level_zero/tools/source/metrics/linux/os_metric_ip_sampling_imp_linux.h"
#include "level_zero/tools/source/metrics/os_interface_metric.h"
namespace NEO {
@@ -188,6 +189,23 @@ HWTEST2_F(MetricIpSamplingLinuxTestPrelim, givenI915PerfIoctlEnableFailsWhenStar
EXPECT_EQ(metricIpSamplingOsInterface->startMeasurement(notifyEveryNReports, samplingPeriodNs), ZE_RESULT_ERROR_UNKNOWN);
}
HWTEST2_F(MetricIpSamplingLinuxTestPrelim, givenI915PerfIoctlEnableFailsThenClampingNotifyEveryNReportsReturnsCorrectValue, IsPVC) {
VariableBackup<decltype(SysCalls::sysCallsIoctl)> mockIoctl(&SysCalls::sysCallsIoctl, [](int fileDescriptor, unsigned long int request, void *arg) -> int {
if (request == I915_PERF_IOCTL_ENABLE) {
return -1;
}
return 0;
});
auto linuxIface = static_cast<MetricIpSamplingLinuxImp *>(metricIpSamplingOsInterface.get());
EXPECT_EQ(0u, linuxIface->clampNReports(0));
EXPECT_EQ(1u, linuxIface->clampNReports(1));
auto reqBufSize = metricIpSamplingOsInterface->getRequiredBufferSize(std::numeric_limits<uint32_t>::max());
EXPECT_EQ(reqBufSize, linuxIface->clampNReports(std::numeric_limits<uint32_t>::max()));
}
HWTEST2_F(MetricIpSamplingLinuxTestPrelim, givenPerfOpenEuStallStreamWhenStartMeasurementIsCalledThenReturnFailure, IsPVC) {
auto drm = static_cast<DrmPrelimMock *>(device->getOsInterface()->getDriverModel()->as<NEO::Drm>());