psu-ng: Set the PowerSystemInputs status on Brownout condition
When a brownout condition is detected, set the PowerSystemInputs status
property to Fault to avoid an autorestart, reference design doc:
https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/48015
Add a Before=xyz.openbmc_project.State.Chassis.service to the psu
monitor service file since the chassis service is the one that will be
reading the property.
Add additional data to the Blackout error log.
Tested: On simulation:
1. Clear brownout at runtime:
- At power on, inject a power fault to all PSUs to trigger a brownout
and verify the CurrentPowerStatus is set to Fault:
Mar 20 19:49:14 p10bmc phosphor-log-manager[318]: Created PEL 0x5000000d
(BMC ID 13) with SRC 110000AC
Mar 20 19:49:14 p10bmc phosphor-power-control[307]:
callbackSetPowerSupplyError:
xyz.openbmc_project.State.Shutdown.Power.Error.Blackout
‣ Type=signal Endian=l Flags=1 Version=1 Cookie=94 Timestamp="Sun
2022-03-20 19:49:14.241856 UTC"
Sender=:1.1296
Path=/xyz/openbmc_project/power/power_supplies/chassis0/psus
Interface=org.freedesktop.DBus.Properties Member=PropertiesChanged
...
STRING
"xyz.openbmc_project.State.Decorator.PowerSystemInputs";
...
STRING
"xyz.openbmc_project.State.Decorator.PowerSystemInputs.Status.Fault";
- Additional data on the error log:
"User Data 1": {
"Section Version": "1",
"Sub-section type": "1",
"Created by": "0x2000",
"NOT_PRESENT_COUNT": "2",
"VIN_FAULT_COUNT": "2",
"_PID": "10244"
}
- Clear the brownout condition and verify the status is set to Good.
Change-Id: I29695b641fb81515680a478e872bac29a6de560a
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/phosphor-power-supply/psu_manager.cpp b/phosphor-power-supply/psu_manager.cpp
index e6a3225..03ee9e4 100644
--- a/phosphor-power-supply/psu_manager.cpp
+++ b/phosphor-power-supply/psu_manager.cpp
@@ -363,7 +363,6 @@
{
powerOn = false;
runValidateConfig = true;
- brownoutLogged = false;
}
}
}
@@ -459,41 +458,36 @@
psu->analyze();
}
+ std::map<std::string, std::string> additionalData;
+
+ auto notPresentCount = decltype(psus.size())(
+ std::count_if(psus.begin(), psus.end(),
+ [](const auto& psu) { return !psu->isPresent(); }));
+
+ auto hasVINUVFaultCount = decltype(psus.size())(
+ std::count_if(psus.begin(), psus.end(),
+ [](const auto& psu) { return psu->hasVINUVFault(); }));
+
+ // The PSU D-Bus objects may not be available yet, so ignore if all
+ // PSUs are not present or the number of PSUs is still 0.
+ if ((psus.size() == (notPresentCount + hasVINUVFaultCount)) &&
+ (psus.size() != notPresentCount) && (psus.size() != 0))
+ {
+ // Brownout: All PSUs report an AC failure: At least one PSU reports
+ // AC loss VIN fault and the rest either report AC loss VIN fault as
+ // well or are not present.
+ additionalData["NOT_PRESENT_COUNT"] = std::to_string(notPresentCount);
+ additionalData["VIN_FAULT_COUNT"] = std::to_string(hasVINUVFaultCount);
+ setBrownout(additionalData);
+ }
+ else
+ {
+ // Brownout condition is not present or has been cleared
+ clearBrownout();
+ }
+
if (powerOn)
{
- std::map<std::string, std::string> additionalData;
-
- auto notPresentCount = decltype(psus.size())(
- std::count_if(psus.begin(), psus.end(),
- [](const auto& psu) { return !psu->isPresent(); }));
-
- auto hasVINUVFaultCount = decltype(psus.size())(
- std::count_if(psus.begin(), psus.end(), [](const auto& psu) {
- return psu->hasVINUVFault();
- }));
-
- // The PSU D-Bus objects may not be available yet, so ignore if all
- // PSUs are not present or the number of PSUs is still 0.
- if ((psus.size() == (notPresentCount + hasVINUVFaultCount)) &&
- (psus.size() != notPresentCount) && (psus.size() != 0))
- {
- // Brownout: All PSUs report an AC failure: At least one PSU reports
- // AC loss VIN fault and the rest either report AC loss VIN fault as
- // well or are not present.
- if (!brownoutLogged)
- {
- createError(
- "xyz.openbmc_project.State.Shutdown.Power.Error.Blackout",
- additionalData);
- brownoutLogged = true;
- }
- }
- else
- {
- // Brownout condition is not present or has been cleared
- brownoutLogged = false;
- }
-
for (auto& psu : psus)
{
additionalData.clear();
@@ -869,4 +863,27 @@
}
}
+void PSUManager::setBrownout(std::map<std::string, std::string>& additionalData)
+{
+ powerSystemInputs.status(sdbusplus::xyz::openbmc_project::State::Decorator::
+ server::PowerSystemInputs::Status::Fault);
+ if (!brownoutLogged)
+ {
+ if (powerOn)
+ {
+ createError(
+ "xyz.openbmc_project.State.Shutdown.Power.Error.Blackout",
+ additionalData);
+ brownoutLogged = true;
+ }
+ }
+}
+
+void PSUManager::clearBrownout()
+{
+ powerSystemInputs.status(sdbusplus::xyz::openbmc_project::State::Decorator::
+ server::PowerSystemInputs::Status::Good);
+ brownoutLogged = false;
+}
+
} // namespace phosphor::power::manager
diff --git a/phosphor-power-supply/psu_manager.hpp b/phosphor-power-supply/psu_manager.hpp
index d291324..02fff3f 100644
--- a/phosphor-power-supply/psu_manager.hpp
+++ b/phosphor-power-supply/psu_manager.hpp
@@ -325,6 +325,21 @@
void setPowerConfigGPIO();
/**
+ * @brief Indicate that the system is in a brownout condition by creating an
+ * error log and setting the PowerSystemInputs status property to Fault.
+ *
+ * @param[in] additionalData - Contains debug information on the number of
+ * PSUs in fault state or not present.
+ */
+ void setBrownout(std::map<std::string, std::string>& additionalData);
+
+ /**
+ * @brief Indicate that the system is no longer in a brownout condition by
+ * setting the PowerSystemInputs status property to Good.
+ */
+ void clearBrownout();
+
+ /**
* @brief Map of supported PSU configurations that include the model name
* and their properties.
*/
diff --git a/services/phosphor-psu-monitor.service b/services/phosphor-psu-monitor.service
index 8e369b4..6c26565 100644
--- a/services/phosphor-psu-monitor.service
+++ b/services/phosphor-psu-monitor.service
@@ -2,6 +2,7 @@
Description=Phosphor Power Supply Monitor
Wants=mapper-wait@-xyz-openbmc_project-inventory-system.service
After=mapper-wait@-xyz-openbmc_project-inventory-system.service
+Before=xyz.openbmc_project.State.Chassis.service
[Service]
Restart=on-failure