diff options
author | Ziyi Cui <ziyic@google.com> | 2022-10-06 07:06:19 +0000 |
---|---|---|
committer | Ziyi Cui <ziyic@google.com> | 2022-11-29 21:39:49 +0000 |
commit | 55ae6c52a3c72bed3e4ae4cff6260f81f53fc2d6 (patch) | |
tree | 18db214bcd40b3581b57586530d3e24ad25e9d70 | |
parent | 6fcf739e42f283f7a0d36a7a5ac82da417c36a30 (diff) |
pixelatom: add atom for resume latency metrics
Add pixel atom for resume latency metrics
Bug: 227809911
Bug: 232541623
Test: Verified the existence of atom and correctness of atom stats
adb shell
cmd stats print-logs && logcat -b all | grep -i 105044
Signed-off-by: Ziyi Cui <ziyic@google.com>
Change-Id: Id1de281a6432d75085e70af50299d687e2238e08
(cherry picked from commit 716ffa3025e70210d82a3e9fe6ba01fb81c5fe09)
-rw-r--r-- | pixelstats/SysfsCollector.cpp | 102 | ||||
-rw-r--r-- | pixelstats/include/pixelstats/SysfsCollector.h | 9 | ||||
-rw-r--r-- | pixelstats/pixelatoms.proto | 53 |
3 files changed, 162 insertions, 2 deletions
diff --git a/pixelstats/SysfsCollector.cpp b/pixelstats/SysfsCollector.cpp index 698644f..203ff0f 100644 --- a/pixelstats/SysfsCollector.cpp +++ b/pixelstats/SysfsCollector.cpp @@ -56,6 +56,7 @@ using android::hardware::google::pixel::PixelAtoms::VendorAudioHardwareStatsRepo using android::hardware::google::pixel::PixelAtoms::VendorChargeCycles; using android::hardware::google::pixel::PixelAtoms::VendorHardwareFailed; using android::hardware::google::pixel::PixelAtoms::VendorLongIRQStatsReported; +using android::hardware::google::pixel::PixelAtoms::VendorResumeLatencyStats; using android::hardware::google::pixel::PixelAtoms::VendorSlowIo; using android::hardware::google::pixel::PixelAtoms::VendorSpeakerImpedance; using android::hardware::google::pixel::PixelAtoms::VendorSpeakerStatsReported; @@ -93,7 +94,8 @@ SysfsCollector::SysfsCollector(const struct SysfsPaths &sysfs_paths) kThermalStatsPaths(sysfs_paths.ThermalStatsPaths), kCCARatePath(sysfs_paths.CCARatePath), kTempResidencyPath(sysfs_paths.TempResidencyPath), - kLongIRQMetricsPath(sysfs_paths.LongIRQMetricsPath) {} + kLongIRQMetricsPath(sysfs_paths.LongIRQMetricsPath), + kResumeLatencyMetricsPath(sysfs_paths.ResumeLatencyMetricsPath) {} bool SysfsCollector::ReadFileToInt(const std::string &path, int *val) { return ReadFileToInt(path.c_str(), val); @@ -1052,6 +1054,103 @@ void SysfsCollector::logVendorAudioHardwareStats(const std::shared_ptr<IStats> & ALOGE("Unable to report VendorAudioHardwareStatsReported to Stats service"); } +/** + * Logs the Resume Latency stats. + */ +void SysfsCollector::logVendorResumeLatencyStats(const std::shared_ptr<IStats> &stats_client) { + std::string file_contents; + if (!kResumeLatencyMetricsPath) { + ALOGE("ResumeLatencyMetrics path not specified"); + return; + } + if (!ReadFileToString(kResumeLatencyMetricsPath, &file_contents)) { + ALOGE("Unable to ResumeLatencyMetric %s - %s", kResumeLatencyMetricsPath, strerror(errno)); + return; + } + + int offset = 0; + int bytes_read; + const char *data = file_contents.c_str(); + int data_len = file_contents.length(); + + int curr_bucket_cnt; + if (!sscanf(data + offset, "Resume Latency Bucket Count: %d\n%n", &curr_bucket_cnt, + &bytes_read)) + return; + offset += bytes_read; + if (offset >= data_len) + return; + + int64_t max_latency; + if (!sscanf(data + offset, "Max Resume Latency: %ld\n%n", &max_latency, &bytes_read)) + return; + offset += bytes_read; + if (offset >= data_len) + return; + + uint64_t sum_latency; + if (!sscanf(data + offset, "Sum Resume Latency: %lu\n%n", &sum_latency, &bytes_read)) + return; + offset += bytes_read; + if (offset >= data_len) + return; + + if (curr_bucket_cnt > kMaxResumeLatencyBuckets) + return; + if (curr_bucket_cnt != prev_data.bucket_cnt) { + prev_data.resume_latency_buckets.clear(); + } + + int64_t total_latency_cnt = 0; + int64_t count; + int index = 2; + std::vector<VendorAtomValue> values(curr_bucket_cnt + 2); + VendorAtomValue tmp; + // Iterate over resume latency buckets to get latency count within some latency thresholds + while (sscanf(data + offset, "%*ld - %*ldms ====> %ld\n%n", &count, &bytes_read) == 1 || + sscanf(data + offset, "%*ld - infms ====> %ld\n%n", &count, &bytes_read) == 1) { + offset += bytes_read; + if (offset >= data_len && (index + 1 < curr_bucket_cnt + 2)) + return; + if (curr_bucket_cnt == prev_data.bucket_cnt) { + tmp.set<VendorAtomValue::longValue>(count - + prev_data.resume_latency_buckets[index - 2]); + prev_data.resume_latency_buckets[index - 2] = count; + } else { + tmp.set<VendorAtomValue::longValue>(count); + prev_data.resume_latency_buckets.push_back(count); + } + if (index >= curr_bucket_cnt + 2) + return; + values[index] = tmp; + index += 1; + total_latency_cnt += count; + } + tmp.set<VendorAtomValue::longValue>(max_latency); + values[0] = tmp; + if ((sum_latency - prev_data.resume_latency_sum_ms < 0) || + (total_latency_cnt - prev_data.resume_count <= 0)) { + tmp.set<VendorAtomValue::longValue>(-1); + ALOGI("average resume latency get overflow"); + } else { + tmp.set<VendorAtomValue::longValue>( + (int64_t)(sum_latency - prev_data.resume_latency_sum_ms) / + (total_latency_cnt - prev_data.resume_count)); + } + values[1] = tmp; + + prev_data.resume_latency_sum_ms = sum_latency; + prev_data.resume_count = total_latency_cnt; + prev_data.bucket_cnt = curr_bucket_cnt; + // Send vendor atom to IStats HAL + VendorAtom event = {.reverseDomainName = "", + .atomId = PixelAtoms::Atom::kVendorResumeLatencyStats, + .values = std::move(values)}; + const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event); + if (!ret.isOk()) + ALOGE("Unable to report VendorResumeLatencyStats to Stats service"); +} + bool cmp(const std::pair<int, int64_t> &a, const std::pair<int, int64_t> &b) { return a.second > b.second; } @@ -1210,6 +1309,7 @@ void SysfsCollector::logPerDay() { logThermalStats(stats_client); logTempResidencyStats(stats_client); logVendorLongIRQStatsReported(stats_client); + logVendorResumeLatencyStats(stats_client); } void SysfsCollector::aggregatePer5Min() { diff --git a/pixelstats/include/pixelstats/SysfsCollector.h b/pixelstats/include/pixelstats/SysfsCollector.h index e0aef81..df4a331 100644 --- a/pixelstats/include/pixelstats/SysfsCollector.h +++ b/pixelstats/include/pixelstats/SysfsCollector.h @@ -68,6 +68,7 @@ class SysfsCollector { const char *const CCARatePath; const char *const TempResidencyPath; const char *const LongIRQMetricsPath; + const char *const ResumeLatencyMetricsPath; }; SysfsCollector(const struct SysfsPaths &paths); @@ -109,6 +110,7 @@ class SysfsCollector { int getReclaimedSegments(const std::string &mode); void logVendorAudioHardwareStats(const std::shared_ptr<IStats> &stats_client); void logVendorLongIRQStatsReported(const std::shared_ptr<IStats> &stats_client); + void logVendorResumeLatencyStats(const std::shared_ptr<IStats> &stats_client); const char *const kSlowioReadCntPath; const char *const kSlowioWriteCntPath; @@ -139,6 +141,7 @@ class SysfsCollector { const char *const kCCARatePath; const char *const kTempResidencyPath; const char *const kLongIRQMetricsPath; + const char *const kResumeLatencyMetricsPath; BatteryEEPROMReporter battery_EEPROM_reporter_; MmMetricsReporter mm_metrics_reporter_; @@ -153,11 +156,17 @@ class SysfsCollector { bool log_once_reported = false; int64_t prev_huge_pages_since_boot_ = -1; + struct perf_metrics_data { int64_t softirq_count; int64_t irq_count; + uint64_t resume_latency_sum_ms; + int64_t resume_count; + std::vector<int64_t> resume_latency_buckets; + int bucket_cnt; }; struct perf_metrics_data prev_data; + const int kMaxResumeLatencyBuckets = 36; }; } // namespace pixel diff --git a/pixelstats/pixelatoms.proto b/pixelstats/pixelatoms.proto index 9e9c83e..33796c7 100644 --- a/pixelstats/pixelatoms.proto +++ b/pixelstats/pixelatoms.proto @@ -85,6 +85,7 @@ message Atom { ThermalDfsStats thermal_dfs_stats = 105042; VendorLongIRQStatsReported vendor_long_irq_stats_reported = 105043; + VendorResumeLatencyStats vendor_resume_latency_stats = 105044; VendorTempResidencyStats vendor_temp_residency_stats = 105045; } // AOSP atom ID range ends at 109999 @@ -1291,7 +1292,7 @@ message VendorAudioHardwareStatsReported { * Stats include top 5 slowest IRQs: their numbers and the worst latency. * Stats are reset after every report. */ - message VendorLongIRQStatsReported { +message VendorLongIRQStatsReported { optional string reverse_domain_name = 1; // Count of long soft IRQ since last report. @@ -1360,3 +1361,53 @@ message VendorTempResidencyStats { optional int64 temp_residency_ms_bucket_19 = 22; optional int64 temp_residency_ms_bucket_20 = 23; } + +/** + * Logs the Resume Latency stats. + */ +message VendorResumeLatencyStats { + optional string reverse_domain_name = 1; + optional int64 max_latency_ms = 2; + optional int64 avg_latency_ms = 3; + + // Resume Latency stats is measured by count of resumes that lay within some latency thresholds + // e.g. + // With resume times thresholds predefined as thresholds_i, thresholds_i+1, + // resume_count_bucket_i measures count of resumes that lay within this two thresholds + optional int64 resume_count_bucket_1 = 4; + optional int64 resume_count_bucket_2 = 5; + optional int64 resume_count_bucket_3 = 6; + optional int64 resume_count_bucket_4 = 7; + optional int64 resume_count_bucket_5 = 8; + optional int64 resume_count_bucket_6 = 9; + optional int64 resume_count_bucket_7 = 10; + optional int64 resume_count_bucket_8 = 11; + optional int64 resume_count_bucket_9 = 12; + optional int64 resume_count_bucket_10 = 13; + optional int64 resume_count_bucket_11 = 14; + optional int64 resume_count_bucket_12 = 15; + optional int64 resume_count_bucket_13 = 16; + optional int64 resume_count_bucket_14 = 17; + optional int64 resume_count_bucket_15 = 18; + optional int64 resume_count_bucket_16 = 19; + optional int64 resume_count_bucket_17 = 20; + optional int64 resume_count_bucket_18 = 21; + optional int64 resume_count_bucket_19 = 22; + optional int64 resume_count_bucket_20 = 23; + optional int64 resume_count_bucket_21 = 24; + optional int64 resume_count_bucket_22 = 25; + optional int64 resume_count_bucket_23 = 26; + optional int64 resume_count_bucket_24 = 27; + optional int64 resume_count_bucket_25 = 28; + optional int64 resume_count_bucket_26 = 29; + optional int64 resume_count_bucket_27 = 30; + optional int64 resume_count_bucket_28 = 31; + optional int64 resume_count_bucket_29 = 32; + optional int64 resume_count_bucket_30 = 33; + optional int64 resume_count_bucket_31 = 34; + optional int64 resume_count_bucket_32 = 35; + optional int64 resume_count_bucket_33 = 36; + optional int64 resume_count_bucket_34 = 37; + optional int64 resume_count_bucket_35 = 38; + optional int64 resume_count_bucket_36 = 39; +} |