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 "PackageInfoResolver.h" 21 #include "ProcDiskStats.h" 22 #include "ProcPidStat.h" 23 #include "ProcStat.h" 24 #include "UidIoStats.h" 25 #include "WatchdogPerfService.h" 26 27 #include <android-base/result.h> 28 #include <cutils/multiuser.h> 29 #include <gtest/gtest_prod.h> 30 #include <utils/Errors.h> 31 #include <utils/Mutex.h> 32 #include <utils/RefBase.h> 33 34 #include <ctime> 35 #include <string> 36 #include <unordered_set> 37 #include <vector> 38 39 namespace android { 40 namespace automotive { 41 namespace watchdog { 42 43 // Number of periodic collection perf data snapshots to cache in memory. 44 const int32_t kDefaultPeriodicCollectionBufferSize = 180; 45 constexpr const char* kEmptyCollectionMessage = "No collection recorded\n"; 46 47 // Performance data collected from the `/proc/uid_io/stats` file. 48 struct UidIoPerfData { 49 struct Stats { 50 userid_t userId = 0; 51 std::string packageName; 52 int64_t bytes[UID_STATES]; 53 int64_t fsync[UID_STATES]; 54 }; 55 std::vector<Stats> topNReads = {}; 56 std::vector<Stats> topNWrites = {}; 57 int64_t total[METRIC_TYPES][UID_STATES] = {{0}}; 58 }; 59 60 std::string toString(const UidIoPerfData& perfData); 61 62 // Performance data collected from the `/proc/stats` file. 63 struct SystemIoPerfData { 64 uint64_t cpuIoWaitTime = 0; 65 uint64_t totalCpuTime = 0; 66 uint32_t ioBlockedProcessesCnt = 0; 67 uint32_t totalProcessesCnt = 0; 68 }; 69 70 std::string toString(const SystemIoPerfData& perfData); 71 72 // Performance data collected from the `/proc/[pid]/stat` and `/proc/[pid]/task/[tid]/stat` files. 73 struct ProcessIoPerfData { 74 struct UidStats { 75 userid_t userId = 0; 76 std::string packageName; 77 uint64_t count = 0; 78 struct ProcessStats { 79 std::string comm = ""; 80 uint64_t count = 0; 81 }; 82 std::vector<ProcessStats> topNProcesses = {}; 83 }; 84 std::vector<UidStats> topNIoBlockedUids = {}; 85 // Total # of tasks owned by each UID in |topNIoBlockedUids|. 86 std::vector<uint64_t> topNIoBlockedUidsTotalTaskCnt = {}; 87 std::vector<UidStats> topNMajorFaultUids = {}; 88 uint64_t totalMajorFaults = 0; 89 // Percentage of increase/decrease in the major page faults since last collection. 90 double majorFaultsPercentChange = 0.0; 91 }; 92 93 std::string toString(const ProcessIoPerfData& data); 94 95 struct IoPerfRecord { 96 time_t time; // Collection time. 97 UidIoPerfData uidIoPerfData; 98 SystemIoPerfData systemIoPerfData; 99 ProcessIoPerfData processIoPerfData; 100 }; 101 102 std::string toString(const IoPerfRecord& record); 103 104 struct CollectionInfo { 105 size_t maxCacheSize = 0; // Maximum cache size for the collection. 106 std::vector<IoPerfRecord> records; // Cache of collected performance records. 107 }; 108 109 std::string toString(const CollectionInfo& collectionInfo); 110 111 // Forward declaration for testing use only. 112 namespace internal { 113 114 class IoPerfCollectionPeer; 115 116 } // namespace internal 117 118 // IoPerfCollection implements the I/O performance data collection module. 119 class IoPerfCollection : public IDataProcessorInterface { 120 public: IoPerfCollection()121 IoPerfCollection() : 122 mTopNStatsPerCategory(0), 123 mTopNStatsPerSubcategory(0), 124 mPackageInfoResolver(PackageInfoResolver::getInstance()), 125 mBoottimeCollection({}), 126 mPeriodicCollection({}), 127 mCustomCollection({}), 128 mLastMajorFaults(0) {} 129 ~IoPerfCollection()130 ~IoPerfCollection() { terminate(); } 131 name()132 std::string name() { return "IoPerfCollection"; } 133 134 // Implements IDataProcessorInterface. 135 android::base::Result<void> onBoottimeCollection(time_t time, 136 const android::wp<UidIoStats>& uidIoStats, 137 const android::wp<ProcStat>& procStat, 138 const android::wp<ProcPidStat>& procPidStat); 139 140 android::base::Result<void> onPeriodicCollection(time_t time, SystemState systemState, 141 const android::wp<UidIoStats>& uidIoStats, 142 const android::wp<ProcStat>& procStat, 143 const android::wp<ProcPidStat>& procPidStat); 144 145 android::base::Result<void> onCustomCollection( 146 time_t time, SystemState systemState, 147 const std::unordered_set<std::string>& filterPackages, 148 const android::wp<UidIoStats>& uidIoStats, const android::wp<ProcStat>& procStat, 149 const android::wp<ProcPidStat>& procPidStat); 150 onPeriodicMonitor(time_t time,const android::wp<IProcDiskStatsInterface> & procDiskStats,const std::function<void ()> & alertHandler)151 android::base::Result<void> onPeriodicMonitor( 152 [[maybe_unused]] time_t time, 153 [[maybe_unused]] const android::wp<IProcDiskStatsInterface>& procDiskStats, 154 [[maybe_unused]] const std::function<void()>& alertHandler) { 155 // No monitoring done here as this DataProcessor only collects I/O performance records. 156 return {}; 157 } 158 159 android::base::Result<void> onDump(int fd); 160 161 android::base::Result<void> onCustomCollectionDump(int fd); 162 163 protected: 164 android::base::Result<void> init(); 165 166 // Clears in-memory cache. 167 void terminate(); 168 169 private: 170 // Processes the collected data. 171 android::base::Result<void> processLocked(time_t time, 172 const std::unordered_set<std::string>& filterPackages, 173 const android::wp<UidIoStats>& uidIoStats, 174 const android::wp<ProcStat>& procStat, 175 const android::wp<ProcPidStat>& procPidStat, 176 CollectionInfo* collectionInfo); 177 178 // Processes performance data from the `/proc/uid_io/stats` file. 179 void processUidIoPerfData(const std::unordered_set<std::string>& filterPackages, 180 const android::wp<UidIoStats>& uidIoStats, 181 UidIoPerfData* uidIoPerfData) const; 182 183 // Processes performance data from the `/proc/stats` file. 184 void processSystemIoPerfData(const android::wp<ProcStat>& procStat, 185 SystemIoPerfData* systemIoPerfData) const; 186 187 // Processes performance data from the `/proc/[pid]/stat` and `/proc/[pid]/task/[tid]/stat` 188 // files. 189 void processProcessIoPerfDataLocked(const std::unordered_set<std::string>& filterPackages, 190 const android::wp<ProcPidStat>& procPidStat, 191 ProcessIoPerfData* processIoPerfData); 192 193 // Top N per-UID stats per category. 194 int mTopNStatsPerCategory; 195 196 // Top N per-process stats per subcategory. 197 int mTopNStatsPerSubcategory; 198 199 // Local IPackageInfoResolver instance. Useful to mock in tests. 200 sp<IPackageInfoResolver> mPackageInfoResolver; 201 202 // Makes sure only one collection is running at any given time. 203 Mutex mMutex; 204 205 // Info for the boot-time collection event. The cache is persisted until system shutdown/reboot. 206 CollectionInfo mBoottimeCollection GUARDED_BY(mMutex); 207 208 // Info for the periodic collection event. The cache size is limited by 209 // |ro.carwatchdog.periodic_collection_buffer_size|. 210 CollectionInfo mPeriodicCollection GUARDED_BY(mMutex); 211 212 // Info for the custom collection event. The info is cleared at the end of every custom 213 // collection. 214 CollectionInfo mCustomCollection GUARDED_BY(mMutex); 215 216 // Major faults delta from last collection. Useful when calculating the percentage change in 217 // major faults since last collection. 218 uint64_t mLastMajorFaults GUARDED_BY(mMutex); 219 220 friend class WatchdogPerfService; 221 222 // For unit tests. 223 friend class internal::IoPerfCollectionPeer; 224 FRIEND_TEST(IoPerfCollectionTest, TestUidIoStatsGreaterThanTopNStatsLimit); 225 FRIEND_TEST(IoPerfCollectionTest, TestUidIOStatsLessThanTopNStatsLimit); 226 FRIEND_TEST(IoPerfCollectionTest, TestProcessSystemIoPerfData); 227 FRIEND_TEST(IoPerfCollectionTest, TestProcPidContentsGreaterThanTopNStatsLimit); 228 FRIEND_TEST(IoPerfCollectionTest, TestProcPidContentsLessThanTopNStatsLimit); 229 }; 230 231 } // namespace watchdog 232 } // namespace automotive 233 } // namespace android 234 235 #endif // CPP_WATCHDOG_SERVER_SRC_IOPERFCOLLECTION_H_ 236