summaryrefslogtreecommitdiff
path: root/thermal
diff options
context:
space:
mode:
authorGeorge Lee <geolee@google.com>2020-10-05 11:59:36 -0700
committerGeorge Lee <geolee@google.com>2020-12-02 09:43:13 -0800
commit9af1e97ad1ca83448d31773fcce1c727dd7865de (patch)
treeb55c6ba5ae8655f5f62d5298f5174f16a0b0a7fc /thermal
parent55d72137813ba3f66f9e7e4f82ab8abaa85f399d (diff)
downloadpixel-9af1e97ad1ca83448d31773fcce1c727dd7865de.tar.gz
thermal: Combination sensors monitoring.
Enable BCL virtual sensor monitoring in ThermalHAL. Bug: 170304779 Test: Local Test Signed-off-by: George Lee <geolee@google.com> Change-Id: I6482cfa6883d7a030195243983945c9621bc2b3e
Diffstat (limited to 'thermal')
-rw-r--r--thermal/thermal-helper.cpp103
-rw-r--r--thermal/thermal-helper.h4
-rw-r--r--thermal/utils/config_parser.cpp63
-rw-r--r--thermal/utils/config_parser.h17
4 files changed, 175 insertions, 12 deletions
diff --git a/thermal/thermal-helper.cpp b/thermal/thermal-helper.cpp
index 6f371132..f016d663 100644
--- a/thermal/thermal-helper.cpp
+++ b/thermal/thermal-helper.cpp
@@ -364,18 +364,26 @@ bool ThermalHelper::readTemperature(std::string_view sensor_name, Temperature_1_
bool ThermalHelper::readTemperature(
std::string_view sensor_name, Temperature_2_0 *out,
- std::pair<ThrottlingSeverity, ThrottlingSeverity> *throtting_status) const {
+ std::pair<ThrottlingSeverity, ThrottlingSeverity> *throtting_status,
+ bool is_virtual_sensor) const {
// Read the file. If the file can't be read temp will be empty string.
std::string temp;
- if (!thermal_sensors_.readThermalFile(sensor_name, &temp)) {
- LOG(ERROR) << "readTemperature: sensor not found: " << sensor_name;
- return false;
- }
+ if (!is_virtual_sensor) {
+ if (!thermal_sensors_.readThermalFile(sensor_name, &temp)) {
+ LOG(ERROR) << "readTemperature: sensor not found: " << sensor_name;
+ return false;
+ }
- if (temp.empty()) {
- LOG(ERROR) << "readTemperature: failed to read sensor: " << sensor_name;
- return false;
+ if (temp.empty()) {
+ LOG(ERROR) << "readTemperature: failed to read sensor: " << sensor_name;
+ return false;
+ }
+ } else {
+ if (!checkVirtualSensor(sensor_name.data(), &temp)) {
+ LOG(ERROR) << "readTemperature: failed to read virtual sensor: " << sensor_name;
+ return false;
+ }
}
const auto &sensor_info = sensor_info_map_.at(sensor_name.data());
@@ -474,12 +482,18 @@ std::pair<ThrottlingSeverity, ThrottlingSeverity> ThermalHelper::getSeverityFrom
bool ThermalHelper::initializeSensorMap(const std::map<std::string, std::string> &path_map) {
for (const auto &sensor_info_pair : sensor_info_map_) {
std::string_view sensor_name = sensor_info_pair.first;
+ if (sensor_info_pair.second.is_virtual_sensor) {
+ sensor_name = sensor_info_pair.second.trigger_sensor;
+ }
if (!path_map.count(sensor_name.data())) {
LOG(ERROR) << "Could not find " << sensor_name << " in sysfs";
continue;
}
std::string path = android::base::StringPrintf(
"%s/%s", path_map.at(sensor_name.data()).c_str(), kSensorTempSuffix.data());
+ if (sensor_info_pair.second.is_virtual_sensor) {
+ sensor_name = sensor_info_pair.first;
+ }
if (!thermal_sensors_.addThermalFile(sensor_name, path)) {
LOG(ERROR) << "Could not add " << sensor_name << "to sensors map";
}
@@ -516,6 +530,9 @@ bool ThermalHelper::initializeTrip(const std::map<std::string, std::string> &pat
for (const auto &sensor_info : sensor_info_map_) {
if (sensor_info.second.is_monitor) {
std::string_view sensor_name = sensor_info.first;
+ if (sensor_info.second.is_virtual_sensor) {
+ continue;
+ }
std::string_view tz_path = path_map.at(sensor_name.data());
std::string tz_policy;
std::string path = android::base::StringPrintf("%s/%s", (tz_path.data()),
@@ -654,6 +671,63 @@ bool ThermalHelper::fillCpuUsages(hidl_vec<CpuUsage> *cpu_usages) const {
return true;
}
+bool ThermalHelper::checkVirtualSensor(std::string_view sensor_name, std::string *temp) const {
+ double mTemp = 0;
+ for (const auto &sensor_info_pair : sensor_info_map_) {
+ int idx = 0;
+ if (sensor_info_pair.first != sensor_name.data()) {
+ continue;
+ }
+ for (int i = 0; i < static_cast<int>(kCombinationCount); i++) {
+ if (sensor_info_pair.second.linked_sensors[i].compare("NAN") == 0) {
+ continue;
+ }
+ if (sensor_info_pair.second.linked_sensors[i].size() <= 0) {
+ continue;
+ }
+ std::string data;
+ idx += 1;
+ if (!thermal_sensors_.readThermalFile(sensor_info_pair.second.linked_sensors[i],
+ &data)) {
+ continue;
+ }
+ data = ::android::base::Trim(data);
+ float sensor_reading = std::stof(data);
+ if (std::isnan(sensor_info_pair.second.coefficients[i])) {
+ continue;
+ }
+ float coefficient = sensor_info_pair.second.coefficients[i];
+ switch (sensor_info_pair.second.formula) {
+ case FormulaOption::COUNT_THRESHOLD:
+ if ((coefficient < 0 && sensor_reading < -coefficient) ||
+ (coefficient >= 0 && sensor_reading >= coefficient))
+ mTemp += 1;
+ break;
+ case FormulaOption::WEIGHTED_AVG:
+ mTemp += sensor_reading * coefficient;
+ break;
+ case FormulaOption::MAXIMUM:
+ if (i == 0)
+ mTemp = std::numeric_limits<float>::lowest();
+ if (sensor_reading * coefficient > mTemp)
+ mTemp = sensor_reading * coefficient;
+ break;
+ case FormulaOption::MINIMUM:
+ if (i == 0)
+ mTemp = std::numeric_limits<float>::max();
+ if (sensor_reading * coefficient < mTemp)
+ mTemp = sensor_reading * coefficient;
+ break;
+ default:
+ break;
+ }
+ }
+ *temp = std::to_string(mTemp);
+ return true;
+ }
+ return false;
+}
+
// This is called in the different thread context and will update sensor_status
// uevent_sensors is the set of sensors which trigger uevent from thermal core driver.
bool ThermalHelper::thermalWatcherCallbackFunc(const std::set<std::string> &uevent_sensors) {
@@ -662,15 +736,24 @@ bool ThermalHelper::thermalWatcherCallbackFunc(const std::set<std::string> &ueve
for (auto &name_status_pair : sensor_status_map_) {
Temperature_2_0 temp;
TemperatureThreshold threshold;
+ bool is_virtual_sensor = false;
SensorStatus &sensor_status = name_status_pair.second;
const SensorInfo &sensor_info = sensor_info_map_.at(name_status_pair.first);
// Only send notification on whitelisted sensors
if (!sensor_info.is_monitor) {
continue;
}
+
+ is_virtual_sensor = sensor_info.is_virtual_sensor;
+
+ std::string uevent_sensor_name = name_status_pair.first;
+ if (is_virtual_sensor) {
+ const SensorInfo &sensor_info = sensor_info_map_.at(name_status_pair.first);
+ uevent_sensor_name = sensor_info.trigger_sensor;
+ }
// If callback is triggered by uevent, only check the sensors within uevent_sensors
if (uevent_sensors.size() != 0 &&
- uevent_sensors.find(name_status_pair.first) == uevent_sensors.end()) {
+ uevent_sensors.find(uevent_sensor_name) == uevent_sensors.end()) {
if (sensor_status.severity != ThrottlingSeverity::NONE) {
thermal_triggered = true;
}
@@ -678,7 +761,7 @@ bool ThermalHelper::thermalWatcherCallbackFunc(const std::set<std::string> &ueve
}
std::pair<ThrottlingSeverity, ThrottlingSeverity> throtting_status;
- if (!readTemperature(name_status_pair.first, &temp, &throtting_status)) {
+ if (!readTemperature(name_status_pair.first, &temp, &throtting_status, is_virtual_sensor)) {
LOG(ERROR) << __func__
<< ": error reading temperature for sensor: " << name_status_pair.first;
continue;
diff --git a/thermal/thermal-helper.h b/thermal/thermal-helper.h
index 37a2dea3..927ca600 100644
--- a/thermal/thermal-helper.h
+++ b/thermal/thermal-helper.h
@@ -121,7 +121,8 @@ class ThermalHelper {
bool readTemperature(std::string_view sensor_name, Temperature_1_0 *out) const;
bool readTemperature(
std::string_view sensor_name, Temperature_2_0 *out,
- std::pair<ThrottlingSeverity, ThrottlingSeverity> *throtting_status = nullptr) const;
+ std::pair<ThrottlingSeverity, ThrottlingSeverity> *throtting_status = nullptr,
+ bool is_virtual_sensor = false) const;
bool readTemperatureThreshold(std::string_view sensor_name, TemperatureThreshold *out) const;
// Read the value of a single cooling device.
bool readCoolingDevice(std::string_view cooling_device, CoolingDevice_2_0 *out) const;
@@ -147,6 +148,7 @@ class ThermalHelper {
const ThrottlingArray &hot_hysteresis, const ThrottlingArray &cold_hysteresis,
ThrottlingSeverity prev_hot_severity, ThrottlingSeverity prev_cold_severity,
float value) const;
+ bool checkVirtualSensor(std::string_view sensor_name, std::string *temp) const;
bool connectToPowerHal();
void updateSupportedPowerHints();
diff --git a/thermal/utils/config_parser.cpp b/thermal/utils/config_parser.cpp
index daba0ee3..ece337c1 100644
--- a/thermal/utils/config_parser.cpp
+++ b/thermal/utils/config_parser.cpp
@@ -115,7 +115,19 @@ std::map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path)
hot_hysteresis.fill(0.0);
std::array<float, kThrottlingSeverityCount> cold_hysteresis;
cold_hysteresis.fill(0.0);
-
+ std::array<std::string, kCombinationCount> linked_sensors;
+ linked_sensors.fill("NAN");
+ std::array<float, kCombinationCount> coefficients;
+ coefficients.fill(0.0);
+
+ std::string trigger_sensor;
+ FormulaOption formula = FormulaOption::COUNT_THRESHOLD;
+ bool is_virtual_sensor = false;
+ if (sensors[i]["VirtualSensor"].empty() || !sensors[i]["VirtualSensor"].isBool()) {
+ LOG(INFO) << "Failed to read Sensor[" << name << "]'s VirtualSensor, set to 'false'";
+ } else {
+ is_virtual_sensor = sensors[i]["VirtualSensor"].asBool();
+ }
Json::Value values = sensors[i]["HotThreshold"];
if (values.size() != kThrottlingSeverityCount) {
LOG(ERROR) << "Invalid "
@@ -201,6 +213,50 @@ std::map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path)
}
}
+ if (is_virtual_sensor) {
+ values = sensors[i]["Combination"];
+ if (values.size() > kCombinationCount) {
+ LOG(ERROR) << "Invalid "
+ << "Sensor[" << name << "]'s Combination count" << values.size();
+ sensors_parsed.clear();
+ return sensors_parsed;
+ } else {
+ for (Json::Value::ArrayIndex j = 0; j < kCombinationCount; ++j) {
+ if (values[j].isString()) {
+ if (values[j].asString().compare("NAN") != 0) {
+ linked_sensors[j] = values[j].asString();
+ }
+ }
+ }
+ }
+ values = sensors[i]["Coefficient"];
+ if (values.size() > kCombinationCount) {
+ LOG(ERROR) << "Invalid "
+ << "Sensor[" << name << "]'s Combination count" << values.size();
+ sensors_parsed.clear();
+ return sensors_parsed;
+ } else {
+ for (Json::Value::ArrayIndex j = 0; j < kCombinationCount; ++j) {
+ if (values[j].isString()) {
+ if (values[j].asString().compare("NAN") != 0) {
+ coefficients[j] = std::stof(values[j].asString());
+ }
+ } else {
+ coefficients[j] = values[j].asFloat();
+ }
+ }
+ }
+ trigger_sensor = sensors[i]["TriggerSensor"].asString();
+ if (sensors[i]["Formula"].asString().compare("COUNT_THRESHOLD") == 0)
+ formula = FormulaOption::COUNT_THRESHOLD;
+ else if (sensors[i]["Formula"].asString().compare("WEIGHTED_AVG") == 0)
+ formula = FormulaOption::WEIGHTED_AVG;
+ else if (sensors[i]["Formula"].asString().compare("MAXIMUM") == 0)
+ formula = FormulaOption::MAXIMUM;
+ else
+ formula = FormulaOption::MINIMUM;
+ }
+
float vr_threshold = NAN;
vr_threshold = getFloatFromValue(sensors[i]["VrThreshold"]);
LOG(INFO) << "Sensor[" << name << "]'s VrThreshold: " << vr_threshold;
@@ -232,6 +288,11 @@ std::map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path)
.cold_thresholds = cold_thresholds,
.hot_hysteresis = hot_hysteresis,
.cold_hysteresis = cold_hysteresis,
+ .is_virtual_sensor = is_virtual_sensor,
+ .linked_sensors = linked_sensors,
+ .coefficients = coefficients,
+ .trigger_sensor = trigger_sensor,
+ .formula = formula,
.vr_threshold = vr_threshold,
.multiplier = multiplier,
.is_monitor = is_monitor,
diff --git a/thermal/utils/config_parser.h b/thermal/utils/config_parser.h
index 399fef63..2cfd4d75 100644
--- a/thermal/utils/config_parser.h
+++ b/thermal/utils/config_parser.h
@@ -28,6 +28,13 @@ namespace thermal {
namespace V2_0 {
namespace implementation {
+enum FormulaOption : uint32_t {
+ COUNT_THRESHOLD = 0,
+ WEIGHTED_AVG,
+ MAXIMUM,
+ MINIMUM,
+};
+
using ::android::hardware::hidl_enum_range;
using ::android::hardware::thermal::V2_0::CoolingType;
using TemperatureType_2_0 = ::android::hardware::thermal::V2_0::TemperatureType;
@@ -35,6 +42,9 @@ using ::android::hardware::thermal::V2_0::ThrottlingSeverity;
constexpr size_t kThrottlingSeverityCount = std::distance(
hidl_enum_range<ThrottlingSeverity>().begin(), hidl_enum_range<ThrottlingSeverity>().end());
using ThrottlingArray = std::array<float, static_cast<size_t>(kThrottlingSeverityCount)>;
+constexpr size_t kCombinationCount = 10;
+using LinkedSensorArray = std::array<std::string, static_cast<size_t>(kCombinationCount)>;
+using CoefficientArray = std::array<float, static_cast<size_t>(kCombinationCount)>;
struct SensorInfo {
TemperatureType_2_0 type;
@@ -42,6 +52,13 @@ struct SensorInfo {
ThrottlingArray cold_thresholds;
ThrottlingArray hot_hysteresis;
ThrottlingArray cold_hysteresis;
+
+ LinkedSensorArray linked_sensors;
+ CoefficientArray coefficients;
+ std::string trigger_sensor;
+ FormulaOption formula;
+ bool is_virtual_sensor;
+
float vr_threshold;
float multiplier;
bool is_monitor;