• 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::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