diff options
Diffstat (limited to 'thermal/utils/thermal_throttling.cpp')
-rw-r--r-- | thermal/utils/thermal_throttling.cpp | 183 |
1 files changed, 139 insertions, 44 deletions
diff --git a/thermal/utils/thermal_throttling.cpp b/thermal/utils/thermal_throttling.cpp index 6f2d1205..8aac95d4 100644 --- a/thermal/utils/thermal_throttling.cpp +++ b/thermal/utils/thermal_throttling.cpp @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#define ATRACE_TAG (ATRACE_TAG_THERMAL | ATRACE_TAG_HAL) #include "thermal_throttling.h" @@ -32,18 +33,18 @@ #include "power_files.h" #include "thermal_info.h" +namespace aidl { namespace android { namespace hardware { namespace thermal { -namespace V2_0 { namespace implementation { -using android::base::StringPrintf; +using ::android::base::StringPrintf; // To find the next PID target state according to the current thermal severity size_t getTargetStateOfPID(const SensorInfo &sensor_info, const ThrottlingSeverity curr_severity) { size_t target_state = 0; - for (const auto &severity : hidl_enum_range<ThrottlingSeverity>()) { + for (const auto &severity : ::ndk::enum_range<ThrottlingSeverity>()) { size_t state = static_cast<size_t>(severity); if (std::isnan(sensor_info.throttling_info->s_power[state])) { continue; @@ -131,6 +132,7 @@ bool ThermalThrottling::registerThermalThrottling( .pid_cdev_request_map[binded_cdev_pair.first] = 0; thermal_throttling_status_map_[sensor_name.data()] .cdev_status_map[binded_cdev_pair.first] = 0; + cdev_all_request_map_[binded_cdev_pair.first].insert(0); break; } } @@ -141,6 +143,7 @@ bool ThermalThrottling::registerThermalThrottling( .hardlimit_cdev_request_map[binded_cdev_pair.first] = 0; thermal_throttling_status_map_[sensor_name.data()] .cdev_status_map[binded_cdev_pair.first] = 0; + cdev_all_request_map_[binded_cdev_pair.first].insert(0); break; } } @@ -159,8 +162,7 @@ bool ThermalThrottling::registerThermalThrottling( } // return power budget based on PID algo -float ThermalThrottling::updatePowerBudget(const Temperature_2_0 &temp, - const SensorInfo &sensor_info, +float ThermalThrottling::updatePowerBudget(const Temperature &temp, const SensorInfo &sensor_info, std::chrono::milliseconds time_elapsed_ms, ThrottlingSeverity curr_severity) { float p = 0, d = 0; @@ -168,6 +170,7 @@ float ThermalThrottling::updatePowerBudget(const Temperature_2_0 &temp, bool target_changed = false; float budget_transient = 0.0; auto &throttling_status = thermal_throttling_status_map_.at(temp.name); + std::string sensor_name = temp.name; if (curr_severity == ThrottlingSeverity::NONE) { return power_budget; @@ -231,6 +234,24 @@ float ThermalThrottling::updatePowerBudget(const Temperature_2_0 &temp, << " i=" << throttling_status.i_budget << " d=" << d << " budget transient=" << budget_transient << " control target=" << target_state; + ATRACE_INT((sensor_name + std::string("-power_budget")).c_str(), + static_cast<int>(power_budget)); + ATRACE_INT((sensor_name + std::string("-s_power")).c_str(), + static_cast<int>(sensor_info.throttling_info->s_power[target_state])); + ATRACE_INT((sensor_name + std::string("-time_elapsed_ms")).c_str(), + static_cast<int>(time_elapsed_ms.count())); + ATRACE_INT((sensor_name + std::string("-budget_transient")).c_str(), + static_cast<int>(budget_transient)); + ATRACE_INT((sensor_name + std::string("-i")).c_str(), + static_cast<int>(throttling_status.i_budget)); + ATRACE_INT((sensor_name + std::string("-target_state")).c_str(), + static_cast<int>(target_state)); + + ATRACE_INT((sensor_name + std::string("-err")).c_str(), static_cast<int>(err / sensor_info.multiplier)); + ATRACE_INT((sensor_name + std::string("-p")).c_str(), static_cast<int>(p)); + ATRACE_INT((sensor_name + std::string("-d")).c_str(), static_cast<int>(d)); + ATRACE_INT((sensor_name + std::string("-temp")).c_str(), static_cast<int>(temp.value / sensor_info.multiplier)); + throttling_status.prev_power_budget = power_budget; return power_budget; @@ -238,8 +259,8 @@ float ThermalThrottling::updatePowerBudget(const Temperature_2_0 &temp, float ThermalThrottling::computeExcludedPower( const SensorInfo &sensor_info, const ThrottlingSeverity curr_severity, - const std::unordered_map<std::string, PowerStatus> &power_status_map, - std::string *log_buf) { + const std::unordered_map<std::string, PowerStatus> &power_status_map, std::string *log_buf, + std::string_view sensor_name) { float excluded_power = 0.0; for (const auto &excluded_power_info_pair : @@ -253,14 +274,22 @@ float ThermalThrottling::computeExcludedPower( "(%s: %0.2f mW, cdev_weight: %f)", excluded_power_info_pair.first.c_str(), last_updated_avg_power, excluded_power_info_pair.second[static_cast<size_t>(curr_severity)])); + + ATRACE_INT((std::string(sensor_name) + std::string("-") + + excluded_power_info_pair.first + std::string("-avg_power")) + .c_str(), + static_cast<int>(last_updated_avg_power)); } } + + ATRACE_INT((std::string(sensor_name) + std::string("-excluded_power")).c_str(), + static_cast<int>(excluded_power)); return excluded_power; } // Allocate power budget to binded cooling devices base on the real ODPM power data bool ThermalThrottling::allocatePowerToCdev( - const Temperature_2_0 &temp, const SensorInfo &sensor_info, + const Temperature &temp, const SensorInfo &sensor_info, const ThrottlingSeverity curr_severity, const std::chrono::milliseconds time_elapsed_ms, const std::unordered_map<std::string, PowerStatus> &power_status_map, const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map) { @@ -278,9 +307,8 @@ bool ThermalThrottling::allocatePowerToCdev( auto total_power_budget = updatePowerBudget(temp, sensor_info, time_elapsed_ms, curr_severity); if (sensor_info.throttling_info->excluded_power_info_map.size()) { - std::string log_buf; - total_power_budget -= - computeExcludedPower(sensor_info, curr_severity, power_status_map, &log_buf); + total_power_budget -= computeExcludedPower(sensor_info, curr_severity, power_status_map, + &log_buf, temp.name); total_power_budget = std::max(total_power_budget, 0.0f); if (!log_buf.empty()) { LOG(INFO) << temp.name << " power budget=" << total_power_budget << " after " << log_buf @@ -326,6 +354,11 @@ bool ThermalThrottling::allocatePowerToCdev( power_data_invalid = true; break; } + + ATRACE_INT((temp.name + std::string("-") + + binded_cdev_info_pair.second.power_rail + std::string("-avg_power")) + .c_str(), + static_cast<int>(last_updated_avg_power)); } else { power_data_invalid = true; break; @@ -346,18 +379,21 @@ bool ThermalThrottling::allocatePowerToCdev( allocated_power += last_updated_avg_power; allocated_weight += cdev_weight; allocated_cdev.insert(binded_cdev_info_pair.first); - log_buf.append(StringPrintf("(%s: %0.2f mW)", - binded_cdev_info_pair.second.power_rail.c_str(), - last_updated_avg_power)); - + if (!binded_cdev_info_pair.second.power_rail.empty()) { + log_buf.append(StringPrintf("(%s: %0.2f mW)", + binded_cdev_info_pair.second.power_rail.c_str(), + last_updated_avg_power)); + } LOG(VERBOSE) << temp.name << " binded " << binded_cdev_info_pair.first << " has been already at min state 0"; } } else { const CdevInfo &cdev_info = cooling_device_info_map.at(binded_cdev_info_pair.first); - log_buf.append(StringPrintf("(%s: %0.2f mW)", - binded_cdev_info_pair.second.power_rail.c_str(), - last_updated_avg_power)); + if (!binded_cdev_info_pair.second.power_rail.empty()) { + log_buf.append(StringPrintf("(%s: %0.2f mW)", + binded_cdev_info_pair.second.power_rail.c_str(), + last_updated_avg_power)); + } // Ignore the power distribution if the CDEV has no space to reduce power if ((cdev_power_adjustment < 0 && thermal_throttling_status_map_[temp.name].pid_cdev_request_map.at( @@ -390,25 +426,37 @@ bool ThermalThrottling::allocatePowerToCdev( cdev_power_budget = 0; } - const auto curr_state = + int max_cdev_vote; + if (!getCdevMaxRequest(binded_cdev_info_pair.first, &max_cdev_vote)) { + return false; + } + + const auto curr_cdev_vote = thermal_throttling_status_map_[temp.name].pid_cdev_request_map.at( binded_cdev_info_pair.first); if (binded_cdev_info_pair.second.max_release_step != std::numeric_limits<int>::max() && - cdev_power_adjustment > 0) { - auto target_state = - std::max(curr_state - binded_cdev_info_pair.second.max_release_step, 0); - cdev_power_budget = - std::min(cdev_power_budget, cdev_info.state2power[target_state]); + (power_data_invalid || cdev_power_adjustment > 0)) { + if (!power_data_invalid && curr_cdev_vote < max_cdev_vote) { + cdev_power_budget = cdev_info.state2power[curr_cdev_vote]; + LOG(VERBOSE) << temp.name << "'s " << binded_cdev_info_pair.first + << " vote: " << curr_cdev_vote + << " is lower than max cdev vote: " << max_cdev_vote; + } else { + const auto target_state = std::max( + curr_cdev_vote - binded_cdev_info_pair.second.max_release_step, 0); + cdev_power_budget = + std::min(cdev_power_budget, cdev_info.state2power[target_state]); + } } if (binded_cdev_info_pair.second.max_throttle_step != std::numeric_limits<int>::max() && - cdev_power_adjustment < 0) { - auto target_state = - std::min(curr_state + binded_cdev_info_pair.second.max_throttle_step, - cdev_info.max_state); + (power_data_invalid || cdev_power_adjustment < 0)) { + const auto target_state = std::min( + curr_cdev_vote + binded_cdev_info_pair.second.max_throttle_step, + cdev_info.max_state); cdev_power_budget = std::max(cdev_power_budget, cdev_info.state2power[target_state]); } @@ -527,6 +575,13 @@ bool ThermalThrottling::throttlingReleaseUpdate( << ": power threshold = " << binded_cdev_info_pair.second.power_thresholds[static_cast<int>(severity)] << ", avg power = " << avg_power; + std::string atrace_prefix = ::android::base::StringPrintf( + "%s-%s", sensor_name.data(), binded_cdev_info_pair.second.power_rail.data()); + ATRACE_INT( + (atrace_prefix + std::string("-power_threshold")).c_str(), + static_cast<int>( + binded_cdev_info_pair.second.power_thresholds[static_cast<int>(severity)])); + ATRACE_INT((atrace_prefix + std::string("-avg_power")).c_str(), avg_power); switch (binded_cdev_info_pair.second.release_logic) { case ReleaseLogic::INCREASE: @@ -570,7 +625,7 @@ bool ThermalThrottling::throttlingReleaseUpdate( } void ThermalThrottling::thermalThrottlingUpdate( - const Temperature_2_0 &temp, const SensorInfo &sensor_info, + const Temperature &temp, const SensorInfo &sensor_info, const ThrottlingSeverity curr_severity, const std::chrono::milliseconds time_elapsed_ms, const std::unordered_map<std::string, PowerStatus> &power_status_map, const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map) { @@ -603,8 +658,8 @@ void ThermalThrottling::thermalThrottlingUpdate( void ThermalThrottling::computeCoolingDevicesRequest( std::string_view sensor_name, const SensorInfo &sensor_info, - const ThrottlingSeverity curr_severity, - std::vector<std::string> *cooling_devices_to_update) { + const ThrottlingSeverity curr_severity, std::vector<std::string> *cooling_devices_to_update, + ThermalStatsHelper *thermal_stats_helper) { int release_step = 0; std::unique_lock<std::shared_mutex> _lock(thermal_throttling_status_map_mutex_); @@ -618,33 +673,41 @@ void ThermalThrottling::computeCoolingDevicesRequest( for (auto &cdev_request_pair : thermal_throttling_status.cdev_status_map) { int pid_cdev_request = 0; int hardlimit_cdev_request = 0; + const auto &cdev_name = cdev_request_pair.first; const auto &binded_cdev_info = - sensor_info.throttling_info->binded_cdev_info_map.at(cdev_request_pair.first); + sensor_info.throttling_info->binded_cdev_info_map.at(cdev_name); const auto cdev_ceiling = binded_cdev_info.cdev_ceiling[static_cast<size_t>(curr_severity)]; const auto cdev_floor = binded_cdev_info.cdev_floor_with_power_link[static_cast<size_t>(curr_severity)]; release_step = 0; - if (thermal_throttling_status.pid_cdev_request_map.count(cdev_request_pair.first)) { - pid_cdev_request = - thermal_throttling_status.pid_cdev_request_map.at(cdev_request_pair.first); + if (thermal_throttling_status.pid_cdev_request_map.count(cdev_name)) { + pid_cdev_request = thermal_throttling_status.pid_cdev_request_map.at(cdev_name); } - if (thermal_throttling_status.hardlimit_cdev_request_map.count(cdev_request_pair.first)) { - hardlimit_cdev_request = thermal_throttling_status.hardlimit_cdev_request_map.at( - cdev_request_pair.first); + if (thermal_throttling_status.hardlimit_cdev_request_map.count(cdev_name)) { + hardlimit_cdev_request = + thermal_throttling_status.hardlimit_cdev_request_map.at(cdev_name); } - if (cdev_release_map.count(cdev_request_pair.first)) { - release_step = cdev_release_map.at(cdev_request_pair.first); + if (cdev_release_map.count(cdev_name)) { + release_step = cdev_release_map.at(cdev_name); } - LOG(VERBOSE) << sensor_name.data() << " binded cooling device " << cdev_request_pair.first + LOG(VERBOSE) << sensor_name.data() << " binded cooling device " << cdev_name << "'s pid_request=" << pid_cdev_request << " hardlimit_cdev_request=" << hardlimit_cdev_request << " release_step=" << release_step << " cdev_floor_with_power_link=" << cdev_floor << " cdev_ceiling=" << cdev_ceiling; + std::string atrace_prefix = + ::android::base::StringPrintf("%s-%s", sensor_name.data(), cdev_name.data()); + ATRACE_INT((atrace_prefix + std::string("-pid_request")).c_str(), pid_cdev_request); + ATRACE_INT((atrace_prefix + std::string("-hardlimit_request")).c_str(), + hardlimit_cdev_request); + ATRACE_INT((atrace_prefix + std::string("-release_step")).c_str(), release_step); + ATRACE_INT((atrace_prefix + std::string("-cdev_floor")).c_str(), cdev_floor); + ATRACE_INT((atrace_prefix + std::string("-cdev_ceiling")).c_str(), cdev_ceiling); auto request_state = std::max(pid_cdev_request, hardlimit_cdev_request); if (release_step) { @@ -657,16 +720,48 @@ void ThermalThrottling::computeCoolingDevicesRequest( request_state = std::max(request_state, cdev_floor); } request_state = std::min(request_state, cdev_ceiling); - if (cdev_request_pair.second != request_state) { + if (updateCdevMaxRequestAndNotifyIfChange(cdev_name, cdev_request_pair.second, + request_state)) { + cooling_devices_to_update->emplace_back(cdev_name); + } cdev_request_pair.second = request_state; - cooling_devices_to_update->emplace_back(cdev_request_pair.first); + // Update sensor cdev request time in state + thermal_stats_helper->updateSensorCdevRequestStats(sensor_name, cdev_name, + cdev_request_pair.second); } } } +bool ThermalThrottling::updateCdevMaxRequestAndNotifyIfChange(std::string_view cdev_name, + int cur_request, int new_request) { + std::unique_lock<std::shared_mutex> _lock(cdev_all_request_map_mutex_); + auto &request_set = cdev_all_request_map_.at(cdev_name.data()); + int cur_max_request = (*request_set.begin()); + // Remove old cdev request and add the new one. + request_set.erase(request_set.find(cur_request)); + request_set.insert(new_request); + // Check if there is any change in aggregated max cdev request. + int new_max_request = (*request_set.begin()); + LOG(VERBOSE) << "For cooling device [" << cdev_name.data() + << "] cur_max_request is: " << cur_max_request + << " new_max_request is: " << new_max_request; + return new_max_request != cur_max_request; +} + +bool ThermalThrottling::getCdevMaxRequest(std::string_view cdev_name, int *max_state) { + std::shared_lock<std::shared_mutex> _lock(cdev_all_request_map_mutex_); + if (!cdev_all_request_map_.count(cdev_name.data())) { + LOG(ERROR) << "Cooling device [" << cdev_name.data() + << "] not present in cooling device request map"; + return false; + } + *max_state = *cdev_all_request_map_.at(cdev_name.data()).begin(); + return true; +} + } // namespace implementation -} // namespace V2_0 } // namespace thermal } // namespace hardware } // namespace android +} // namespace aidl |