diff options
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.patch | 237 |
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 + |