summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0017-Add-more-boundary-checking-in-Texitair-calculation.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0017-Add-more-boundary-checking-in-Texitair-calculation.patch')
-rw-r--r--meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0017-Add-more-boundary-checking-in-Texitair-calculation.patch237
1 files changed, 237 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0017-Add-more-boundary-checking-in-Texitair-calculation.patch b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0017-Add-more-boundary-checking-in-Texitair-calculation.patch
new file mode 100644
index 000000000..08f26b642
--- /dev/null
+++ b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0017-Add-more-boundary-checking-in-Texitair-calculation.patch
@@ -0,0 +1,237 @@
+From 5c2981d14b00b510f123bbde3805f4b0c96ee735 Mon Sep 17 00:00:00 2001
+From: Zhikui Ren <zhikui.ren@intel.com>
+Date: Thu, 4 Feb 2021 13:54:33 -0800
+Subject: [PATCH 1/3] Add more boundary checking in ExitAir calculation
+
+There are sightings that exitair temp calculation can produce
+extreme result, for example 3000+ degrees or negative degrees.
+Additional boundary checks are added to prevent these results:
+1. totalCFM limit to greater than minimum CFM from a fan (Qmin)
+2. ensure alphaDT is greater than 0, which is used as:
+Tavg = T * alphaDT + T * (1-alphaDT) (It has already limited to be <= 1.0)
+3. additional debug logging if Texit exceeds 100 degrees, which is not expected
+4. adjust CFM reading max limit base on new thermal data
+
+Effciency improvements:
+1. Add tolerance in equality check with double value
+2. Use current CFM sensor value when calculating Texit to avoid circular
+dependency
+
+Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
+
+exit air update
+---
+ src/ExitAirTempSensor.cpp | 75 +++++++++++++++++++++++++++++++--------
+ 1 file changed, 61 insertions(+), 14 deletions(-)
+
+diff --git a/src/ExitAirTempSensor.cpp b/src/ExitAirTempSensor.cpp
+index d27aa06..9f7afe0 100644
+--- a/src/ExitAirTempSensor.cpp
++++ b/src/ExitAirTempSensor.cpp
+@@ -42,6 +42,7 @@
+ #include <vector>
+
+ constexpr const float altitudeFactor = 1.14;
++static constexpr double exitAirTempResolution = 0.5;
+ constexpr const char* exitAirIface =
+ "xyz.openbmc_project.Configuration.ExitAirTempSensor";
+ constexpr const char* cfmIface = "xyz.openbmc_project.Configuration.CFMSensor";
+@@ -56,7 +57,8 @@ constexpr const char* cfmSettingIface = "xyz.openbmc_project.Control.CFMLimit";
+
+ static constexpr bool DEBUG = false;
+
+-static constexpr double cfmMaxReading = 255;
++static constexpr double cfmMaxReading =
++ 6 * 255; // currently there 6 fans-need better strategy LGTM
+ static constexpr double cfmMinReading = 0;
+
+ static constexpr size_t minSystemCfm = 50;
+@@ -304,6 +306,7 @@ void CFMSensor::addTachRanges(const std::string& serviceName,
+ if (ec)
+ {
+ std::cerr << "Error getting properties from " << path << "\n";
++ std::cerr << ec.message() << "\n";
+ return;
+ }
+
+@@ -326,13 +329,18 @@ void CFMSensor::updateReading(void)
+ double val = 0.0;
+ if (calculate(val))
+ {
+- if (value != val && parent)
++ if (!std::isfinite(value) ||
++ (fabs(value - val) > exitAirTempResolution))
+ {
+- parent->updateReading();
++ updateValue(val);
++ if (parent)
++ {
++ parent->updateReading();
++ }
+ }
+- updateValue(val);
++ return;
+ }
+- else
++ if (!std::isnan(value))
+ {
+ updateValue(std::numeric_limits<double>::quiet_NaN());
+ }
+@@ -483,6 +491,7 @@ bool CFMSensor::calculate(double& value)
+ {
+ std::cerr << "cfm value = " << value << "\n";
+ }
++
+ return true;
+ }
+
+@@ -588,6 +597,7 @@ void ExitAirTempSensor::setupMatches(void)
+ if (ec)
+ {
+ std::cerr << "Error contacting mapper\n";
++ std::cerr << ec.message() << "\n";
+ return;
+ }
+ for (const auto& item : subtree)
+@@ -610,6 +620,7 @@ void ExitAirTempSensor::setupMatches(void)
+ {
+ std::cerr << "Error getting value from " << path
+ << "\n";
++ std::cerr << ec.message() << "\n";
+ }
+
+ double reading =
+@@ -641,6 +652,7 @@ void ExitAirTempSensor::addPowerRanges(const std::string& serviceName,
+ if (ec)
+ {
+ std::cerr << "Error getting properties from " << path << "\n";
++ std::cerr << ec.message() << "\n";
+ return;
+ }
+
+@@ -660,9 +672,13 @@ void ExitAirTempSensor::updateReading(void)
+ if (calculate(val))
+ {
+ val = std::floor(val + 0.5);
+- updateValue(val);
++ if (!std::isfinite(value) || value != val)
++ {
++ updateValue(val);
++ }
++ return;
+ }
+- else
++ if (!std::isnan(value))
+ {
+ updateValue(std::numeric_limits<double>::quiet_NaN());
+ }
+@@ -674,7 +690,10 @@ double ExitAirTempSensor::getTotalCFM(void)
+ for (auto& sensor : cfmSensors)
+ {
+ double reading = 0;
+- if (!sensor->calculate(reading))
++ // cfmSensors match on fan tach value changes and calculate new CFM
++ // use the CFM sensor value directly without recalculate
++ reading = sensor->value;
++ if (!std::isfinite(reading))
+ {
+ return -1;
+ }
+@@ -687,11 +706,11 @@ double ExitAirTempSensor::getTotalCFM(void)
+ bool ExitAirTempSensor::calculate(double& val)
+ {
+ constexpr size_t maxErrorPrint = 5;
+- static bool firstRead = false;
++ static bool firstRead = true;
+ static size_t errorPrint = maxErrorPrint;
+
+ double cfm = getTotalCFM();
+- if (cfm <= 0 || cfm > cfmMaxReading)
++ if (cfm <= cfmMinReading || cfm > cfmMaxReading)
+ {
+ if (errorPrint > 0)
+ {
+@@ -765,6 +784,10 @@ bool ExitAirTempSensor::calculate(double& val)
+ float powerFactor = 0.0;
+ if (cfm <= qMin)
+ {
++ // limit lower bound of cfm to prevent reporting extreme high
++ // exit air temp. fan failures or error in reading fan sensors
++ // are expected to be caught by sensor threshold.
++ cfm = qMin;
+ powerFactor = powerFactorMin;
+ }
+ else if (cfm >= qMax)
+@@ -793,6 +816,7 @@ bool ExitAirTempSensor::calculate(double& val)
+
+ if constexpr (DEBUG)
+ {
++ std::cout << "totalCFM " << cfm << "\n";
+ std::cout << "Power Factor " << powerFactor << "\n";
+ std::cout << "Inlet Temp " << inletTemp << "\n";
+ std::cout << "Total Power" << totalPower << "\n";
+@@ -814,7 +838,7 @@ bool ExitAirTempSensor::calculate(double& val)
+ // Ai = As + (Af - As)/(QMax - QMin) * (CFM - QMin)
+
+ double alpha = 0.0;
+- if (cfm < qMin)
++ if (cfm <= qMin)
+ {
+ alpha = alphaS;
+ }
+@@ -828,9 +852,9 @@ bool ExitAirTempSensor::calculate(double& val)
+ }
+
+ auto time = std::chrono::system_clock::now();
+- if (!firstRead)
++ if (firstRead)
+ {
+- firstRead = true;
++ firstRead = false;
+ lastTime = time;
+ lastReading = reading;
+ }
+@@ -844,6 +868,10 @@ bool ExitAirTempSensor::calculate(double& val)
+ {
+ alphaDT = 1.0;
+ }
++ else if (alphaDT < 0.0)
++ {
++ alphaDT = 0.0;
++ }
+
+ if constexpr (DEBUG)
+ {
+@@ -858,9 +886,28 @@ bool ExitAirTempSensor::calculate(double& val)
+ }
+
+ val = reading;
++ if (val > 90)
++ {
++ if (errorPrint > 0)
++ {
++ errorPrint--;
++ std::cerr << "Inlet Temp " << inletTemp << "\n";
++ std::cerr << "Total Power " << totalPower << "\n";
++ std::cerr << "powerFactor " << powerFactor << "\n";
++ std::cerr << "pOffset " << pOffset << "\n";
++ std::cerr << "totalCFM " << cfm << "\n";
++ std::cerr << "lastReading " << lastReading << "\n";
++ std::cerr << "alphaDT " << alphaDT << "\n";
++ }
++ }
++ else
++ {
++ errorPrint = maxErrorPrint;
++ }
++
+ lastReading = reading;
+ lastTime = time;
+- errorPrint = maxErrorPrint;
++
+ return true;
+ }
+
+--
+2.17.1
+