diff options
author | Ocean Chen <oceanchen@google.com> | 2019-12-10 17:42:55 +0800 |
---|---|---|
committer | Thierry Strudel <tstrudel@google.com> | 2020-02-27 08:26:25 +0000 |
commit | 3189ee9aab687cebf898c81b34b07a24a5e9373a (patch) | |
tree | 89932be3be24bf0777b15fd121407bd32a63a248 | |
parent | 0772cc0ef3498f5beffb640377aab1f5f3c3a30e (diff) | |
download | pixel-3189ee9aab687cebf898c81b34b07a24a5e9373a.tar.gz |
pixelstats: Upload f2fs status about fragmentation
Upload the following items
- dirty segments
- free segments
- CP calls (foreground/background)
- GC calls (foreground/background)
- moved blocks (foreground/background)
- avg. valid blocks
Bug: 146053177
Change-Id: I15ef3ff0ccb1796d10bcc874eccb77c2df5f3274
(cherry picked from commit 95c9f6dc4079233229717e8e58afa058f9875fe9)
-rw-r--r-- | pixelstats/SysfsCollector.cpp | 141 | ||||
-rw-r--r-- | pixelstats/include/pixelstats/SysfsCollector.h | 13 | ||||
-rw-r--r-- | pixelstats/pixelatoms.proto | 34 |
3 files changed, 187 insertions, 1 deletions
diff --git a/pixelstats/SysfsCollector.cpp b/pixelstats/SysfsCollector.cpp index f588c411..4b74e42d 100644 --- a/pixelstats/SysfsCollector.cpp +++ b/pixelstats/SysfsCollector.cpp @@ -20,6 +20,7 @@ #include <android-base/file.h> #include <android-base/parseint.h> +#include <android-base/properties.h> #include <android-base/strings.h> #include <android/frameworks/stats/1.0/IStats.h> #include <hardware/google/pixel/pixelstats/pixelatoms.pb.h> @@ -45,6 +46,8 @@ using android::frameworks::stats::V1_0::SpeakerImpedance; using android::frameworks::stats::V1_0::SpeechDspStat; using android::frameworks::stats::V1_0::VendorAtom; using android::hardware::google::pixel::PixelAtoms::BatteryCapacity; +using android::hardware::google::pixel::PixelAtoms::StorageUfsHealth; +using android::hardware::google::pixel::PixelAtoms::F2fsStatsInfo; SysfsCollector::SysfsCollector(const struct SysfsPaths &sysfs_paths) : kSlowioReadCntPath(sysfs_paths.SlowioReadCntPath), @@ -57,7 +60,12 @@ SysfsCollector::SysfsCollector(const struct SysfsPaths &sysfs_paths) kCodec1Path(sysfs_paths.Codec1Path), kSpeechDspPath(sysfs_paths.SpeechDspPath), kBatteryCapacityCC(sysfs_paths.BatteryCapacityCC), - kBatteryCapacityVFSOC(sysfs_paths.BatteryCapacityVFSOC) {} + kBatteryCapacityVFSOC(sysfs_paths.BatteryCapacityVFSOC), + kUFSLifetimeA(sysfs_paths.UFSLifetimeA), + kUFSLifetimeB(sysfs_paths.UFSLifetimeB), + kUFSLifetimeC(sysfs_paths.UFSLifetimeC), + kF2fsStatsPath(sysfs_paths.F2fsStatsPath), + kUserdataBlockProp(sysfs_paths.UserdataBlockProp) {} bool SysfsCollector::ReadFileToInt(const std::string &path, int *val) { return ReadFileToInt(path.c_str(), val); @@ -277,6 +285,135 @@ void SysfsCollector::logBatteryCapacity() { ALOGE("Unable to report ChargeStats to Stats service"); } +void SysfsCollector::logUFSLifetime() { + std::string file_contents; + if (kUFSLifetimeA == nullptr || strlen(kUFSLifetimeA) == 0) { + ALOGV("UFS lifetimeA path not specified"); + return; + } + if (kUFSLifetimeB == nullptr || strlen(kUFSLifetimeB) == 0) { + ALOGV("UFS lifetimeB path not specified"); + return; + } + if (kUFSLifetimeC == nullptr || strlen(kUFSLifetimeC) == 0) { + ALOGV("UFS lifetimeC path not specified"); + return; + } + + int lifetimeA = 0, lifetimeB = 0, lifetimeC = 0; + if (!ReadFileToInt(kUFSLifetimeA, &lifetimeA) || + !ReadFileToInt(kUFSLifetimeB, &lifetimeB) || + !ReadFileToInt(kUFSLifetimeC, &lifetimeC)) { + ALOGE("Unable to read UFS lifetime : %s", strerror(errno)); + return; + } + + // Load values array + std::vector<VendorAtom::Value> values(3); + VendorAtom::Value tmp; + tmp.intValue(lifetimeA); + values[StorageUfsHealth::kLifetimeAFieldNumber - kVendorAtomOffset] = tmp; + tmp.intValue(lifetimeB); + values[StorageUfsHealth::kLifetimeBFieldNumber - kVendorAtomOffset] = tmp; + tmp.intValue(lifetimeC); + values[StorageUfsHealth::kLifetimeCFieldNumber - kVendorAtomOffset] = tmp; + + + // Send vendor atom to IStats HAL + VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(), + .atomId = PixelAtoms::Ids::STORAGE_UFS_HEALTH, + .values = values}; + Return<void> ret = stats_->reportVendorAtom(event); + if (!ret.isOk()) { + ALOGE("Unable to report UfsHealthStat to Stats service"); + } +} + +void SysfsCollector::logF2fsStats() { + std::string userdataBlock; + int dirty, free, cp_calls_fg, gc_calls_fg, moved_block_fg, vblocks; + int cp_calls_bg, gc_calls_bg, moved_block_bg; + + if (kF2fsStatsPath == nullptr) { + ALOGE("F2fs stats path not specified"); + return; + } + + if (kUserdataBlockProp == nullptr) { + ALOGE("Userdata block property not specified"); + return; + } + + userdataBlock = android::base::GetProperty(kUserdataBlockProp, ""); + + if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/dirty_segments"), &dirty)) { + ALOGV("Unable to read dirty segments"); + } + + if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/free_segments"), &free)) { + ALOGV("Unable to read free segments"); + } + + if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/cp_foreground_calls"), &cp_calls_fg)) { + ALOGV("Unable to read cp_foreground_calls"); + } + + if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/cp_background_calls"), &cp_calls_bg)) { + ALOGV("Unable to read cp_background_calls"); + } + + if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/gc_foreground_calls"), &gc_calls_fg)) { + ALOGV("Unable to read gc_foreground_calls"); + } + + if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/gc_background_calls"), &gc_calls_bg)) { + ALOGV("Unable to read gc_background_calls"); + } + + if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/moved_blocks_foreground"), &moved_block_fg)) { + ALOGV("Unable to read moved_blocks_foreground"); + } + + if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/moved_blocks_background"), &moved_block_bg)) { + ALOGV("Unable to read moved_blocks_background"); + } + + if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/avg_vblocks"), &vblocks)) { + ALOGV("Unable to read avg_vblocks"); + } + + // Load values array + std::vector<VendorAtom::Value> values(10); + VendorAtom::Value tmp; + tmp.intValue(dirty); + values[F2fsStatsInfo::kDirtySegmentsFieldNumber - kVendorAtomOffset] = tmp; + tmp.intValue(free); + values[F2fsStatsInfo::kFreeSegmentsFieldNumber - kVendorAtomOffset] = tmp; + tmp.intValue(cp_calls_fg); + values[F2fsStatsInfo::kCpCallsFgFieldNumber - kVendorAtomOffset] = tmp; + tmp.intValue(cp_calls_bg); + values[F2fsStatsInfo::kCpCallsBgFieldNumber - kVendorAtomOffset] = tmp; + tmp.intValue(gc_calls_fg); + values[F2fsStatsInfo::kGcCallsFgFieldNumber - kVendorAtomOffset] = tmp; + tmp.intValue(gc_calls_bg); + values[F2fsStatsInfo::kGcCallsBgFieldNumber - kVendorAtomOffset] = tmp; + tmp.intValue(moved_block_fg); + values[F2fsStatsInfo::kMovedBlocksFgFieldNumber - kVendorAtomOffset] = tmp; + tmp.intValue(moved_block_bg); + values[F2fsStatsInfo::kMovedBlocksBgFieldNumber - kVendorAtomOffset] = tmp; + tmp.intValue(vblocks); + values[F2fsStatsInfo::kValidBlocksFieldNumber - kVendorAtomOffset] = tmp; + + // Send vendor atom to IStats HAL + VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(), + .atomId = PixelAtoms::Ids::F2FS_STATS, + .values = values}; + Return<void> ret = stats_->reportVendorAtom(event); + if (!ret.isOk()) { + ALOGE("Unable to report F2fs stats to Stats service"); + } +} + void SysfsCollector::logAll() { stats_ = IStats::tryGetService(); if (!stats_) { @@ -291,6 +428,8 @@ void SysfsCollector::logAll() { logSpeakerImpedance(); logSpeechDspStat(); logBatteryCapacity(); + logUFSLifetime(); + logF2fsStats(); stats_.clear(); } diff --git a/pixelstats/include/pixelstats/SysfsCollector.h b/pixelstats/include/pixelstats/SysfsCollector.h index d784ed59..0c234c00 100644 --- a/pixelstats/include/pixelstats/SysfsCollector.h +++ b/pixelstats/include/pixelstats/SysfsCollector.h @@ -43,6 +43,11 @@ class SysfsCollector { const char *const SpeechDspPath; const char *const BatteryCapacityCC; const char *const BatteryCapacityVFSOC; + const char *const UFSLifetimeA; + const char *const UFSLifetimeB; + const char *const UFSLifetimeC; + const char *const F2fsStatsPath; + const char *const UserdataBlockProp; }; SysfsCollector(const struct SysfsPaths &paths); @@ -60,8 +65,11 @@ class SysfsCollector { void logSpeakerImpedance(); void logSpeechDspStat(); void logBatteryCapacity(); + void logUFSLifetime(); + void logF2fsStats(); void reportSlowIoFromFile(const char *path, const SlowIo::IoOperation &operation_s); + unsigned int getValueFromStatus(std::string &f2fsStatus, const char * key); const char *const kSlowioReadCntPath; const char *const kSlowioWriteCntPath; @@ -74,6 +82,11 @@ class SysfsCollector { const char *const kSpeechDspPath; const char *const kBatteryCapacityCC; const char *const kBatteryCapacityVFSOC; + const char *const kUFSLifetimeA; + const char *const kUFSLifetimeB; + const char *const kUFSLifetimeC; + const char *const kF2fsStatsPath; + const char *const kUserdataBlockProp; sp<IStats> stats_; // Proto messages are 1-indexed and VendorAtom field numbers start at 2, so diff --git a/pixelstats/pixelatoms.proto b/pixelstats/pixelatoms.proto index 804a952b..74cd52f4 100644 --- a/pixelstats/pixelatoms.proto +++ b/pixelstats/pixelatoms.proto @@ -37,6 +37,8 @@ enum Ids { CHARGE_STATS = 105000; VOLTAGE_TIER_STATS = 105001; BATTERY_CAPACITY = 105002; + STORAGE_UFS_HEALTH = 105003; + F2FS_STATS = 105004; // AOSP atom ID range ends at 109999 } @@ -128,3 +130,35 @@ message BatteryCapacity { /* Sum of the change in state of charge (battery level). */ optional int32 delta_vfsoc_sum = 3; } + +/* A message containing health values of UFS */ +message StorageUfsHealth { + /* The value of lifetimeA for UFS health */ + optional int32 lifetime_a = 2; + /* The value of lifetimeB for UFS health */ + optional int32 lifetime_b = 3; + /* The value of lifetimeC for UFS health */ + optional int32 lifetime_c = 4; +} + +/* A message containing filesystem stats of F2FS */ +message F2fsStatsInfo { + /* The value of dirty segments of f2fs */ + optional int32 dirty_segments = 2; + /* The value of free segments of f2fs */ + optional int32 free_segments = 3; + /* The times of checkpoint function called in foreground*/ + optional int32 cp_calls_fg = 4; + /* The times of checkpoint function called in background */ + optional int32 cp_calls_bg = 6; + /* The times of garbage collection function called in foreground */ + optional int32 gc_calls_fg = 7; + /* The times of garbage collection function called in background */ + optional int32 gc_calls_bg = 8; + /* The amount of blocks been moved by garbage collection in foreground */ + optional int32 moved_blocks_fg = 9; + /* The amount of blocks been moved by garbage collection in background */ + optional int32 moved_blocks_bg = 10; + /* The average of how many valid blocks is in a segment */ + optional int32 valid_blocks = 11; +} |