18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#include <linux/fs.h>
38c2ecf20Sopenharmony_ci#include <linux/init.h>
48c2ecf20Sopenharmony_ci#include <linux/kernel.h>
58c2ecf20Sopenharmony_ci#include <linux/mm.h>
68c2ecf20Sopenharmony_ci#include <linux/hugetlb.h>
78c2ecf20Sopenharmony_ci#include <linux/mman.h>
88c2ecf20Sopenharmony_ci#include <linux/mmzone.h>
98c2ecf20Sopenharmony_ci#include <linux/proc_fs.h>
108c2ecf20Sopenharmony_ci#include <linux/percpu.h>
118c2ecf20Sopenharmony_ci#include <linux/seq_file.h>
128c2ecf20Sopenharmony_ci#include <linux/swap.h>
138c2ecf20Sopenharmony_ci#include <linux/vmstat.h>
148c2ecf20Sopenharmony_ci#include <linux/atomic.h>
158c2ecf20Sopenharmony_ci#include <linux/vmalloc.h>
168c2ecf20Sopenharmony_ci#ifdef CONFIG_CMA
178c2ecf20Sopenharmony_ci#include <linux/cma.h>
188c2ecf20Sopenharmony_ci#endif
198c2ecf20Sopenharmony_ci#ifdef CONFIG_MEM_PURGEABLE
208c2ecf20Sopenharmony_ci#include <linux/mm_purgeable.h>
218c2ecf20Sopenharmony_ci#endif
228c2ecf20Sopenharmony_ci#include <asm/page.h>
238c2ecf20Sopenharmony_ci#include "internal.h"
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_civoid __attribute__((weak)) arch_report_meminfo(struct seq_file *m)
268c2ecf20Sopenharmony_ci{
278c2ecf20Sopenharmony_ci}
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cistatic void show_val_kb(struct seq_file *m, const char *s, unsigned long num)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	seq_put_decimal_ull_width(m, s, num << (PAGE_SHIFT - 10), 8);
328c2ecf20Sopenharmony_ci	seq_write(m, " kB\n", 4);
338c2ecf20Sopenharmony_ci}
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_cistatic int meminfo_proc_show(struct seq_file *m, void *v)
368c2ecf20Sopenharmony_ci{
378c2ecf20Sopenharmony_ci	struct sysinfo i;
388c2ecf20Sopenharmony_ci	unsigned long committed;
398c2ecf20Sopenharmony_ci	long cached;
408c2ecf20Sopenharmony_ci	long available;
418c2ecf20Sopenharmony_ci	unsigned long pages[NR_LRU_LISTS];
428c2ecf20Sopenharmony_ci	unsigned long sreclaimable, sunreclaim;
438c2ecf20Sopenharmony_ci	int lru;
448c2ecf20Sopenharmony_ci	unsigned long nr_purg_active = 0;
458c2ecf20Sopenharmony_ci	unsigned long nr_purg_inactive = 0;
468c2ecf20Sopenharmony_ci#ifdef CONFIG_MEM_PURGEABLE
478c2ecf20Sopenharmony_ci	unsigned long nr_purg_pined = 0;
488c2ecf20Sopenharmony_ci#endif
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	si_meminfo(&i);
518c2ecf20Sopenharmony_ci	si_swapinfo(&i);
528c2ecf20Sopenharmony_ci	committed = vm_memory_committed();
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	cached = global_node_page_state(NR_FILE_PAGES) -
558c2ecf20Sopenharmony_ci			total_swapcache_pages() - i.bufferram;
568c2ecf20Sopenharmony_ci	if (cached < 0)
578c2ecf20Sopenharmony_ci		cached = 0;
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
608c2ecf20Sopenharmony_ci		pages[lru] = global_node_page_state(NR_LRU_BASE + lru);
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci#ifdef CONFIG_MEM_PURGEABLE
638c2ecf20Sopenharmony_ci	nr_purg_active = pages[LRU_ACTIVE_PURGEABLE];
648c2ecf20Sopenharmony_ci	nr_purg_inactive = pages[LRU_INACTIVE_PURGEABLE];
658c2ecf20Sopenharmony_ci	purg_pages_info(NULL, &nr_purg_pined);
668c2ecf20Sopenharmony_ci	nr_purg_pined = min(nr_purg_pined, nr_purg_active + nr_purg_inactive);
678c2ecf20Sopenharmony_ci#endif
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	available = si_mem_available();
708c2ecf20Sopenharmony_ci	sreclaimable = global_node_page_state_pages(NR_SLAB_RECLAIMABLE_B);
718c2ecf20Sopenharmony_ci	sunreclaim = global_node_page_state_pages(NR_SLAB_UNRECLAIMABLE_B);
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	show_val_kb(m, "MemTotal:       ", i.totalram);
748c2ecf20Sopenharmony_ci	show_val_kb(m, "MemFree:        ", i.freeram);
758c2ecf20Sopenharmony_ci	show_val_kb(m, "MemAvailable:   ", available);
768c2ecf20Sopenharmony_ci	show_val_kb(m, "Buffers:        ", i.bufferram);
778c2ecf20Sopenharmony_ci	show_val_kb(m, "Cached:         ", cached);
788c2ecf20Sopenharmony_ci	show_val_kb(m, "SwapCached:     ", total_swapcache_pages());
798c2ecf20Sopenharmony_ci	show_val_kb(m, "Active:         ", pages[LRU_ACTIVE_ANON] +
808c2ecf20Sopenharmony_ci					   pages[LRU_ACTIVE_FILE] +
818c2ecf20Sopenharmony_ci					   nr_purg_active);
828c2ecf20Sopenharmony_ci	show_val_kb(m, "Inactive:       ", pages[LRU_INACTIVE_ANON] +
838c2ecf20Sopenharmony_ci					   pages[LRU_INACTIVE_FILE] +
848c2ecf20Sopenharmony_ci					   nr_purg_inactive);
858c2ecf20Sopenharmony_ci	show_val_kb(m, "Active(anon):   ", pages[LRU_ACTIVE_ANON]);
868c2ecf20Sopenharmony_ci	show_val_kb(m, "Inactive(anon): ", pages[LRU_INACTIVE_ANON]);
878c2ecf20Sopenharmony_ci	show_val_kb(m, "Active(file):   ", pages[LRU_ACTIVE_FILE]);
888c2ecf20Sopenharmony_ci	show_val_kb(m, "Inactive(file): ", pages[LRU_INACTIVE_FILE]);
898c2ecf20Sopenharmony_ci#ifdef CONFIG_MEM_PURGEABLE
908c2ecf20Sopenharmony_ci	show_val_kb(m, "Active(purg):   ", nr_purg_active);
918c2ecf20Sopenharmony_ci	show_val_kb(m, "Inactive(purg): ", nr_purg_inactive);
928c2ecf20Sopenharmony_ci	show_val_kb(m, "Pined(purg):    ", nr_purg_pined);
938c2ecf20Sopenharmony_ci#endif
948c2ecf20Sopenharmony_ci	show_val_kb(m, "Unevictable:    ", pages[LRU_UNEVICTABLE]);
958c2ecf20Sopenharmony_ci	show_val_kb(m, "Mlocked:        ", global_zone_page_state(NR_MLOCK));
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM
988c2ecf20Sopenharmony_ci	show_val_kb(m, "HighTotal:      ", i.totalhigh);
998c2ecf20Sopenharmony_ci	show_val_kb(m, "HighFree:       ", i.freehigh);
1008c2ecf20Sopenharmony_ci	show_val_kb(m, "LowTotal:       ", i.totalram - i.totalhigh);
1018c2ecf20Sopenharmony_ci	show_val_kb(m, "LowFree:        ", i.freeram - i.freehigh);
1028c2ecf20Sopenharmony_ci#endif
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci#ifndef CONFIG_MMU
1058c2ecf20Sopenharmony_ci	show_val_kb(m, "MmapCopy:       ",
1068c2ecf20Sopenharmony_ci		    (unsigned long)atomic_long_read(&mmap_pages_allocated));
1078c2ecf20Sopenharmony_ci#endif
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	show_val_kb(m, "SwapTotal:      ", i.totalswap);
1108c2ecf20Sopenharmony_ci	show_val_kb(m, "SwapFree:       ", i.freeswap);
1118c2ecf20Sopenharmony_ci	show_val_kb(m, "Dirty:          ",
1128c2ecf20Sopenharmony_ci		    global_node_page_state(NR_FILE_DIRTY));
1138c2ecf20Sopenharmony_ci	show_val_kb(m, "Writeback:      ",
1148c2ecf20Sopenharmony_ci		    global_node_page_state(NR_WRITEBACK));
1158c2ecf20Sopenharmony_ci	show_val_kb(m, "AnonPages:      ",
1168c2ecf20Sopenharmony_ci		    global_node_page_state(NR_ANON_MAPPED));
1178c2ecf20Sopenharmony_ci	show_val_kb(m, "Mapped:         ",
1188c2ecf20Sopenharmony_ci		    global_node_page_state(NR_FILE_MAPPED));
1198c2ecf20Sopenharmony_ci	show_val_kb(m, "Shmem:          ", i.sharedram);
1208c2ecf20Sopenharmony_ci	show_val_kb(m, "KReclaimable:   ", sreclaimable +
1218c2ecf20Sopenharmony_ci		    global_node_page_state(NR_KERNEL_MISC_RECLAIMABLE));
1228c2ecf20Sopenharmony_ci	show_val_kb(m, "Slab:           ", sreclaimable + sunreclaim);
1238c2ecf20Sopenharmony_ci	show_val_kb(m, "SReclaimable:   ", sreclaimable);
1248c2ecf20Sopenharmony_ci	show_val_kb(m, "SUnreclaim:     ", sunreclaim);
1258c2ecf20Sopenharmony_ci	seq_printf(m, "KernelStack:    %8lu kB\n",
1268c2ecf20Sopenharmony_ci		   global_node_page_state(NR_KERNEL_STACK_KB));
1278c2ecf20Sopenharmony_ci#ifdef CONFIG_SHADOW_CALL_STACK
1288c2ecf20Sopenharmony_ci	seq_printf(m, "ShadowCallStack:%8lu kB\n",
1298c2ecf20Sopenharmony_ci		   global_node_page_state(NR_KERNEL_SCS_KB));
1308c2ecf20Sopenharmony_ci#endif
1318c2ecf20Sopenharmony_ci	show_val_kb(m, "PageTables:     ",
1328c2ecf20Sopenharmony_ci		    global_zone_page_state(NR_PAGETABLE));
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	show_val_kb(m, "NFS_Unstable:   ", 0);
1358c2ecf20Sopenharmony_ci	show_val_kb(m, "Bounce:         ",
1368c2ecf20Sopenharmony_ci		    global_zone_page_state(NR_BOUNCE));
1378c2ecf20Sopenharmony_ci	show_val_kb(m, "WritebackTmp:   ",
1388c2ecf20Sopenharmony_ci		    global_node_page_state(NR_WRITEBACK_TEMP));
1398c2ecf20Sopenharmony_ci	show_val_kb(m, "CommitLimit:    ", vm_commit_limit());
1408c2ecf20Sopenharmony_ci	show_val_kb(m, "Committed_AS:   ", committed);
1418c2ecf20Sopenharmony_ci	seq_printf(m, "VmallocTotal:   %8lu kB\n",
1428c2ecf20Sopenharmony_ci		   (unsigned long)VMALLOC_TOTAL >> 10);
1438c2ecf20Sopenharmony_ci	show_val_kb(m, "VmallocUsed:    ", vmalloc_nr_pages());
1448c2ecf20Sopenharmony_ci	show_val_kb(m, "VmallocChunk:   ", 0ul);
1458c2ecf20Sopenharmony_ci	show_val_kb(m, "Percpu:         ", pcpu_nr_pages());
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci#ifdef CONFIG_PAGE_TRACING
1488c2ecf20Sopenharmony_ci	show_val_kb(m, "Skb:            ", global_zone_page_state(NR_SKB_PAGES));
1498c2ecf20Sopenharmony_ci#endif
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci#ifdef CONFIG_MEMORY_FAILURE
1528c2ecf20Sopenharmony_ci	seq_printf(m, "HardwareCorrupted: %5lu kB\n",
1538c2ecf20Sopenharmony_ci		   atomic_long_read(&num_poisoned_pages) << (PAGE_SHIFT - 10));
1548c2ecf20Sopenharmony_ci#endif
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci#ifdef CONFIG_TRANSPARENT_HUGEPAGE
1578c2ecf20Sopenharmony_ci	show_val_kb(m, "AnonHugePages:  ",
1588c2ecf20Sopenharmony_ci		    global_node_page_state(NR_ANON_THPS) * HPAGE_PMD_NR);
1598c2ecf20Sopenharmony_ci	show_val_kb(m, "ShmemHugePages: ",
1608c2ecf20Sopenharmony_ci		    global_node_page_state(NR_SHMEM_THPS) * HPAGE_PMD_NR);
1618c2ecf20Sopenharmony_ci	show_val_kb(m, "ShmemPmdMapped: ",
1628c2ecf20Sopenharmony_ci		    global_node_page_state(NR_SHMEM_PMDMAPPED) * HPAGE_PMD_NR);
1638c2ecf20Sopenharmony_ci	show_val_kb(m, "FileHugePages:  ",
1648c2ecf20Sopenharmony_ci		    global_node_page_state(NR_FILE_THPS) * HPAGE_PMD_NR);
1658c2ecf20Sopenharmony_ci	show_val_kb(m, "FilePmdMapped:  ",
1668c2ecf20Sopenharmony_ci		    global_node_page_state(NR_FILE_PMDMAPPED) * HPAGE_PMD_NR);
1678c2ecf20Sopenharmony_ci#endif
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci#ifdef CONFIG_CMA
1708c2ecf20Sopenharmony_ci	show_val_kb(m, "CmaTotal:       ", totalcma_pages);
1718c2ecf20Sopenharmony_ci	show_val_kb(m, "CmaFree:        ",
1728c2ecf20Sopenharmony_ci		    global_zone_page_state(NR_FREE_CMA_PAGES));
1738c2ecf20Sopenharmony_ci#endif
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci#ifdef CONFIG_PAGE_TRACING
1768c2ecf20Sopenharmony_ci	seq_puts(m, "GLTrack:               - kB\n");
1778c2ecf20Sopenharmony_ci	show_val_kb(m, "ZspageUsed:	", global_zone_page_state(NR_ZSPAGES));
1788c2ecf20Sopenharmony_ci#endif
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	hugetlb_report_meminfo(m);
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	arch_report_meminfo(m);
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	return 0;
1858c2ecf20Sopenharmony_ci}
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_cistatic int __init proc_meminfo_init(void)
1888c2ecf20Sopenharmony_ci{
1898c2ecf20Sopenharmony_ci	proc_create_single("meminfo", 0, NULL, meminfo_proc_show);
1908c2ecf20Sopenharmony_ci	return 0;
1918c2ecf20Sopenharmony_ci}
1928c2ecf20Sopenharmony_cifs_initcall(proc_meminfo_init);
193