diff options
author | George Lee <geolee@google.com> | 2020-10-05 11:59:36 -0700 |
---|---|---|
committer | George Lee <geolee@google.com> | 2020-12-02 09:43:13 -0800 |
commit | 9af1e97ad1ca83448d31773fcce1c727dd7865de (patch) | |
tree | b55c6ba5ae8655f5f62d5298f5174f16a0b0a7fc | |
parent | 55d72137813ba3f66f9e7e4f82ab8abaa85f399d (diff) | |
download | pixel-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
-rw-r--r-- | thermal/thermal-helper.cpp | 103 | ||||
-rw-r--r-- | thermal/thermal-helper.h | 4 | ||||
-rw-r--r-- | thermal/utils/config_parser.cpp | 63 | ||||
-rw-r--r-- | thermal/utils/config_parser.h | 17 |
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; |