Skip to content

Commit 5b9e1e3

Browse files
fix: Synchronize power property retrievals
Related-To: NEO-10525 Signed-off-by: Bellekallu Rajkiran <[email protected]> Source: a023b40
1 parent e7a6a35 commit 5b9e1e3

File tree

6 files changed

+71
-6
lines changed

6 files changed

+71
-6
lines changed

level_zero/sysman/source/api/power/linux/sysman_os_power_imp.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ class LinuxPowerImp::PowerLimitRestorer : NEO::NonCopyableOrMovableClass {
4242
uint64_t powerLimitValue = 0;
4343
};
4444

45+
std::unique_lock<std::mutex> LinuxPowerImp::obtainMutex() {
46+
return std::unique_lock<std::mutex>(this->powerLimitMutex);
47+
}
48+
4549
ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) {
4650
pProperties->onSubdevice = isSubdevice;
4751
pProperties->subdeviceId = subdeviceId;
@@ -60,6 +64,7 @@ ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) {
6064
return result;
6165
}
6266

67+
auto lock = this->obtainMutex();
6368
auto powerLimitRestorer = L0::Sysman::LinuxPowerImp::PowerLimitRestorer(pSysfsAccess, sustainedPowerLimit);
6469
if (powerLimitRestorer != ZE_RESULT_SUCCESS) {
6570
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(powerLimitRestorer));

level_zero/sysman/source/api/power/linux/sysman_os_power_imp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "level_zero/sysman/source/api/power/sysman_os_power.h"
1212

1313
#include <memory>
14+
#include <mutex>
1415
#include <string>
1516

1617
namespace L0 {
@@ -44,12 +45,14 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass {
4445
SysFsAccessInterface *pSysfsAccess = nullptr;
4546
SysmanKmdInterface *pSysmanKmdInterface = nullptr;
4647
SysmanProductHelper *pSysmanProductHelper = nullptr;
48+
virtual std::unique_lock<std::mutex> obtainMutex();
4749

4850
private:
4951
std::string intelGraphicsHwmonDir = {};
5052
std::string criticalPowerLimit = {};
5153
std::string sustainedPowerLimit = {};
5254
std::string sustainedPowerLimitInterval = {};
55+
std::mutex powerLimitMutex{};
5356
bool canControl = false;
5457
bool isSubdevice = false;
5558
uint32_t subdeviceId = 0;

level_zero/sysman/test/unit_tests/sources/power/linux/test_zes_power.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,31 @@ TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenGettingPowerProper
105105
}
106106
}
107107

108+
TEST_F(SysmanDevicePowerFixtureI915, GivenValidMockMutexPowerImpWhenGettingPowerPropertiesThenMutexLockCounterMatchesNumberOfGetCalls) {
109+
class MockMutexPowerImp : public L0::Sysman::LinuxPowerImp {
110+
public:
111+
using L0::Sysman::LinuxPowerImp::pSysfsAccess;
112+
MockMutexPowerImp(L0::Sysman::OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) : L0::Sysman::LinuxPowerImp(pOsSysman, onSubdevice, subdeviceId) {}
113+
uint32_t mutexLockCounter = 0;
114+
std::unique_lock<std::mutex> obtainMutex() override {
115+
mutexLockCounter++;
116+
std::unique_lock<std::mutex> mutexLock = L0::Sysman::LinuxPowerImp::obtainMutex();
117+
EXPECT_TRUE(mutexLock.owns_lock());
118+
return mutexLock;
119+
}
120+
};
121+
122+
std::unique_ptr<MockMutexPowerImp> pLinuxPowerImp(new MockMutexPowerImp(pOsSysman, false, 0));
123+
pLinuxPowerImp->pSysfsAccess = pSysfsAccess;
124+
125+
zes_power_properties_t properties{};
126+
uint32_t testReadCount = 0;
127+
for (uint32_t i = 0; i < testReadCount; i++) {
128+
EXPECT_EQ(ZE_RESULT_SUCCESS, pLinuxPowerImp->getProperties(&properties));
129+
}
130+
EXPECT_EQ(pLinuxPowerImp->mutexLockCounter, testReadCount);
131+
}
132+
108133
TEST_F(SysmanDevicePowerFixtureI915, GivenValidPowerHandleWhenGettingPowerPropertiesAndExtPropertiesThenCallSucceeds) {
109134
auto handles = getPowerHandles(powerHandleComponentCount);
110135

level_zero/tools/source/sysman/power/linux/os_power_imp_prelim.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2020-2023 Intel Corporation
2+
* Copyright (C) 2020-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -45,6 +45,10 @@ class LinuxPowerImp::PowerLimitRestorer : NEO::NonCopyableOrMovableClass {
4545
uint64_t powerLimitValue = 0;
4646
};
4747

48+
std::unique_lock<std::mutex> LinuxPowerImp::obtainMutex() {
49+
return std::unique_lock<std::mutex>(this->powerLimitMutex);
50+
}
51+
4852
ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) {
4953
pProperties->onSubdevice = isSubdevice;
5054
pProperties->subdeviceId = subdeviceId;
@@ -64,7 +68,8 @@ ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) {
6468
}
6569

6670
std::string sustainedLimit = i915HwmonDir + "/" + sustainedPowerLimit;
67-
auto powerLimitRestorer = L0::LinuxPowerImp::PowerLimitRestorer(pSysfsAccess, sustainedLimit);
71+
auto lock = this->obtainMutex();
72+
auto powerLimitRestorer = L0::LinuxPowerImp::PowerLimitRestorer(pSysfsAccess, sustainedLimit); // 600
6873
if (powerLimitRestorer != ZE_RESULT_SUCCESS) {
6974
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(powerLimitRestorer));
7075
return getErrorCode(powerLimitRestorer);
@@ -88,7 +93,7 @@ ze_result_t LinuxPowerImp::getMinLimit(int32_t &minLimit) {
8893
return getErrorCode(result);
8994
}
9095

91-
result = pSysfsAccess->read(sustainedLimit, powerLimit);
96+
result = pSysfsAccess->read(sustainedLimit, powerLimit); // 300
9297
if (ZE_RESULT_SUCCESS != result) {
9398
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result));
9499
return getErrorCode(result);
@@ -109,7 +114,7 @@ ze_result_t LinuxPowerImp::getMaxLimit(int32_t &maxLimit) {
109114
return getErrorCode(result);
110115
}
111116

112-
result = pSysfsAccess->read(sustainedLimit, powerLimit);
117+
result = pSysfsAccess->read(sustainedLimit, powerLimit); // 600
113118
if (ZE_RESULT_SUCCESS != result) {
114119
NEO::printDebugString(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read %s and returning error:0x%x \n", __FUNCTION__, sustainedPowerLimit.c_str(), getErrorCode(result));
115120
return getErrorCode(result);

level_zero/tools/source/sysman/power/linux/os_power_imp_prelim.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2020-2023 Intel Corporation
2+
* Copyright (C) 2020-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -42,10 +42,12 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass {
4242
protected:
4343
PlatformMonitoringTech *pPmt = nullptr;
4444
SysfsAccess *pSysfsAccess = nullptr;
45+
virtual std::unique_lock<std::mutex> obtainMutex();
4546

4647
private:
4748
std::string i915HwmonDir;
4849
std::string criticalPowerLimit;
50+
std::mutex powerLimitMutex{};
4951
static const std::string hwmonDir;
5052
static const std::string i915;
5153
static const std::string sustainedPowerLimit;

level_zero/tools/test/unit_tests/sources/sysman/power/linux/test_zes_power_prelim.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2020-2023 Intel Corporation
2+
* Copyright (C) 2020-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -121,6 +121,31 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerProperties
121121
}
122122
}
123123

124+
TEST_F(SysmanDevicePowerFixture, GivenValidMockMutexPowerImpWhenGettingPowerPropertiesThenMutexLockCounterMatchesNumberOfGetCalls) {
125+
class MockMutexPowerImp : public L0::LinuxPowerImp {
126+
public:
127+
using L0::LinuxPowerImp::pSysfsAccess;
128+
MockMutexPowerImp(L0::OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) : L0::LinuxPowerImp(pOsSysman, onSubdevice, subdeviceId) {}
129+
uint32_t mutexLockCounter = 0;
130+
std::unique_lock<std::mutex> obtainMutex() override {
131+
mutexLockCounter++;
132+
std::unique_lock<std::mutex> mutexLock = L0::LinuxPowerImp::obtainMutex();
133+
EXPECT_TRUE(mutexLock.owns_lock());
134+
return mutexLock;
135+
}
136+
};
137+
138+
std::unique_ptr<MockMutexPowerImp> pLinuxPowerImp(new MockMutexPowerImp(pOsSysman, false, 0));
139+
pLinuxPowerImp->pSysfsAccess = pSysfsAccess.get();
140+
141+
uint32_t testReadCount = 0;
142+
zes_power_properties_t properties{};
143+
for (uint32_t i = 0; i < testReadCount; i++) {
144+
EXPECT_EQ(ZE_RESULT_SUCCESS, pLinuxPowerImp->getProperties(&properties));
145+
}
146+
EXPECT_EQ(pLinuxPowerImp->mutexLockCounter, testReadCount);
147+
}
148+
124149
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAndExtPropertiesThenCallSucceeds) {
125150
auto handles = getPowerHandles(powerHandleComponentCount);
126151

0 commit comments

Comments
 (0)