diff options
author | George Lee <geolee@google.com> | 2021-07-22 17:48:25 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-07-22 17:48:25 +0000 |
commit | ea51d987339dd14a20299ee0ab583a865f6fd031 (patch) | |
tree | 357dff48bcf9e3417e310c3107fc398a201ed015 | |
parent | ad63638bdddb67ad33c47f7983c581e96b1cd7a7 (diff) | |
parent | 15f7cbc46e3c5895c8294f0ec2e7c266fdc4e665 (diff) | |
download | pixel-ea51d987339dd14a20299ee0ab583a865f6fd031.tar.gz |
Merge "pixelstats: enable mitigation stats" into sc-dev am: 15f7cbc46e
Original change: https://googleplex-android-review.googlesource.com/c/platform/hardware/google/pixel/+/14985324
Change-Id: I66790d2504eb0e886c54fb29bd49b7dcbf4da31c
-rw-r--r-- | pixelstats/Android.bp | 1 | ||||
-rw-r--r-- | pixelstats/MitigationStatsReporter.cpp | 218 | ||||
-rw-r--r-- | pixelstats/SysfsCollector.cpp | 6 | ||||
-rw-r--r-- | pixelstats/include/pixelstats/MitigationStatsReporter.h | 90 | ||||
-rw-r--r-- | pixelstats/include/pixelstats/SysfsCollector.h | 4 | ||||
-rw-r--r-- | pixelstats/pixelatoms.proto | 56 |
6 files changed, 374 insertions, 1 deletions
diff --git a/pixelstats/Android.bp b/pixelstats/Android.bp index c728a1da..116173ed 100644 --- a/pixelstats/Android.bp +++ b/pixelstats/Android.bp @@ -61,6 +61,7 @@ cc_library { "BatteryEEPROMReporter.cpp", "DropDetect.cpp", "MmMetricsReporter.cpp", + "MitigationStatsReporter.cpp", "OrientationCollector.cpp", "StatsHelper.cpp", "SysfsCollector.cpp", diff --git a/pixelstats/MitigationStatsReporter.cpp b/pixelstats/MitigationStatsReporter.cpp new file mode 100644 index 00000000..82ad15ff --- /dev/null +++ b/pixelstats/MitigationStatsReporter.cpp @@ -0,0 +1,218 @@ +/* + * 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: PowerMitigationStats" + +#include <aidl/android/frameworks/stats/IStats.h> +#include <android-base/file.h> +#include <android-base/parseint.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/MitigationStatsReporter.h> +#include <utils/Log.h> + +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::PowerMitigationStats; + +MitigationStatsReporter::MitigationStatsReporter() {} + +bool MitigationStatsReporter::ReadFileToInt(const std::string &path, int *val) { + std::string file_contents; + + if (!ReadFileToString(path.c_str(), &file_contents)) { + ALOGI("Unable to read %s - %s", path.c_str(), strerror(errno)); + return false; + } else { + file_contents = android::base::Trim(file_contents); + if (!android::base::ParseInt(file_contents, val)) { + ALOGI("Unable to convert %s to int - %s", path.c_str(), strerror(errno)); + return false; + } + } + return true; +} + +void MitigationStatsReporter::logMitigationStatsPerHour(const std::shared_ptr<IStats> &stats_client, + const std::string &path) { + struct MitigationCount last_count = {}; + struct MitigationCap last_cap = {}; + + if (!logMitigationCount(path, &last_count)) + return; + logMitigationCap(path, &last_cap); + + VendorAtomValue tmp; + std::vector<VendorAtomValue> values(24); + tmp.set<VendorAtomValue::intValue>(last_count.batoilo_count - prev_count.batoilo_count); + values[PowerMitigationStats::kBatoiloCountFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_count.vdroop1_count - prev_count.vdroop1_count); + values[PowerMitigationStats::kVdroop1CountFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_count.vdroop2_count - prev_count.vdroop2_count); + values[PowerMitigationStats::kVdroop2CountFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_count.smpl_warn_count - prev_count.smpl_warn_count); + values[PowerMitigationStats::kSmplWarnCountFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_count.ocp_cpu1_count - prev_count.ocp_cpu1_count); + values[PowerMitigationStats::kOcpCpu1CountFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_count.ocp_cpu2_count - prev_count.ocp_cpu2_count); + values[PowerMitigationStats::kOcpCpu2CountFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_count.ocp_gpu_count - prev_count.ocp_gpu_count); + values[PowerMitigationStats::kOcpGpuCountFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_count.ocp_tpu_count - prev_count.ocp_tpu_count); + values[PowerMitigationStats::kOcpTpuCountFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_count.soft_ocp_cpu1_count - + prev_count.soft_ocp_cpu1_count); + values[PowerMitigationStats::kSoftOcpCpu1CountFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_count.soft_ocp_cpu2_count - + prev_count.soft_ocp_cpu2_count); + values[PowerMitigationStats::kSoftOcpCpu2CountFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_count.soft_ocp_gpu_count - + prev_count.soft_ocp_gpu_count); + values[PowerMitigationStats::kSoftOcpGpuCountFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_count.soft_ocp_tpu_count - + prev_count.soft_ocp_tpu_count); + values[PowerMitigationStats::kSoftOcpTpuCountFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_cap.batoilo_cap); + values[PowerMitigationStats::kBatoiloCapFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_cap.vdroop1_cap); + values[PowerMitigationStats::kVdroop1CapFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_cap.vdroop2_cap); + values[PowerMitigationStats::kVdroop2CapFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_cap.smpl_warn_cap); + values[PowerMitigationStats::kSmplWarnCapFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_cap.ocp_cpu1_cap); + values[PowerMitigationStats::kOcpCpu1CapFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_cap.ocp_cpu2_cap); + values[PowerMitigationStats::kOcpCpu2CapFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_cap.ocp_gpu_cap); + values[PowerMitigationStats::kOcpGpuCapFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_cap.ocp_tpu_cap); + values[PowerMitigationStats::kOcpTpuCapFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_cap.soft_ocp_cpu1_cap); + values[PowerMitigationStats::kSoftOcpCpu1CapFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_cap.soft_ocp_cpu2_cap); + values[PowerMitigationStats::kSoftOcpCpu2CapFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_cap.soft_ocp_gpu_cap); + values[PowerMitigationStats::kSoftOcpGpuCapFieldNumber - kVendorAtomOffset] = tmp; + tmp.set<VendorAtomValue::intValue>(last_cap.soft_ocp_tpu_cap); + values[PowerMitigationStats::kSoftOcpTpuCapFieldNumber - kVendorAtomOffset] = tmp; + + prev_count = last_count; + // Send vendor atom to IStats HAL + VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(), + .atomId = PixelAtoms::Atom::kMitigationStats, + .values = std::move(values)}; + const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event); + if (!ret.isOk()) + ALOGE("Unable to report to Stats service"); +} + +void MitigationStatsReporter::logMitigationCap(const std::string kMitigationDir, + struct MitigationCap *last_cap) { + ReadFileToInt(kMitigationDir + "/last_triggered_capacity/batoilo_cap", + &(last_cap->batoilo_cap)); + ReadFileToInt(kMitigationDir + "/last_triggered_capacity/ocp_cpu1_cap", + &(last_cap->ocp_cpu1_cap)); + ReadFileToInt(kMitigationDir + "/last_triggered_capacity/ocp_cpu2_cap", + &(last_cap->ocp_cpu2_cap)); + ReadFileToInt(kMitigationDir + "/last_triggered_capacity/ocp_gpu_cap", + &(last_cap->ocp_gpu_cap)); + ReadFileToInt(kMitigationDir + "/last_triggered_capacity/ocp_tpu_cap", + &(last_cap->ocp_tpu_cap)); + ReadFileToInt(kMitigationDir + "/last_triggered_capacity/smpl_warn_cap", + &(last_cap->smpl_warn_cap)); + ReadFileToInt(kMitigationDir + "/last_triggered_capacity/soft_ocp_cpu1_cap", + &(last_cap->soft_ocp_cpu1_cap)); + ReadFileToInt(kMitigationDir + "/last_triggered_capacity/soft_ocp_cpu2_cap", + &(last_cap->soft_ocp_cpu2_cap)); + ReadFileToInt(kMitigationDir + "/last_triggered_capacity/soft_ocp_gpu_cap", + &(last_cap->soft_ocp_gpu_cap)); + ReadFileToInt(kMitigationDir + "/last_triggered_capacity/soft_ocp_tpu_cap", + &(last_cap->soft_ocp_tpu_cap)); + ReadFileToInt(kMitigationDir + "/last_triggered_capacity/vdroop1_cap", + &(last_cap->vdroop1_cap)); + ReadFileToInt(kMitigationDir + "/last_triggered_capacity/vdroop2_cap", + &(last_cap->vdroop2_cap)); +} + +bool MitigationStatsReporter::logMitigationCount(const std::string kMitigationDir, + struct MitigationCount *last_count) { + bool send_stats = false; + if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/batoilo_count", + &(last_count->batoilo_count))) + return false; + send_stats |= (last_count->batoilo_count - prev_count.batoilo_count) > 0; + if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/ocp_cpu1_count", + &(last_count->ocp_cpu1_count))) + return false; + send_stats |= (last_count->ocp_cpu1_count - prev_count.ocp_cpu1_count) > 0; + if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/ocp_cpu2_count", + &(last_count->ocp_cpu2_count))) + return false; + send_stats |= (last_count->ocp_cpu2_count - prev_count.ocp_cpu2_count) > 0; + if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/ocp_gpu_count", + &(last_count->ocp_gpu_count))) + return false; + send_stats |= (last_count->ocp_gpu_count - prev_count.ocp_gpu_count) > 0; + if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/ocp_tpu_count", + &(last_count->ocp_tpu_count))) + return false; + send_stats |= (last_count->ocp_tpu_count - prev_count.ocp_tpu_count) > 0; + if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/smpl_warn_count", + &(last_count->smpl_warn_count))) + return false; + send_stats |= (last_count->smpl_warn_count - prev_count.smpl_warn_count) > 0; + if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/soft_ocp_cpu1_count", + &(last_count->soft_ocp_cpu1_count))) + return false; + send_stats |= (last_count->soft_ocp_cpu1_count - prev_count.soft_ocp_cpu1_count) > 0; + if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/soft_ocp_cpu2_count", + &(last_count->soft_ocp_cpu2_count))) + return false; + send_stats |= (last_count->soft_ocp_cpu2_count - prev_count.soft_ocp_cpu2_count) > 0; + if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/soft_ocp_gpu_count", + &(last_count->soft_ocp_gpu_count))) + return false; + send_stats |= (last_count->soft_ocp_gpu_count - prev_count.soft_ocp_gpu_count) > 0; + if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/soft_ocp_tpu_count", + &(last_count->soft_ocp_tpu_count))) + return false; + send_stats |= (last_count->soft_ocp_tpu_count - prev_count.soft_ocp_tpu_count) > 0; + if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/vdroop1_count", + &(last_count->vdroop1_count))) + return false; + send_stats |= (last_count->vdroop1_count - prev_count.vdroop1_count) > 0; + if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/vdroop2_count", + &(last_count->vdroop2_count))) + return false; + send_stats |= (last_count->vdroop2_count - prev_count.vdroop2_count) > 0; + return send_stats; +} + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android diff --git a/pixelstats/SysfsCollector.cpp b/pixelstats/SysfsCollector.cpp index 584097a6..8b002d02 100644 --- a/pixelstats/SysfsCollector.cpp +++ b/pixelstats/SysfsCollector.cpp @@ -76,7 +76,8 @@ SysfsCollector::SysfsCollector(const struct SysfsPaths &sysfs_paths) kF2fsStatsPath(sysfs_paths.F2fsStatsPath), kZramMmStatPath("/sys/block/zram0/mm_stat"), kZramBdStatPath("/sys/block/zram0/bd_stat"), - kEEPROMPath(sysfs_paths.EEPROMPath) {} + kEEPROMPath(sysfs_paths.EEPROMPath), + kPowerMitigationStatsPath(sysfs_paths.MitigationPath) {} bool SysfsCollector::ReadFileToInt(const std::string &path, int *val) { return ReadFileToInt(path.c_str(), val); @@ -813,6 +814,9 @@ void SysfsCollector::logPerHour() { return; } mm_metrics_reporter_.logPixelMmMetricsPerHour(stats_client); + if (kPowerMitigationStatsPath != nullptr && strlen(kPowerMitigationStatsPath) > 0) + mitigation_stats_reporter_.logMitigationStatsPerHour(stats_client, + kPowerMitigationStatsPath); } /** diff --git a/pixelstats/include/pixelstats/MitigationStatsReporter.h b/pixelstats/include/pixelstats/MitigationStatsReporter.h new file mode 100644 index 00000000..219cfa8a --- /dev/null +++ b/pixelstats/include/pixelstats/MitigationStatsReporter.h @@ -0,0 +1,90 @@ +/* + * 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_MITIGATIONSTATSREPORTER_H +#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_MITIGATIONSTATSREPORTER_H + +#include <map> +#include <string> + +#include <aidl/android/frameworks/stats/IStats.h> +#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h> + +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 Mitigation Stats metrics + */ +class MitigationStatsReporter { + public: + MitigationStatsReporter(); + void logMitigationStatsPerHour(const std::shared_ptr<IStats> &stats_client, + const std::string &path); + + private: + struct MitigationCount { + int batoilo_count; + int vdroop1_count; + int vdroop2_count; + int smpl_warn_count; + int ocp_cpu1_count; + int ocp_cpu2_count; + int ocp_tpu_count; + int ocp_gpu_count; + int soft_ocp_cpu1_count; + int soft_ocp_cpu2_count; + int soft_ocp_tpu_count; + int soft_ocp_gpu_count; + }; + + struct MitigationCap { + int batoilo_cap; + int vdroop1_cap; + int vdroop2_cap; + int smpl_warn_cap; + int ocp_cpu1_cap; + int ocp_cpu2_cap; + int ocp_tpu_cap; + int ocp_gpu_cap; + int soft_ocp_cpu1_cap; + int soft_ocp_cpu2_cap; + int soft_ocp_tpu_cap; + int soft_ocp_gpu_cap; + }; + + // 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; + struct MitigationCount prev_count; + + bool logMitigationCount(const std::string kMitigationDir, struct MitigationCount *last_count); + void logMitigationCap(const std::string kMitigationDir, struct MitigationCap *last_cap); + bool ReadFileToInt(const std::string &path, int *val); +}; + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android + +#endif // HARDWARE_GOOGLE_PIXEL_PIXELSTATS_MITIGATIONSTATSREPORTER_H diff --git a/pixelstats/include/pixelstats/SysfsCollector.h b/pixelstats/include/pixelstats/SysfsCollector.h index d92e751f..8045d4aa 100644 --- a/pixelstats/include/pixelstats/SysfsCollector.h +++ b/pixelstats/include/pixelstats/SysfsCollector.h @@ -20,6 +20,7 @@ #include <aidl/android/frameworks/stats/IStats.h> #include <hardware/google/pixel/pixelstats/pixelatoms.pb.h> #include "BatteryEEPROMReporter.h" +#include "MitigationStatsReporter.h" #include "MmMetricsReporter.h" namespace android { @@ -53,6 +54,7 @@ class SysfsCollector { const char *const ZramMmStatPath; const char *const ZramBdStatPath; const char *const EEPROMPath; + const char *const MitigationPath; }; SysfsCollector(const struct SysfsPaths &paths); @@ -105,9 +107,11 @@ class SysfsCollector { const char *const kZramMmStatPath; const char *const kZramBdStatPath; const char *const kEEPROMPath; + const char *const kPowerMitigationStatsPath; BatteryEEPROMReporter battery_EEPROM_reporter_; MmMetricsReporter mm_metrics_reporter_; + MitigationStatsReporter mitigation_stats_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 diff --git a/pixelstats/pixelatoms.proto b/pixelstats/pixelatoms.proto index 90b9c338..1e6b0ebb 100644 --- a/pixelstats/pixelatoms.proto +++ b/pixelstats/pixelatoms.proto @@ -64,6 +64,7 @@ message Atom { VendorBatteryHealthSnapshot vendor_battery_health_snapshot = 105026; // moved from atoms.proto VendorBatteryCausedShutdown vendor_battery_caused_shutdown = 105027; // moved from atoms.proto F2fsGcSegmentInfo f2fs_gc_segment_info = 105028; + PowerMitigationStats mitigation_stats = 105029; // moved from atoms.proto CitadelVersion citadel_version = 100018; // moved from vendor proprietary CitadelEvent citadel_event = 100019; // moved from vendor proprietary @@ -702,6 +703,61 @@ message VendorBatteryCausedShutdown { } /** + * Log mitigation statistics. + */ +message PowerMitigationStats { + optional string reverse_domain_name = 1; + // The last triggered count: batoilo. + optional int32 batoilo_count = 2; + // The last triggered count: vdroop1. + optional int32 vdroop1_count = 3; + // The last triggered count: vdroop2. + optional int32 vdroop2_count = 4; + // The last triggered count: smpl_warn. + optional int32 smpl_warn_count = 5; + // The last triggered count: ocp_cpu1. + optional int32 ocp_cpu1_count = 6; + // The last triggered count: ocp_cpu2. + optional int32 ocp_cpu2_count = 7; + // The last triggered count: ocp_gpu. + optional int32 ocp_gpu_count = 8; + // The last triggered count: ocp_tpu. + optional int32 ocp_tpu_count = 9; + // The last triggered count: soft_ocp_cpu1. + optional int32 soft_ocp_cpu1_count = 10; + // The last triggered count: soft_ocp_cpu2. + optional int32 soft_ocp_cpu2_count = 11; + // The last triggered count: soft_ocp_gpu. + optional int32 soft_ocp_gpu_count = 12; + // The last triggered count: soft_ocp_tpu. + optional int32 soft_ocp_tpu_count = 13; + // The last triggered capacity: batoilo. + optional int32 batoilo_cap = 14; + // The last triggered capacity: vdroop1. + optional int32 vdroop1_cap = 15; + // The last triggered capacity: vdroop2. + optional int32 vdroop2_cap = 16; + // The last triggered capacity: smpl_warn. + optional int32 smpl_warn_cap = 17; + // The last triggered capacity: ocp_cpu1. + optional int32 ocp_cpu1_cap = 18; + // The last triggered capacity: ocp_cpu2. + optional int32 ocp_cpu2_cap = 19; + // The last triggered capacity: ocp_gpu. + optional int32 ocp_gpu_cap = 20; + // The last triggered capacity: ocp_tpu. + optional int32 ocp_tpu_cap = 21; + // The last triggered capacity: soft_ocp_cpu1. + optional int32 soft_ocp_cpu1_cap = 22; + // The last triggered capacity: soft_ocp_cpu2. + optional int32 soft_ocp_cpu2_cap = 23; + // The last triggered capacity: soft_ocp_gpu. + optional int32 soft_ocp_gpu_cap = 24; + // The last triggered capacity: soft_ocp_tpu. + optional int32 soft_ocp_tpu_cap = 25; +} + +/** * Log how many segments have been reclaimed in a specific GC mode. */ message F2fsGcSegmentInfo { |