| 1 | |
| 2 | #include <linux/fs.h>
|
| 3 | #include <linux/init.h>
|
| 4 | #include <linux/kernel.h>
|
| 5 | #include <linux/mm.h>
|
| 6 | #include <linux/hugetlb.h>
|
| 7 | #include <linux/mman.h>
|
| 8 | #include <linux/mmzone.h>
|
| 9 | #include <linux/memblock.h>
|
| 10 | #include <linux/proc_fs.h>
|
| 11 | #include <linux/percpu.h>
|
| 12 | #include <linux/seq_file.h>
|
| 13 | #include <linux/swap.h>
|
| 14 | #include <linux/vmstat.h>
|
| 15 | #include <linux/atomic.h>
|
| 16 | #include <linux/vmalloc.h>
|
| 17 | #ifdef CONFIG_CMA
|
| 18 | #include <linux/cma.h>
|
| 19 | #endif
|
| 20 | #include <linux/zswap.h>
|
| 21 | #include <asm/page.h>
|
| 22 | #include "internal.h"
|
| 23 |
|
| 24 | void __attribute__((weak)) arch_report_meminfo(struct seq_file *m)
|
| 25 | {
|
| 26 | }
|
| 27 |
|
| 28 | static void show_val_kb(struct seq_file *m, const char *s, unsigned long num)
|
| 29 | {
|
| 30 | seq_put_decimal_ull_width(m, s, num << (PAGE_SHIFT - 10), 8);
|
| 31 | seq_write(m, " kB\n", 4);
|
| 32 | }
|
| 33 |
|
| 34 | static int meminfo_proc_show(struct seq_file *m, void *v)
|
| 35 | {
|
| 36 | struct sysinfo i;
|
| 37 | unsigned long committed;
|
| 38 | long cached;
|
| 39 | long available;
|
| 40 | unsigned long pages[NR_LRU_LISTS];
|
| 41 | unsigned long sreclaimable, sunreclaim;
|
| 42 | int lru;
|
| 43 |
|
| 44 | si_meminfo(&i);
|
| 45 | si_swapinfo(&i);
|
| 46 | committed = vm_memory_committed();
|
| 47 |
|
| 48 | cached = global_node_page_state(NR_FILE_PAGES) -
|
| 49 | total_swapcache_pages() - i.bufferram;
|
| 50 | if (cached < 0)
|
| 51 | cached = 0;
|
| 52 |
|
| 53 | for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
|
| 54 | pages[lru] = global_node_page_state(NR_LRU_BASE + lru);
|
| 55 |
|
| 56 | available = si_mem_available();
|
| 57 | sreclaimable = global_node_page_state_pages(NR_SLAB_RECLAIMABLE_B);
|
| 58 | sunreclaim = global_node_page_state_pages(NR_SLAB_UNRECLAIMABLE_B);
|
| 59 |
|
| 60 | show_val_kb(m, "MemTotal: ", i.totalram);
|
| 61 | show_val_kb(m, "MemFree: ", i.freeram);
|
| 62 | show_val_kb(m, "MemAvailable: ", available);
|
| 63 | show_val_kb(m, "Buffers: ", i.bufferram);
|
| 64 | show_val_kb(m, "Cached: ", cached);
|
| 65 | show_val_kb(m, "SwapCached: ", total_swapcache_pages());
|
| 66 | show_val_kb(m, "Active: ", pages[LRU_ACTIVE_ANON] +
|
| 67 | pages[LRU_ACTIVE_FILE]);
|
| 68 | show_val_kb(m, "Inactive: ", pages[LRU_INACTIVE_ANON] +
|
| 69 | pages[LRU_INACTIVE_FILE]);
|
| 70 | show_val_kb(m, "Active(anon): ", pages[LRU_ACTIVE_ANON]);
|
| 71 | show_val_kb(m, "Inactive(anon): ", pages[LRU_INACTIVE_ANON]);
|
| 72 | show_val_kb(m, "Active(file): ", pages[LRU_ACTIVE_FILE]);
|
| 73 | show_val_kb(m, "Inactive(file): ", pages[LRU_INACTIVE_FILE]);
|
| 74 | show_val_kb(m, "Unevictable: ", pages[LRU_UNEVICTABLE]);
|
| 75 | show_val_kb(m, "Mlocked: ", global_zone_page_state(NR_MLOCK));
|
| 76 |
|
| 77 | #ifdef CONFIG_HIGHMEM
|
| 78 | show_val_kb(m, "HighTotal: ", i.totalhigh);
|
| 79 | show_val_kb(m, "HighFree: ", i.freehigh);
|
| 80 | show_val_kb(m, "LowTotal: ", i.totalram - i.totalhigh);
|
| 81 | show_val_kb(m, "LowFree: ", i.freeram - i.freehigh);
|
| 82 | #endif
|
| 83 |
|
| 84 | #ifndef CONFIG_MMU
|
| 85 | show_val_kb(m, "MmapCopy: ",
|
| 86 | (unsigned long)atomic_long_read(&mmap_pages_allocated));
|
| 87 | #endif
|
| 88 |
|
| 89 | show_val_kb(m, "SwapTotal: ", i.totalswap);
|
| 90 | show_val_kb(m, "SwapFree: ", i.freeswap);
|
| 91 | #ifdef CONFIG_ZSWAP
|
| 92 | show_val_kb(m, "Zswap: ", zswap_total_pages());
|
| 93 | seq_printf(m, "Zswapped: %8lu kB\n",
|
| 94 | (unsigned long)atomic_long_read(&zswap_stored_pages) <<
|
| 95 | (PAGE_SHIFT - 10));
|
| 96 | #endif
|
| 97 | show_val_kb(m, "Dirty: ",
|
| 98 | global_node_page_state(NR_FILE_DIRTY));
|
| 99 | show_val_kb(m, "Writeback: ",
|
| 100 | global_node_page_state(NR_WRITEBACK));
|
| 101 | show_val_kb(m, "AnonPages: ",
|
| 102 | global_node_page_state(NR_ANON_MAPPED));
|
| 103 | show_val_kb(m, "Mapped: ",
|
| 104 | global_node_page_state(NR_FILE_MAPPED));
|
| 105 | show_val_kb(m, "Shmem: ", i.sharedram);
|
| 106 | show_val_kb(m, "KReclaimable: ", sreclaimable +
|
| 107 | global_node_page_state(NR_KERNEL_MISC_RECLAIMABLE));
|
| 108 | show_val_kb(m, "Slab: ", sreclaimable + sunreclaim);
|
| 109 | show_val_kb(m, "SReclaimable: ", sreclaimable);
|
| 110 | show_val_kb(m, "SUnreclaim: ", sunreclaim);
|
| 111 | seq_printf(m, "KernelStack: %8lu kB\n",
|
| 112 | global_node_page_state(NR_KERNEL_STACK_KB));
|
| 113 | #ifdef CONFIG_SHADOW_CALL_STACK
|
| 114 | seq_printf(m, "ShadowCallStack:%8lu kB\n",
|
| 115 | global_node_page_state(NR_KERNEL_SCS_KB));
|
| 116 | #endif
|
| 117 | show_val_kb(m, "PageTables: ",
|
| 118 | global_node_page_state(NR_PAGETABLE));
|
| 119 | show_val_kb(m, "SecPageTables: ",
|
| 120 | global_node_page_state(NR_SECONDARY_PAGETABLE));
|
| 121 |
|
| 122 | show_val_kb(m, "NFS_Unstable: ", 0);
|
| 123 | show_val_kb(m, "Bounce: ", 0);
|
| 124 | show_val_kb(m, "WritebackTmp: ", 0);
|
| 125 | show_val_kb(m, "CommitLimit: ", vm_commit_limit());
|
| 126 | show_val_kb(m, "Committed_AS: ", committed);
|
| 127 | seq_printf(m, "VmallocTotal: %8lu kB\n",
|
| 128 | (unsigned long)VMALLOC_TOTAL >> 10);
|
| 129 | show_val_kb(m, "VmallocUsed: ",
|
| 130 | global_node_page_state(NR_VMALLOC));
|
| 131 | show_val_kb(m, "VmallocChunk: ", 0ul);
|
| 132 | show_val_kb(m, "Percpu: ", pcpu_nr_pages());
|
| 133 |
|
| 134 | memtest_report_meminfo(m);
|
| 135 |
|
| 136 | #ifdef CONFIG_MEMORY_FAILURE
|
| 137 | seq_printf(m, "HardwareCorrupted: %5lu kB\n",
|
| 138 | atomic_long_read(&num_poisoned_pages) << (PAGE_SHIFT - 10));
|
| 139 | #endif
|
| 140 |
|
| 141 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
| 142 | show_val_kb(m, "AnonHugePages: ",
|
| 143 | global_node_page_state(NR_ANON_THPS));
|
| 144 | show_val_kb(m, "ShmemHugePages: ",
|
| 145 | global_node_page_state(NR_SHMEM_THPS));
|
| 146 | show_val_kb(m, "ShmemPmdMapped: ",
|
| 147 | global_node_page_state(NR_SHMEM_PMDMAPPED));
|
| 148 | show_val_kb(m, "FileHugePages: ",
|
| 149 | global_node_page_state(NR_FILE_THPS));
|
| 150 | show_val_kb(m, "FilePmdMapped: ",
|
| 151 | global_node_page_state(NR_FILE_PMDMAPPED));
|
| 152 | #endif
|
| 153 |
|
| 154 | #ifdef CONFIG_CMA
|
| 155 | show_val_kb(m, "CmaTotal: ", totalcma_pages);
|
| 156 | show_val_kb(m, "CmaFree: ",
|
| 157 | global_zone_page_state(NR_FREE_CMA_PAGES));
|
| 158 | #endif
|
| 159 |
|
| 160 | #ifdef CONFIG_UNACCEPTED_MEMORY
|
| 161 | show_val_kb(m, "Unaccepted: ",
|
| 162 | global_zone_page_state(NR_UNACCEPTED));
|
| 163 | #endif
|
| 164 | show_val_kb(m, "Balloon: ",
|
| 165 | global_node_page_state(NR_BALLOON_PAGES));
|
| 166 |
|
| 167 | show_val_kb(m, "GPUActive: ",
|
| 168 | global_node_page_state(NR_GPU_ACTIVE));
|
| 169 |
|
| 170 | show_val_kb(m, "GPUReclaim: ",
|
| 171 | global_node_page_state(NR_GPU_RECLAIM));
|
| 172 |
|
| 173 | hugetlb_report_meminfo(m);
|
| 174 |
|
| 175 | arch_report_meminfo(m);
|
| 176 |
|
| 177 | return 0;
|
| 178 | }
|
| 179 |
|
| 180 | static int __init proc_meminfo_init(void)
|
| 181 | {
|
| 182 | struct proc_dir_entry *pde;
|
| 183 |
|
| 184 | pde = proc_create_single("meminfo", 0, NULL, meminfo_proc_show);
|
| 185 | pde_make_permanent(pde);
|
| 186 | return 0;
|
| 187 | }
|
| 188 | fs_initcall(proc_meminfo_init);
|