• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::MEMINFO_UNSPECIFIED, "MemUnspecified"},
43     {SysMeminfoType::MEMINFO_MEM_TOTAL, "MemTotal"},
44     {SysMeminfoType::MEMINFO_MEM_FREE, "MemFree"},
45     {SysMeminfoType::MEMINFO_MEM_AVAILABLE, "MemAvailable"},
46     {SysMeminfoType::MEMINFO_BUFFERS, "Buffers"},
47     {SysMeminfoType::MEMINFO_CACHED, "Cached"},
48     {SysMeminfoType::MEMINFO_SWAP_CACHED, "SwapCached"},
49     {SysMeminfoType::MEMINFO_ACTIVE, "Active"},
50     {SysMeminfoType::MEMINFO_INACTIVE, "Inactive"},
51     {SysMeminfoType::MEMINFO_ACTIVE_ANON, "Active(anon)"},
52     {SysMeminfoType::MEMINFO_INACTIVE_ANON, "Inactive(anon)"},
53     {SysMeminfoType::MEMINFO_ACTIVE_FILE, "Active(file)"},
54     {SysMeminfoType::MEMINFO_INACTIVE_FILE, "Inactive(file)"},
55     {SysMeminfoType::MEMINFO_UNEVICTABLE, "Unevictable"},
56     {SysMeminfoType::MEMINFO_MLOCKED, "Mlocked"},
57     {SysMeminfoType::MEMINFO_SWAP_TOTAL, "SwapTotal"},
58     {SysMeminfoType::MEMINFO_SWAP_FREE, "SwapFree"},
59     {SysMeminfoType::MEMINFO_DIRTY, "Dirty"},
60     {SysMeminfoType::MEMINFO_WRITEBACK, "Writeback"},
61     {SysMeminfoType::MEMINFO_ANON_PAGES, "AnonPages"},
62     {SysMeminfoType::MEMINFO_MAPPED, "Mapped"},
63     {SysMeminfoType::MEMINFO_SHMEM, "Shmem"},
64     {SysMeminfoType::MEMINFO_SLAB, "Slab"},
65     {SysMeminfoType::MEMINFO_SLAB_RECLAIMABLE, "SReclaimable"},
66     {SysMeminfoType::MEMINFO_SLAB_UNRECLAIMABLE, "SUnreclaim"},
67     {SysMeminfoType::MEMINFO_KERNEL_STACK, "KernelStack"},
68     {SysMeminfoType::MEMINFO_PAGE_TABLES, "PageTables"},
69     {SysMeminfoType::MEMINFO_COMMIT_LIMIT, "CommitLimit"},
70     {SysMeminfoType::MEMINFO_COMMITED_AS, "Committed_AS"},
71     {SysMeminfoType::MEMINFO_VMALLOC_TOTAL, "VmallocTotal"},
72     {SysMeminfoType::MEMINFO_VMALLOC_USED, "VmallocUsed"},
73     {SysMeminfoType::MEMINFO_VMALLOC_CHUNK, "VmallocChunk"},
74     {SysMeminfoType::MEMINFO_CMA_TOTAL, "CmaTotal"},
75     {SysMeminfoType::MEMINFO_CMA_FREE, "CmaFree"},
76 };
77 
78 constexpr Proto2StrMapping vmeminfoMapping[] = {
79     {SysVMeminfoType::VMEMINFO_UNSPECIFIED, "unspecified"},
80     {SysVMeminfoType::VMEMINFO_NR_FREE_PAGES, "nr_free_pages"},
81     {SysVMeminfoType::VMEMINFO_NR_ALLOC_BATCH, "nr_alloc_batch"},
82     {SysVMeminfoType::VMEMINFO_NR_INACTIVE_ANON, "nr_inactive_anon"},
83     {SysVMeminfoType::VMEMINFO_NR_ACTIVE_ANON, "nr_active_anon"},
84     {SysVMeminfoType::VMEMINFO_NR_INACTIVE_FILE, "nr_inactive_file"},
85     {SysVMeminfoType::VMEMINFO_NR_ACTIVE_FILE, "nr_active_file"},
86     {SysVMeminfoType::VMEMINFO_NR_UNEVICTABLE, "nr_unevictable"},
87     {SysVMeminfoType::VMEMINFO_NR_MLOCK, "nr_mlock"},
88     {SysVMeminfoType::VMEMINFO_NR_ANON_PAGES, "nr_anon_pages"},
89     {SysVMeminfoType::VMEMINFO_NR_MAPPED, "nr_mapped"},
90     {SysVMeminfoType::VMEMINFO_NR_FILE_PAGES, "nr_file_pages"},
91     {SysVMeminfoType::VMEMINFO_NR_DIRTY, "nr_dirty"},
92     {SysVMeminfoType::VMEMINFO_NR_WRITEBACK, "nr_writeback"},
93     {SysVMeminfoType::VMEMINFO_NR_SLAB_RECLAIMABLE, "nr_slab_reclaimable"},
94     {SysVMeminfoType::VMEMINFO_NR_SLAB_UNRECLAIMABLE, "nr_slab_unreclaimable"},
95     {SysVMeminfoType::VMEMINFO_NR_PAGE_TABLE_PAGES, "nr_page_table_pages"},
96     {SysVMeminfoType::VMEMINFO_NR_KERNEL_STACK, "nr_kernel_stack"},
97     {SysVMeminfoType::VMEMINFO_NR_OVERHEAD, "nr_overhead"},
98     {SysVMeminfoType::VMEMINFO_NR_UNSTABLE, "nr_unstable"},
99     {SysVMeminfoType::VMEMINFO_NR_BOUNCE, "nr_bounce"},
100     {SysVMeminfoType::VMEMINFO_NR_VMSCAN_WRITE, "nr_vmscan_write"},
101     {SysVMeminfoType::VMEMINFO_NR_VMSCAN_IMMEDIATE_RECLAIM, "nr_vmscan_immediate_reclaim"},
102     {SysVMeminfoType::VMEMINFO_NR_WRITEBACK_TEMP, "nr_writeback_temp"},
103     {SysVMeminfoType::VMEMINFO_NR_ISOLATED_ANON, "nr_isolated_anon"},
104     {SysVMeminfoType::VMEMINFO_NR_ISOLATED_FILE, "nr_isolated_file"},
105     {SysVMeminfoType::VMEMINFO_NR_SHMEM, "nr_shmem"},
106     {SysVMeminfoType::VMEMINFO_NR_DIRTIED, "nr_dirtied"},
107     {SysVMeminfoType::VMEMINFO_NR_WRITTEN, "nr_written"},
108     {SysVMeminfoType::VMEMINFO_NR_PAGES_SCANNED, "nr_pages_scanned"},
109     {SysVMeminfoType::VMEMINFO_WORKINGSET_REFAULT, "workingset_refault"},
110     {SysVMeminfoType::VMEMINFO_WORKINGSET_ACTIVATE, "workingset_activate"},
111     {SysVMeminfoType::VMEMINFO_WORKINGSET_NODERECLAIM, "workingset_nodereclaim"},
112     {SysVMeminfoType::VMEMINFO_NR_ANON_TRANSPARENT_HUGEPAGES, "nr_anon_transparent_hugepages"},
113     {SysVMeminfoType::VMEMINFO_NR_FREE_CMA, "nr_free_cma"},
114     {SysVMeminfoType::VMEMINFO_NR_SWAPCACHE, "nr_swapcache"},
115     {SysVMeminfoType::VMEMINFO_NR_DIRTY_THRESHOLD, "nr_dirty_threshold"},
116     {SysVMeminfoType::VMEMINFO_NR_DIRTY_BACKGROUND_THRESHOLD, "nr_dirty_background_threshold"},
117     {SysVMeminfoType::VMEMINFO_PGPGIN, "pgpgin"},
118     {SysVMeminfoType::VMEMINFO_PGPGOUT, "pgpgout"},
119     {SysVMeminfoType::VMEMINFO_PGPGOUTCLEAN, "pgpgoutclean"},
120     {SysVMeminfoType::VMEMINFO_PSWPIN, "pswpin"},
121     {SysVMeminfoType::VMEMINFO_PSWPOUT, "pswpou"},
122     {SysVMeminfoType::VMEMINFO_PGALLOC_DMA, "pgalloc_dma"},
123     {SysVMeminfoType::VMEMINFO_PGALLOC_NORMAL, "pgalloc_normal"},
124     {SysVMeminfoType::VMEMINFO_PGALLOC_MOVABLE, "pgalloc_movable"},
125     {SysVMeminfoType::VMEMINFO_PGFREE, "pgfree"},
126     {SysVMeminfoType::VMEMINFO_PGACTIVATE, "pgactivate"},
127     {SysVMeminfoType::VMEMINFO_PGDEACTIVATE, "pgdeactivate"},
128     {SysVMeminfoType::VMEMINFO_PGFAULT, "pgfault"},
129     {SysVMeminfoType::VMEMINFO_PGMAJFAULT, "pgmajfault"},
130     {SysVMeminfoType::VMEMINFO_PGREFILL_DMA, "pgrefill_dma"},
131     {SysVMeminfoType::VMEMINFO_PGREFILL_NORMAL, "pgrefill_normal"},
132     {SysVMeminfoType::VMEMINFO_PGREFILL_MOVABLE, "pgrefill_movable"},
133     {SysVMeminfoType::VMEMINFO_PGSTEAL_KSWAPD_DMA, "pgsteal_kswapd_dma"},
134     {SysVMeminfoType::VMEMINFO_PGSTEAL_KSWAPD_NORMAL, "pgsteal_kswapd_normal"},
135     {SysVMeminfoType::VMEMINFO_PGSTEAL_KSWAPD_MOVABLE, "pgsteal_kswapd_movable"},
136     {SysVMeminfoType::VMEMINFO_PGSTEAL_DIRECT_DMA, "pgsteal_direct_dma"},
137     {SysVMeminfoType::VMEMINFO_PGSTEAL_DIRECT_NORMAL, "pgsteal_direct_normal"},
138     {SysVMeminfoType::VMEMINFO_PGSTEAL_DIRECT_MOVABLE, "pgsteal_direct_movable"},
139     {SysVMeminfoType::VMEMINFO_PGSCAN_KSWAPD_DMA, "pgscan_kswapd_dma"},
140     {SysVMeminfoType::VMEMINFO_PGSCAN_KSWAPD_NORMAL, "pgscan_kswapd_normal"},
141     {SysVMeminfoType::VMEMINFO_PGSCAN_KSWAPD_MOVABLE, "pgscan_kswapd_movable"},
142     {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT_DMA, "pgscan_direct_dma"},
143     {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT_NORMAL, "pgscan_direct_normal"},
144     {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT_MOVABLE, "pgscan_direct_movable"},
145     {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT_THROTTLE, "pgscan_direct_throttle"},
146     {SysVMeminfoType::VMEMINFO_PGINODESTEAL, "pginodesteal"},
147     {SysVMeminfoType::VMEMINFO_SLABS_SCANNED, "slabs_scanned"},
148     {SysVMeminfoType::VMEMINFO_KSWAPD_INODESTEAL, "kswapd_inodesteal"},
149     {SysVMeminfoType::VMEMINFO_KSWAPD_LOW_WMARK_HIT_QUICKLY, "kswapd_low_wmark_hit_quickly"},
150     {SysVMeminfoType::VMEMINFO_KSWAPD_HIGH_WMARK_HIT_QUICKLY, "kswapd_high_wmark_hit_quickly"},
151     {SysVMeminfoType::VMEMINFO_PAGEOUTRUN, "pageoutrun"},
152     {SysVMeminfoType::VMEMINFO_ALLOCSTALL, "allocstall"},
153     {SysVMeminfoType::VMEMINFO_PGROTATED, "pgrotated"},
154     {SysVMeminfoType::VMEMINFO_DROP_PAGECACHE, "drop_pagecache"},
155     {SysVMeminfoType::VMEMINFO_DROP_SLAB, "drop_slab"},
156     {SysVMeminfoType::VMEMINFO_PGMIGRATE_SUCCESS, "pgmigrate_success"},
157     {SysVMeminfoType::VMEMINFO_PGMIGRATE_FAIL, "pgmigrate_fail"},
158     {SysVMeminfoType::VMEMINFO_COMPACT_MIGRATE_SCANNED, "compact_migrate_scanned"},
159     {SysVMeminfoType::VMEMINFO_COMPACT_FREE_SCANNED, "compact_free_scanned"},
160     {SysVMeminfoType::VMEMINFO_COMPACT_ISOLATED, "compact_isolated"},
161     {SysVMeminfoType::VMEMINFO_COMPACT_STALL, "compact_stall"},
162     {SysVMeminfoType::VMEMINFO_COMPACT_FAIL, "compact_fail"},
163     {SysVMeminfoType::VMEMINFO_COMPACT_SUCCESS, "compact_success"},
164     {SysVMeminfoType::VMEMINFO_COMPACT_DAEMON_WAKE, "compact_daemon_wake"},
165     {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_CULLED, "unevictable_pgs_culled"},
166     {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_SCANNED, "unevictable_pgs_scanned"},
167     {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_RESCUED, "unevictable_pgs_rescued"},
168     {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_MLOCKED, "unevictable_pgs_mlocked"},
169     {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_MUNLOCKED, "unevictable_pgs_munlocked"},
170     {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_CLEARED, "unevictable_pgs_cleared"},
171     {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_STRANDED, "unevictable_pgs_stranded"},
172     {SysVMeminfoType::VMEMINFO_NR_ZSPAGES, "nr_zspages"},
173     {SysVMeminfoType::VMEMINFO_NR_ION_HEAP, "nr_ion_heap"},
174     {SysVMeminfoType::VMEMINFO_NR_GPU_HEAP, "nr_gpu_heap"},
175     {SysVMeminfoType::VMEMINFO_ALLOCSTALL_DMA, "allocstall_dma"},
176     {SysVMeminfoType::VMEMINFO_ALLOCSTALL_MOVABLE, "allocstall_movable"},
177     {SysVMeminfoType::VMEMINFO_ALLOCSTALL_NORMAL, "allocstall_normal"},
178     {SysVMeminfoType::VMEMINFO_COMPACT_DAEMON_FREE_SCANNED, "compact_daemon_free_scanned"},
179     {SysVMeminfoType::VMEMINFO_COMPACT_DAEMON_MIGRATE_SCANNED, "compact_daemon_migrate_scanned"},
180     {SysVMeminfoType::VMEMINFO_NR_FASTRPC, "nr_fastrpc"},
181     {SysVMeminfoType::VMEMINFO_NR_INDIRECTLY_RECLAIMABLE, "nr_indirectly_reclaimable"},
182     {SysVMeminfoType::VMEMINFO_NR_ION_HEAP_POOL, "nr_ion_heap_pool"},
183     {SysVMeminfoType::VMEMINFO_NR_KERNEL_MISC_RECLAIMABLE, "nr_kernel_misc_reclaimable"},
184     {SysVMeminfoType::VMEMINFO_NR_SHADOW_CALL_STACK_BYTES, "nr_shadow_call_stack_bytes"},
185     {SysVMeminfoType::VMEMINFO_NR_SHMEM_HUGEPAGES, "nr_shmem_hugepages"},
186     {SysVMeminfoType::VMEMINFO_NR_SHMEM_PMDMAPPED, "nr_shmem_pmdmapped"},
187     {SysVMeminfoType::VMEMINFO_NR_UNRECLAIMABLE_PAGES, "nr_unreclaimable_pages"},
188     {SysVMeminfoType::VMEMINFO_NR_ZONE_ACTIVE_ANON, "nr_zone_active_anon"},
189     {SysVMeminfoType::VMEMINFO_NR_ZONE_ACTIVE_FILE, "nr_zone_active_file"},
190     {SysVMeminfoType::VMEMINFO_NR_ZONE_INACTIVE_ANON, "nr_zone_inactive_anon"},
191     {SysVMeminfoType::VMEMINFO_NR_ZONE_INACTIVE_FILE, "nr_zone_inactive_file"},
192     {SysVMeminfoType::VMEMINFO_NR_ZONE_UNEVICTABLE, "nr_zone_unevictable"},
193     {SysVMeminfoType::VMEMINFO_NR_ZONE_WRITE_PENDING, "nr_zone_write_pending"},
194     {SysVMeminfoType::VMEMINFO_OOM_KILL, "oom_kill"},
195     {SysVMeminfoType::VMEMINFO_PGLAZYFREE, "pglazyfree"},
196     {SysVMeminfoType::VMEMINFO_PGLAZYFREED, "pglazyfreed"},
197     {SysVMeminfoType::VMEMINFO_PGREFILL, "pgrefill"},
198     {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT, "pgscan_direct"},
199     {SysVMeminfoType::VMEMINFO_PGSCAN_KSWAPD, "pgscan_kswapd"},
200     {SysVMeminfoType::VMEMINFO_PGSKIP_DMA, "pgskip_dma"},
201     {SysVMeminfoType::VMEMINFO_PGSKIP_MOVABLE, "pgskip_movable"},
202     {SysVMeminfoType::VMEMINFO_PGSKIP_NORMAL, "pgskip_normal"},
203     {SysVMeminfoType::VMEMINFO_PGSTEAL_DIRECT, "pgsteal_direct"},
204     {SysVMeminfoType::VMEMINFO_PGSTEAL_KSWAPD, "pgsteal_kswapd"},
205     {SysVMeminfoType::VMEMINFO_SWAP_RA, "swap_ra"},
206     {SysVMeminfoType::VMEMINFO_SWAP_RA_HIT, "swap_ra_hit"},
207     {SysVMeminfoType::VMEMINFO_WORKINGSET_RESTORE, "workingset_restore"},
208 };
209 
210 struct ProcStatusMapping {
211     int procid;
212     const char* procstr;
213 };
214 
215 enum StatusType {
216     PRO_TGID = 1,
217     PRO_NAME,
218     PRO_VMSIZE,
219     PRO_VMRSS,
220     PRO_RSSANON,
221     PRO_RSSFILE,
222     PRO_RSSSHMEM,
223     PRO_VMSWAP,
224     PRO_VMLCK,
225     PRO_VMHWM,
226 };
227 
228 constexpr ProcStatusMapping procStatusMapping[] = {
229     {StatusType::PRO_TGID, "Tgid"},         {StatusType::PRO_NAME, "Name"},       {StatusType::PRO_VMSIZE, "VmSize"},
230     {StatusType::PRO_VMRSS, "VmRSS"},       {StatusType::PRO_RSSANON, "RssAnon"}, {StatusType::PRO_RSSFILE, "RssFile"},
231     {StatusType::PRO_RSSSHMEM, "RssShmem"}, {StatusType::PRO_VMSWAP, "VmSwap"},   {StatusType::PRO_VMLCK, "VmLck"},
232     {StatusType::PRO_VMHWM, "VmHWM"},
233 };
234 
235 enum ErrorType {
236     RET_NULL_ADDR,
237     RET_IVALID_PID,
238     RET_TGID_VALUE_NULL,
239     RET_FAIL = -1,
240     RET_SUCC = 0,
241 };
242 
243 enum FileType {
244     FILE_STATUS = 0,
245     FILE_OOM,
246     FILE_SMAPS,
247 };
248 
249 struct ProcfdMapping {
250     int procid;
251     const char* file;
252 };
253 
254 constexpr ProcfdMapping procfdMapping[] = {
255     {FileType::FILE_STATUS, "status"},
256     {FileType::FILE_OOM, "oom_score_adj"},
257     {FileType::FILE_SMAPS, "smaps"},
258 };
259 
260 class MemoryDataPlugin {
261 public:
262     MemoryDataPlugin();
263     ~MemoryDataPlugin();
264     int Start(const uint8_t* configData, uint32_t configSize);
265     int Report(uint8_t* configData, uint32_t configSize);
266     int Stop();
SetPath(char * path)267     void SetPath(char* path)
268     {
269         testpath_ = path;
270     };
271     void WriteProcesseList(MemoryData& data);
272     void WriteProcinfoByPidfds(ProcessMemoryInfo* processinfo, int32_t pid);
273     DIR* OpenDestDir(const char* dirPath);
274     int32_t GetValidPid(DIR* dirp);
275     // for test change static
276     int ParseNumber(std::string line);
277 
278 private:
279     /* data */
280     MemoryConfig protoConfig_;
281 
282     std::unique_ptr<uint8_t[]> buffer_;
283 
284     int meminfoFd_;
285     int vmstatFd_;
286     std::map<std::string, int> meminfoCounters_;
287     std::map<std::string, int> vmstatCounters_;
288 
289     void InitProto2StrVector();
290     std::vector<const char*> meminfoStrList_;
291     std::vector<const char*> vmstatStrList_;
292     // SmapsStats *
293     void WriteVmstat(MemoryData& data);
294     void WriteMeminfo(MemoryData& data);
295 
296     std::unordered_map<int32_t, std::vector<int>> pidFds_;
297     std::vector<int32_t> seenPids_;
298     char* testpath_;
299     int32_t err_;
300     int32_t ReadFile(int fd);
301     std::vector<int> OpenProcPidFiles(int32_t pid);
302     int32_t ReadProcPidFile(int32_t pid, const char* pFileName);
303     void WriteProcessInfo(MemoryData& data, int32_t pid);
304     void SetEmptyProcessInfo(ProcessMemoryInfo* processinfo);
305     void WriteOomInfo(ProcessMemoryInfo* processinfo, int32_t pid);
306     void WriteProcess(ProcessMemoryInfo* processinfo, const char* pFile, uint32_t fileLen, int32_t pid);
307     void WriteAppsummary(ProcessMemoryInfo* processinfo, SmapsStats& smapInfo);
308     void SetProcessInfo(ProcessMemoryInfo* processinfo, int key, const char* word);
309     bool StringToUll(const char* word, uint64_t& value);
310 
311     bool BufnCmp(const char* src, int srcLen, const char* key, int keyLen);
312     bool addPidBySort(int32_t pid);
313     int GetProcStatusId(const char* src, int srcLen);
314 
315     bool ParseMemInfo(const char* data, ProcessMemoryInfo* memoryInfo);
316     bool GetMemInfoByMemoryService(uint32_t pid, ProcessMemoryInfo* memoryInfo);
317     int InitMemVmemFd();
318 };
319 
320 #endif
321