diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-09-24 01:21:56 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-09-24 01:21:56 +0000 |
commit | d1e405a06c5af539ec4c5617df0c959cd08debae (patch) | |
tree | 27881adb7c28bc46b907715fa76429412a80a02c | |
parent | ec56e39e35641d336d2177d373c2d5e98875e7d7 (diff) | |
parent | d525e3fbef59c055767cbd33c375bcde9c49d4ca (diff) | |
download | pixel-d1e405a06c5af539ec4c5617df0c959cd08debae.tar.gz |
Snap for 9100386 from d525e3fbef59c055767cbd33c375bcde9c49d4ca to tm-d4-release
Change-Id: Ia20a78d5c8090b6618fabc0e724fb743d4b4987f
-rw-r--r-- | pixelstats/Android.bp | 1 | ||||
-rw-r--r-- | pixelstats/SysfsCollector.cpp | 9 | ||||
-rw-r--r-- | pixelstats/ThermalStatsReporter.cpp | 190 | ||||
-rw-r--r-- | pixelstats/include/pixelstats/SysfsCollector.h | 5 | ||||
-rw-r--r-- | pixelstats/include/pixelstats/ThermalStatsReporter.h | 71 | ||||
-rw-r--r-- | pixelstats/pixelatoms.proto | 21 | ||||
-rw-r--r-- | thermal/thermal-helper.cpp | 30 | ||||
-rw-r--r-- | thermal/thermal-helper.h | 3 | ||||
-rw-r--r-- | thermal/utils/thermal_throttling.cpp | 17 |
9 files changed, 326 insertions, 21 deletions
diff --git a/pixelstats/Android.bp b/pixelstats/Android.bp index f99e8e86..eadd8a96 100644 --- a/pixelstats/Android.bp +++ b/pixelstats/Android.bp @@ -72,6 +72,7 @@ cc_library { "PcaChargeStats.cpp", "StatsHelper.cpp", "SysfsCollector.cpp", + "ThermalStatsReporter.cpp", "UeventListener.cpp", "WirelessChargeStats.cpp", "WlcReporter.cpp", diff --git a/pixelstats/SysfsCollector.cpp b/pixelstats/SysfsCollector.cpp index 4a3711b9..391c8b17 100644 --- a/pixelstats/SysfsCollector.cpp +++ b/pixelstats/SysfsCollector.cpp @@ -51,6 +51,7 @@ using android::hardware::google::pixel::PixelAtoms::F2fsSmartIdleMaintEnabledSta using android::hardware::google::pixel::PixelAtoms::F2fsStatsInfo; using android::hardware::google::pixel::PixelAtoms::StorageUfsHealth; using android::hardware::google::pixel::PixelAtoms::StorageUfsResetCount; +using android::hardware::google::pixel::PixelAtoms::ThermalDfsStats; using android::hardware::google::pixel::PixelAtoms::VendorAudioHardwareStatsReported; using android::hardware::google::pixel::PixelAtoms::VendorChargeCycles; using android::hardware::google::pixel::PixelAtoms::VendorHardwareFailed; @@ -86,7 +87,8 @@ SysfsCollector::SysfsCollector(const struct SysfsPaths &sysfs_paths) kSpeakerHeartbeatPath(sysfs_paths.SpeakerHeartBeatPath), kUFSErrStatsPath(sysfs_paths.UFSErrStatsPath), kBlockStatsLength(sysfs_paths.BlockStatsLength), - kAmsRatePath(sysfs_paths.AmsRatePath) {} + kAmsRatePath(sysfs_paths.AmsRatePath), + kThermalStatsPaths(sysfs_paths.ThermalStatsPaths) {} bool SysfsCollector::ReadFileToInt(const std::string &path, int *val) { return ReadFileToInt(path.c_str(), val); @@ -371,6 +373,10 @@ void SysfsCollector::logSpeakerHealthStats(const std::shared_ptr<IStats> &stats_ reportSpeakerHealthStat(stats_client, right_obj); } +void SysfsCollector::logThermalStats(const std::shared_ptr<IStats> &stats_client) { + thermal_stats_reporter_.logThermalStats(stats_client, kThermalStatsPaths); +} + /** * Report the Speech DSP state. */ @@ -1039,6 +1045,7 @@ void SysfsCollector::logPerDay() { mm_metrics_reporter_.logCmaStatus(stats_client); mm_metrics_reporter_.logPixelMmMetricsPerDay(stats_client); logVendorAudioHardwareStats(stats_client); + logThermalStats(stats_client); } void SysfsCollector::aggregatePer5Min() { diff --git a/pixelstats/ThermalStatsReporter.cpp b/pixelstats/ThermalStatsReporter.cpp new file mode 100644 index 00000000..30fb30d3 --- /dev/null +++ b/pixelstats/ThermalStatsReporter.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "pixelstats: ThermalStats" + +#include <aidl/android/frameworks/stats/IStats.h> +#include <android-base/file.h> +#include <android-base/properties.h> +#include <android-base/stringprintf.h> +#include <android-base/strings.h> +#include <android/binder_manager.h> +#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h> +#include <pixelstats/ThermalStatsReporter.h> +#include <utils/Log.h> + +#include <cinttypes> + +namespace android { +namespace hardware { +namespace google { +namespace pixel { + +using aidl::android::frameworks::stats::IStats; +using aidl::android::frameworks::stats::VendorAtom; +using aidl::android::frameworks::stats::VendorAtomValue; +using android::base::ReadFileToString; +using android::hardware::google::pixel::PixelAtoms::ThermalDfsStats; + +ThermalStatsReporter::ThermalStatsReporter() {} + +bool ThermalStatsReporter::readDfsCount(const std::string &path, int64_t *val) { + std::string file_contents; + + if (path.empty()) { + ALOGE("Empty path"); + return false; + } + + if (!ReadFileToString(path.c_str(), &file_contents)) { + ALOGE("Unable to read %s - %s", path.c_str(), strerror(errno)); + return false; + } else { + int64_t trips[8]; + + if (sscanf(file_contents.c_str(), + "%" SCNd64 " %" SCNd64 " %" SCNd64 " %" SCNd64 " %" SCNd64 " %" SCNd64 + " %" SCNd64 " %" SCNd64, + &trips[0], &trips[1], &trips[2], &trips[3], &trips[4], &trips[5], &trips[6], + &trips[7]) < 8) { + ALOGE("Unable to parse trip_counters %s from file %s", file_contents.c_str(), + path.c_str()); + return false; + } + + /* Trip#6 corresponds to DFS count */ + *val = trips[6]; + } + + return true; +} + +bool ThermalStatsReporter::captureThermalDfsStats( + const std::vector<std::string> &thermal_stats_paths, struct ThermalDfsCounts *pcur_data) { + bool report_stats = false; + std::string path; + + if (thermal_stats_paths.size() < kNumOfThermalDfsStats) { + ALOGE("Number of thermal stats paths (%lu) is less than expected (%d)", + thermal_stats_paths.size(), kNumOfThermalDfsStats); + return false; + } + + path = thermal_stats_paths[ThermalDfsStats::kBigDfsCountFieldNumber - kVendorAtomOffset]; + if (!readDfsCount(path, &(pcur_data->big_count))) { + pcur_data->big_count = prev_data.big_count; + } else { + report_stats |= (pcur_data->big_count > prev_data.big_count); + } + + path = thermal_stats_paths[ThermalDfsStats::kMidDfsCountFieldNumber - kVendorAtomOffset]; + if (!readDfsCount(path, &(pcur_data->mid_count))) { + pcur_data->mid_count = prev_data.mid_count; + } else { + report_stats |= (pcur_data->mid_count > prev_data.mid_count); + } + + path = thermal_stats_paths[ThermalDfsStats::kLittleDfsCountFieldNumber - kVendorAtomOffset]; + if (!readDfsCount(path, &(pcur_data->little_count))) { + pcur_data->little_count = prev_data.little_count; + } else { + report_stats |= (pcur_data->little_count > prev_data.little_count); + } + + path = thermal_stats_paths[ThermalDfsStats::kGpuDfsCountFieldNumber - kVendorAtomOffset]; + if (!readDfsCount(path, &(pcur_data->gpu_count))) { + pcur_data->gpu_count = prev_data.gpu_count; + } else { + report_stats |= (pcur_data->gpu_count > prev_data.gpu_count); + } + + path = thermal_stats_paths[ThermalDfsStats::kTpuDfsCountFieldNumber - kVendorAtomOffset]; + if (!readDfsCount(path, &(pcur_data->tpu_count))) { + pcur_data->tpu_count = prev_data.tpu_count; + } else { + report_stats |= (pcur_data->tpu_count > prev_data.tpu_count); + } + + path = thermal_stats_paths[ThermalDfsStats::kAurDfsCountFieldNumber - kVendorAtomOffset]; + if (!readDfsCount(path, &(pcur_data->aur_count))) { + pcur_data->aur_count = prev_data.aur_count; + } else { + report_stats |= (pcur_data->aur_count > prev_data.aur_count); + } + + return report_stats; +} + +void ThermalStatsReporter::logThermalDfsStats(const std::shared_ptr<IStats> &stats_client, + const std::vector<std::string> &thermal_stats_paths) { + struct ThermalDfsCounts cur_data = prev_data; + + if (!captureThermalDfsStats(thermal_stats_paths, &cur_data)) { + prev_data = cur_data; + ALOGI("No update found for thermal stats"); + return; + } + + VendorAtomValue tmp; + int64_t max_dfs_count = static_cast<int64_t>(INT32_MAX); + int dfs_count; + std::vector<VendorAtomValue> values(kNumOfThermalDfsStats); + + dfs_count = std::min<int64_t>(cur_data.big_count - prev_data.big_count, max_dfs_count); + tmp.set<VendorAtomValue::intValue>(dfs_count); + values[ThermalDfsStats::kBigDfsCountFieldNumber - kVendorAtomOffset] = tmp; + + dfs_count = std::min<int64_t>(cur_data.mid_count - prev_data.mid_count, max_dfs_count); + tmp.set<VendorAtomValue::intValue>(dfs_count); + values[ThermalDfsStats::kMidDfsCountFieldNumber - kVendorAtomOffset] = tmp; + + dfs_count = std::min<int64_t>(cur_data.little_count - prev_data.little_count, max_dfs_count); + tmp.set<VendorAtomValue::intValue>(dfs_count); + values[ThermalDfsStats::kLittleDfsCountFieldNumber - kVendorAtomOffset] = tmp; + + dfs_count = std::min<int64_t>(cur_data.gpu_count - prev_data.gpu_count, max_dfs_count); + tmp.set<VendorAtomValue::intValue>(dfs_count); + values[ThermalDfsStats::kGpuDfsCountFieldNumber - kVendorAtomOffset] = tmp; + + dfs_count = std::min<int64_t>(cur_data.tpu_count - prev_data.tpu_count, max_dfs_count); + tmp.set<VendorAtomValue::intValue>(dfs_count); + values[ThermalDfsStats::kTpuDfsCountFieldNumber - kVendorAtomOffset] = tmp; + + dfs_count = std::min<int64_t>(cur_data.aur_count - prev_data.aur_count, max_dfs_count); + tmp.set<VendorAtomValue::intValue>(dfs_count); + values[ThermalDfsStats::kAurDfsCountFieldNumber - kVendorAtomOffset] = tmp; + + prev_data = cur_data; + + ALOGD("Report updated thermal metrics to stats service"); + // Send vendor atom to IStats HAL + VendorAtom event = {.reverseDomainName = "", + .atomId = PixelAtoms::Atom::kThermalDfsStats, + .values = std::move(values)}; + const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event); + if (!ret.isOk()) + ALOGE("Unable to report thermal DFS stats to Stats service"); +} + +void ThermalStatsReporter::logThermalStats(const std::shared_ptr<IStats> &stats_client, + const std::vector<std::string> &thermal_stats_paths) { + logThermalDfsStats(stats_client, thermal_stats_paths); +} + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android diff --git a/pixelstats/include/pixelstats/SysfsCollector.h b/pixelstats/include/pixelstats/SysfsCollector.h index c8bfb433..75b1a09e 100644 --- a/pixelstats/include/pixelstats/SysfsCollector.h +++ b/pixelstats/include/pixelstats/SysfsCollector.h @@ -24,6 +24,7 @@ #include "BatteryHealthReporter.h" #include "MitigationStatsReporter.h" #include "MmMetricsReporter.h" +#include "ThermalStatsReporter.h" namespace android { namespace hardware { @@ -62,6 +63,7 @@ class SysfsCollector { const std::vector<std::string> UFSErrStatsPath; const int BlockStatsLength; const char *const AmsRatePath; + const std::vector<std::string> ThermalStatsPaths; }; SysfsCollector(const struct SysfsPaths &paths); @@ -93,6 +95,7 @@ class SysfsCollector { void logBatteryEEPROM(const std::shared_ptr<IStats> &stats_client); void logSpeakerHealthStats(const std::shared_ptr<IStats> &stats_client); void logF2fsSmartIdleMaintEnabled(const std::shared_ptr<IStats> &stats_client); + void logThermalStats(const std::shared_ptr<IStats> &stats_client); void reportSlowIoFromFile(const std::shared_ptr<IStats> &stats_client, const char *path, const VendorSlowIo::IoOperation &operation_s); @@ -126,10 +129,12 @@ class SysfsCollector { const std::vector<std::string> kUFSErrStatsPath; const int kBlockStatsLength; const char *const kAmsRatePath; + const std::vector<std::string> kThermalStatsPaths; BatteryEEPROMReporter battery_EEPROM_reporter_; MmMetricsReporter mm_metrics_reporter_; MitigationStatsReporter mitigation_stats_reporter_; + ThermalStatsReporter thermal_stats_reporter_; BatteryHealthReporter battery_health_reporter_; // Proto messages are 1-indexed and VendorAtom field numbers start at 2, so diff --git a/pixelstats/include/pixelstats/ThermalStatsReporter.h b/pixelstats/include/pixelstats/ThermalStatsReporter.h new file mode 100644 index 00000000..57f246eb --- /dev/null +++ b/pixelstats/include/pixelstats/ThermalStatsReporter.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HARDWARE_GOOGLE_PIXEL_PIXELSTATS_THERMALSTATSREPORTER_H +#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_THERMALSTATSREPORTER_H + +#include <aidl/android/frameworks/stats/IStats.h> +#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h> + +#include <string> + +namespace android { +namespace hardware { +namespace google { +namespace pixel { + +using aidl::android::frameworks::stats::IStats; +using aidl::android::frameworks::stats::VendorAtomValue; + +/** + * A class to upload Pixel Thermal Stats metrics + */ +class ThermalStatsReporter { + public: + ThermalStatsReporter(); + void logThermalStats(const std::shared_ptr<IStats> &stats_client, + const std::vector<std::string> &thermal_stats_paths); + + private: + struct ThermalDfsCounts { + int64_t big_count; + int64_t mid_count; + int64_t little_count; + int64_t gpu_count; + int64_t tpu_count; + int64_t aur_count; + }; + + // Proto messages are 1-indexed and VendorAtom field numbers start at 2, so + // store everything in the values array at the index of the field number + // -2. + const int kVendorAtomOffset = 2; + const int kNumOfThermalDfsStats = 6; + struct ThermalDfsCounts prev_data; + + void logThermalDfsStats(const std::shared_ptr<IStats> &stats_client, + const std::vector<std::string> &thermal_stats_paths); + bool captureThermalDfsStats(const std::vector<std::string> &thermal_stats_paths, + struct ThermalDfsCounts *cur_data); + bool readDfsCount(const std::string &path, int64_t *val); +}; + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android + +#endif // HARDWARE_GOOGLE_PIXEL_PIXELSTATS_THERMALSTATSREPORTER_H diff --git a/pixelstats/pixelatoms.proto b/pixelstats/pixelatoms.proto index 3d957bf9..23005268 100644 --- a/pixelstats/pixelatoms.proto +++ b/pixelstats/pixelatoms.proto @@ -82,6 +82,8 @@ message Atom { F2fsSmartIdleMaintEnabledStateChanged f2fs_smart_idle_maint_enabled_state_changed = 105039; BlockStatsReported block_stats_reported = 105040; VendorAudioHardwareStatsReported vendor_audio_hardware_stats_reported = 105041; + + ThermalDfsStats thermal_dfs_stats = 105042; } // AOSP atom ID range ends at 109999 } @@ -903,6 +905,25 @@ message PowerMitigationStats { } /** + * Log thermal statistics. + */ +message ThermalDfsStats { + optional string reverse_domain_name = 1; + // The last count of BIG cluster dfs triggers + optional int32 big_dfs_count = 2; + // The last count of MID cluster dfs triggers + optional int32 mid_dfs_count = 3; + // The last count of LITTLE cluster dfs triggers + optional int32 little_dfs_count = 4; + // The last count of GPU dfs triggers + optional int32 gpu_dfs_count = 5; + // The last count of TPU dfs triggers + optional int32 tpu_dfs_count = 6; + // The last count of DSP dfs triggers + optional int32 aur_dfs_count = 7; +} + +/** * Log how many segments have been reclaimed in a specific GC mode. */ message F2fsGcSegmentInfo { diff --git a/thermal/thermal-helper.cpp b/thermal/thermal-helper.cpp index ae58daa5..85ccc5d5 100644 --- a/thermal/thermal-helper.cpp +++ b/thermal/thermal-helper.cpp @@ -334,7 +334,8 @@ bool ThermalHelper::readCoolingDevice(std::string_view cooling_device, bool ThermalHelper::readTemperature(std::string_view sensor_name, Temperature_1_0 *out) { // Return fail if the thermal sensor cannot be read. float temp; - if (!readThermalSensor(sensor_name, &temp, false)) { + std::string sensor_log; + if (!readThermalSensor(sensor_name, &temp, false, &sensor_log)) { LOG(ERROR) << "readTemperature: failed to read sensor: " << sensor_name; return false; } @@ -353,6 +354,10 @@ bool ThermalHelper::readTemperature(std::string_view sensor_name, Temperature_1_ sensor_info.hot_thresholds[static_cast<size_t>(ThrottlingSeverity::SHUTDOWN)]; out->vrThrottlingThreshold = sensor_info.vr_threshold; + if (sensor_info.is_watch) { + LOG(INFO) << sensor_name.data() << ":" << out->currentValue << " raw data:[" << sensor_log + << "]"; + } return true; } @@ -362,8 +367,9 @@ bool ThermalHelper::readTemperature( const bool force_no_cache) { // Return fail if the thermal sensor cannot be read. float temp; + std::string sensor_log; - if (!readThermalSensor(sensor_name, &temp, force_no_cache)) { + if (!readThermalSensor(sensor_name, &temp, force_no_cache, &sensor_log)) { LOG(ERROR) << "readTemperature: failed to read sensor: " << sensor_name; return false; } @@ -395,7 +401,9 @@ bool ThermalHelper::readTemperature( out->throttlingStatus = static_cast<size_t>(status.first) > static_cast<size_t>(status.second) ? status.first : status.second; - + if (sensor_info.is_watch) { + LOG(INFO) << sensor_name.data() << ":" << out->value << " raw data:[" << sensor_log << "]"; + } return true; } @@ -784,10 +792,10 @@ bool ThermalHelper::fillCpuUsages(hidl_vec<CpuUsage> *cpu_usages) const { } bool ThermalHelper::readThermalSensor(std::string_view sensor_name, float *temp, - const bool force_no_cache) { + const bool force_no_cache, std::string *sensor_log) { float temp_val = 0.0; std::string file_reading; - std::string log_buf; + std::string sub_sensor_log; boot_clock::time_point now = boot_clock::now(); ATRACE_NAME(StringPrintf("ThermalHelper::readThermalSensor - %s", sensor_name.data()).c_str()); @@ -806,6 +814,7 @@ bool ThermalHelper::readThermalSensor(std::string_view sensor_name, float *temp, now - sensor_status.thermal_cached.timestamp) < sensor_info.time_resolution) && !isnan(sensor_status.thermal_cached.temp)) { *temp = sensor_status.thermal_cached.temp; + sensor_log->append(StringPrintf("%s:%0.f ", sensor_name.data(), *temp)); LOG(VERBOSE) << "read " << sensor_name.data() << " from buffer, value:" << *temp; return true; } @@ -821,16 +830,14 @@ bool ThermalHelper::readThermalSensor(std::string_view sensor_name, float *temp, return false; } *temp = std::stof(::android::base::Trim(file_reading)); + sensor_log->append(StringPrintf("%s:%0.f ", sensor_name.data(), *temp)); } else { for (size_t i = 0; i < sensor_info.virtual_sensor_info->linked_sensors.size(); i++) { float sensor_reading = 0.0; if (!readThermalSensor(sensor_info.virtual_sensor_info->linked_sensors[i], - &sensor_reading, force_no_cache)) { + &sensor_reading, force_no_cache, &sub_sensor_log)) { return false; } - log_buf.append(StringPrintf("(%s: %0.2f)", - sensor_info.virtual_sensor_info->linked_sensors[i].c_str(), - sensor_reading)); if (std::isnan(sensor_info.virtual_sensor_info->coefficients[i])) { return false; } @@ -861,8 +868,9 @@ bool ThermalHelper::readThermalSensor(std::string_view sensor_name, float *temp, break; } } - LOG(VERBOSE) << sensor_name.data() << "'s sub sensors:" << log_buf; *temp = (temp_val + sensor_info.virtual_sensor_info->offset); + sensor_log->append( + StringPrintf("%s:%0.f(%s) ", sensor_name.data(), *temp, sub_sensor_log.data())); } { @@ -994,10 +1002,8 @@ std::chrono::milliseconds ThermalHelper::thermalWatcherCallbackFunc( } if (sensor_status.severity == ThrottlingSeverity::NONE) { - LOG(VERBOSE) << temp.name << ": " << temp.value; thermal_throttling_.clearThrottlingData(name_status_pair.first, sensor_info); } else { - LOG(INFO) << temp.name << ": " << temp.value; // update thermal throttling request thermal_throttling_.thermalThrottlingUpdate( temp, sensor_info, sensor_status.severity, time_elapsed_ms, diff --git a/thermal/thermal-helper.h b/thermal/thermal-helper.h index 6b7cd9a9..eca98059 100644 --- a/thermal/thermal-helper.h +++ b/thermal/thermal-helper.h @@ -150,7 +150,8 @@ class ThermalHelper { ThrottlingSeverity prev_hot_severity, ThrottlingSeverity prev_cold_severity, float value) const; // Read temperature data according to thermal sensor's info - bool readThermalSensor(std::string_view sensor_name, float *temp, const bool force_sysfs); + bool readThermalSensor(std::string_view sensor_name, float *temp, const bool force_sysfs, + std::string *sensor_log); bool connectToPowerHal(); void updateSupportedPowerHints(); void updateCoolingDevices(const std::vector<std::string> &cooling_devices_to_update); diff --git a/thermal/utils/thermal_throttling.cpp b/thermal/utils/thermal_throttling.cpp index 6f2d1205..fcaee8f9 100644 --- a/thermal/utils/thermal_throttling.cpp +++ b/thermal/utils/thermal_throttling.cpp @@ -346,18 +346,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( |