162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include <linux/fs.h> 362306a36Sopenharmony_ci#include <linux/init.h> 462306a36Sopenharmony_ci#include <linux/kernel.h> 562306a36Sopenharmony_ci#include <linux/mm.h> 662306a36Sopenharmony_ci#include <linux/hugetlb.h> 762306a36Sopenharmony_ci#include <linux/mman.h> 862306a36Sopenharmony_ci#include <linux/mmzone.h> 962306a36Sopenharmony_ci#include <linux/memblock.h> 1062306a36Sopenharmony_ci#include <linux/proc_fs.h> 1162306a36Sopenharmony_ci#include <linux/percpu.h> 1262306a36Sopenharmony_ci#include <linux/seq_file.h> 1362306a36Sopenharmony_ci#include <linux/swap.h> 1462306a36Sopenharmony_ci#include <linux/vmstat.h> 1562306a36Sopenharmony_ci#include <linux/atomic.h> 1662306a36Sopenharmony_ci#include <linux/vmalloc.h> 1762306a36Sopenharmony_ci#ifdef CONFIG_CMA 1862306a36Sopenharmony_ci#include <linux/cma.h> 1962306a36Sopenharmony_ci#endif 2062306a36Sopenharmony_ci#ifdef CONFIG_MEM_PURGEABLE 2162306a36Sopenharmony_ci#include <linux/mm_purgeable.h> 2262306a36Sopenharmony_ci#endif 2362306a36Sopenharmony_ci#include <linux/zswap.h> 2462306a36Sopenharmony_ci#include <asm/page.h> 2562306a36Sopenharmony_ci#include "internal.h" 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_civoid __attribute__((weak)) arch_report_meminfo(struct seq_file *m) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci} 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic void show_val_kb(struct seq_file *m, const char *s, unsigned long num) 3262306a36Sopenharmony_ci{ 3362306a36Sopenharmony_ci seq_put_decimal_ull_width(m, s, num << (PAGE_SHIFT - 10), 8); 3462306a36Sopenharmony_ci seq_write(m, " kB\n", 4); 3562306a36Sopenharmony_ci} 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic int meminfo_proc_show(struct seq_file *m, void *v) 3862306a36Sopenharmony_ci{ 3962306a36Sopenharmony_ci struct sysinfo i; 4062306a36Sopenharmony_ci unsigned long committed; 4162306a36Sopenharmony_ci long cached; 4262306a36Sopenharmony_ci long available; 4362306a36Sopenharmony_ci unsigned long pages[NR_LRU_LISTS]; 4462306a36Sopenharmony_ci unsigned long sreclaimable, sunreclaim; 4562306a36Sopenharmony_ci int lru; 4662306a36Sopenharmony_ci unsigned long nr_purg_active = 0; 4762306a36Sopenharmony_ci unsigned long nr_purg_inactive = 0; 4862306a36Sopenharmony_ci#ifdef CONFIG_MEM_PURGEABLE 4962306a36Sopenharmony_ci unsigned long nr_purg_pined = 0; 5062306a36Sopenharmony_ci#endif 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci si_meminfo(&i); 5362306a36Sopenharmony_ci si_swapinfo(&i); 5462306a36Sopenharmony_ci committed = vm_memory_committed(); 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci cached = global_node_page_state(NR_FILE_PAGES) - 5762306a36Sopenharmony_ci total_swapcache_pages() - i.bufferram; 5862306a36Sopenharmony_ci if (cached < 0) 5962306a36Sopenharmony_ci cached = 0; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++) 6262306a36Sopenharmony_ci pages[lru] = global_node_page_state(NR_LRU_BASE + lru); 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci#ifdef CONFIG_MEM_PURGEABLE 6562306a36Sopenharmony_ci nr_purg_active = pages[LRU_ACTIVE_PURGEABLE]; 6662306a36Sopenharmony_ci nr_purg_inactive = pages[LRU_INACTIVE_PURGEABLE]; 6762306a36Sopenharmony_ci purg_pages_info(NULL, &nr_purg_pined); 6862306a36Sopenharmony_ci nr_purg_pined = min(nr_purg_pined, nr_purg_active + nr_purg_inactive); 6962306a36Sopenharmony_ci#endif 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci available = si_mem_available(); 7262306a36Sopenharmony_ci sreclaimable = global_node_page_state_pages(NR_SLAB_RECLAIMABLE_B); 7362306a36Sopenharmony_ci sunreclaim = global_node_page_state_pages(NR_SLAB_UNRECLAIMABLE_B); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci show_val_kb(m, "MemTotal: ", i.totalram); 7662306a36Sopenharmony_ci show_val_kb(m, "MemFree: ", i.freeram); 7762306a36Sopenharmony_ci show_val_kb(m, "MemAvailable: ", available); 7862306a36Sopenharmony_ci show_val_kb(m, "Buffers: ", i.bufferram); 7962306a36Sopenharmony_ci show_val_kb(m, "Cached: ", cached); 8062306a36Sopenharmony_ci show_val_kb(m, "SwapCached: ", total_swapcache_pages()); 8162306a36Sopenharmony_ci show_val_kb(m, "Active: ", pages[LRU_ACTIVE_ANON] + 8262306a36Sopenharmony_ci#ifdef CONFIG_MEM_PURGEABLE 8362306a36Sopenharmony_ci pages[LRU_ACTIVE_FILE] + 8462306a36Sopenharmony_ci nr_purg_active); 8562306a36Sopenharmony_ci#else 8662306a36Sopenharmony_ci pages[LRU_ACTIVE_FILE]); 8762306a36Sopenharmony_ci#endif 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci show_val_kb(m, "Inactive: ", pages[LRU_INACTIVE_ANON] + 9062306a36Sopenharmony_ci pages[LRU_INACTIVE_FILE] + 9162306a36Sopenharmony_ci nr_purg_inactive); 9262306a36Sopenharmony_ci show_val_kb(m, "Active(anon): ", pages[LRU_ACTIVE_ANON]); 9362306a36Sopenharmony_ci show_val_kb(m, "Inactive(anon): ", pages[LRU_INACTIVE_ANON]); 9462306a36Sopenharmony_ci show_val_kb(m, "Active(file): ", pages[LRU_ACTIVE_FILE]); 9562306a36Sopenharmony_ci show_val_kb(m, "Inactive(file): ", pages[LRU_INACTIVE_FILE]); 9662306a36Sopenharmony_ci#ifdef CONFIG_MEM_PURGEABLE 9762306a36Sopenharmony_ci show_val_kb(m, "Active(purg): ", nr_purg_active); 9862306a36Sopenharmony_ci show_val_kb(m, "Inactive(purg): ", nr_purg_inactive); 9962306a36Sopenharmony_ci show_val_kb(m, "Pined(purg): ", nr_purg_pined); 10062306a36Sopenharmony_ci#endif 10162306a36Sopenharmony_ci show_val_kb(m, "Unevictable: ", pages[LRU_UNEVICTABLE]); 10262306a36Sopenharmony_ci show_val_kb(m, "Mlocked: ", global_zone_page_state(NR_MLOCK)); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci#ifdef CONFIG_HIGHMEM 10562306a36Sopenharmony_ci show_val_kb(m, "HighTotal: ", i.totalhigh); 10662306a36Sopenharmony_ci show_val_kb(m, "HighFree: ", i.freehigh); 10762306a36Sopenharmony_ci show_val_kb(m, "LowTotal: ", i.totalram - i.totalhigh); 10862306a36Sopenharmony_ci show_val_kb(m, "LowFree: ", i.freeram - i.freehigh); 10962306a36Sopenharmony_ci#endif 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci#ifndef CONFIG_MMU 11262306a36Sopenharmony_ci show_val_kb(m, "MmapCopy: ", 11362306a36Sopenharmony_ci (unsigned long)atomic_long_read(&mmap_pages_allocated)); 11462306a36Sopenharmony_ci#endif 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci show_val_kb(m, "SwapTotal: ", i.totalswap); 11762306a36Sopenharmony_ci show_val_kb(m, "SwapFree: ", i.freeswap); 11862306a36Sopenharmony_ci#ifdef CONFIG_ZSWAP 11962306a36Sopenharmony_ci seq_printf(m, "Zswap: %8lu kB\n", 12062306a36Sopenharmony_ci (unsigned long)(zswap_pool_total_size >> 10)); 12162306a36Sopenharmony_ci seq_printf(m, "Zswapped: %8lu kB\n", 12262306a36Sopenharmony_ci (unsigned long)atomic_read(&zswap_stored_pages) << 12362306a36Sopenharmony_ci (PAGE_SHIFT - 10)); 12462306a36Sopenharmony_ci#endif 12562306a36Sopenharmony_ci show_val_kb(m, "Dirty: ", 12662306a36Sopenharmony_ci global_node_page_state(NR_FILE_DIRTY)); 12762306a36Sopenharmony_ci show_val_kb(m, "Writeback: ", 12862306a36Sopenharmony_ci global_node_page_state(NR_WRITEBACK)); 12962306a36Sopenharmony_ci show_val_kb(m, "AnonPages: ", 13062306a36Sopenharmony_ci global_node_page_state(NR_ANON_MAPPED)); 13162306a36Sopenharmony_ci show_val_kb(m, "Mapped: ", 13262306a36Sopenharmony_ci global_node_page_state(NR_FILE_MAPPED)); 13362306a36Sopenharmony_ci show_val_kb(m, "Shmem: ", i.sharedram); 13462306a36Sopenharmony_ci show_val_kb(m, "KReclaimable: ", sreclaimable + 13562306a36Sopenharmony_ci global_node_page_state(NR_KERNEL_MISC_RECLAIMABLE)); 13662306a36Sopenharmony_ci show_val_kb(m, "Slab: ", sreclaimable + sunreclaim); 13762306a36Sopenharmony_ci show_val_kb(m, "SReclaimable: ", sreclaimable); 13862306a36Sopenharmony_ci show_val_kb(m, "SUnreclaim: ", sunreclaim); 13962306a36Sopenharmony_ci seq_printf(m, "KernelStack: %8lu kB\n", 14062306a36Sopenharmony_ci global_node_page_state(NR_KERNEL_STACK_KB)); 14162306a36Sopenharmony_ci#ifdef CONFIG_SHADOW_CALL_STACK 14262306a36Sopenharmony_ci seq_printf(m, "ShadowCallStack:%8lu kB\n", 14362306a36Sopenharmony_ci global_node_page_state(NR_KERNEL_SCS_KB)); 14462306a36Sopenharmony_ci#endif 14562306a36Sopenharmony_ci show_val_kb(m, "PageTables: ", 14662306a36Sopenharmony_ci global_node_page_state(NR_PAGETABLE)); 14762306a36Sopenharmony_ci show_val_kb(m, "SecPageTables: ", 14862306a36Sopenharmony_ci global_node_page_state(NR_SECONDARY_PAGETABLE)); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci show_val_kb(m, "NFS_Unstable: ", 0); 15162306a36Sopenharmony_ci show_val_kb(m, "Bounce: ", 15262306a36Sopenharmony_ci global_zone_page_state(NR_BOUNCE)); 15362306a36Sopenharmony_ci show_val_kb(m, "WritebackTmp: ", 15462306a36Sopenharmony_ci global_node_page_state(NR_WRITEBACK_TEMP)); 15562306a36Sopenharmony_ci show_val_kb(m, "CommitLimit: ", vm_commit_limit()); 15662306a36Sopenharmony_ci show_val_kb(m, "Committed_AS: ", committed); 15762306a36Sopenharmony_ci seq_printf(m, "VmallocTotal: %8lu kB\n", 15862306a36Sopenharmony_ci (unsigned long)VMALLOC_TOTAL >> 10); 15962306a36Sopenharmony_ci show_val_kb(m, "VmallocUsed: ", vmalloc_nr_pages()); 16062306a36Sopenharmony_ci show_val_kb(m, "VmallocChunk: ", 0ul); 16162306a36Sopenharmony_ci show_val_kb(m, "Percpu: ", pcpu_nr_pages()); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci memtest_report_meminfo(m); 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci#ifdef CONFIG_MEMORY_FAILURE 16662306a36Sopenharmony_ci seq_printf(m, "HardwareCorrupted: %5lu kB\n", 16762306a36Sopenharmony_ci atomic_long_read(&num_poisoned_pages) << (PAGE_SHIFT - 10)); 16862306a36Sopenharmony_ci#endif 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci#ifdef CONFIG_TRANSPARENT_HUGEPAGE 17162306a36Sopenharmony_ci show_val_kb(m, "AnonHugePages: ", 17262306a36Sopenharmony_ci global_node_page_state(NR_ANON_THPS)); 17362306a36Sopenharmony_ci show_val_kb(m, "ShmemHugePages: ", 17462306a36Sopenharmony_ci global_node_page_state(NR_SHMEM_THPS)); 17562306a36Sopenharmony_ci show_val_kb(m, "ShmemPmdMapped: ", 17662306a36Sopenharmony_ci global_node_page_state(NR_SHMEM_PMDMAPPED)); 17762306a36Sopenharmony_ci show_val_kb(m, "FileHugePages: ", 17862306a36Sopenharmony_ci global_node_page_state(NR_FILE_THPS)); 17962306a36Sopenharmony_ci show_val_kb(m, "FilePmdMapped: ", 18062306a36Sopenharmony_ci global_node_page_state(NR_FILE_PMDMAPPED)); 18162306a36Sopenharmony_ci#endif 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci#ifdef CONFIG_CMA 18462306a36Sopenharmony_ci show_val_kb(m, "CmaTotal: ", totalcma_pages); 18562306a36Sopenharmony_ci show_val_kb(m, "CmaFree: ", 18662306a36Sopenharmony_ci global_zone_page_state(NR_FREE_CMA_PAGES)); 18762306a36Sopenharmony_ci#endif 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci#ifdef CONFIG_UNACCEPTED_MEMORY 19062306a36Sopenharmony_ci show_val_kb(m, "Unaccepted: ", 19162306a36Sopenharmony_ci global_zone_page_state(NR_UNACCEPTED)); 19262306a36Sopenharmony_ci#endif 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci hugetlb_report_meminfo(m); 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci arch_report_meminfo(m); 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci return 0; 19962306a36Sopenharmony_ci} 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_cistatic int __init proc_meminfo_init(void) 20262306a36Sopenharmony_ci{ 20362306a36Sopenharmony_ci struct proc_dir_entry *pde; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci pde = proc_create_single("meminfo", 0, NULL, meminfo_proc_show); 20662306a36Sopenharmony_ci pde_make_permanent(pde); 20762306a36Sopenharmony_ci return 0; 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_cifs_initcall(proc_meminfo_init); 210