diff options
author | Sayanna Chandula <sayanna@google.com> | 2022-08-17 15:01:06 -0700 |
---|---|---|
committer | Sayanna Chandula <sayanna@google.com> | 2022-09-20 17:07:39 -0700 |
commit | 9e3b945a37641b4c64d2b57ae028513bf65c17b1 (patch) | |
tree | b9f1115cb5562e5a9508ac6323e122ad39a48197 | |
parent | d09fb3c9e07040dd785cfba6456f3e4266e5d523 (diff) |
pixelstats: support thermal stats
Add support for thermal stats with dfs metrics
Bug: 228247740
Test: Build and boot on device
adb shell cmd stats print-stats | grep -i <atom-id>
Change-Id: Id466c43ee8503c1bdf99c3ad8218336874ebe595
-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 |
6 files changed, 296 insertions, 1 deletions
diff --git a/pixelstats/Android.bp b/pixelstats/Android.bp index f99e8e8..eadd8a9 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 4a3711b..391c8b1 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 0000000..30fb30d --- /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 c8bfb43..75b1a09 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 0000000..57f246e --- /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 3d957bf..2300526 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 { |