blob: 20a8f47e5747358439aa0e29afdf549cab70e060 [file] [log] [blame]
Chris Cain5d66a0a2022-02-09 08:52:10 -06001#include "occ_status.hpp"
2
Chris Cainb6535e82022-01-21 08:24:13 -06003#include <fmt/core.h>
4
Andrew Geissler32016d12017-06-20 15:46:52 -05005#include <phosphor-logging/log.hpp>
Gunnar Mills94df8c92018-09-14 14:50:03 -05006#include <powercap.hpp>
George Liub5ca1012021-09-10 12:53:11 +08007
8#include <cassert>
Chris Caine2d0a432022-03-28 11:08:49 -05009#include <filesystem>
Andrew Geissler32016d12017-06-20 15:46:52 -050010
11namespace open_power
12{
13namespace occ
14{
15namespace powercap
16{
17
Gunnar Mills94df8c92018-09-14 14:50:03 -050018constexpr auto PCAP_PATH = "/xyz/openbmc_project/control/host0/power_cap";
Andrew Geissler52cf26a2017-07-06 12:56:32 -050019constexpr auto PCAP_INTERFACE = "xyz.openbmc_project.Control.Power.Cap";
20
Andrew Geissler52cf26a2017-07-06 12:56:32 -050021constexpr auto POWER_CAP_PROP = "PowerCap";
22constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable";
Chris Cain613dc902022-04-08 09:56:22 -050023constexpr auto POWER_CAP_SOFT_MIN = "MinSoftPowerCapValue";
Chris Cain5d66a0a2022-02-09 08:52:10 -060024constexpr auto POWER_CAP_HARD_MIN = "MinPowerCapValue";
25constexpr auto POWER_CAP_MAX = "MaxPowerCapValue";
Andrew Geissler52cf26a2017-07-06 12:56:32 -050026
Andrew Geissler32016d12017-06-20 15:46:52 -050027using namespace phosphor::logging;
George Liubcef3b42021-09-10 12:39:02 +080028namespace fs = std::filesystem;
Andrew Geissler32016d12017-06-20 15:46:52 -050029
Chris Cain5d66a0a2022-02-09 08:52:10 -060030void PowerCap::updatePcapBounds()
31{
32 // Build the hwmon string to write the power cap bounds
33 fs::path minName = getPcapFilename(std::regex{"power\\d+_cap_min$"});
Chris Cain613dc902022-04-08 09:56:22 -050034 fs::path softMinName =
35 getPcapFilename(std::regex{"power\\d+_cap_min_soft$"});
Chris Cain5d66a0a2022-02-09 08:52:10 -060036 fs::path maxName = getPcapFilename(std::regex{"power\\d+_cap_max$"});
37
Chris Cain81c83432022-06-27 08:21:52 -050038 // Read the current cap bounds from dbus
39 uint32_t capSoftMin, capHardMin, capMax;
40 readDbusPcapLimits(capSoftMin, capHardMin, capMax);
Chris Cain613dc902022-04-08 09:56:22 -050041
Chris Cain81c83432022-06-27 08:21:52 -050042 // Read the power cap bounds from sysfs files (from OCC)
43 uint64_t cap;
Chris Cain613dc902022-04-08 09:56:22 -050044 std::ifstream softMinFile(softMinName, std::ios::in);
45 if (softMinFile)
46 {
47 softMinFile >> cap;
48 softMinFile.close();
Chris Cain81c83432022-06-27 08:21:52 -050049 // Convert to input/AC Power in Watts (round up)
Chris Cain613dc902022-04-08 09:56:22 -050050 capSoftMin = ((cap / (PS_DERATING_FACTOR / 100.0) / 1000000) + 0.9);
51 }
52 else
53 {
54 log<level::ERR>(
55 fmt::format(
56 "updatePcapBounds: unable to find pcap_min_soft file: {} (errno={})",
57 pcapBasePathname.c_str(), errno)
58 .c_str());
59 }
60
Chris Cain5d66a0a2022-02-09 08:52:10 -060061 std::ifstream minFile(minName, std::ios::in);
62 if (minFile)
63 {
64 minFile >> cap;
65 minFile.close();
Chris Cain81c83432022-06-27 08:21:52 -050066 // Convert to input/AC Power in Watts (round up)
Chris Cain8676e032022-03-24 15:06:23 -050067 capHardMin = ((cap / (PS_DERATING_FACTOR / 100.0) / 1000000) + 0.9);
Chris Cain5d66a0a2022-02-09 08:52:10 -060068 }
69 else
70 {
71 log<level::ERR>(
72 fmt::format(
73 "updatePcapBounds: unable to find cap_min file: {} (errno={})",
74 pcapBasePathname.c_str(), errno)
75 .c_str());
76 }
Chris Cain613dc902022-04-08 09:56:22 -050077
Chris Cain5d66a0a2022-02-09 08:52:10 -060078 std::ifstream maxFile(maxName, std::ios::in);
79 if (maxFile)
80 {
81 maxFile >> cap;
82 maxFile.close();
Chris Cain81c83432022-06-27 08:21:52 -050083 // Convert to input/AC Power in Watts (truncate remainder)
Chris Cain8676e032022-03-24 15:06:23 -050084 capMax = cap / (PS_DERATING_FACTOR / 100.0) / 1000000;
Chris Cain5d66a0a2022-02-09 08:52:10 -060085 }
86 else
87 {
88 log<level::ERR>(
89 fmt::format(
90 "updatePcapBounds: unable to find cap_max file: {} (errno={})",
91 pcapBasePathname.c_str(), errno)
92 .c_str());
93 }
94
Chris Cain81c83432022-06-27 08:21:52 -050095 // Save the power cap bounds to dbus
96 updateDbusPcapLimits(capSoftMin, capHardMin, capMax);
Chris Cain40501a22022-03-14 17:33:27 -050097
Chris Cain81c83432022-06-27 08:21:52 -050098 // Validate user power cap (if enabled) is within the bounds
Chris Cain40501a22022-03-14 17:33:27 -050099 const uint32_t dbusUserCap = getPcap();
Chris Cain81c83432022-06-27 08:21:52 -0500100 const bool pcapEnabled = getPcapEnabled();
101 if (pcapEnabled && (dbusUserCap != 0))
Chris Cain40501a22022-03-14 17:33:27 -0500102 {
Chris Cain81c83432022-06-27 08:21:52 -0500103 const uint32_t hwmonUserCap = readUserCapHwmon();
104 if ((dbusUserCap >= capSoftMin) && (dbusUserCap <= capMax))
105 {
106 // Validate dbus and hwmon user caps match
107 if ((hwmonUserCap != 0) && (dbusUserCap != hwmonUserCap))
108 {
109 // User power cap is enabled, but does not match dbus
110 log<level::ERR>(
111 fmt::format(
112 "updatePcapBounds: user powercap mismatch (hwmon:{}W, bdus:{}W) - using dbus",
113 hwmonUserCap, dbusUserCap)
114 .c_str());
115 auto occInput = getOccInput(dbusUserCap, pcapEnabled);
116 writeOcc(occInput);
117 }
118 }
119 else
120 {
121 // User power cap is outside of current bounds
122 uint32_t newCap = capMax;
123 if (dbusUserCap < capSoftMin)
124 {
125 newCap = capSoftMin;
126 }
127 log<level::ERR>(
128 fmt::format(
129 "updatePcapBounds: user powercap {}W is outside bounds "
130 "(soft min:{}, min:{}, max:{})",
131 dbusUserCap, capSoftMin, capHardMin, capMax)
132 .c_str());
133 try
134 {
135 log<level::INFO>(
136 fmt::format(
137 "updatePcapBounds: Updating user powercap from {} to {}W",
138 hwmonUserCap, newCap)
139 .c_str());
140 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP,
141 newCap);
142 auto occInput = getOccInput(newCap, pcapEnabled);
143 writeOcc(occInput);
144 }
145 catch (const sdbusplus::exception::exception& e)
146 {
147 log<level::ERR>(
148 fmt::format(
149 "updatePcapBounds: Failed to update user powercap due to ",
150 e.what())
151 .c_str());
152 }
153 }
Chris Cain40501a22022-03-14 17:33:27 -0500154 }
Chris Cain5d66a0a2022-02-09 08:52:10 -0600155}
156
Chris Cain81c83432022-06-27 08:21:52 -0500157// Get value of power cap to send to the OCC (output/DC power)
Andrew Geissler4cea4d22017-07-10 15:13:33 -0500158uint32_t PowerCap::getOccInput(uint32_t pcap, bool pcapEnabled)
159{
160 if (!pcapEnabled)
161 {
162 // Pcap disabled, return 0 to indicate disabled
163 return 0;
164 }
165
166 // If pcap is not disabled then just return the pcap with the derating
Chris Cain81c83432022-06-27 08:21:52 -0500167 // factor applied (output/DC power).
Gunnar Mills94df8c92018-09-14 14:50:03 -0500168 return ((static_cast<uint64_t>(pcap) * PS_DERATING_FACTOR) / 100);
Andrew Geissler4cea4d22017-07-10 15:13:33 -0500169}
170
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500171uint32_t PowerCap::getPcap()
172{
George Liuf3b75142021-06-10 11:22:50 +0800173 utils::PropertyValue pcap{};
174 try
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500175 {
George Liuf3b75142021-06-10 11:22:50 +0800176 pcap = utils::getProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP);
177
178 return std::get<uint32_t>(pcap);
179 }
Patrick Williams25613622021-09-02 09:29:54 -0500180 catch (const sdbusplus::exception::exception& e)
George Liuf3b75142021-06-10 11:22:50 +0800181 {
182 log<level::ERR>("Failed to get PowerCap property",
183 entry("ERROR=%s", e.what()),
184 entry("PATH=%s", PCAP_PATH));
185
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500186 return 0;
187 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500188}
189
190bool PowerCap::getPcapEnabled()
191{
George Liuf3b75142021-06-10 11:22:50 +0800192 utils::PropertyValue pcapEnabled{};
193 try
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500194 {
George Liuf3b75142021-06-10 11:22:50 +0800195 pcapEnabled = utils::getProperty(PCAP_PATH, PCAP_INTERFACE,
196 POWER_CAP_ENABLE_PROP);
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500197
George Liuf3b75142021-06-10 11:22:50 +0800198 return std::get<bool>(pcapEnabled);
199 }
Patrick Williams25613622021-09-02 09:29:54 -0500200 catch (const sdbusplus::exception::exception& e)
George Liuf3b75142021-06-10 11:22:50 +0800201 {
202 log<level::ERR>("Failed to get PowerCapEnable property",
203 entry("ERROR=%s", e.what()),
204 entry("PATH=%s", PCAP_PATH));
205
206 return false;
207 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500208}
Andrew Geissler32016d12017-06-20 15:46:52 -0500209
Chris Cain5d66a0a2022-02-09 08:52:10 -0600210fs::path PowerCap::getPcapFilename(const std::regex& expr)
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500211{
Chris Cain5d66a0a2022-02-09 08:52:10 -0600212 if (pcapBasePathname.empty())
213 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600214 pcapBasePathname = occStatus.getHwmonPath();
Chris Cain5d66a0a2022-02-09 08:52:10 -0600215 }
Chris Caine2d0a432022-03-28 11:08:49 -0500216
217 if (fs::exists(pcapBasePathname))
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500218 {
Chris Caine2d0a432022-03-28 11:08:49 -0500219 // Search for pcap file based on the supplied expr
220 for (auto& file : fs::directory_iterator(pcapBasePathname))
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500221 {
Chris Caine2d0a432022-03-28 11:08:49 -0500222 if (std::regex_search(file.path().string(), expr))
223 {
224 // Found match
225 return file;
226 }
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500227 }
228 }
Chris Caine2d0a432022-03-28 11:08:49 -0500229 else
230 {
231 log<level::ERR>(fmt::format("Power Cap base filename not found: {}",
232 pcapBasePathname.c_str())
233 .c_str());
234 }
235
Chris Cain5d66a0a2022-02-09 08:52:10 -0600236 // return empty path
237 return fs::path{};
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500238}
239
Chris Cain81c83432022-06-27 08:21:52 -0500240// Write the user power cap to sysfs (output/DC power)
Chris Cain40501a22022-03-14 17:33:27 -0500241// This will trigger the driver to send the cap to the OCC
Andrew Geissler6ac874e2017-07-10 15:54:58 -0500242void PowerCap::writeOcc(uint32_t pcapValue)
243{
Chris Caind4c19a02022-04-22 15:46:13 -0500244 if (!occStatus.occActive())
245 {
246 // OCC not running, skip update
247 return;
248 }
249
Chris Cain5d66a0a2022-02-09 08:52:10 -0600250 // Build the hwmon string to write the user power cap
251 fs::path fileName = getPcapFilename(std::regex{"power\\d+_cap_user$"});
252 if (fileName.empty())
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500253 {
Chris Cainb6535e82022-01-21 08:24:13 -0600254 log<level::ERR>(
255 fmt::format("Could not find a power cap file to write to: {})",
Chris Cain5d66a0a2022-02-09 08:52:10 -0600256 pcapBasePathname.c_str())
Chris Cainb6535e82022-01-21 08:24:13 -0600257 .c_str());
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500258 return;
259 }
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500260
261 uint64_t microWatts = pcapValue * 1000000ull;
262
263 auto pcapString{std::to_string(microWatts)};
Andrew Geissler6ac874e2017-07-10 15:54:58 -0500264
Andrew Geissler6ac874e2017-07-10 15:54:58 -0500265 // Open the hwmon file and write the power cap
Chris Cain5d66a0a2022-02-09 08:52:10 -0600266 std::ofstream file(fileName, std::ios::out);
267 if (file)
268 {
269 log<level::INFO>(fmt::format("Writing {}uW to {}", pcapString.c_str(),
270 fileName.c_str())
271 .c_str());
272 file << pcapString;
273 file.close();
274 }
275 else
276 {
277 log<level::ERR>(fmt::format("Failed writing {}uW to {} (errno={})",
278 microWatts, fileName.c_str(), errno)
279 .c_str());
280 }
281
Andrew Geissler6ac874e2017-07-10 15:54:58 -0500282 return;
283}
284
Chris Cain81c83432022-06-27 08:21:52 -0500285// Read the current user power cap from sysfs as input/AC power
Chris Cain40501a22022-03-14 17:33:27 -0500286uint32_t PowerCap::readUserCapHwmon()
287{
288 uint32_t userCap = 0;
289
290 // Get the sysfs filename for the user power cap
291 fs::path userCapName = getPcapFilename(std::regex{"power\\d+_cap_user$"});
292 if (userCapName.empty())
293 {
294 log<level::ERR>(
295 fmt::format(
296 "readUserCapHwmon: Could not find a power cap file to read: {})",
297 pcapBasePathname.c_str())
298 .c_str());
299 return 0;
300 }
301
302 // Open the sysfs file and read the power cap
Chris Cain40501a22022-03-14 17:33:27 -0500303 std::ifstream file(userCapName, std::ios::in);
304 if (file)
305 {
Chris Caine2d0a432022-03-28 11:08:49 -0500306 uint64_t cap;
Chris Cain40501a22022-03-14 17:33:27 -0500307 file >> cap;
308 file.close();
Chris Cain81c83432022-06-27 08:21:52 -0500309 // Convert to input/AC Power in Watts
310 userCap = (cap / (PS_DERATING_FACTOR / 100.0) / 1000000);
Chris Cain40501a22022-03-14 17:33:27 -0500311 }
312 else
313 {
314 log<level::ERR>(
315 fmt::format("readUserCapHwmon: Failed reading {} (errno={})",
316 userCapName.c_str(), errno)
317 .c_str());
318 }
319
320 return userCap;
321}
322
Andrew Geissler32016d12017-06-20 15:46:52 -0500323void PowerCap::pcapChanged(sdbusplus::message::message& msg)
324{
Andrew Geissler32016d12017-06-20 15:46:52 -0500325 if (!occStatus.occActive())
326 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600327 // Nothing to do
Andrew Geissler32016d12017-06-20 15:46:52 -0500328 return;
329 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500330
331 uint32_t pcap = 0;
332 bool pcapEnabled = false;
333
334 std::string msgSensor;
Patrick Williamse0962702020-05-13 17:50:22 -0500335 std::map<std::string, std::variant<uint32_t, bool>> msgData;
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500336 msg.read(msgSensor, msgData);
337
Chris Cain5d66a0a2022-02-09 08:52:10 -0600338 bool changeFound = false;
339 for (const auto& [prop, value] : msgData)
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500340 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600341 if (prop == POWER_CAP_PROP)
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500342 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600343 pcap = std::get<uint32_t>(value);
344 pcapEnabled = getPcapEnabled();
345 changeFound = true;
346 }
347 else if (prop == POWER_CAP_ENABLE_PROP)
348 {
349 pcapEnabled = std::get<bool>(value);
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500350 pcap = getPcap();
Chris Cain5d66a0a2022-02-09 08:52:10 -0600351 changeFound = true;
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500352 }
353 else
354 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600355 // Ignore other properties
356 log<level::DEBUG>(
357 fmt::format(
358 "pcapChanged: Unknown power cap property changed {} to {}",
359 prop.c_str(), std::get<uint32_t>(value))
360 .c_str());
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500361 }
362 }
363
Chris Cain81c83432022-06-27 08:21:52 -0500364 // Validate the cap is within supported range
365 uint32_t capSoftMin, capHardMin, capMax;
366 readDbusPcapLimits(capSoftMin, capHardMin, capMax);
367 if (((pcap > 0) && (pcap < capSoftMin)) || ((pcap == 0) && (pcapEnabled)))
368 {
369 log<level::ERR>(
370 fmt::format(
371 "pcapChanged: Power cap of {}W is lower than allowed (soft min:{}, min:{}) - using soft min",
372 pcap, capSoftMin, capHardMin)
373 .c_str());
374 pcap = capSoftMin;
375 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP, pcap);
376 }
377 else if (pcap > capMax)
378 {
379 log<level::ERR>(
380 fmt::format(
381 "pcapChanged: Power cap of {}W is higher than allowed (max:{}) - using max",
382 pcap, capSoftMin, capHardMin)
383 .c_str());
384 pcap = capMax;
385 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP, pcap);
386 }
387
Chris Cain5d66a0a2022-02-09 08:52:10 -0600388 if (changeFound)
389 {
390 log<level::INFO>(
391 fmt::format(
392 "Power Cap Property Change (cap={}W (input), enabled={})", pcap,
393 pcapEnabled ? 'y' : 'n')
394 .c_str());
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500395
Chris Cain5d66a0a2022-02-09 08:52:10 -0600396 // Determine desired action to write to occ
Chris Cain5d66a0a2022-02-09 08:52:10 -0600397 auto occInput = getOccInput(pcap, pcapEnabled);
Chris Cain5d66a0a2022-02-09 08:52:10 -0600398 // Write action to occ
399 writeOcc(occInput);
400 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500401
402 return;
Andrew Geissler32016d12017-06-20 15:46:52 -0500403}
404
Chris Cain5d66a0a2022-02-09 08:52:10 -0600405// Update the Power Cap bounds on DBus
Chris Cain81c83432022-06-27 08:21:52 -0500406bool PowerCap::updateDbusPcapLimits(uint32_t softMin, uint32_t hardMin,
407 uint32_t max)
Chris Cain5d66a0a2022-02-09 08:52:10 -0600408{
409 bool complete = true;
410
411 try
412 {
Chris Cain613dc902022-04-08 09:56:22 -0500413 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_SOFT_MIN,
414 softMin);
415 }
416 catch (const sdbusplus::exception::exception& e)
417 {
418 log<level::ERR>(
419 fmt::format(
Chris Cain81c83432022-06-27 08:21:52 -0500420 "updateDbusPcapLimits: Failed to set SOFT PCAP to {}W due to {}",
Chris Cain613dc902022-04-08 09:56:22 -0500421 softMin, e.what())
422 .c_str());
423 complete = false;
424 }
425
426 try
427 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600428 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_HARD_MIN,
429 hardMin);
430 }
431 catch (const sdbusplus::exception::exception& e)
432 {
433 log<level::ERR>(
434 fmt::format(
Chris Cain81c83432022-06-27 08:21:52 -0500435 "updateDbusPcapLimits: Failed to set HARD PCAP to {}W due to {}",
Chris Cain5d66a0a2022-02-09 08:52:10 -0600436 hardMin, e.what())
437 .c_str());
438 complete = false;
439 }
440
441 try
442 {
443 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_MAX, max);
444 }
445 catch (const sdbusplus::exception::exception& e)
446 {
447 log<level::ERR>(
448 fmt::format(
Chris Cain81c83432022-06-27 08:21:52 -0500449 "updateDbusPcapLimits: Failed to set MAX PCAP to {}W due to {}",
450 max, e.what())
Chris Cain5d66a0a2022-02-09 08:52:10 -0600451 .c_str());
452 complete = false;
453 }
454
455 return complete;
456}
Chris Cain81c83432022-06-27 08:21:52 -0500457
458// Read the Power Cap bounds from DBus
459bool PowerCap::readDbusPcapLimits(uint32_t& softMin, uint32_t& hardMin,
460 uint32_t& max)
461{
462 bool complete = true;
463 utils::PropertyValue prop{};
464
465 try
466 {
467 prop =
468 utils::getProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_SOFT_MIN);
469 softMin = std::get<uint32_t>(prop);
470 }
471 catch (const sdbusplus::exception::exception& e)
472 {
473 log<level::ERR>(
474 fmt::format("readDbusPcapLimits: Failed to get SOFT PCAP due to {}",
475 e.what())
476 .c_str());
477 softMin = 0;
478 complete = false;
479 }
480
481 try
482 {
483 prop =
484 utils::getProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_HARD_MIN);
485 hardMin = std::get<uint32_t>(prop);
486 }
487 catch (const sdbusplus::exception::exception& e)
488 {
489 log<level::ERR>(
490 fmt::format("readDbusPcapLimits: Failed to get HARD PCAP due to {}",
491 e.what())
492 .c_str());
493 hardMin = 0;
494 complete = false;
495 }
496
497 try
498 {
499 prop = utils::getProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_MAX);
500 max = std::get<uint32_t>(prop);
501 }
502 catch (const sdbusplus::exception::exception& e)
503 {
504 log<level::ERR>(
505 fmt::format("readDbusPcapLimits: Failed to get MAX PCAP due to {}",
506 e.what())
507 .c_str());
508 max = INT_MAX;
509 complete = false;
510 }
511
512 return complete;
513}
514
Gunnar Mills94df8c92018-09-14 14:50:03 -0500515} // namespace powercap
Andrew Geissler32016d12017-06-20 15:46:52 -0500516
517} // namespace occ
518
Gunnar Mills94df8c92018-09-14 14:50:03 -0500519} // namespace open_power