| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 1 | #include "occ_status.hpp" | 
|  | 2 |  | 
| Chris Cain | b6535e8 | 2022-01-21 08:24:13 -0600 | [diff] [blame] | 3 | #include <fmt/core.h> | 
|  | 4 |  | 
| Andrew Geissler | 32016d1 | 2017-06-20 15:46:52 -0500 | [diff] [blame] | 5 | #include <phosphor-logging/log.hpp> | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 6 | #include <powercap.hpp> | 
| George Liu | b5ca101 | 2021-09-10 12:53:11 +0800 | [diff] [blame] | 7 |  | 
|  | 8 | #include <cassert> | 
| Andrew Geissler | 32016d1 | 2017-06-20 15:46:52 -0500 | [diff] [blame] | 9 |  | 
|  | 10 | namespace open_power | 
|  | 11 | { | 
|  | 12 | namespace occ | 
|  | 13 | { | 
|  | 14 | namespace powercap | 
|  | 15 | { | 
|  | 16 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 17 | constexpr auto PCAP_PATH = "/xyz/openbmc_project/control/host0/power_cap"; | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 18 | constexpr auto PCAP_INTERFACE = "xyz.openbmc_project.Control.Power.Cap"; | 
|  | 19 |  | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 20 | constexpr auto POWER_CAP_PROP = "PowerCap"; | 
|  | 21 | constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable"; | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 22 | constexpr auto POWER_CAP_HARD_MIN = "MinPowerCapValue"; | 
|  | 23 | constexpr auto POWER_CAP_MAX = "MaxPowerCapValue"; | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 24 |  | 
| Andrew Geissler | 32016d1 | 2017-06-20 15:46:52 -0500 | [diff] [blame] | 25 | using namespace phosphor::logging; | 
| George Liu | bcef3b4 | 2021-09-10 12:39:02 +0800 | [diff] [blame] | 26 | namespace fs = std::filesystem; | 
| Andrew Geissler | 32016d1 | 2017-06-20 15:46:52 -0500 | [diff] [blame] | 27 |  | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 28 | void PowerCap::updatePcapBounds() | 
|  | 29 | { | 
|  | 30 | // Build the hwmon string to write the power cap bounds | 
|  | 31 | fs::path minName = getPcapFilename(std::regex{"power\\d+_cap_min$"}); | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 32 | fs::path maxName = getPcapFilename(std::regex{"power\\d+_cap_max$"}); | 
|  | 33 |  | 
|  | 34 | // Read the power cap bounds from sysfs files | 
|  | 35 | uint64_t cap; | 
| Chris Cain | 40501a2 | 2022-03-14 17:33:27 -0500 | [diff] [blame^] | 36 | uint32_t capHardMin = 0, capMax = INT_MAX; | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 37 | std::ifstream minFile(minName, std::ios::in); | 
|  | 38 | if (minFile) | 
|  | 39 | { | 
|  | 40 | minFile >> cap; | 
|  | 41 | minFile.close(); | 
|  | 42 | // Convert to Watts | 
|  | 43 | capHardMin = cap / 1000000; | 
|  | 44 | } | 
|  | 45 | else | 
|  | 46 | { | 
|  | 47 | log<level::ERR>( | 
|  | 48 | fmt::format( | 
|  | 49 | "updatePcapBounds: unable to find cap_min file: {} (errno={})", | 
|  | 50 | pcapBasePathname.c_str(), errno) | 
|  | 51 | .c_str()); | 
|  | 52 | } | 
|  | 53 | std::ifstream maxFile(maxName, std::ios::in); | 
|  | 54 | if (maxFile) | 
|  | 55 | { | 
|  | 56 | maxFile >> cap; | 
|  | 57 | maxFile.close(); | 
|  | 58 | // Convert to Watts | 
|  | 59 | capMax = cap / 1000000; | 
|  | 60 | } | 
|  | 61 | else | 
|  | 62 | { | 
|  | 63 | log<level::ERR>( | 
|  | 64 | fmt::format( | 
|  | 65 | "updatePcapBounds: unable to find cap_max file: {} (errno={})", | 
|  | 66 | pcapBasePathname.c_str(), errno) | 
|  | 67 | .c_str()); | 
|  | 68 | } | 
|  | 69 |  | 
|  | 70 | // Save the bounds to dbus | 
| Chris Cain | 40501a2 | 2022-03-14 17:33:27 -0500 | [diff] [blame^] | 71 | updateDbusPcap(capHardMin, capMax); | 
|  | 72 |  | 
|  | 73 | // Validate dbus and hwmon user caps match | 
|  | 74 | const uint32_t dbusUserCap = getPcap(); | 
|  | 75 | const uint32_t hwmonUserCap = readUserCapHwmon(); | 
|  | 76 | if ((hwmonUserCap != 0) && (dbusUserCap != hwmonUserCap)) | 
|  | 77 | { | 
|  | 78 | // User power cap is enabled, but does not match dbus | 
|  | 79 | log<level::ERR>( | 
|  | 80 | fmt::format( | 
|  | 81 | "updatePcapBounds: user powercap mismatch (hwmon:{}W, bdus:{}W) - using dbus", | 
|  | 82 | hwmonUserCap, dbusUserCap) | 
|  | 83 | .c_str()); | 
|  | 84 | writeOcc(dbusUserCap); | 
|  | 85 | } | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 86 | } | 
|  | 87 |  | 
| Andrew Geissler | 4cea4d2 | 2017-07-10 15:13:33 -0500 | [diff] [blame] | 88 | uint32_t PowerCap::getOccInput(uint32_t pcap, bool pcapEnabled) | 
|  | 89 | { | 
|  | 90 | if (!pcapEnabled) | 
|  | 91 | { | 
|  | 92 | // Pcap disabled, return 0 to indicate disabled | 
|  | 93 | return 0; | 
|  | 94 | } | 
|  | 95 |  | 
|  | 96 | // If pcap is not disabled then just return the pcap with the derating | 
|  | 97 | // factor applied. | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 98 | return ((static_cast<uint64_t>(pcap) * PS_DERATING_FACTOR) / 100); | 
| Andrew Geissler | 4cea4d2 | 2017-07-10 15:13:33 -0500 | [diff] [blame] | 99 | } | 
|  | 100 |  | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 101 | uint32_t PowerCap::getPcap() | 
|  | 102 | { | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 103 | utils::PropertyValue pcap{}; | 
|  | 104 | try | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 105 | { | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 106 | pcap = utils::getProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP); | 
|  | 107 |  | 
|  | 108 | return std::get<uint32_t>(pcap); | 
|  | 109 | } | 
| Patrick Williams | 2561362 | 2021-09-02 09:29:54 -0500 | [diff] [blame] | 110 | catch (const sdbusplus::exception::exception& e) | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 111 | { | 
|  | 112 | log<level::ERR>("Failed to get PowerCap property", | 
|  | 113 | entry("ERROR=%s", e.what()), | 
|  | 114 | entry("PATH=%s", PCAP_PATH)); | 
|  | 115 |  | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 116 | return 0; | 
|  | 117 | } | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 118 | } | 
|  | 119 |  | 
|  | 120 | bool PowerCap::getPcapEnabled() | 
|  | 121 | { | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 122 | utils::PropertyValue pcapEnabled{}; | 
|  | 123 | try | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 124 | { | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 125 | pcapEnabled = utils::getProperty(PCAP_PATH, PCAP_INTERFACE, | 
|  | 126 | POWER_CAP_ENABLE_PROP); | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 127 |  | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 128 | return std::get<bool>(pcapEnabled); | 
|  | 129 | } | 
| Patrick Williams | 2561362 | 2021-09-02 09:29:54 -0500 | [diff] [blame] | 130 | catch (const sdbusplus::exception::exception& e) | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 131 | { | 
|  | 132 | log<level::ERR>("Failed to get PowerCapEnable property", | 
|  | 133 | entry("ERROR=%s", e.what()), | 
|  | 134 | entry("PATH=%s", PCAP_PATH)); | 
|  | 135 |  | 
|  | 136 | return false; | 
|  | 137 | } | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 138 | } | 
| Andrew Geissler | 32016d1 | 2017-06-20 15:46:52 -0500 | [diff] [blame] | 139 |  | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 140 | fs::path PowerCap::getPcapFilename(const std::regex& expr) | 
| Matt Spinler | eaaf3b2 | 2019-07-16 10:29:27 -0500 | [diff] [blame] | 141 | { | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 142 | if (pcapBasePathname.empty()) | 
|  | 143 | { | 
|  | 144 | static bool tracedError = false; | 
|  | 145 | pcapBasePathname = occStatus.getHwmonPath(); | 
|  | 146 | if (!fs::exists(pcapBasePathname) && !tracedError) | 
|  | 147 | { | 
|  | 148 | log<level::ERR>(fmt::format("Power Cap base filename not found: {}", | 
|  | 149 | pcapBasePathname.c_str()) | 
|  | 150 | .c_str()); | 
|  | 151 | tracedError = true; | 
|  | 152 | } | 
|  | 153 | } | 
|  | 154 | for (auto& file : fs::directory_iterator(pcapBasePathname)) | 
| Matt Spinler | eaaf3b2 | 2019-07-16 10:29:27 -0500 | [diff] [blame] | 155 | { | 
|  | 156 | if (std::regex_search(file.path().string(), expr)) | 
|  | 157 | { | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 158 | return file; | 
| Matt Spinler | eaaf3b2 | 2019-07-16 10:29:27 -0500 | [diff] [blame] | 159 | } | 
|  | 160 | } | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 161 | // return empty path | 
|  | 162 | return fs::path{}; | 
| Matt Spinler | eaaf3b2 | 2019-07-16 10:29:27 -0500 | [diff] [blame] | 163 | } | 
|  | 164 |  | 
| Chris Cain | 40501a2 | 2022-03-14 17:33:27 -0500 | [diff] [blame^] | 165 | // Write the user power cap to sysfs. | 
|  | 166 | // This will trigger the driver to send the cap to the OCC | 
| Andrew Geissler | 6ac874e | 2017-07-10 15:54:58 -0500 | [diff] [blame] | 167 | void PowerCap::writeOcc(uint32_t pcapValue) | 
|  | 168 | { | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 169 | // Build the hwmon string to write the user power cap | 
|  | 170 | fs::path fileName = getPcapFilename(std::regex{"power\\d+_cap_user$"}); | 
|  | 171 | if (fileName.empty()) | 
| Matt Spinler | eaaf3b2 | 2019-07-16 10:29:27 -0500 | [diff] [blame] | 172 | { | 
| Chris Cain | b6535e8 | 2022-01-21 08:24:13 -0600 | [diff] [blame] | 173 | log<level::ERR>( | 
|  | 174 | fmt::format("Could not find a power cap file to write to: {})", | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 175 | pcapBasePathname.c_str()) | 
| Chris Cain | b6535e8 | 2022-01-21 08:24:13 -0600 | [diff] [blame] | 176 | .c_str()); | 
| Matt Spinler | eaaf3b2 | 2019-07-16 10:29:27 -0500 | [diff] [blame] | 177 | return; | 
|  | 178 | } | 
| Matt Spinler | eaaf3b2 | 2019-07-16 10:29:27 -0500 | [diff] [blame] | 179 |  | 
|  | 180 | uint64_t microWatts = pcapValue * 1000000ull; | 
|  | 181 |  | 
|  | 182 | auto pcapString{std::to_string(microWatts)}; | 
| Andrew Geissler | 6ac874e | 2017-07-10 15:54:58 -0500 | [diff] [blame] | 183 |  | 
| Andrew Geissler | 6ac874e | 2017-07-10 15:54:58 -0500 | [diff] [blame] | 184 | // Open the hwmon file and write the power cap | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 185 | std::ofstream file(fileName, std::ios::out); | 
|  | 186 | if (file) | 
|  | 187 | { | 
|  | 188 | log<level::INFO>(fmt::format("Writing {}uW to {}", pcapString.c_str(), | 
|  | 189 | fileName.c_str()) | 
|  | 190 | .c_str()); | 
|  | 191 | file << pcapString; | 
|  | 192 | file.close(); | 
|  | 193 | } | 
|  | 194 | else | 
|  | 195 | { | 
|  | 196 | log<level::ERR>(fmt::format("Failed writing {}uW to {} (errno={})", | 
|  | 197 | microWatts, fileName.c_str(), errno) | 
|  | 198 | .c_str()); | 
|  | 199 | } | 
|  | 200 |  | 
| Andrew Geissler | 6ac874e | 2017-07-10 15:54:58 -0500 | [diff] [blame] | 201 | return; | 
|  | 202 | } | 
|  | 203 |  | 
| Chris Cain | 40501a2 | 2022-03-14 17:33:27 -0500 | [diff] [blame^] | 204 | // Read the current user power cap from sysfs. | 
|  | 205 | uint32_t PowerCap::readUserCapHwmon() | 
|  | 206 | { | 
|  | 207 | uint32_t userCap = 0; | 
|  | 208 |  | 
|  | 209 | // Get the sysfs filename for the user power cap | 
|  | 210 | fs::path userCapName = getPcapFilename(std::regex{"power\\d+_cap_user$"}); | 
|  | 211 | if (userCapName.empty()) | 
|  | 212 | { | 
|  | 213 | log<level::ERR>( | 
|  | 214 | fmt::format( | 
|  | 215 | "readUserCapHwmon: Could not find a power cap file to read: {})", | 
|  | 216 | pcapBasePathname.c_str()) | 
|  | 217 | .c_str()); | 
|  | 218 | return 0; | 
|  | 219 | } | 
|  | 220 |  | 
|  | 221 | // Open the sysfs file and read the power cap | 
|  | 222 | uint64_t cap; | 
|  | 223 | std::ifstream file(userCapName, std::ios::in); | 
|  | 224 | if (file) | 
|  | 225 | { | 
|  | 226 | file >> cap; | 
|  | 227 | file.close(); | 
|  | 228 | // Convert to Watts | 
|  | 229 | userCap = cap / 1000000; | 
|  | 230 | } | 
|  | 231 | else | 
|  | 232 | { | 
|  | 233 | log<level::ERR>( | 
|  | 234 | fmt::format("readUserCapHwmon: Failed reading {} (errno={})", | 
|  | 235 | userCapName.c_str(), errno) | 
|  | 236 | .c_str()); | 
|  | 237 | } | 
|  | 238 |  | 
|  | 239 | return userCap; | 
|  | 240 | } | 
|  | 241 |  | 
| Andrew Geissler | 32016d1 | 2017-06-20 15:46:52 -0500 | [diff] [blame] | 242 | void PowerCap::pcapChanged(sdbusplus::message::message& msg) | 
|  | 243 | { | 
| Andrew Geissler | 32016d1 | 2017-06-20 15:46:52 -0500 | [diff] [blame] | 244 | if (!occStatus.occActive()) | 
|  | 245 | { | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 246 | // Nothing to do | 
| Andrew Geissler | 32016d1 | 2017-06-20 15:46:52 -0500 | [diff] [blame] | 247 | return; | 
|  | 248 | } | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 249 |  | 
|  | 250 | uint32_t pcap = 0; | 
|  | 251 | bool pcapEnabled = false; | 
|  | 252 |  | 
|  | 253 | std::string msgSensor; | 
| Patrick Williams | e096270 | 2020-05-13 17:50:22 -0500 | [diff] [blame] | 254 | std::map<std::string, std::variant<uint32_t, bool>> msgData; | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 255 | msg.read(msgSensor, msgData); | 
|  | 256 |  | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 257 | bool changeFound = false; | 
|  | 258 | for (const auto& [prop, value] : msgData) | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 259 | { | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 260 | if (prop == POWER_CAP_PROP) | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 261 | { | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 262 | pcap = std::get<uint32_t>(value); | 
|  | 263 | pcapEnabled = getPcapEnabled(); | 
|  | 264 | changeFound = true; | 
|  | 265 | } | 
|  | 266 | else if (prop == POWER_CAP_ENABLE_PROP) | 
|  | 267 | { | 
|  | 268 | pcapEnabled = std::get<bool>(value); | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 269 | pcap = getPcap(); | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 270 | changeFound = true; | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 271 | } | 
|  | 272 | else | 
|  | 273 | { | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 274 | // Ignore other properties | 
|  | 275 | log<level::DEBUG>( | 
|  | 276 | fmt::format( | 
|  | 277 | "pcapChanged: Unknown power cap property changed {} to {}", | 
|  | 278 | prop.c_str(), std::get<uint32_t>(value)) | 
|  | 279 | .c_str()); | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 280 | } | 
|  | 281 | } | 
|  | 282 |  | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 283 | if (changeFound) | 
|  | 284 | { | 
|  | 285 | log<level::INFO>( | 
|  | 286 | fmt::format( | 
|  | 287 | "Power Cap Property Change (cap={}W (input), enabled={})", pcap, | 
|  | 288 | pcapEnabled ? 'y' : 'n') | 
|  | 289 | .c_str()); | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 290 |  | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 291 | // Determine desired action to write to occ | 
| Andrew Geissler | 6ac874e | 2017-07-10 15:54:58 -0500 | [diff] [blame] | 292 |  | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 293 | auto occInput = getOccInput(pcap, pcapEnabled); | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 294 |  | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 295 | // Write action to occ | 
|  | 296 | writeOcc(occInput); | 
|  | 297 | } | 
| Andrew Geissler | 52cf26a | 2017-07-06 12:56:32 -0500 | [diff] [blame] | 298 |  | 
|  | 299 | return; | 
| Andrew Geissler | 32016d1 | 2017-06-20 15:46:52 -0500 | [diff] [blame] | 300 | } | 
|  | 301 |  | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 302 | // Update the Power Cap bounds on DBus | 
| Chris Cain | 40501a2 | 2022-03-14 17:33:27 -0500 | [diff] [blame^] | 303 | bool PowerCap::updateDbusPcap(uint32_t hardMin, uint32_t max) | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 304 | { | 
|  | 305 | bool complete = true; | 
|  | 306 |  | 
|  | 307 | try | 
|  | 308 | { | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 309 | utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_HARD_MIN, | 
|  | 310 | hardMin); | 
|  | 311 | } | 
|  | 312 | catch (const sdbusplus::exception::exception& e) | 
|  | 313 | { | 
|  | 314 | log<level::ERR>( | 
|  | 315 | fmt::format( | 
|  | 316 | "updateDbusPcap: Failed to set HARD PCAP to {}W due to {}", | 
|  | 317 | hardMin, e.what()) | 
|  | 318 | .c_str()); | 
|  | 319 | complete = false; | 
|  | 320 | } | 
|  | 321 |  | 
|  | 322 | try | 
|  | 323 | { | 
|  | 324 | utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_MAX, max); | 
|  | 325 | } | 
|  | 326 | catch (const sdbusplus::exception::exception& e) | 
|  | 327 | { | 
|  | 328 | log<level::ERR>( | 
|  | 329 | fmt::format( | 
|  | 330 | "updateDbusPcap: Failed to set MAX PCAP to {}W due to {}", max, | 
|  | 331 | e.what()) | 
|  | 332 | .c_str()); | 
|  | 333 | complete = false; | 
|  | 334 | } | 
|  | 335 |  | 
|  | 336 | return complete; | 
|  | 337 | } | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 338 | } // namespace powercap | 
| Andrew Geissler | 32016d1 | 2017-06-20 15:46:52 -0500 | [diff] [blame] | 339 |  | 
|  | 340 | } // namespace occ | 
|  | 341 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 342 | } // namespace open_power |