From c618626b4fbb2c018d5e5d046d5914b661a91e6c Mon Sep 17 00:00:00 2001 From: TeYuan Wang Date: Tue, 27 Apr 2021 15:11:44 +0800 Subject: thermal: Enhance thermal debugging 1. Add throttling request state dump 2. Add power history dump 3. Add virtual sesnor info dump 4. Refer max_state from thermal sysfs 5. Support power link disabled property Bug: 170653634 Bug: 184608718 Test: adb shell lshal debug android.hardware.thermal@2.0::IThermal/default Test: boot to home with "fastboot oem cmdline set maxcpus=4" Change-Id: I36e81af297f5522265e56752418e0c66751c1c78 Signed-off-by: TeYuan Wang --- thermal/Thermal.cpp | 283 +++++++++++++++++++++++++++++----------- thermal/Thermal.h | 3 + thermal/thermal-helper.cpp | 56 +++++--- thermal/thermal-helper.h | 21 ++- thermal/utils/config_parser.cpp | 74 ++++++----- thermal/utils/config_parser.h | 1 + thermal/utils/power_files.cpp | 24 ++-- thermal/utils/power_files.h | 12 +- 8 files changed, 329 insertions(+), 145 deletions(-) (limited to 'thermal') diff --git a/thermal/Thermal.cpp b/thermal/Thermal.cpp index 1b9cca71..4e58fb7c 100644 --- a/thermal/Thermal.cpp +++ b/thermal/Thermal.cpp @@ -255,6 +255,195 @@ void Thermal::sendThermalChangedCallback(const Temperature_2_0 &t) { callbacks_.end()); } +void Thermal::dumpVirtualSensorInfo(std::ostringstream *dump_buf) { + *dump_buf << "VirtualSensorInfo:" << std::endl; + const auto &map = thermal_helper_.GetSensorInfoMap(); + for (const auto &sensor_info_pair : map) { + if (sensor_info_pair.second.virtual_sensor_info != nullptr) { + *dump_buf << " Name: " << sensor_info_pair.first << std::endl; + *dump_buf << " LinkedSensorName: ["; + for (size_t i = 0; + i < sensor_info_pair.second.virtual_sensor_info->linked_sensors.size(); i++) { + *dump_buf << sensor_info_pair.second.virtual_sensor_info->linked_sensors[i] << " "; + } + *dump_buf << "]" << std::endl; + *dump_buf << " LinkedSensorCoefficient: ["; + for (size_t i = 0; i < sensor_info_pair.second.virtual_sensor_info->coefficients.size(); + i++) { + *dump_buf << sensor_info_pair.second.virtual_sensor_info->coefficients[i] << " "; + } + *dump_buf << "]" << std::endl; + *dump_buf << " Offset: " << sensor_info_pair.second.virtual_sensor_info->offset + << std::endl; + *dump_buf << " Trigger Sensor: " + << (sensor_info_pair.second.virtual_sensor_info->trigger_sensor.empty() + ? "N/A" + : sensor_info_pair.second.virtual_sensor_info->trigger_sensor) + << std::endl; + *dump_buf << " Formula: "; + switch (sensor_info_pair.second.virtual_sensor_info->formula) { + case FormulaOption::COUNT_THRESHOLD: + *dump_buf << "COUNT_THRESHOLD"; + break; + case FormulaOption::MAXIMUM: + *dump_buf << "MAXIMUM"; + break; + case FormulaOption::MINIMUM: + *dump_buf << "MINIMUM"; + break; + default: + *dump_buf << "None"; + break; + } + + *dump_buf << std::endl; + } + } +} + +void Thermal::dumpThrottlingInfo(std::ostringstream *dump_buf) { + *dump_buf << "Throttling Info:" << std::endl; + const auto &map = thermal_helper_.GetSensorInfoMap(); + for (const auto &name_info_pair : map) { + if (name_info_pair.second.throttling_info->binded_cdev_info_map.size()) { + *dump_buf << " Name: " << name_info_pair.first << std::endl; + *dump_buf << " PID Info:" << std::endl; + *dump_buf << " K_po: ["; + for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { + *dump_buf << name_info_pair.second.throttling_info->k_po[i] << " "; + } + *dump_buf << "]" << std::endl; + *dump_buf << " K_pu: ["; + for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { + *dump_buf << name_info_pair.second.throttling_info->k_pu[i] << " "; + } + *dump_buf << "]" << std::endl; + *dump_buf << " K_i: ["; + for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { + *dump_buf << name_info_pair.second.throttling_info->k_i[i] << " "; + } + *dump_buf << "]" << std::endl; + *dump_buf << " K_d: ["; + for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { + *dump_buf << name_info_pair.second.throttling_info->k_d[i] << " "; + } + *dump_buf << "]" << std::endl; + *dump_buf << " i_max: ["; + for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { + *dump_buf << name_info_pair.second.throttling_info->i_max[i] << " "; + } + *dump_buf << "]" << std::endl; + *dump_buf << " max_alloc_power: ["; + for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { + *dump_buf << name_info_pair.second.throttling_info->max_alloc_power[i] << " "; + } + *dump_buf << "]" << std::endl; + *dump_buf << " min_alloc_power: ["; + for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { + *dump_buf << name_info_pair.second.throttling_info->min_alloc_power[i] << " "; + } + *dump_buf << "]" << std::endl; + *dump_buf << " s_power: ["; + for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { + *dump_buf << name_info_pair.second.throttling_info->s_power[i] << " "; + } + *dump_buf << "]" << std::endl; + *dump_buf << " i_cutoff: ["; + for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { + *dump_buf << name_info_pair.second.throttling_info->i_cutoff[i] << " "; + } + *dump_buf << "]" << std::endl; + *dump_buf << " Binded CDEV Info:" << std::endl; + if (name_info_pair.second.throttling_info->binded_cdev_info_map.size()) { + for (const auto &binded_cdev_info_pair : + name_info_pair.second.throttling_info->binded_cdev_info_map) { + *dump_buf << " Cooling device name: " << binded_cdev_info_pair.first + << std::endl; + *dump_buf << " Hard limit: ["; + for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { + *dump_buf << binded_cdev_info_pair.second.limit_info[i] << " "; + } + *dump_buf << "]"; + *dump_buf << " Power threshold: ["; + for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { + *dump_buf << binded_cdev_info_pair.second.power_thresholds[i] << " "; + } + *dump_buf << "]"; + *dump_buf << " Release logic: "; + switch (binded_cdev_info_pair.second.release_logic) { + case ReleaseLogic::DECREASE: + *dump_buf << "DECREASE"; + break; + case ReleaseLogic::BYPASS: + *dump_buf << "BYPASS"; + break; + default: + *dump_buf << "None"; + break; + } + *dump_buf << std::endl; + *dump_buf << " Weight: " << binded_cdev_info_pair.second.cdev_weight; + *dump_buf << " Cdev_ceiling: " << binded_cdev_info_pair.second.cdev_ceiling; + *dump_buf << " Power_sample_count: " + << binded_cdev_info_pair.second.power_sample_count; + *dump_buf << " Power_sample_delay: " + << binded_cdev_info_pair.second.power_sample_delay.count(); + *dump_buf << " Power_reversly_check: " + << binded_cdev_info_pair.second.power_reversly_check << std::endl; + } + } + } + } +} + +void Thermal::dumpThrottlingRequestStatus(std::ostringstream *dump_buf) { + const auto &sensor_status_map = thermal_helper_.GetSensorStatusMap(); + const auto &cdev_status_map = thermal_helper_.GetCdevStatusMap(); + const auto &release_map = thermal_helper_.GetThrottlingReleaseMap(); + const auto &cdev_info_map = thermal_helper_.GetCdevInfoMap(); + *dump_buf << "Throttling Request Status " << std::endl; + for (const auto &cdev_status_pair : cdev_status_map) { + *dump_buf << " Name: " << cdev_status_pair.first << std::endl; + for (const auto &request_pair : cdev_status_pair.second) { + *dump_buf << " Request Sensor: " << request_pair.first << std::endl; + *dump_buf << " Request Throttling State: " << request_pair.second << std::endl; + if (sensor_status_map.at(request_pair.first).pid_request_map.size() && + sensor_status_map.at(request_pair.first) + .pid_request_map.count(cdev_status_pair.first)) { + *dump_buf << " PID Request State: " + << sensor_status_map.at(request_pair.first) + .pid_request_map.at(cdev_status_pair.first) + << std::endl; + } + if (sensor_status_map.at(request_pair.first).hard_limit_request_map.size() && + sensor_status_map.at(request_pair.first) + .hard_limit_request_map.count(cdev_status_pair.first)) { + *dump_buf << " Hard Limit Request State: " + << sensor_status_map.at(request_pair.first) + .hard_limit_request_map.at(cdev_status_pair.first) + << std::endl; + } + if (release_map.count(request_pair.first) && + release_map.at(request_pair.first) + .count(cdev_info_map.at(cdev_status_pair.first).power_rail)) { + const auto &cdev_release_info = + release_map.at(request_pair.first) + .at(cdev_info_map.at(cdev_status_pair.first).power_rail); + *dump_buf << " Release Step: " << cdev_release_info.release_step << std::endl; + *dump_buf << " Power History: "; + auto power_history = cdev_release_info.power_history; + while (power_history.size() > 0) { + const auto power_sample = power_history.front(); + power_history.pop(); + *dump_buf << "(T=" << power_sample.duration + << ", uWs=" << power_sample.energy_counter << ") "; + } + *dump_buf << std::endl; + } + } + } +} + Return Thermal::debug(const hidl_handle &handle, const hidl_vec &) { if (handle != nullptr && handle->numFds >= 1) { int fd = handle->data[0]; @@ -368,24 +557,30 @@ Return Thermal::debug(const hidl_handle &handle, const hidl_vec Thermal::debug(const hidl_handle &handle, const hidl_vecbinded_cdev_info_map.size()) { - dump_buf << " Name: " << name_info_pair.first << std::endl; - dump_buf << " PID Info:" << std::endl; - dump_buf << " K_po: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << name_info_pair.second.throttling_info->k_po[i] << " "; - } - dump_buf << "]" << std::endl; - dump_buf << " K_pu: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << name_info_pair.second.throttling_info->k_pu[i] << " "; - } - dump_buf << "]" << std::endl; - dump_buf << " K_i: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << name_info_pair.second.throttling_info->k_i[i] << " "; - } - dump_buf << "]" << std::endl; - dump_buf << " K_d: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << name_info_pair.second.throttling_info->k_d[i] << " "; - } - dump_buf << "]" << std::endl; - dump_buf << " i_max: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << name_info_pair.second.throttling_info->i_max[i] << " "; - } - dump_buf << "]" << std::endl; - dump_buf << " max_alloc_power: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << name_info_pair.second.throttling_info->max_alloc_power[i] - << " "; - } - dump_buf << "]" << std::endl; - dump_buf << " min_alloc_power: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << name_info_pair.second.throttling_info->min_alloc_power[i] - << " "; - } - dump_buf << "]" << std::endl; - dump_buf << " s_power: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << name_info_pair.second.throttling_info->s_power[i] << " "; - } - dump_buf << "]" << std::endl; - dump_buf << " i_cutoff: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << name_info_pair.second.throttling_info->i_cutoff[i] << " "; - } - dump_buf << "]" << std::endl; - dump_buf << " Hard Limit Info:" << std::endl; - if (name_info_pair.second.throttling_info->binded_cdev_info_map.size()) { - for (const auto &binded_cdev_info_pair : - name_info_pair.second.throttling_info->binded_cdev_info_map) { - dump_buf << " Cdev limit " << binded_cdev_info_pair.first - << ": ["; - - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << binded_cdev_info_pair.second.limit_info[i] << " "; - } - dump_buf << "]" << std::endl; - } - } - } - } - } } std::string buf = dump_buf.str(); if (!android::base::WriteStringToFd(buf, fd)) { diff --git a/thermal/Thermal.h b/thermal/Thermal.h index fde746d2..53a826d7 100644 --- a/thermal/Thermal.h +++ b/thermal/Thermal.h @@ -82,6 +82,9 @@ class Thermal : public IThermal { private: ThermalHelper thermal_helper_; + void dumpVirtualSensorInfo(std::ostringstream *dump_buf); + void dumpThrottlingInfo(std::ostringstream *dump_buf); + void dumpThrottlingRequestStatus(std::ostringstream *dump_buf); std::mutex thermal_callback_mutex_; std::vector callbacks_; }; diff --git a/thermal/thermal-helper.cpp b/thermal/thermal-helper.cpp index 2fd86d0f..2b94517b 100644 --- a/thermal/thermal-helper.cpp +++ b/thermal/thermal-helper.cpp @@ -50,6 +50,7 @@ constexpr std::string_view kSensorTripPointTempZeroFile("trip_point_0_temp"); constexpr std::string_view kSensorTripPointHystZeroFile("trip_point_0_hyst"); constexpr std::string_view kUserSpaceSuffix("user_space"); constexpr std::string_view kCoolingDeviceCurStateSuffix("cur_state"); +constexpr std::string_view kCoolingDeviceMaxStateSuffix("max_state"); constexpr std::string_view kConfigProperty("vendor.thermal.config"); constexpr std::string_view kConfigDefaultFileName("thermal_info_config.json"); constexpr std::string_view kThermalGenlProperty("persist.vendor.enable.thermal.genl"); @@ -273,6 +274,14 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb) sensor_info_map_(ParseSensorInfo( "/vendor/etc/" + android::base::GetProperty(kConfigProperty.data(), kConfigDefaultFileName.data()))) { + auto tz_map = parseThermalPathMap(kSensorPrefix.data()); + auto cdev_map = parseThermalPathMap(kCoolingDevicePrefix.data()); + + is_initialized_ = initializeSensorMap(tz_map) && initializeCoolingDevices(cdev_map); + if (!is_initialized_) { + LOG(FATAL) << "ThermalHAL could not be initialized properly."; + } + for (auto const &name_status_pair : sensor_info_map_) { sensor_status_map_[name_status_pair.first] = { .severity = ThrottlingSeverity::NONE, @@ -306,8 +315,9 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb) power_files_.findEnergySourceToWatch()) { const auto power_rail = cooling_device_info_map_.at(binded_cdev_pair.first).power_rail; - if (!power_files_.registerPowerRailsToWatch(name_status_pair.first, power_rail, - binded_cdev_pair.second)) { + if (!power_files_.registerPowerRailsToWatch( + name_status_pair.first, power_rail, binded_cdev_pair.second, + cooling_device_info_map_.at(binded_cdev_pair.first))) { invalid_binded_cdev = true; LOG(ERROR) << "Could not find " << binded_cdev_pair.first << "'s power energy source: " << power_rail; @@ -334,14 +344,6 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb) } } - auto tz_map = parseThermalPathMap(kSensorPrefix.data()); - auto cdev_map = parseThermalPathMap(kCoolingDevicePrefix.data()); - - is_initialized_ = initializeSensorMap(tz_map) && initializeCoolingDevices(cdev_map); - if (!is_initialized_) { - LOG(FATAL) << "ThermalHAL could not be initialized properly."; - } - const bool thermal_throttling_disabled = android::base::GetBoolProperty(kThermalDisabledProperty.data(), false); @@ -654,19 +656,24 @@ void ThermalHelper::computeCoolingDevicesRequest( std::vector *cooling_devices_to_update) { unsigned int release_step = 0; + std::unique_lock _lock(cdev_status_map_mutex_); for (auto &cdev_request_pair : cdev_status_map_) { - unsigned int pid_max = 0; - unsigned int limit_max = 0; + unsigned int pid_request = 0; + unsigned int hard_limit_request = 0; + const auto max_state = cooling_device_info_map_.at(cdev_request_pair.first).max_state; release_step = 0; if (sensor_status.pid_request_map.count(cdev_request_pair.first)) { - pid_max = sensor_status.pid_request_map.at(cdev_request_pair.first); + pid_request = + std::min(sensor_status.pid_request_map.at(cdev_request_pair.first), max_state); } + if (sensor_status.hard_limit_request_map.count(cdev_request_pair.first)) { - limit_max = sensor_status.hard_limit_request_map.at(cdev_request_pair.first); + hard_limit_request = std::min( + sensor_status.hard_limit_request_map.at(cdev_request_pair.first), max_state); } - auto request_state = fmax(pid_max, limit_max); + auto request_state = std::max(pid_request, hard_limit_request); release_step = power_files_.getReleaseStep( sensor_name, cooling_device_info_map_.at(cdev_request_pair.first).power_rail); @@ -770,7 +777,7 @@ bool ThermalHelper::initializeSensorMap( bool ThermalHelper::initializeCoolingDevices( const std::unordered_map &path_map) { - for (const auto &cooling_device_info_pair : cooling_device_info_map_) { + for (auto &cooling_device_info_pair : cooling_device_info_map_) { std::string cooling_device_name = cooling_device_info_pair.first; if (!path_map.count(cooling_device_name)) { LOG(ERROR) << "Could not find " << cooling_device_name << " in sysfs"; @@ -791,6 +798,20 @@ bool ThermalHelper::initializeCoolingDevices( continue; } + // Get max cooling device request state + std::string max_state; + std::string max_state_path = android::base::StringPrintf( + "%s/%s", path.data(), kCoolingDeviceMaxStateSuffix.data()); + if (!android::base::ReadFileToString(max_state_path, &max_state)) { + LOG(ERROR) << cooling_device_info_pair.first + << " could not open max state file:" << max_state_path; + cooling_device_info_pair.second.max_state = std::numeric_limits::max(); + } else { + cooling_device_info_pair.second.max_state = std::stoi(android::base::Trim(max_state)); + LOG(INFO) << "Cooling device " << cooling_device_info_pair.first + << " max state: " << cooling_device_info_pair.second.max_state; + } + // Add cooling device path for thermalHAL to request state cooling_device_name = android::base::StringPrintf("%s_%s", cooling_device_name.c_str(), "w"); @@ -1207,9 +1228,6 @@ void ThermalHelper::updateSupportedPowerHints() { } ThrottlingSeverity current_severity = ThrottlingSeverity::NONE; for (const auto &severity : hidl_enum_range()) { - LOG(ERROR) << "sensor: " << name_status_pair.first - << " current_severity :" << toString(current_severity) << " severity " - << toString(severity); if (severity == ThrottlingSeverity::NONE) { supported_powerhint_map_[name_status_pair.first][ThrottlingSeverity::NONE] = ThrottlingSeverity::NONE; diff --git a/thermal/thermal-helper.h b/thermal/thermal-helper.h index 129b5dfd..f5618fe3 100644 --- a/thermal/thermal-helper.h +++ b/thermal/thermal-helper.h @@ -140,9 +140,25 @@ class ThermalHelper { const std::unordered_map &GetSensorInfoMap() const { return sensor_info_map_; } - + // Get CdevInfo Map + const std::unordered_map &GetCdevInfoMap() const { + return cooling_device_info_map_; + } + // Get SensorStatus Map + const std::unordered_map &GetSensorStatusMap() const { + std::shared_lock _lock(sensor_status_map_mutex_); + return sensor_status_map_; + } + // Get CdevStatus Map + const std::unordered_map &GetCdevStatusMap() const { + std::shared_lock _lock(cdev_status_map_mutex_); + return cdev_status_map_; + } + // Get throttling release Map + const std::unordered_map &GetThrottlingReleaseMap() const { + return power_files_.GetThrottlingReleaseMap(); + } void sendPowerExtHint(const Temperature_2_0 &t); - bool isAidlPowerHalExist() { return power_hal_service_.isAidlPowerHalExist(); } bool isPowerHalConnected() { return power_hal_service_.isPowerHalConnected(); } bool isPowerHalExtConnected() { return power_hal_service_.isPowerHalExtConnected(); } @@ -192,6 +208,7 @@ class ThermalHelper { mutable std::shared_mutex sensor_status_map_mutex_; std::unordered_map sensor_status_map_; + mutable std::shared_mutex cdev_status_map_mutex_; std::unordered_map cdev_status_map_; }; diff --git a/thermal/utils/config_parser.cpp b/thermal/utils/config_parser.cpp index 19197615..72572aa6 100644 --- a/thermal/utils/config_parser.cpp +++ b/thermal/utils/config_parser.cpp @@ -15,6 +15,7 @@ */ #include #include +#include #include #include #include @@ -30,6 +31,8 @@ namespace thermal { namespace V2_0 { namespace implementation { +constexpr std::string_view kPowerLinkDisabledProperty("vendor.disable.thermal.powerlink"); + using ::android::hardware::hidl_enum_range; using ::android::hardware::thermal::V2_0::toString; using TemperatureType_2_0 = ::android::hardware::thermal::V2_0::TemperatureType; @@ -489,45 +492,50 @@ std::unordered_map ParseSensorInfo(std::string_view con bool is_power_data_invalid = false; bool power_reversly_check = false; int power_sample_count = 0; - std::chrono::milliseconds power_sample_delay; - if (!values[j]["PowerSampleDelay"]) { - power_sample_delay = std::chrono::milliseconds::max(); - } else { - power_sample_delay = - std::chrono::milliseconds(getIntFromValue(values[j]["PowerSampleDelay"])); - } - LOG(INFO) << "Power sample delay: " << power_sample_delay.count(); - - if (values[j]["PowerReverslyCheck"].asBool()) { - power_reversly_check = true; - } - LOG(INFO) << "Power reversly check: " << power_reversly_check; - - power_sample_count = values[j]["PowerSampleCount"].asInt(); - LOG(INFO) << "Power sample Count: " << power_sample_count; - sub_values = values[j]["PowerThreshold"]; - if (sub_values.size()) { - LOG(INFO) << "Sensor[" << name << "]: Parse " << cdev_name << "'s Power threshold"; - if (!getFloatFromJsonValues(sub_values, &power_thresholds, false, false)) { - LOG(ERROR) << "Sensor[" << name << "]: failed to parse power thresholds"; - is_power_data_invalid = true; + const bool power_link_disabled = + android::base::GetBoolProperty(kPowerLinkDisabledProperty.data(), false); + if (!power_link_disabled) { + if (!values[j]["PowerSampleDelay"]) { + power_sample_delay = std::chrono::milliseconds::max(); + } else { + power_sample_delay = std::chrono::milliseconds( + getIntFromValue(values[j]["PowerSampleDelay"])); } + LOG(INFO) << "Power sample delay: " << power_sample_delay.count(); - if (values[j]["ReleaseLogic"].asString() == "DECREASE") { - release_logic = ReleaseLogic::DECREASE; - LOG(INFO) << "Release logic: DECREASE"; - } else if (values[j]["ReleaseLogic"].asString() == "BYPASS") { - release_logic = ReleaseLogic::BYPASS; - LOG(INFO) << "Release logic: BYPASS"; - } else { - is_power_data_invalid = true; + if (values[j]["PowerReverslyCheck"].asBool()) { + power_reversly_check = true; } + LOG(INFO) << "Power reversly check: " << power_reversly_check; + + power_sample_count = values[j]["PowerSampleCount"].asInt(); + LOG(INFO) << "Power sample Count: " << power_sample_count; + + sub_values = values[j]["PowerThreshold"]; + if (sub_values.size()) { + LOG(INFO) << "Sensor[" << name << "]: Parse " << cdev_name + << "'s Power threshold"; + if (!getFloatFromJsonValues(sub_values, &power_thresholds, false, false)) { + LOG(ERROR) << "Sensor[" << name << "]: failed to parse power thresholds"; + is_power_data_invalid = true; + } - if (is_power_data_invalid) { - sensors_parsed.clear(); - return sensors_parsed; + if (values[j]["ReleaseLogic"].asString() == "DECREASE") { + release_logic = ReleaseLogic::DECREASE; + LOG(INFO) << "Release logic: DECREASE"; + } else if (values[j]["ReleaseLogic"].asString() == "BYPASS") { + release_logic = ReleaseLogic::BYPASS; + LOG(INFO) << "Release logic: BYPASS"; + } else { + is_power_data_invalid = true; + } + + if (is_power_data_invalid) { + sensors_parsed.clear(); + return sensors_parsed; + } } } diff --git a/thermal/utils/config_parser.h b/thermal/utils/config_parser.h index 9238093c..6d4bab49 100644 --- a/thermal/utils/config_parser.h +++ b/thermal/utils/config_parser.h @@ -109,6 +109,7 @@ struct CdevInfo { std::string power_rail; std::chrono::milliseconds power_sample_rate; int power_sample_count; + unsigned int max_state; }; std::unordered_map ParseSensorInfo(std::string_view config_path); diff --git a/thermal/utils/power_files.cpp b/thermal/utils/power_files.cpp index 16d663c1..cfa31027 100644 --- a/thermal/utils/power_files.cpp +++ b/thermal/utils/power_files.cpp @@ -36,6 +36,7 @@ using android::base::ReadFileToString; using android::base::StringPrintf; void PowerFiles::setPowerDataToDefault(std::string_view sensor_name) { + std::unique_lock _lock(throttling_release_map_mutex_); if (!throttling_release_map_.count(sensor_name.data())) { return; } @@ -55,6 +56,7 @@ void PowerFiles::setPowerDataToDefault(std::string_view sensor_name) { unsigned int PowerFiles::getReleaseStep(std::string_view sensor_name, std::string_view power_rail) { unsigned int release_step = 0; + std::shared_lock _lock(throttling_release_map_mutex_); if (throttling_release_map_.count(sensor_name.data()) && throttling_release_map_[sensor_name.data()].count(power_rail.data())) { @@ -66,7 +68,8 @@ unsigned int PowerFiles::getReleaseStep(std::string_view sensor_name, std::strin bool PowerFiles::registerPowerRailsToWatch(std::string_view sensor_name, std::string_view power_rail, - const BindedCdevInfo &binded_cdev_info) { + const BindedCdevInfo &binded_cdev_info, + const CdevInfo &cdev_info) { std::queue power_history; PowerSample power_sample = { .energy_counter = 0, @@ -78,16 +81,14 @@ bool PowerFiles::registerPowerRailsToWatch(std::string_view sensor_name, return false; } - for (int i = 0; i < binded_cdev_info.power_sample_count; i++) { - if (energy_info_map_.count(power_rail.data())) { + if (energy_info_map_.count(power_rail.data())) { + for (int i = 0; i < binded_cdev_info.power_sample_count; i++) { power_history.emplace(power_sample); } - } - - if (energy_info_map_.count(power_rail.data())) { throttling_release_map_[sensor_name.data()][power_rail.data()] = { .power_history = power_history, .release_step = 0, + .max_release_step = cdev_info.max_state, .time_remaining = binded_cdev_info.power_sample_delay, }; } else { @@ -199,6 +200,7 @@ void PowerFiles::throttlingReleaseUpdate(std::string_view sensor_name, const std::chrono::milliseconds time_elapsed_ms, const BindedCdevInfo &binded_cdev_info, std::string_view power_rail) { + std::unique_lock _lock(throttling_release_map_mutex_); if (!throttling_release_map_.count(sensor_name.data()) || !throttling_release_map_[sensor_name.data()].count(power_rail.data())) { return; @@ -254,16 +256,16 @@ void PowerFiles::throttlingReleaseUpdate(std::string_view sensor_name, is_over_budget = false; } } - LOG(VERBOSE) << "Power rail " << power_rail << ": power threshold = " - << binded_cdev_info.power_thresholds[static_cast(severity)] - << ", avg power = " << avg_power << ", duration = " << duration - << ", deltaEnergy = " << deltaEnergy; + LOG(INFO) << "Power rail " << power_rail << ": power threshold = " + << binded_cdev_info.power_thresholds[static_cast(severity)] + << ", avg power = " << avg_power << ", duration = " << duration + << ", deltaEnergy = " << deltaEnergy; } switch (binded_cdev_info.release_logic) { case ReleaseLogic::DECREASE: if (!is_over_budget) { - if (cdev_release_status.release_step < std::numeric_limits::max()) { + if (cdev_release_status.release_step < cdev_release_status.max_release_step) { cdev_release_status.release_step++; } } else { diff --git a/thermal/utils/power_files.h b/thermal/utils/power_files.h index 814badf4..b76e028a 100644 --- a/thermal/utils/power_files.h +++ b/thermal/utils/power_files.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include #include @@ -39,6 +40,7 @@ struct ReleaseStatus { // A queue to record ODPM info pair (timestamp, mWs) std::queue power_history; unsigned int release_step; + unsigned int max_release_step; }; using CdevReleaseStatus = std::unordered_map; @@ -55,7 +57,8 @@ class PowerFiles { // Register a map for the throttling release decision of target power rail // Return false if the power_rail is not supported. bool registerPowerRailsToWatch(std::string_view sensor_name, std::string_view power_rail, - const BindedCdevInfo &binded_cdev_info); + const BindedCdevInfo &binded_cdev_info, + const CdevInfo &cdev_info); // Find the energy source path, return false if no energy source found. bool findEnergySourceToWatch(void); @@ -79,11 +82,18 @@ class PowerFiles { // Clear the data of throttling_release_map_. void setPowerDataToDefault(std::string_view sensor_name); + // Get throttling release status map + const std::unordered_map &GetThrottlingReleaseMap() const { + std::shared_lock _lock(throttling_release_map_mutex_); + return throttling_release_map_; + } + private: // The map to record the energy info for each power rail. std::unordered_map energy_info_map_; // The map to record the throttling release status for each thermal sensor. std::unordered_map throttling_release_map_; + mutable std::shared_mutex throttling_release_map_mutex_; // The set to store the energy source paths std::unordered_set energy_path_set_; }; -- cgit v1.2.3