1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef MEMORY_DATA_PLUGIN_H 17 #define MEMORY_DATA_PLUGIN_H 18 19 #include <algorithm> 20 #include <dirent.h> 21 #include <fcntl.h> 22 #include <inttypes.h> 23 #include <iomanip> 24 #include <string> 25 #include <sys/stat.h> 26 #include <sys/types.h> 27 #include <unistd.h> 28 #include <unordered_map> 29 #include <utility> 30 31 #include "logging.h" 32 #include "memory_plugin_config.pb.h" 33 #include "memory_plugin_result.pb.h" 34 #include "smaps_stats.h" 35 36 struct Proto2StrMapping { 37 int protobufid; 38 const char* procstr; 39 }; 40 41 constexpr Proto2StrMapping meminfoMapping[] = { 42 {SysMeminfoType::PMEM_UNSPECIFIED, "MemUnspecified"}, 43 {SysMeminfoType::PMEM_MEM_TOTAL, "MemTotal"}, 44 {SysMeminfoType::PMEM_MEM_FREE, "MemFree"}, 45 {SysMeminfoType::PMEM_MEM_AVAILABLE, "MemAvailable"}, 46 {SysMeminfoType::PMEM_BUFFERS, "Buffers"}, 47 {SysMeminfoType::PMEM_CACHED, "Cached"}, 48 {SysMeminfoType::PMEM_SWAP_CACHED, "SwapCached"}, 49 {SysMeminfoType::PMEM_ACTIVE, "Active"}, 50 {SysMeminfoType::PMEM_INACTIVE, "Inactive"}, 51 {SysMeminfoType::PMEM_ACTIVE_ANON, "Active(anon)"}, 52 {SysMeminfoType::PMEM_INACTIVE_ANON, "Inactive(anon)"}, 53 {SysMeminfoType::PMEM_ACTIVE_FILE, "Active(file)"}, 54 {SysMeminfoType::PMEM_INACTIVE_FILE, "Inactive(file)"}, 55 {SysMeminfoType::PMEM_UNEVICTABLE, "Unevictable"}, 56 {SysMeminfoType::PMEM_MLOCKED, "Mlocked"}, 57 {SysMeminfoType::PMEM_SWAP_TOTAL, "SwapTotal"}, 58 {SysMeminfoType::PMEM_SWAP_FREE, "SwapFree"}, 59 {SysMeminfoType::PMEM_DIRTY, "Dirty"}, 60 {SysMeminfoType::PMEM_WRITEBACK, "Writeback"}, 61 {SysMeminfoType::PMEM_ANON_PAGES, "AnonPages"}, 62 {SysMeminfoType::PMEM_MAPPED, "Mapped"}, 63 {SysMeminfoType::PMEM_SHMEM, "Shmem"}, 64 {SysMeminfoType::PMEM_SLAB, "Slab"}, 65 {SysMeminfoType::PMEM_SLAB_RECLAIMABLE, "SReclaimable"}, 66 {SysMeminfoType::PMEM_SLAB_UNRECLAIMABLE, "SUnreclaim"}, 67 {SysMeminfoType::PMEM_KERNEL_STACK, "KernelStack"}, 68 {SysMeminfoType::PMEM_PAGE_TABLES, "PageTables"}, 69 {SysMeminfoType::PMEM_COMMIT_LIMIT, "CommitLimit"}, 70 {SysMeminfoType::PMEM_COMMITED_AS, "Committed_AS"}, 71 {SysMeminfoType::PMEM_VMALLOC_TOTAL, "VmallocTotal"}, 72 {SysMeminfoType::PMEM_VMALLOC_USED, "VmallocUsed"}, 73 {SysMeminfoType::PMEM_VMALLOC_CHUNK, "VmallocChunk"}, 74 {SysMeminfoType::PMEM_CMA_TOTAL, "CmaTotal"}, 75 {SysMeminfoType::PMEM_CMA_FREE, "CmaFree"}, 76 {SysMeminfoType::PMEM_KERNEL_RECLAIMABLE, "KReclaimable"}, 77 }; 78 79 constexpr Proto2StrMapping vmeminfoMapping[] = { 80 {SysVMeminfoType::VMEMINFO_UNSPECIFIED, "unspecified"}, 81 {SysVMeminfoType::VMEMINFO_NR_FREE_PAGES, "nr_free_pages"}, 82 {SysVMeminfoType::VMEMINFO_NR_ALLOC_BATCH, "nr_alloc_batch"}, 83 {SysVMeminfoType::VMEMINFO_NR_INACTIVE_ANON, "nr_inactive_anon"}, 84 {SysVMeminfoType::VMEMINFO_NR_ACTIVE_ANON, "nr_active_anon"}, 85 {SysVMeminfoType::VMEMINFO_NR_INACTIVE_FILE, "nr_inactive_file"}, 86 {SysVMeminfoType::VMEMINFO_NR_ACTIVE_FILE, "nr_active_file"}, 87 {SysVMeminfoType::VMEMINFO_NR_UNEVICTABLE, "nr_unevictable"}, 88 {SysVMeminfoType::VMEMINFO_NR_MLOCK, "nr_mlock"}, 89 {SysVMeminfoType::VMEMINFO_NR_ANON_PAGES, "nr_anon_pages"}, 90 {SysVMeminfoType::VMEMINFO_NR_MAPPED, "nr_mapped"}, 91 {SysVMeminfoType::VMEMINFO_NR_FILE_PAGES, "nr_file_pages"}, 92 {SysVMeminfoType::VMEMINFO_NR_DIRTY, "nr_dirty"}, 93 {SysVMeminfoType::VMEMINFO_NR_WRITEBACK, "nr_writeback"}, 94 {SysVMeminfoType::VMEMINFO_NR_SLAB_RECLAIMABLE, "nr_slab_reclaimable"}, 95 {SysVMeminfoType::VMEMINFO_NR_SLAB_UNRECLAIMABLE, "nr_slab_unreclaimable"}, 96 {SysVMeminfoType::VMEMINFO_NR_PAGE_TABLE_PAGES, "nr_page_table_pages"}, 97 {SysVMeminfoType::VMEMINFO_NR_KERNEL_STACK, "nr_kernel_stack"}, 98 {SysVMeminfoType::VMEMINFO_NR_OVERHEAD, "nr_overhead"}, 99 {SysVMeminfoType::VMEMINFO_NR_UNSTABLE, "nr_unstable"}, 100 {SysVMeminfoType::VMEMINFO_NR_BOUNCE, "nr_bounce"}, 101 {SysVMeminfoType::VMEMINFO_NR_VMSCAN_WRITE, "nr_vmscan_write"}, 102 {SysVMeminfoType::VMEMINFO_NR_VMSCAN_IMMEDIATE_RECLAIM, "nr_vmscan_immediate_reclaim"}, 103 {SysVMeminfoType::VMEMINFO_NR_WRITEBACK_TEMP, "nr_writeback_temp"}, 104 {SysVMeminfoType::VMEMINFO_NR_ISOLATED_ANON, "nr_isolated_anon"}, 105 {SysVMeminfoType::VMEMINFO_NR_ISOLATED_FILE, "nr_isolated_file"}, 106 {SysVMeminfoType::VMEMINFO_NR_SHMEM, "nr_shmem"}, 107 {SysVMeminfoType::VMEMINFO_NR_DIRTIED, "nr_dirtied"}, 108 {SysVMeminfoType::VMEMINFO_NR_WRITTEN, "nr_written"}, 109 {SysVMeminfoType::VMEMINFO_NR_PAGES_SCANNED, "nr_pages_scanned"}, 110 {SysVMeminfoType::VMEMINFO_WORKINGSET_REFAULT, "workingset_refault"}, 111 {SysVMeminfoType::VMEMINFO_WORKINGSET_ACTIVATE, "workingset_activate"}, 112 {SysVMeminfoType::VMEMINFO_WORKINGSET_NODERECLAIM, "workingset_nodereclaim"}, 113 {SysVMeminfoType::VMEMINFO_NR_ANON_TRANSPARENT_HUGEPAGES, "nr_anon_transparent_hugepages"}, 114 {SysVMeminfoType::VMEMINFO_NR_FREE_CMA, "nr_free_cma"}, 115 {SysVMeminfoType::VMEMINFO_NR_SWAPCACHE, "nr_swapcache"}, 116 {SysVMeminfoType::VMEMINFO_NR_DIRTY_THRESHOLD, "nr_dirty_threshold"}, 117 {SysVMeminfoType::VMEMINFO_NR_DIRTY_BACKGROUND_THRESHOLD, "nr_dirty_background_threshold"}, 118 {SysVMeminfoType::VMEMINFO_PGPGIN, "pgpgin"}, 119 {SysVMeminfoType::VMEMINFO_PGPGOUT, "pgpgout"}, 120 {SysVMeminfoType::VMEMINFO_PGPGOUTCLEAN, "pgpgoutclean"}, 121 {SysVMeminfoType::VMEMINFO_PSWPIN, "pswpin"}, 122 {SysVMeminfoType::VMEMINFO_PSWPOUT, "pswpou"}, 123 {SysVMeminfoType::VMEMINFO_PGALLOC_DMA, "pgalloc_dma"}, 124 {SysVMeminfoType::VMEMINFO_PGALLOC_NORMAL, "pgalloc_normal"}, 125 {SysVMeminfoType::VMEMINFO_PGALLOC_MOVABLE, "pgalloc_movable"}, 126 {SysVMeminfoType::VMEMINFO_PGFREE, "pgfree"}, 127 {SysVMeminfoType::VMEMINFO_PGACTIVATE, "pgactivate"}, 128 {SysVMeminfoType::VMEMINFO_PGDEACTIVATE, "pgdeactivate"}, 129 {SysVMeminfoType::VMEMINFO_PGFAULT, "pgfault"}, 130 {SysVMeminfoType::VMEMINFO_PGMAJFAULT, "pgmajfault"}, 131 {SysVMeminfoType::VMEMINFO_PGREFILL_DMA, "pgrefill_dma"}, 132 {SysVMeminfoType::VMEMINFO_PGREFILL_NORMAL, "pgrefill_normal"}, 133 {SysVMeminfoType::VMEMINFO_PGREFILL_MOVABLE, "pgrefill_movable"}, 134 {SysVMeminfoType::VMEMINFO_PGSTEAL_KSWAPD_DMA, "pgsteal_kswapd_dma"}, 135 {SysVMeminfoType::VMEMINFO_PGSTEAL_KSWAPD_NORMAL, "pgsteal_kswapd_normal"}, 136 {SysVMeminfoType::VMEMINFO_PGSTEAL_KSWAPD_MOVABLE, "pgsteal_kswapd_movable"}, 137 {SysVMeminfoType::VMEMINFO_PGSTEAL_DIRECT_DMA, "pgsteal_direct_dma"}, 138 {SysVMeminfoType::VMEMINFO_PGSTEAL_DIRECT_NORMAL, "pgsteal_direct_normal"}, 139 {SysVMeminfoType::VMEMINFO_PGSTEAL_DIRECT_MOVABLE, "pgsteal_direct_movable"}, 140 {SysVMeminfoType::VMEMINFO_PGSCAN_KSWAPD_DMA, "pgscan_kswapd_dma"}, 141 {SysVMeminfoType::VMEMINFO_PGSCAN_KSWAPD_NORMAL, "pgscan_kswapd_normal"}, 142 {SysVMeminfoType::VMEMINFO_PGSCAN_KSWAPD_MOVABLE, "pgscan_kswapd_movable"}, 143 {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT_DMA, "pgscan_direct_dma"}, 144 {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT_NORMAL, "pgscan_direct_normal"}, 145 {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT_MOVABLE, "pgscan_direct_movable"}, 146 {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT_THROTTLE, "pgscan_direct_throttle"}, 147 {SysVMeminfoType::VMEMINFO_PGINODESTEAL, "pginodesteal"}, 148 {SysVMeminfoType::VMEMINFO_SLABS_SCANNED, "slabs_scanned"}, 149 {SysVMeminfoType::VMEMINFO_KSWAPD_INODESTEAL, "kswapd_inodesteal"}, 150 {SysVMeminfoType::VMEMINFO_KSWAPD_LOW_WMARK_HIT_QUICKLY, "kswapd_low_wmark_hit_quickly"}, 151 {SysVMeminfoType::VMEMINFO_KSWAPD_HIGH_WMARK_HIT_QUICKLY, "kswapd_high_wmark_hit_quickly"}, 152 {SysVMeminfoType::VMEMINFO_PAGEOUTRUN, "pageoutrun"}, 153 {SysVMeminfoType::VMEMINFO_ALLOCSTALL, "allocstall"}, 154 {SysVMeminfoType::VMEMINFO_PGROTATED, "pgrotated"}, 155 {SysVMeminfoType::VMEMINFO_DROP_PAGECACHE, "drop_pagecache"}, 156 {SysVMeminfoType::VMEMINFO_DROP_SLAB, "drop_slab"}, 157 {SysVMeminfoType::VMEMINFO_PGMIGRATE_SUCCESS, "pgmigrate_success"}, 158 {SysVMeminfoType::VMEMINFO_PGMIGRATE_FAIL, "pgmigrate_fail"}, 159 {SysVMeminfoType::VMEMINFO_COMPACT_MIGRATE_SCANNED, "compact_migrate_scanned"}, 160 {SysVMeminfoType::VMEMINFO_COMPACT_FREE_SCANNED, "compact_free_scanned"}, 161 {SysVMeminfoType::VMEMINFO_COMPACT_ISOLATED, "compact_isolated"}, 162 {SysVMeminfoType::VMEMINFO_COMPACT_STALL, "compact_stall"}, 163 {SysVMeminfoType::VMEMINFO_COMPACT_FAIL, "compact_fail"}, 164 {SysVMeminfoType::VMEMINFO_COMPACT_SUCCESS, "compact_success"}, 165 {SysVMeminfoType::VMEMINFO_COMPACT_DAEMON_WAKE, "compact_daemon_wake"}, 166 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_CULLED, "unevictable_pgs_culled"}, 167 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_SCANNED, "unevictable_pgs_scanned"}, 168 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_RESCUED, "unevictable_pgs_rescued"}, 169 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_MLOCKED, "unevictable_pgs_mlocked"}, 170 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_MUNLOCKED, "unevictable_pgs_munlocked"}, 171 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_CLEARED, "unevictable_pgs_cleared"}, 172 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_STRANDED, "unevictable_pgs_stranded"}, 173 {SysVMeminfoType::VMEMINFO_NR_ZSPAGES, "nr_zspages"}, 174 {SysVMeminfoType::VMEMINFO_NR_ION_HEAP, "nr_ion_heap"}, 175 {SysVMeminfoType::VMEMINFO_NR_GPU_HEAP, "nr_gpu_heap"}, 176 {SysVMeminfoType::VMEMINFO_ALLOCSTALL_DMA, "allocstall_dma"}, 177 {SysVMeminfoType::VMEMINFO_ALLOCSTALL_MOVABLE, "allocstall_movable"}, 178 {SysVMeminfoType::VMEMINFO_ALLOCSTALL_NORMAL, "allocstall_normal"}, 179 {SysVMeminfoType::VMEMINFO_COMPACT_DAEMON_FREE_SCANNED, "compact_daemon_free_scanned"}, 180 {SysVMeminfoType::VMEMINFO_COMPACT_DAEMON_MIGRATE_SCANNED, "compact_daemon_migrate_scanned"}, 181 {SysVMeminfoType::VMEMINFO_NR_FASTRPC, "nr_fastrpc"}, 182 {SysVMeminfoType::VMEMINFO_NR_INDIRECTLY_RECLAIMABLE, "nr_indirectly_reclaimable"}, 183 {SysVMeminfoType::VMEMINFO_NR_ION_HEAP_POOL, "nr_ion_heap_pool"}, 184 {SysVMeminfoType::VMEMINFO_NR_KERNEL_MISC_RECLAIMABLE, "nr_kernel_misc_reclaimable"}, 185 {SysVMeminfoType::VMEMINFO_NR_SHADOW_CALL_STACK_BYTES, "nr_shadow_call_stack_bytes"}, 186 {SysVMeminfoType::VMEMINFO_NR_SHMEM_HUGEPAGES, "nr_shmem_hugepages"}, 187 {SysVMeminfoType::VMEMINFO_NR_SHMEM_PMDMAPPED, "nr_shmem_pmdmapped"}, 188 {SysVMeminfoType::VMEMINFO_NR_UNRECLAIMABLE_PAGES, "nr_unreclaimable_pages"}, 189 {SysVMeminfoType::VMEMINFO_NR_ZONE_ACTIVE_ANON, "nr_zone_active_anon"}, 190 {SysVMeminfoType::VMEMINFO_NR_ZONE_ACTIVE_FILE, "nr_zone_active_file"}, 191 {SysVMeminfoType::VMEMINFO_NR_ZONE_INACTIVE_ANON, "nr_zone_inactive_anon"}, 192 {SysVMeminfoType::VMEMINFO_NR_ZONE_INACTIVE_FILE, "nr_zone_inactive_file"}, 193 {SysVMeminfoType::VMEMINFO_NR_ZONE_UNEVICTABLE, "nr_zone_unevictable"}, 194 {SysVMeminfoType::VMEMINFO_NR_ZONE_WRITE_PENDING, "nr_zone_write_pending"}, 195 {SysVMeminfoType::VMEMINFO_OOM_KILL, "oom_kill"}, 196 {SysVMeminfoType::VMEMINFO_PGLAZYFREE, "pglazyfree"}, 197 {SysVMeminfoType::VMEMINFO_PGLAZYFREED, "pglazyfreed"}, 198 {SysVMeminfoType::VMEMINFO_PGREFILL, "pgrefill"}, 199 {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT, "pgscan_direct"}, 200 {SysVMeminfoType::VMEMINFO_PGSCAN_KSWAPD, "pgscan_kswapd"}, 201 {SysVMeminfoType::VMEMINFO_PGSKIP_DMA, "pgskip_dma"}, 202 {SysVMeminfoType::VMEMINFO_PGSKIP_MOVABLE, "pgskip_movable"}, 203 {SysVMeminfoType::VMEMINFO_PGSKIP_NORMAL, "pgskip_normal"}, 204 {SysVMeminfoType::VMEMINFO_PGSTEAL_DIRECT, "pgsteal_direct"}, 205 {SysVMeminfoType::VMEMINFO_PGSTEAL_KSWAPD, "pgsteal_kswapd"}, 206 {SysVMeminfoType::VMEMINFO_SWAP_RA, "swap_ra"}, 207 {SysVMeminfoType::VMEMINFO_SWAP_RA_HIT, "swap_ra_hit"}, 208 {SysVMeminfoType::VMEMINFO_WORKINGSET_RESTORE, "workingset_restore"}, 209 }; 210 211 struct ProcStatusMapping { 212 int procid; 213 const char* procstr; 214 }; 215 216 enum StatusType { 217 PRO_TGID = 1, 218 PRO_NAME, 219 PRO_VMSIZE, 220 PRO_VMRSS, 221 PRO_RSSANON, 222 PRO_RSSFILE, 223 PRO_RSSSHMEM, 224 PRO_VMSWAP, 225 PRO_VMLCK, 226 PRO_VMHWM, 227 }; 228 229 constexpr ProcStatusMapping procStatusMapping[] = { 230 {StatusType::PRO_TGID, "Tgid"}, {StatusType::PRO_NAME, "Name"}, {StatusType::PRO_VMSIZE, "VmSize"}, 231 {StatusType::PRO_VMRSS, "VmRSS"}, {StatusType::PRO_RSSANON, "RssAnon"}, {StatusType::PRO_RSSFILE, "RssFile"}, 232 {StatusType::PRO_RSSSHMEM, "RssShmem"}, {StatusType::PRO_VMSWAP, "VmSwap"}, {StatusType::PRO_VMLCK, "VmLck"}, 233 {StatusType::PRO_VMHWM, "VmHWM"}, 234 }; 235 236 enum ErrorType { 237 RET_NULL_ADDR, 238 RET_IVALID_PID, 239 RET_TGID_VALUE_NULL, 240 RET_FAIL = -1, 241 RET_SUCC = 0, 242 }; 243 244 enum FileType { 245 FILE_STATUS = 0, 246 FILE_OOM, 247 FILE_SMAPS, 248 }; 249 250 struct ProcfdMapping { 251 int procid; 252 const char* file; 253 }; 254 255 constexpr ProcfdMapping procfdMapping[] = { 256 {FileType::FILE_STATUS, "status"}, 257 {FileType::FILE_OOM, "oom_score_adj"}, 258 {FileType::FILE_SMAPS, "smaps"}, 259 }; 260 261 class MemoryDataPlugin { 262 public: 263 MemoryDataPlugin(); 264 ~MemoryDataPlugin(); 265 int Start(const uint8_t* configData, uint32_t configSize); 266 int Report(uint8_t* configData, uint32_t configSize); 267 int Stop(); SetPath(char * path)268 void SetPath(char* path) 269 { 270 testpath_ = path; 271 }; 272 void WriteProcesseList(MemoryData& data); 273 void WriteProcinfoByPidfds(ProcessMemoryInfo* processinfo, int32_t pid); 274 DIR* OpenDestDir(const char* dirPath); 275 int32_t GetValidPid(DIR* dirp); 276 // for test change static 277 int ParseNumber(std::string line); 278 279 private: 280 /* data */ 281 MemoryConfig protoConfig_; 282 283 std::unique_ptr<uint8_t[]> buffer_; 284 285 int meminfoFd_; 286 int vmstatFd_; 287 std::map<std::string, int> meminfoCounters_; 288 std::map<std::string, int> vmstatCounters_; 289 290 void InitProto2StrVector(); 291 std::vector<const char*> meminfoStrList_; 292 std::vector<const char*> vmstatStrList_; 293 // SmapsStats * 294 void WriteVmstat(MemoryData& data); 295 void WriteMeminfo(MemoryData& data); 296 void WriteZramData(MemoryData& data); 297 298 std::unordered_map<int32_t, std::vector<int>> pidFds_; 299 std::vector<int32_t> seenPids_; 300 char* testpath_; 301 int32_t err_; 302 int32_t ReadFile(int fd); 303 std::string ReadFile(const std::string& path); 304 std::vector<int> OpenProcPidFiles(int32_t pid); 305 int32_t ReadProcPidFile(int32_t pid, const char* pFileName); 306 void WriteProcessInfo(MemoryData& data, int32_t pid); 307 void WriteOomInfo(ProcessMemoryInfo* processinfo, int32_t pid); 308 void WriteProcess(ProcessMemoryInfo* processinfo, const char* pFile, uint32_t fileLen, int32_t pid); 309 void WriteAppsummary(ProcessMemoryInfo* processinfo, SmapsStats& smapInfo); 310 void SetProcessInfo(ProcessMemoryInfo* processinfo, int key, const char* word); 311 bool StringToUll(const char* word, uint64_t& value); 312 313 bool BufnCmp(const char* src, int srcLen, const char* key, int keyLen); 314 bool addPidBySort(int32_t pid); 315 int GetProcStatusId(const char* src, int srcLen); 316 317 bool ParseMemInfo(const char* data, ProcessMemoryInfo* memoryInfo); 318 bool GetMemInfoByMemoryService(uint32_t pid, ProcessMemoryInfo* memoryInfo); 319 int InitMemVmemFd(); 320 }; 321 322 #endif 323