• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /**
33  * @defgroup los_vm_dump virtual memory dump operation
34  * @ingroup kernel
35  */
36 
37 #include "los_vm_dump.h"
38 #include "los_mmu_descriptor_v6.h"
39 #ifdef LOSCFG_FS_VFS
40 #include "fs/file.h"
41 #include "vnode.h"
42 #endif
43 #include "los_printf.h"
44 #include "los_vm_page.h"
45 #include "los_vm_phys.h"
46 #include "los_process_pri.h"
47 #include "los_atomic.h"
48 #include "los_vm_lock.h"
49 #include "los_memory_pri.h"
50 
51 
52 #ifdef LOSCFG_KERNEL_VM
53 
54 #define     FLAG_SIZE               4
55 #define     FLAG_START              2
56 
OsGetRegionNameOrFilePath(LosVmMapRegion * region)57 const CHAR *OsGetRegionNameOrFilePath(LosVmMapRegion *region)
58 {
59     struct Vnode *vnode = NULL;
60     if (region == NULL) {
61         return "";
62 #ifdef LOSCFG_FS_VFS
63     } else if (LOS_IsRegionFileValid(region)) {
64         vnode = region->unTypeData.rf.vnode;
65         return vnode->filePath;
66 #endif
67     } else if (region->regionFlags & VM_MAP_REGION_FLAG_HEAP) {
68         return "HEAP";
69     } else if (region->regionFlags & VM_MAP_REGION_FLAG_STACK) {
70         return "STACK";
71     } else if (region->regionFlags & VM_MAP_REGION_FLAG_TEXT) {
72         return "Text";
73     } else if (region->regionFlags & VM_MAP_REGION_FLAG_VDSO) {
74         return "VDSO";
75     } else if (region->regionFlags & VM_MAP_REGION_FLAG_MMAP) {
76         return "MMAP";
77     } else if (region->regionFlags & VM_MAP_REGION_FLAG_SHM) {
78         return "SHM";
79     } else if (region->regionFlags & VM_MAP_REGION_FLAG_LITEIPC) {
80         return "LITEIPC";
81     } else {
82         return "";
83     }
84     return "";
85 }
86 
OsRegionOverlapCheckUnlock(LosVmSpace * space,LosVmMapRegion * region)87 INT32 OsRegionOverlapCheckUnlock(LosVmSpace *space, LosVmMapRegion *region)
88 {
89     LosVmMapRegion *regionTemp = NULL;
90     LosRbNode *pstRbNode = NULL;
91     LosRbNode *pstRbNodeNext = NULL;
92 
93     /* search the region list */
94     RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)
95         regionTemp = (LosVmMapRegion *)pstRbNode;
96         if (region->range.base == regionTemp->range.base && region->range.size == regionTemp->range.size) {
97             continue;
98         }
99         if (((region->range.base + region->range.size) > regionTemp->range.base) &&
100             (region->range.base < (regionTemp->range.base + regionTemp->range.size))) {
101             VM_ERR("overlap between regions:\n"
102                    "flags:%#x base:%p size:%08x space:%p\n"
103                    "flags:%#x base:%p size:%08x space:%p",
104                    region->regionFlags, region->range.base, region->range.size, region->space,
105                    regionTemp->regionFlags, regionTemp->range.base, regionTemp->range.size, regionTemp->space);
106             return -1;
107         }
108     RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext)
109 
110     return 0;
111 }
112 
OsShellCmdProcessVmUsage(LosVmSpace * space)113 UINT32 OsShellCmdProcessVmUsage(LosVmSpace *space)
114 {
115     LosVmMapRegion *region = NULL;
116     LosRbNode *pstRbNode = NULL;
117     LosRbNode *pstRbNodeNext = NULL;
118     UINT32 used = 0;
119 
120     if (space == NULL) {
121         return 0;
122     }
123 
124     if (space == LOS_GetKVmSpace()) {
125         OsShellCmdProcessPmUsage(space, NULL, &used);
126         return used;
127     }
128     UINT32 ret = LOS_MuxAcquire(&space->regionMux);
129     if (ret != 0) {
130         return 0;
131     }
132 
133     RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)
134         region = (LosVmMapRegion *)pstRbNode;
135         used += region->range.size;
136     RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext)
137     (VOID)LOS_MuxRelease(&space->regionMux);
138     return used;
139 }
140 
OsKProcessPmUsage(LosVmSpace * kSpace,UINT32 * actualPm)141 UINT32 OsKProcessPmUsage(LosVmSpace *kSpace, UINT32 *actualPm)
142 {
143     UINT32 memUsed;
144     UINT32 totalMem;
145     UINT32 freeMem;
146     UINT32 usedCount = 0;
147     UINT32 totalCount = 0;
148     LosVmSpace *space = NULL;
149     LOS_DL_LIST *spaceList = NULL;
150     UINT32 UProcessUsed = 0;
151 
152     if (actualPm == NULL) {
153         return 0;
154     }
155 
156     memUsed = LOS_MemTotalUsedGet(m_aucSysMem1);
157     totalMem = LOS_MemPoolSizeGet(m_aucSysMem1);
158     freeMem = totalMem - memUsed;
159 
160     OsVmPhysUsedInfoGet(&usedCount, &totalCount);
161     /* Kernel resident memory, include default heap memory */
162     memUsed = SYS_MEM_SIZE_DEFAULT - (totalCount << PAGE_SHIFT);
163 
164     spaceList = LOS_GetVmSpaceList();
165     LosMux *vmSpaceListMux = OsGVmSpaceMuxGet();
166     (VOID)LOS_MuxAcquire(vmSpaceListMux);
167     LOS_DL_LIST_FOR_EACH_ENTRY(space, spaceList, LosVmSpace, node) {
168         if (space == LOS_GetKVmSpace()) {
169             continue;
170         }
171         UProcessUsed += OsUProcessPmUsage(space, NULL, NULL);
172     }
173     (VOID)LOS_MuxRelease(vmSpaceListMux);
174 
175     /* Kernel dynamic memory, include extended heap memory */
176     memUsed += ((usedCount << PAGE_SHIFT) - UProcessUsed);
177     /* Remaining heap memory */
178     memUsed -= freeMem;
179 
180     *actualPm = memUsed;
181     return memUsed;
182 }
183 
OsShellCmdProcessPmUsage(LosVmSpace * space,UINT32 * sharePm,UINT32 * actualPm)184 UINT32 OsShellCmdProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm)
185 {
186     if (space == NULL) {
187         return 0;
188     }
189 
190     if ((sharePm == NULL) && (actualPm == NULL)) {
191         return 0;
192     }
193 
194     if (space == LOS_GetKVmSpace()) {
195         return OsKProcessPmUsage(space, actualPm);
196     }
197     return OsUProcessPmUsage(space, sharePm, actualPm);
198 }
199 
OsUProcessPmUsage(LosVmSpace * space,UINT32 * sharePm,UINT32 * actualPm)200 UINT32 OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm)
201 {
202     LosVmMapRegion *region = NULL;
203     LosRbNode *pstRbNode = NULL;
204     LosRbNode *pstRbNodeNext = NULL;
205     LosVmPage *page = NULL;
206     VADDR_T vaddr;
207     size_t size;
208     PADDR_T paddr;
209     STATUS_T ret;
210     INT32 shareRef;
211     UINT32 pmSize = 0;
212 
213     if (sharePm != NULL) {
214         *sharePm = 0;
215     }
216 
217     ret = LOS_MuxAcquire(&space->regionMux);
218     if (ret != 0) {
219         return 0;
220     }
221     RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)
222         region = (LosVmMapRegion *)pstRbNode;
223         vaddr = region->range.base;
224         size = region->range.size;
225         for (; size > 0; vaddr += PAGE_SIZE, size -= PAGE_SIZE) {
226             ret = LOS_ArchMmuQuery(&space->archMmu, vaddr, &paddr, NULL);
227             if (ret < 0) {
228                 continue;
229             }
230             page = LOS_VmPageGet(paddr);
231             if (page == NULL) {
232                 continue;
233             }
234 
235             shareRef = LOS_AtomicRead(&page->refCounts);
236             if (shareRef > 1) {
237                 if (sharePm != NULL) {
238                     *sharePm += PAGE_SIZE;
239                 }
240                 pmSize += PAGE_SIZE / shareRef;
241             } else {
242                 pmSize += PAGE_SIZE;
243             }
244         }
245     RB_SCAN_SAFE_END(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext)
246 
247     (VOID)LOS_MuxRelease(&space->regionMux);
248 
249     if (actualPm != NULL) {
250         *actualPm = pmSize;
251     }
252 
253     return pmSize;
254 }
255 
OsGetPIDByAspace(const LosVmSpace * space)256 LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space)
257 {
258     UINT32 pid;
259     UINT32 intSave;
260     LosProcessCB *processCB = NULL;
261 
262     SCHEDULER_LOCK(intSave);
263     for (pid = 0; pid < g_processMaxNum; ++pid) {
264         processCB = g_processCBArray + pid;
265         if (OsProcessIsUnused(processCB)) {
266             continue;
267         }
268 
269         if (processCB->vmSpace == space) {
270             SCHEDULER_UNLOCK(intSave);
271             return processCB;
272         }
273     }
274     SCHEDULER_UNLOCK(intSave);
275     return NULL;
276 }
277 
OsCountRegionPages(LosVmSpace * space,LosVmMapRegion * region,UINT32 * pssPages)278 UINT32 OsCountRegionPages(LosVmSpace *space, LosVmMapRegion *region, UINT32 *pssPages)
279 {
280     UINT32 regionPages = 0;
281     PADDR_T paddr;
282     VADDR_T vaddr;
283     UINT32 ref;
284     STATUS_T status;
285     float pss = 0;
286     LosVmPage *page = NULL;
287 
288     for (vaddr = region->range.base; vaddr < region->range.base + region->range.size; vaddr = vaddr + PAGE_SIZE) {
289         status = LOS_ArchMmuQuery(&space->archMmu, vaddr, &paddr, NULL);
290         if (status == LOS_OK) {
291             regionPages++;
292             if (pssPages == NULL) {
293                 continue;
294             }
295             page = LOS_VmPageGet(paddr);
296             if (page != NULL) {
297                 ref = LOS_AtomicRead(&page->refCounts);
298                 pss += ((ref > 0) ? (1.0 / ref) : 1);
299             } else {
300                 pss += 1;
301             }
302         }
303     }
304 
305     if (pssPages != NULL) {
306         *pssPages = (UINT32)(pss + 0.5);    /* 0.5, for page alignment */
307     }
308 
309     return regionPages;
310 }
311 
OsCountAspacePages(LosVmSpace * space)312 UINT32 OsCountAspacePages(LosVmSpace *space)
313 {
314     UINT32 spacePages = 0;
315     LosVmMapRegion *region = NULL;
316     LosRbNode *pstRbNode = NULL;
317     LosRbNode *pstRbNodeNext = NULL;
318 
319     RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)
320         region = (LosVmMapRegion *)pstRbNode;
321         spacePages += OsCountRegionPages(space, region, NULL);
322     RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext)
323     return spacePages;
324 }
325 
OsArchFlagsToStr(const UINT32 archFlags)326 CHAR *OsArchFlagsToStr(const UINT32 archFlags)
327 {
328     UINT32 index;
329     UINT32 cacheFlags = archFlags & VM_MAP_REGION_FLAG_CACHE_MASK;
330     UINT32 flagSize = FLAG_SIZE * BITMAP_BITS_PER_WORD * sizeof(CHAR);
331     CHAR *archMmuFlagsStr = (CHAR *)LOS_MemAlloc(m_aucSysMem0, flagSize);
332     if (archMmuFlagsStr == NULL) {
333         return NULL;
334     }
335     (VOID)memset_s(archMmuFlagsStr, flagSize, 0, flagSize);
336     switch (cacheFlags) {
337         case 0UL:
338             (VOID)strcat_s(archMmuFlagsStr, flagSize, " CH\0");
339             break;
340         case 1UL:
341             (VOID)strcat_s(archMmuFlagsStr, flagSize, " UC\0");
342             break;
343         case 2UL:
344             (VOID)strcat_s(archMmuFlagsStr, flagSize, " UD\0");
345             break;
346         case 3UL:
347             (VOID)strcat_s(archMmuFlagsStr, flagSize, " WC\0");
348             break;
349         default:
350             break;
351     }
352 
353     static const CHAR FLAGS[BITMAP_BITS_PER_WORD][FLAG_SIZE] = {
354         [0 ... (__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_USER) - 2)] = "???\0",
355         [__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_USER) - 1] = " US\0",
356         [__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_READ) - 1] = " RD\0",
357         [__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_WRITE) - 1] = " WR\0",
358         [__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_EXECUTE) - 1] = " EX\0",
359         [__builtin_ffsl(VM_MAP_REGION_FLAG_NS) - 1] = " NS\0",
360         [__builtin_ffsl(VM_MAP_REGION_FLAG_INVALID) - 1] = " IN\0",
361         [__builtin_ffsl(VM_MAP_REGION_FLAG_INVALID) ... (BITMAP_BITS_PER_WORD - 1)] = "???\0",
362     };
363 
364     for (index = FLAG_START; index < BITMAP_BITS_PER_WORD; index++) {
365         if (FLAGS[index][0] == '?') {
366             continue;
367         }
368 
369         if (archFlags & (1UL << index)) {
370             UINT32 status = strcat_s(archMmuFlagsStr, flagSize, FLAGS[index]);
371             if (status != 0) {
372                 PRINTK("error\n");
373             }
374         }
375     }
376 
377     return archMmuFlagsStr;
378 }
379 
OsDumpRegion2(LosVmSpace * space,LosVmMapRegion * region)380 VOID OsDumpRegion2(LosVmSpace *space, LosVmMapRegion *region)
381 {
382     UINT32 pssPages = 0;
383     UINT32 regionPages;
384 
385     regionPages = OsCountRegionPages(space, region, &pssPages);
386     CHAR *flagsStr = OsArchFlagsToStr(region->regionFlags);
387     if (flagsStr == NULL) {
388         return;
389     }
390     PRINTK("\t %#010x  %-32.32s %#010x %#010x %-15.15s %4d    %4d\n",
391         region, OsGetRegionNameOrFilePath(region), region->range.base,
392         region->range.size, flagsStr, regionPages, pssPages);
393     (VOID)LOS_MemFree(m_aucSysMem0, flagsStr);
394 }
395 
OsDumpAspace(LosVmSpace * space)396 VOID OsDumpAspace(LosVmSpace *space)
397 {
398     LosVmMapRegion *region = NULL;
399     LosRbNode *pstRbNode = NULL;
400     LosRbNode *pstRbNodeNext = NULL;
401     UINT32 spacePages;
402     LosProcessCB *pcb = OsGetPIDByAspace(space);
403 
404     if (pcb == NULL) {
405         return;
406     }
407 
408     spacePages = OsCountAspacePages(space);
409     PRINTK("\r\n PID    aspace     name       base       size     pages \n");
410     PRINTK(" ----   ------     ----       ----       -----     ----\n");
411     PRINTK(" %-4d %#010x %-10.10s %#010x %#010x     %d\n", pcb->processID, space, pcb->processName,
412         space->base, space->size, spacePages);
413     PRINTK("\r\n\t region      name                base       size       mmu_flags      pages   pg/ref\n");
414     PRINTK("\t ------      ----                ----       ----       ---------      -----   -----\n");
415     RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)
416         region = (LosVmMapRegion *)pstRbNode;
417         if (region != NULL) {
418             OsDumpRegion2(space, region);
419             (VOID)OsRegionOverlapCheck(space, region);
420         } else {
421             PRINTK("region is NULL\n");
422         }
423     RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext)
424     return;
425 }
426 
OsDumpAllAspace(VOID)427 VOID OsDumpAllAspace(VOID)
428 {
429     LosVmSpace *space = NULL;
430     LOS_DL_LIST *aspaceList = LOS_GetVmSpaceList();
431     LOS_DL_LIST_FOR_EACH_ENTRY(space, aspaceList, LosVmSpace, node) {
432         (VOID)LOS_MuxAcquire(&space->regionMux);
433         OsDumpAspace(space);
434         (VOID)LOS_MuxRelease(&space->regionMux);
435     }
436     return;
437 }
438 
OsRegionOverlapCheck(LosVmSpace * space,LosVmMapRegion * region)439 STATUS_T OsRegionOverlapCheck(LosVmSpace *space, LosVmMapRegion *region)
440 {
441     int ret;
442 
443     if (space == NULL || region == NULL) {
444         return -1;
445     }
446 
447     (VOID)LOS_MuxAcquire(&space->regionMux);
448     ret = OsRegionOverlapCheckUnlock(space, region);
449     (VOID)LOS_MuxRelease(&space->regionMux);
450     return ret;
451 }
452 
OsDumpPte(VADDR_T vaddr)453 VOID OsDumpPte(VADDR_T vaddr)
454 {
455     UINT32 l1Index = vaddr >> MMU_DESCRIPTOR_L1_SMALL_SHIFT;
456     LosVmSpace *space = LOS_SpaceGet(vaddr);
457     UINT32 ttEntry;
458     LosVmPage *page = NULL;
459     PTE_T *l2Table = NULL;
460     UINT32 l2Index;
461 
462     if (space == NULL) {
463         return;
464     }
465 
466     ttEntry = space->archMmu.virtTtb[l1Index];
467     if (ttEntry) {
468         l2Table = LOS_PaddrToKVaddr(MMU_DESCRIPTOR_L1_PAGE_TABLE_ADDR(ttEntry));
469         l2Index = (vaddr % MMU_DESCRIPTOR_L1_SMALL_SIZE) >> PAGE_SHIFT;
470         if (l2Table == NULL) {
471             goto ERR;
472         }
473         page = LOS_VmPageGet(l2Table[l2Index] & ~(PAGE_SIZE - 1));
474         if (page == NULL) {
475             goto ERR;
476         }
477         PRINTK("vaddr %p, l1Index %d, ttEntry %p, l2Table %p, l2Index %d, pfn %p count %d\n",
478                vaddr, l1Index, ttEntry, l2Table, l2Index, l2Table[l2Index], LOS_AtomicRead(&page->refCounts));
479     } else {
480         PRINTK("vaddr %p, l1Index %d, ttEntry %p\n", vaddr, l1Index, ttEntry);
481     }
482     return;
483 ERR:
484     PRINTK("%s, error vaddr: %#x, l2Table: %#x, l2Index: %#x\n", __FUNCTION__, vaddr, l2Table, l2Index);
485 }
486 
OsVmPhySegPagesGet(LosVmPhysSeg * seg)487 UINT32 OsVmPhySegPagesGet(LosVmPhysSeg *seg)
488 {
489     UINT32 intSave;
490     UINT32 flindex;
491     UINT32 segFreePages = 0;
492 
493     LOS_SpinLockSave(&seg->freeListLock, &intSave);
494     for (flindex = 0; flindex < VM_LIST_ORDER_MAX; flindex++) {
495         segFreePages += ((1 << flindex) * seg->freeList[flindex].listCnt);
496     }
497     LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
498 
499     return segFreePages;
500 }
501 
OsVmPhysDump(VOID)502 VOID OsVmPhysDump(VOID)
503 {
504     LosVmPhysSeg *seg = NULL;
505     UINT32 segFreePages;
506     UINT32 totalFreePages = 0;
507     UINT32 totalPages = 0;
508     UINT32 segIndex;
509     UINT32 intSave;
510     UINT32 flindex;
511     UINT32 listCount[VM_LIST_ORDER_MAX] = {0};
512 
513     for (segIndex = 0; segIndex < g_vmPhysSegNum; segIndex++) {
514         seg = &g_vmPhysSeg[segIndex];
515         if (seg->size > 0) {
516             segFreePages = OsVmPhySegPagesGet(seg);
517 #ifdef LOSCFG_SHELL_CMD_DEBUG
518             PRINTK("\r\n phys_seg      base         size        free_pages    \n");
519             PRINTK(" --------      -------      ----------  ---------  \n");
520 #endif
521             PRINTK(" 0x%08x    0x%08x   0x%08x   %8u  \n", seg, seg->start, seg->size, segFreePages);
522             totalFreePages += segFreePages;
523             totalPages += (seg->size >> PAGE_SHIFT);
524 
525             LOS_SpinLockSave(&seg->freeListLock, &intSave);
526             for (flindex = 0; flindex < VM_LIST_ORDER_MAX; flindex++) {
527                 listCount[flindex] = seg->freeList[flindex].listCnt;
528             }
529             LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
530             for (flindex = 0; flindex < VM_LIST_ORDER_MAX; flindex++) {
531                 PRINTK("order = %d, free_count = %d\n", flindex, listCount[flindex]);
532             }
533 
534             PRINTK("active   anon   %d\n", seg->lruSize[VM_LRU_ACTIVE_ANON]);
535             PRINTK("inactive anon   %d\n", seg->lruSize[VM_LRU_INACTIVE_ANON]);
536             PRINTK("active   file   %d\n", seg->lruSize[VM_LRU_ACTIVE_FILE]);
537             PRINTK("inactive file   %d\n", seg->lruSize[VM_LRU_INACTIVE_FILE]);
538         }
539     }
540     PRINTK("\n\rpmm pages: total = %u, used = %u, free = %u\n",
541            totalPages, (totalPages - totalFreePages), totalFreePages);
542 }
543 
OsVmPhysUsedInfoGet(UINT32 * usedCount,UINT32 * totalCount)544 VOID OsVmPhysUsedInfoGet(UINT32 *usedCount, UINT32 *totalCount)
545 {
546     UINT32 index;
547     UINT32 segFreePages;
548     LosVmPhysSeg *physSeg = NULL;
549 
550     if (usedCount == NULL || totalCount == NULL) {
551         return;
552     }
553     *usedCount = 0;
554     *totalCount = 0;
555 
556     for (index = 0; index < g_vmPhysSegNum; index++) {
557         physSeg = &g_vmPhysSeg[index];
558         if (physSeg->size > 0) {
559             *totalCount += physSeg->size >> PAGE_SHIFT;
560             segFreePages = OsVmPhySegPagesGet(physSeg);
561             *usedCount += (*totalCount - segFreePages);
562         }
563     }
564 }
565 #endif
566 
567