diff options
author | Ziyi Cui <ziyic@google.com> | 2022-12-01 06:27:28 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2022-12-01 06:27:28 +0000 |
commit | ce07cb5243d56ed2aed03aa0e8155bc533bb9161 (patch) | |
tree | 3a519d0009cc8d3e637de927e62ecad380b7baae | |
parent | 0fb242d71a5158a126b2abab5a60535ca39be426 (diff) | |
parent | d85550eb6fe0e2049042eb6c766cb478e236fb94 (diff) |
Merge "pixelatom: add atom for temperature residency metrics" into tm-qpr-dev
-rw-r--r-- | pixelstats/Android.bp | 1 | ||||
-rw-r--r-- | pixelstats/SysfsCollector.cpp | 9 | ||||
-rw-r--r-- | pixelstats/TempResidencyReporter.cpp | 176 | ||||
-rw-r--r-- | pixelstats/include/pixelstats/SysfsCollector.h | 6 | ||||
-rw-r--r-- | pixelstats/include/pixelstats/TempResidencyReporter.h | 50 | ||||
-rw-r--r-- | pixelstats/pixelatoms.proto | 40 |
6 files changed, 280 insertions, 2 deletions
diff --git a/pixelstats/Android.bp b/pixelstats/Android.bp index eadd8a9..ae49b53 100644 --- a/pixelstats/Android.bp +++ b/pixelstats/Android.bp @@ -73,6 +73,7 @@ cc_library { "StatsHelper.cpp", "SysfsCollector.cpp", "ThermalStatsReporter.cpp", + "TempResidencyReporter.cpp", "UeventListener.cpp", "WirelessChargeStats.cpp", "WlcReporter.cpp", diff --git a/pixelstats/SysfsCollector.cpp b/pixelstats/SysfsCollector.cpp index 8e5c709..3223f64 100644 --- a/pixelstats/SysfsCollector.cpp +++ b/pixelstats/SysfsCollector.cpp @@ -59,6 +59,7 @@ using android::hardware::google::pixel::PixelAtoms::VendorSlowIo; using android::hardware::google::pixel::PixelAtoms::VendorSpeakerImpedance; using android::hardware::google::pixel::PixelAtoms::VendorSpeakerStatsReported; using android::hardware::google::pixel::PixelAtoms::VendorSpeechDspStat; +using android::hardware::google::pixel::PixelAtoms::VendorTempResidencyStats; using android::hardware::google::pixel::PixelAtoms::ZramBdStat; using android::hardware::google::pixel::PixelAtoms::ZramMmStat; @@ -89,7 +90,8 @@ SysfsCollector::SysfsCollector(const struct SysfsPaths &sysfs_paths) kBlockStatsLength(sysfs_paths.BlockStatsLength), kAmsRatePath(sysfs_paths.AmsRatePath), kThermalStatsPaths(sysfs_paths.ThermalStatsPaths), - kCCARatePath(sysfs_paths.CCARatePath) {} + kCCARatePath(sysfs_paths.CCARatePath), + kTempResidencyPath(sysfs_paths.TempResidencyPath) {} bool SysfsCollector::ReadFileToInt(const std::string &path, int *val) { return ReadFileToInt(path.c_str(), val); @@ -814,6 +816,10 @@ void SysfsCollector::logBlockStatsReported(const std::shared_ptr<IStats> &stats_ } } +void SysfsCollector::logTempResidencyStats(const std::shared_ptr<IStats> &stats_client) { + temp_residency_reporter_.logTempResidencyStats(stats_client, kTempResidencyPath); +} + void SysfsCollector::reportZramMmStat(const std::shared_ptr<IStats> &stats_client) { std::string file_contents; if (!kZramMmStatPath) { @@ -1075,6 +1081,7 @@ void SysfsCollector::logPerDay() { mm_metrics_reporter_.logPixelMmMetricsPerDay(stats_client); logVendorAudioHardwareStats(stats_client); logThermalStats(stats_client); + logTempResidencyStats(stats_client); } void SysfsCollector::aggregatePer5Min() { diff --git a/pixelstats/TempResidencyReporter.cpp b/pixelstats/TempResidencyReporter.cpp new file mode 100644 index 0000000..baa1d4a --- /dev/null +++ b/pixelstats/TempResidencyReporter.cpp @@ -0,0 +1,176 @@ +/* + * 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: TempResidencyStats" + +#include <aidl/android/frameworks/stats/IStats.h> +#include <android-base/chrono_utils.h> +#include <android-base/file.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/TempResidencyReporter.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; + +/** + * Parse file_contents and read residency stats into cur_stats. + */ +bool parse_file_contents(std::string file_contents, + std::map<std::string, std::vector<int64_t>> *cur_stats) { + const char *data = file_contents.c_str(); + int data_len = file_contents.length(); + char sensor_name[32]; + int offset = 0; + int bytes_read; + + while (sscanf(data + offset, "THERMAL ZONE: %31s\n%n", sensor_name, &bytes_read) == 1) { + int64_t temp_res_value; + int num_stats_buckets; + int index = 0; + offset += bytes_read; + if (offset >= data_len) + return false; + + std::string sensor_name_str = sensor_name; + + if (!sscanf(data + offset, "NUM_TEMP_RESIDENCY_BUCKETS: %d\n%n", &num_stats_buckets, + &bytes_read)) + return false; + offset += bytes_read; + if (offset >= data_len) + return false; + while (index < num_stats_buckets) { + if (sscanf(data + offset, "-inf - %*d ====> %ldms\n%n", &temp_res_value, &bytes_read) != + 1 && + sscanf(data + offset, "%*d - %*d ====> %ldms\n%n", &temp_res_value, &bytes_read) != + 1 && + sscanf(data + offset, "%*d - inf ====> %ldms\n\n%n", &temp_res_value, + &bytes_read) != 1) + return false; + + (*cur_stats)[sensor_name_str].push_back(temp_res_value); + index++; + + offset += bytes_read; + if ((offset >= data_len) && (index < num_stats_buckets)) + return false; + } + } + return true; +} + +/** + * Logs the Temperature residency stats for every thermal zone. + */ +void TempResidencyReporter::logTempResidencyStats(const std::shared_ptr<IStats> &stats_client, + const char *const temperature_residency_path) { + if (!temperature_residency_path) { + ALOGV("TempResidencyStatsPath path not specified"); + return; + } + std::string file_contents; + if (!ReadFileToString(temperature_residency_path, &file_contents)) { + ALOGE("Unable to read TempResidencyStatsPath %s - %s", temperature_residency_path, + strerror(errno)); + return; + } + std::map<std::string, std::vector<int64_t>> cur_stats_map; + if (!parse_file_contents(file_contents, &cur_stats_map)) { + ALOGE("Fail to parse TempResidencyStatsPath"); + return; + } + if (!cur_stats_map.size()) + return; + ::android::base::boot_clock::time_point curTime = ::android::base::boot_clock::now(); + int64_t since_last_update_ms = + std::chrono::duration_cast<std::chrono::milliseconds>(curTime - prevTime).count(); + + auto cur_stats_map_iterator = cur_stats_map.begin(); + VendorAtomValue tmp_atom_value; + + // Iterate through cur_stats_map by sensor_name + while (cur_stats_map_iterator != cur_stats_map.end()) { + std::vector<VendorAtomValue> values; + std::string sensor_name_str = cur_stats_map_iterator->first; + std::vector<int64_t> residency_stats = cur_stats_map_iterator->second; + tmp_atom_value.set<VendorAtomValue::stringValue>(sensor_name_str); + values.push_back(tmp_atom_value); + tmp_atom_value.set<VendorAtomValue::longValue>(since_last_update_ms); + values.push_back(tmp_atom_value); + + bool key_in_map = (prev_stats.find(sensor_name_str)) != prev_stats.end(); + bool stat_len_match = (residency_stats.size() == prev_stats[sensor_name_str].size()); + if (key_in_map && !stat_len_match) + prev_stats[sensor_name_str].clear(); + + int64_t sum_residency = 0; + if (residency_stats.size() > kMaxBucketLen) { + cur_stats_map_iterator++; + continue; + } + // Iterate over every temperature residency buckets + for (int index = 0; index < residency_stats.size(); index++) { + // Get diff if stats arr length match previous stats + // Otherwise use raw stats as temperature residency stats per day + if (key_in_map && stat_len_match) { + int64_t diff_residency = + residency_stats[index] - prev_stats[sensor_name_str][index]; + tmp_atom_value.set<VendorAtomValue::longValue>(diff_residency); + sum_residency += diff_residency; + prev_stats[sensor_name_str][index] = residency_stats[index]; + } else { + tmp_atom_value.set<VendorAtomValue::longValue>(residency_stats[index]); + sum_residency += residency_stats[index]; + prev_stats[sensor_name_str].push_back(residency_stats[index]); + } + values.push_back(tmp_atom_value); + } + if (abs(since_last_update_ms - sum_residency) > kMaxResidencyDiffMs) + ALOGI("Thermal zone: %s Temperature residency stats not good!\ndevice sum_residency: " + "%ldms, since_last_update_ms %ldms\n", + sensor_name_str.c_str(), sum_residency, since_last_update_ms); + + // Send vendor atom to IStats HAL + VendorAtom event = {.reverseDomainName = "", + .atomId = PixelAtoms::Atom::kVendorTempResidencyStats, + .values = std::move(values)}; + ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event); + if (!ret.isOk()) + ALOGE("Unable to report VendorTempResidencyStats to Stats service"); + + cur_stats_map_iterator++; + } + prevTime = curTime; +} + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android diff --git a/pixelstats/include/pixelstats/SysfsCollector.h b/pixelstats/include/pixelstats/SysfsCollector.h index f487dda..8ee1ec6 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 "TempResidencyReporter.h" #include "ThermalStatsReporter.h" namespace android { @@ -65,6 +66,7 @@ class SysfsCollector { const char *const AmsRatePath; const std::vector<std::string> ThermalStatsPaths; const char *const CCARatePath; + const char *const TempResidencyPath; }; SysfsCollector(const struct SysfsPaths &paths); @@ -100,6 +102,7 @@ class SysfsCollector { void reportSlowIoFromFile(const std::shared_ptr<IStats> &stats_client, const char *path, const VendorSlowIo::IoOperation &operation_s); + void logTempResidencyStats(const std::shared_ptr<IStats> &stats_client); void reportZramMmStat(const std::shared_ptr<IStats> &stats_client); void reportZramBdStat(const std::shared_ptr<IStats> &stats_client); int getReclaimedSegments(const std::string &mode); @@ -132,13 +135,14 @@ class SysfsCollector { const char *const kAmsRatePath; const std::vector<std::string> kThermalStatsPaths; const char *const kCCARatePath; + const char *const kTempResidencyPath; BatteryEEPROMReporter battery_EEPROM_reporter_; MmMetricsReporter mm_metrics_reporter_; MitigationStatsReporter mitigation_stats_reporter_; ThermalStatsReporter thermal_stats_reporter_; BatteryHealthReporter battery_health_reporter_; - + TempResidencyReporter temp_residency_reporter_; // 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. diff --git a/pixelstats/include/pixelstats/TempResidencyReporter.h b/pixelstats/include/pixelstats/TempResidencyReporter.h new file mode 100644 index 0000000..07e3343 --- /dev/null +++ b/pixelstats/include/pixelstats/TempResidencyReporter.h @@ -0,0 +1,50 @@ +/* + * 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. + */ + +#include <aidl/android/frameworks/stats/IStats.h> +#include <android-base/chrono_utils.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 TempResidency Stats metrics + */ +class TempResidencyReporter { + public: + void logTempResidencyStats(const std::shared_ptr<IStats> &stats_client, + const char *const temperature_residency_path); + + private: + std::map<std::string, std::vector<int64_t>> prev_stats; + ::android::base::boot_clock::time_point prevTime = + ::android::base::boot_clock::time_point::min(); + const int kMaxBucketLen = 20; + const int kMaxResidencyDiffMs = 3000; +}; + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android diff --git a/pixelstats/pixelatoms.proto b/pixelstats/pixelatoms.proto index 5563259..a98d28f 100644 --- a/pixelstats/pixelatoms.proto +++ b/pixelstats/pixelatoms.proto @@ -84,6 +84,7 @@ message Atom { VendorAudioHardwareStatsReported vendor_audio_hardware_stats_reported = 105041; ThermalDfsStats thermal_dfs_stats = 105042; + VendorTempResidencyStats vendor_temp_residency_stats = 105045; } // AOSP atom ID range ends at 109999 } @@ -1281,3 +1282,42 @@ message VendorAudioHardwareStatsReported { /* cca_enable: UI enable & algorithm is inactive. (C2) */ optional int32 rate_of_cca_enable_per_day = 4; } + +/** + * Logs the Temperature residency stats per thermal zone. + */ +message VendorTempResidencyStats { + optional string reverse_domain_name = 1; + // Thermal zone name + optional string sensor_name = 2; + + // Time since last collect of this thermal zone + optional int64 since_last_update_ms = 3; + + // Temperature residency stats is measured by time in ms that a temperature zone's temperature + // lay within some temperature thresholds + // e.g. + // With temperature thresholds predefined as thresholds_i, thresholds_i+1, + // temp_residency_ms_bucket_i measures how much time the sensor lay within this two thresholds + optional int64 temp_residency_ms_bucket_1 = 4; + optional int64 temp_residency_ms_bucket_2 = 5; + optional int64 temp_residency_ms_bucket_3 = 6; + optional int64 temp_residency_ms_bucket_4 = 7; + optional int64 temp_residency_ms_bucket_5 = 8; + optional int64 temp_residency_ms_bucket_6 = 9; + optional int64 temp_residency_ms_bucket_7 = 10; + optional int64 temp_residency_ms_bucket_8 = 11; + optional int64 temp_residency_ms_bucket_9 = 12; + optional int64 temp_residency_ms_bucket_10 = 13; + optional int64 temp_residency_ms_bucket_11 = 14; + optional int64 temp_residency_ms_bucket_12 = 15; + optional int64 temp_residency_ms_bucket_13 = 16; + optional int64 temp_residency_ms_bucket_14 = 17; + optional int64 temp_residency_ms_bucket_15 = 18; + optional int64 temp_residency_ms_bucket_16 = 19; + optional int64 temp_residency_ms_bucket_17 = 20; + optional int64 temp_residency_ms_bucket_18 = 21; + optional int64 temp_residency_ms_bucket_19 = 22; + optional int64 temp_residency_ms_bucket_20 = 23; + +} |