summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOcean Chen <oceanchen@google.com>2019-12-10 17:42:55 +0800
committerThierry Strudel <tstrudel@google.com>2020-02-27 08:26:25 +0000
commit3189ee9aab687cebf898c81b34b07a24a5e9373a (patch)
tree89932be3be24bf0777b15fd121407bd32a63a248
parent0772cc0ef3498f5beffb640377aab1f5f3c3a30e (diff)
downloadpixel-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.cpp141
-rw-r--r--pixelstats/include/pixelstats/SysfsCollector.h13
-rw-r--r--pixelstats/pixelatoms.proto34
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;
+}