1 /** 2 * Copyright (c) 2020, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef CPP_WATCHDOG_SERVER_SRC_IOPERFCOLLECTION_H_ 18 #define CPP_WATCHDOG_SERVER_SRC_IOPERFCOLLECTION_H_ 19 20 #include "ProcDiskStats.h" 21 #include "ProcStat.h" 22 #include "UidStatsCollector.h" 23 #include "WatchdogPerfService.h" 24 25 #include <android-base/result.h> 26 #include <cutils/multiuser.h> 27 #include <gtest/gtest_prod.h> 28 #include <utils/Errors.h> 29 #include <utils/Mutex.h> 30 #include <utils/RefBase.h> 31 32 #include <ctime> 33 #include <string> 34 #include <unordered_set> 35 #include <variant> 36 #include <vector> 37 38 namespace android { 39 namespace automotive { 40 namespace watchdog { 41 42 // Number of periodic collection records to cache in memory. 43 constexpr int32_t kDefaultPeriodicCollectionBufferSize = 180; 44 constexpr const char kEmptyCollectionMessage[] = "No collection recorded\n"; 45 46 // Forward declaration for testing use only. 47 namespace internal { 48 49 class IoPerfCollectionPeer; 50 51 } // namespace internal 52 53 // Below structs should be used only by the implementation and unit tests. 54 /** 55 * Struct to represent user package performance stats. 56 */ 57 struct UserPackageStats { 58 struct IoStats { 59 int64_t bytes[UID_STATES] = {0}; 60 int64_t fsync[UID_STATES] = {0}; 61 totalBytesUserPackageStats::IoStats62 int64_t totalBytes() const { 63 return std::numeric_limits<int64_t>::max() - bytes[UidState::FOREGROUND] > 64 bytes[UidState::BACKGROUND] 65 ? bytes[UidState::FOREGROUND] + bytes[UidState::BACKGROUND] 66 : std::numeric_limits<int64_t>::max(); 67 } 68 }; 69 struct ProcStats { 70 uint64_t count = 0; 71 struct ProcessCount { 72 std::string comm = ""; 73 uint64_t count = 0; 74 }; 75 std::vector<ProcessCount> topNProcesses = {}; 76 }; 77 uid_t uid = 0; 78 std::string genericPackageName = ""; 79 std::variant<std::monostate, IoStats, ProcStats> stats; 80 std::string toString(MetricType metricsType, const int64_t totalIoStats[][UID_STATES]) const; 81 std::string toString(int64_t count) const; 82 }; 83 84 /** 85 * User package summary performance stats collected from the `/proc/uid_io/stats`, 86 * `/proc/[pid]/stat`, `/proc/[pid]/task/[tid]/stat`, and /proc/[pid]/status` files. 87 */ 88 struct UserPackageSummaryStats { 89 std::vector<UserPackageStats> topNIoReads = {}; 90 std::vector<UserPackageStats> topNIoWrites = {}; 91 std::vector<UserPackageStats> topNIoBlocked = {}; 92 std::vector<UserPackageStats> topNMajorFaults = {}; 93 int64_t totalIoStats[METRIC_TYPES][UID_STATES] = {{0}}; 94 std::unordered_map<uid_t, uint64_t> taskCountByUid = {}; 95 uint64_t totalMajorFaults = 0; 96 // Percentage of increase/decrease in the major page faults since last collection. 97 double majorFaultsPercentChange = 0.0; 98 std::string toString() const; 99 }; 100 101 // System performance stats collected from the `/proc/stats` file. 102 struct SystemSummaryStats { 103 uint64_t cpuIoWaitTime = 0; 104 uint64_t totalCpuTime = 0; 105 uint32_t ioBlockedProcessCount = 0; 106 uint32_t totalProcessCount = 0; 107 std::string toString() const; 108 }; 109 110 // Performance record collected during a sampling/collection period. 111 struct PerfStatsRecord { 112 time_t time; // Collection time. 113 SystemSummaryStats systemSummaryStats; 114 UserPackageSummaryStats userPackageSummaryStats; 115 std::string toString() const; 116 }; 117 118 // Group of performance records collected for a collection event. 119 struct CollectionInfo { 120 size_t maxCacheSize = 0; // Maximum cache size for the collection. 121 std::vector<PerfStatsRecord> records; // Cache of collected performance records. 122 std::string toString() const; 123 }; 124 125 // IoPerfCollection implements the I/O performance data collection module. 126 class IoPerfCollection : public IDataProcessorInterface { 127 public: IoPerfCollection()128 IoPerfCollection() : 129 mTopNStatsPerCategory(0), 130 mTopNStatsPerSubcategory(0), 131 mBoottimeCollection({}), 132 mPeriodicCollection({}), 133 mCustomCollection({}), 134 mLastMajorFaults(0) {} 135 ~IoPerfCollection()136 ~IoPerfCollection() { terminate(); } 137 name()138 std::string name() const override { return "IoPerfCollection"; } 139 140 // Implements IDataProcessorInterface. 141 android::base::Result<void> onBoottimeCollection( 142 time_t time, const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 143 const android::wp<ProcStat>& procStat) override; 144 145 android::base::Result<void> onPeriodicCollection( 146 time_t time, SystemState systemState, 147 const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 148 const android::wp<ProcStat>& procStat) override; 149 150 android::base::Result<void> onCustomCollection( 151 time_t time, SystemState systemState, 152 const std::unordered_set<std::string>& filterPackages, 153 const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 154 const android::wp<ProcStat>& procStat) override; 155 156 android::base::Result<void> onPeriodicMonitor( 157 [[maybe_unused]] time_t time, 158 [[maybe_unused]] const android::wp<IProcDiskStatsInterface>& procDiskStats, 159 [[maybe_unused]] const std::function<void()>& alertHandler) override { 160 // No monitoring done here as this DataProcessor only collects I/O performance records. 161 return {}; 162 } 163 164 android::base::Result<void> onDump(int fd) const override; 165 166 android::base::Result<void> onCustomCollectionDump(int fd) override; 167 168 protected: 169 android::base::Result<void> init(); 170 171 // Clears in-memory cache. 172 void terminate(); 173 174 private: 175 // Processes the collected data. 176 android::base::Result<void> processLocked( 177 time_t time, const std::unordered_set<std::string>& filterPackages, 178 const android::sp<UidStatsCollectorInterface>& uidStatsCollector, 179 const android::sp<ProcStat>& procStat, CollectionInfo* collectionInfo); 180 181 // Processes per-UID performance data. 182 void processUidStatsLocked(const std::unordered_set<std::string>& filterPackages, 183 const android::sp<UidStatsCollectorInterface>& uidStatsCollector, 184 UserPackageSummaryStats* userPackageSummaryStats); 185 186 // Processes system performance data from the `/proc/stats` file. 187 void processProcStatLocked(const android::sp<ProcStat>& procStat, 188 SystemSummaryStats* systemSummaryStats) const; 189 190 // Top N per-UID stats per category. 191 int mTopNStatsPerCategory; 192 193 // Top N per-process stats per subcategory. 194 int mTopNStatsPerSubcategory; 195 196 // Makes sure only one collection is running at any given time. 197 mutable Mutex mMutex; 198 199 // Info for the boot-time collection event. The cache is persisted until system shutdown/reboot. 200 CollectionInfo mBoottimeCollection GUARDED_BY(mMutex); 201 202 /** 203 * Info for the periodic collection event. The cache size is limited by 204 * |ro.carwatchdog.periodic_collection_buffer_size|. 205 */ 206 CollectionInfo mPeriodicCollection GUARDED_BY(mMutex); 207 208 /** 209 * Info for the custom collection event. The info is cleared at the end of every custom 210 * collection. 211 */ 212 CollectionInfo mCustomCollection GUARDED_BY(mMutex); 213 214 /** 215 * Major faults delta from last collection. Useful when calculating the percentage change in 216 * major faults since last collection. 217 */ 218 uint64_t mLastMajorFaults GUARDED_BY(mMutex); 219 220 friend class WatchdogPerfService; 221 222 // For unit tests. 223 friend class internal::IoPerfCollectionPeer; 224 }; 225 226 } // namespace watchdog 227 } // namespace automotive 228 } // namespace android 229 230 #endif // CPP_WATCHDOG_SERVER_SRC_IOPERFCOLLECTION_H_ 231