Improve cpusensor performance
The cpusensor service is still making some redundant accesses for
reading hwmon attributes on every scanning. Actually, threshold
update is needed only when CPU package's Tcontrol target is
changed so this commit make it do that only when Tcontrol value
is changed.
Tested:
Compare cpu resource consumption of cpusensor service using top.
It should eat less cpu resources than before.
Change-Id: Ieb582996fc5c9c07abbfc7ac0d1b37f593269d00
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
diff --git a/src/CPUSensor.cpp b/src/CPUSensor.cpp
index d8d0ecb..a6dc275 100644
--- a/src/CPUSensor.cpp
+++ b/src/CPUSensor.cpp
@@ -27,39 +27,42 @@
#include <sdbusplus/asio/object_server.hpp>
#include <string>
-static constexpr size_t warnAfterErrorCount = 10;
-static constexpr double maxReading = 127;
-static constexpr double minReading = -128;
-
CPUSensor::CPUSensor(const std::string& path, const std::string& objectType,
sdbusplus::asio::object_server& objectServer,
std::shared_ptr<sdbusplus::asio::connection>& conn,
boost::asio::io_service& io, const std::string& sensorName,
std::vector<thresholds::Threshold>&& _thresholds,
- const std::string& sensorConfiguration) :
+ const std::string& sensorConfiguration, int cpuId,
+ bool show) :
Sensor(boost::replace_all_copy(sensorName, " ", "_"), path,
std::move(_thresholds), sensorConfiguration, objectType, maxReading,
minReading),
objServer(objectServer), inputDev(io, open(path.c_str(), O_RDONLY)),
- waitTimer(io), errCount(0)
-
+ waitTimer(io), show(show),
+ privTcontrol(std::numeric_limits<double>::quiet_NaN()), errCount(0)
{
- sensorInterface = objectServer.add_interface(
- "/xyz/openbmc_project/sensors/temperature/" + name,
- "xyz.openbmc_project.Sensor.Value");
- if (thresholds::hasWarningInterface(thresholds))
+ nameTcontrol = labelTcontrol;
+ nameTcontrol += " CPU" + std::to_string(cpuId);
+
+ if (show)
{
- thresholdInterfaceWarning = objectServer.add_interface(
+ sensorInterface = objectServer.add_interface(
"/xyz/openbmc_project/sensors/temperature/" + name,
- "xyz.openbmc_project.Sensor.Threshold.Warning");
+ "xyz.openbmc_project.Sensor.Value");
+ if (thresholds::hasWarningInterface(thresholds))
+ {
+ thresholdInterfaceWarning = objectServer.add_interface(
+ "/xyz/openbmc_project/sensors/temperature/" + name,
+ "xyz.openbmc_project.Sensor.Threshold.Warning");
+ }
+ if (thresholds::hasCriticalInterface(thresholds))
+ {
+ thresholdInterfaceCritical = objectServer.add_interface(
+ "/xyz/openbmc_project/sensors/temperature/" + name,
+ "xyz.openbmc_project.Sensor.Threshold.Critical");
+ }
+ setInitialProperties(conn);
}
- if (thresholds::hasCriticalInterface(thresholds))
- {
- thresholdInterfaceCritical = objectServer.add_interface(
- "/xyz/openbmc_project/sensors/temperature/" + name,
- "xyz.openbmc_project.Sensor.Threshold.Critical");
- }
- setInitialProperties(conn);
setupPowerMatch(conn);
setupRead();
}
@@ -69,9 +72,12 @@
// close the input dev to cancel async operations
inputDev.close();
waitTimer.cancel();
- objServer.remove_interface(thresholdInterfaceWarning);
- objServer.remove_interface(thresholdInterfaceCritical);
- objServer.remove_interface(sensorInterface);
+ if (show)
+ {
+ objServer.remove_interface(thresholdInterfaceWarning);
+ objServer.remove_interface(thresholdInterfaceCritical);
+ objServer.remove_interface(sensorInterface);
+ }
}
void CPUSensor::setupRead(void)
@@ -96,7 +102,7 @@
try
{
std::getline(responseStream, response);
- float nvalue = std::stof(response);
+ double nvalue = std::stof(response);
responseStream.clear();
nvalue /= CPUSensor::sensorScaleFactor;
if (overridenState)
@@ -105,25 +111,44 @@
}
if (nvalue != value)
{
- updateValue(nvalue);
- }
- if (!thresholds.empty())
- {
- std::vector<thresholds::Threshold> newThresholds;
- if (parseThresholdsFromAttr(newThresholds, path,
- CPUSensor::sensorScaleFactor))
+ if (show)
{
- if (!std::equal(thresholds.begin(), thresholds.end(),
- newThresholds.begin(), newThresholds.end()))
- {
- thresholds = newThresholds;
- thresholds::updateThresholds(this);
- }
+ updateValue(nvalue);
}
else
{
- std::cerr << "Failure to update thresholds for " << name
- << "\n";
+ value = nvalue;
+ }
+ }
+ double gTcontrol = gCpuSensors[nameTcontrol]
+ ? gCpuSensors[nameTcontrol]->value
+ : std::numeric_limits<double>::quiet_NaN();
+ if (gTcontrol != privTcontrol)
+ {
+ privTcontrol = gTcontrol;
+
+ if (!thresholds.empty())
+ {
+ std::vector<thresholds::Threshold> newThresholds;
+ if (parseThresholdsFromAttr(newThresholds, path,
+ CPUSensor::sensorScaleFactor))
+ {
+ if (!std::equal(thresholds.begin(), thresholds.end(),
+ newThresholds.begin(),
+ newThresholds.end()))
+ {
+ thresholds = newThresholds;
+ if (show)
+ {
+ thresholds::updateThresholds(this);
+ }
+ }
+ }
+ else
+ {
+ std::cerr << "Failure to update thresholds for " << name
+ << "\n";
+ }
}
}
errCount = 0;
@@ -150,13 +175,27 @@
std::cerr << "Failure to read sensor " << name << " at " << path
<< "\n";
}
- updateValue(0);
+ if (show)
+ {
+ updateValue(0);
+ }
+ else
+ {
+ value = 0;
+ }
errCount++;
}
else
{
errCount = 0; // check power again in 10 cycles
- updateValue(std::numeric_limits<double>::quiet_NaN());
+ if (show)
+ {
+ updateValue(std::numeric_limits<double>::quiet_NaN());
+ }
+ else
+ {
+ value = std::numeric_limits<double>::quiet_NaN();
+ }
}
}
@@ -180,5 +219,8 @@
void CPUSensor::checkThresholds(void)
{
- thresholds::checkThresholds(this);
+ if (show)
+ {
+ thresholds::checkThresholds(this);
+ }
}