Branch data Line data Source code
1 : : #include <linux/fs.h>
2 : : #include <linux/init.h>
3 : : #include <linux/kernel.h>
4 : : #include <linux/mm.h>
5 : : #include <linux/hugetlb.h>
6 : : #include <linux/mman.h>
7 : : #include <linux/mmzone.h>
8 : : #include <linux/proc_fs.h>
9 : : #include <linux/quicklist.h>
10 : : #include <linux/seq_file.h>
11 : : #include <linux/swap.h>
12 : : #include <linux/vmstat.h>
13 : : #include <linux/atomic.h>
14 : : #include <linux/vmalloc.h>
15 : : #include <asm/page.h>
16 : : #include <asm/pgtable.h>
17 : : #include "internal.h"
18 : :
19 : 0 : void __attribute__((weak)) arch_report_meminfo(struct seq_file *m)
20 : : {
21 : 587 : }
22 : :
23 : 0 : static int meminfo_proc_show(struct seq_file *m, void *v)
24 : : {
25 : : struct sysinfo i;
26 : : unsigned long committed;
27 : : struct vmalloc_info vmi;
28 : : long cached;
29 : : long available;
30 : : unsigned long pagecache;
31 : : unsigned long wmark_low = 0;
32 : : unsigned long pages[NR_LRU_LISTS];
33 : : struct zone *zone;
34 : : int lru;
35 : :
36 : : /*
37 : : * display in kilobytes.
38 : : */
39 : : #define K(x) ((x) << (PAGE_SHIFT - 10))
40 : 587 : si_meminfo(&i);
41 : 587 : si_swapinfo(&i);
42 : 1174 : committed = percpu_counter_read_positive(&vm_committed_as);
43 : :
44 : 1174 : cached = global_page_state(NR_FILE_PAGES) -
45 : 587 : total_swapcache_pages() - i.bufferram;
46 [ - + ]: 587 : if (cached < 0)
47 : : cached = 0;
48 : :
49 : 587 : get_vmalloc_info(&vmi);
50 : :
51 [ + + ]: 3522 : for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
52 : 5870 : pages[lru] = global_page_state(NR_LRU_BASE + lru);
53 : :
54 [ + + ]: 2348 : for_each_zone(zone)
55 : 1761 : wmark_low += zone->watermark[WMARK_LOW];
56 : :
57 : : /*
58 : : * Estimate the amount of memory available for userspace allocations,
59 : : * without causing swapping.
60 : : *
61 : : * Free memory cannot be taken below the low watermark, before the
62 : : * system starts swapping.
63 : : */
64 : 587 : available = i.freeram - wmark_low;
65 : :
66 : : /*
67 : : * Not all the page cache can be freed, otherwise the system will
68 : : * start swapping. Assume at least half of the page cache, or the
69 : : * low watermark worth of cache, needs to stay.
70 : : */
71 : 587 : pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
72 : 587 : pagecache -= min(pagecache / 2, wmark_low);
73 : 587 : available += pagecache;
74 : :
75 : : /*
76 : : * Part of the reclaimable swap consists of items that are in use,
77 : : * and cannot be freed. Cap this estimate at the low watermark.
78 : : */
79 : 587 : available += global_page_state(NR_SLAB_RECLAIMABLE) -
80 : 587 : min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low);
81 : :
82 [ - + ]: 587 : if (available < 0)
83 : : available = 0;
84 : :
85 : : /*
86 : : * Tagged format, for easy grepping and expansion.
87 : : */
88 : 587 : seq_printf(m,
89 : : "MemTotal: %8lu kB\n"
90 : : "MemFree: %8lu kB\n"
91 : : "MemAvailable: %8lu kB\n"
92 : : "Buffers: %8lu kB\n"
93 : : "Cached: %8lu kB\n"
94 : : "SwapCached: %8lu kB\n"
95 : : "Active: %8lu kB\n"
96 : : "Inactive: %8lu kB\n"
97 : : "Active(anon): %8lu kB\n"
98 : : "Inactive(anon): %8lu kB\n"
99 : : "Active(file): %8lu kB\n"
100 : : "Inactive(file): %8lu kB\n"
101 : : "Unevictable: %8lu kB\n"
102 : : "Mlocked: %8lu kB\n"
103 : : #ifdef CONFIG_HIGHMEM
104 : : "HighTotal: %8lu kB\n"
105 : : "HighFree: %8lu kB\n"
106 : : "LowTotal: %8lu kB\n"
107 : : "LowFree: %8lu kB\n"
108 : : #endif
109 : : #ifndef CONFIG_MMU
110 : : "MmapCopy: %8lu kB\n"
111 : : #endif
112 : : "SwapTotal: %8lu kB\n"
113 : : "SwapFree: %8lu kB\n"
114 : : "Dirty: %8lu kB\n"
115 : : "Writeback: %8lu kB\n"
116 : : "AnonPages: %8lu kB\n"
117 : : "Mapped: %8lu kB\n"
118 : : "Shmem: %8lu kB\n"
119 : : "Slab: %8lu kB\n"
120 : : "SReclaimable: %8lu kB\n"
121 : : "SUnreclaim: %8lu kB\n"
122 : : "KernelStack: %8lu kB\n"
123 : : "PageTables: %8lu kB\n"
124 : : #ifdef CONFIG_QUICKLIST
125 : : "Quicklists: %8lu kB\n"
126 : : #endif
127 : : "NFS_Unstable: %8lu kB\n"
128 : : "Bounce: %8lu kB\n"
129 : : "WritebackTmp: %8lu kB\n"
130 : : "CommitLimit: %8lu kB\n"
131 : : "Committed_AS: %8lu kB\n"
132 : : "VmallocTotal: %8lu kB\n"
133 : : "VmallocUsed: %8lu kB\n"
134 : : "VmallocChunk: %8lu kB\n"
135 : : #ifdef CONFIG_MEMORY_FAILURE
136 : : "HardwareCorrupted: %5lu kB\n"
137 : : #endif
138 : : #ifdef CONFIG_TRANSPARENT_HUGEPAGE
139 : : "AnonHugePages: %8lu kB\n"
140 : : #endif
141 : : ,
142 : 587 : K(i.totalram),
143 : : K(i.freeram),
144 : : K(available),
145 : 587 : K(i.bufferram),
146 : : K(cached),
147 : 587 : K(total_swapcache_pages()),
148 : 587 : K(pages[LRU_ACTIVE_ANON] + pages[LRU_ACTIVE_FILE]),
149 : 587 : K(pages[LRU_INACTIVE_ANON] + pages[LRU_INACTIVE_FILE]),
150 : : K(pages[LRU_ACTIVE_ANON]),
151 : : K(pages[LRU_INACTIVE_ANON]),
152 : : K(pages[LRU_ACTIVE_FILE]),
153 : : K(pages[LRU_INACTIVE_FILE]),
154 : 587 : K(pages[LRU_UNEVICTABLE]),
155 : : K(global_page_state(NR_MLOCK)),
156 : : #ifdef CONFIG_HIGHMEM
157 : 587 : K(i.totalhigh),
158 : 587 : K(i.freehigh),
159 : 587 : K(i.totalram-i.totalhigh),
160 : 587 : K(i.freeram-i.freehigh),
161 : : #endif
162 : : #ifndef CONFIG_MMU
163 : : K((unsigned long) atomic_long_read(&mmap_pages_allocated)),
164 : : #endif
165 : 587 : K(i.totalswap),
166 : 587 : K(i.freeswap),
167 : : K(global_page_state(NR_FILE_DIRTY)),
168 : : K(global_page_state(NR_WRITEBACK)),
169 : : K(global_page_state(NR_ANON_PAGES)),
170 : : K(global_page_state(NR_FILE_MAPPED)),
171 : : K(global_page_state(NR_SHMEM)),
172 : 587 : K(global_page_state(NR_SLAB_RECLAIMABLE) +
173 : : global_page_state(NR_SLAB_UNRECLAIMABLE)),
174 : : K(global_page_state(NR_SLAB_RECLAIMABLE)),
175 : : K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
176 : 0 : global_page_state(NR_KERNEL_STACK) * THREAD_SIZE / 1024,
177 : : K(global_page_state(NR_PAGETABLE)),
178 : : #ifdef CONFIG_QUICKLIST
179 : : K(quicklist_total_size()),
180 : : #endif
181 : : K(global_page_state(NR_UNSTABLE_NFS)),
182 : : K(global_page_state(NR_BOUNCE)),
183 : : K(global_page_state(NR_WRITEBACK_TEMP)),
184 : 0 : K(vm_commit_limit()),
185 : : K(committed),
186 : 587 : (unsigned long)VMALLOC_TOTAL >> 10,
187 : 587 : vmi.used >> 10,
188 : 587 : vmi.largest_chunk >> 10
189 : : #ifdef CONFIG_MEMORY_FAILURE
190 : : ,atomic_long_read(&num_poisoned_pages) << (PAGE_SHIFT - 10)
191 : : #endif
192 : : #ifdef CONFIG_TRANSPARENT_HUGEPAGE
193 : : ,K(global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) *
194 : : HPAGE_PMD_NR)
195 : : #endif
196 : : );
197 : :
198 : : hugetlb_report_meminfo(m);
199 : :
200 : 587 : arch_report_meminfo(m);
201 : :
202 : 587 : return 0;
203 : : #undef K
204 : : }
205 : :
206 : 0 : static int meminfo_proc_open(struct inode *inode, struct file *file)
207 : : {
208 : 587 : return single_open(file, meminfo_proc_show, NULL);
209 : : }
210 : :
211 : : static const struct file_operations meminfo_proc_fops = {
212 : : .open = meminfo_proc_open,
213 : : .read = seq_read,
214 : : .llseek = seq_lseek,
215 : : .release = single_release,
216 : : };
217 : :
218 : 0 : static int __init proc_meminfo_init(void)
219 : : {
220 : : proc_create("meminfo", 0, NULL, &meminfo_proc_fops);
221 : 0 : return 0;
222 : : }
223 : : fs_initcall(proc_meminfo_init);
|