diff options
Diffstat (limited to 'fs/proc/meminfo.c')
| -rw-r--r-- | fs/proc/meminfo.c | 62 | 
1 files changed, 52 insertions, 10 deletions
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index a65239cfd97..7445af0b1aa 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c @@ -1,8 +1,8 @@  #include <linux/fs.h> -#include <linux/hugetlb.h>  #include <linux/init.h>  #include <linux/kernel.h>  #include <linux/mm.h> +#include <linux/hugetlb.h>  #include <linux/mman.h>  #include <linux/mmzone.h>  #include <linux/proc_fs.h> @@ -10,7 +10,8 @@  #include <linux/seq_file.h>  #include <linux/swap.h>  #include <linux/vmstat.h> -#include <asm/atomic.h> +#include <linux/atomic.h> +#include <linux/vmalloc.h>  #include <asm/page.h>  #include <asm/pgtable.h>  #include "internal.h" @@ -23,10 +24,13 @@ static int meminfo_proc_show(struct seq_file *m, void *v)  {  	struct sysinfo i;  	unsigned long committed; -	unsigned long allowed;  	struct vmalloc_info vmi;  	long cached; +	long available; +	unsigned long pagecache; +	unsigned long wmark_low = 0;  	unsigned long pages[NR_LRU_LISTS]; +	struct zone *zone;  	int lru;  /* @@ -36,11 +40,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v)  	si_meminfo(&i);  	si_swapinfo(&i);  	committed = percpu_counter_read_positive(&vm_committed_as); -	allowed = ((totalram_pages - hugetlb_total_pages()) -		* sysctl_overcommit_ratio / 100) + total_swap_pages;  	cached = global_page_state(NR_FILE_PAGES) - -			total_swapcache_pages - i.bufferram; +			total_swapcache_pages() - i.bufferram;  	if (cached < 0)  		cached = 0; @@ -49,12 +51,44 @@ static int meminfo_proc_show(struct seq_file *m, void *v)  	for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)  		pages[lru] = global_page_state(NR_LRU_BASE + lru); +	for_each_zone(zone) +		wmark_low += zone->watermark[WMARK_LOW]; + +	/* +	 * Estimate the amount of memory available for userspace allocations, +	 * without causing swapping. +	 * +	 * Free memory cannot be taken below the low watermark, before the +	 * system starts swapping. +	 */ +	available = i.freeram - wmark_low; + +	/* +	 * Not all the page cache can be freed, otherwise the system will +	 * start swapping. Assume at least half of the page cache, or the +	 * low watermark worth of cache, needs to stay. +	 */ +	pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE]; +	pagecache -= min(pagecache / 2, wmark_low); +	available += pagecache; + +	/* +	 * Part of the reclaimable slab consists of items that are in use, +	 * and cannot be freed. Cap this estimate at the low watermark. +	 */ +	available += global_page_state(NR_SLAB_RECLAIMABLE) - +		     min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low); + +	if (available < 0) +		available = 0; +  	/*  	 * Tagged format, for easy grepping and expansion.  	 */  	seq_printf(m,  		"MemTotal:       %8lu kB\n"  		"MemFree:        %8lu kB\n" +		"MemAvailable:   %8lu kB\n"  		"Buffers:        %8lu kB\n"  		"Cached:         %8lu kB\n"  		"SwapCached:     %8lu kB\n" @@ -101,12 +135,16 @@ static int meminfo_proc_show(struct seq_file *m, void *v)  #ifdef CONFIG_MEMORY_FAILURE  		"HardwareCorrupted: %5lu kB\n"  #endif +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +		"AnonHugePages:  %8lu kB\n" +#endif  		,  		K(i.totalram),  		K(i.freeram), +		K(available),  		K(i.bufferram),  		K(cached), -		K(total_swapcache_pages), +		K(total_swapcache_pages()),  		K(pages[LRU_ACTIVE_ANON]   + pages[LRU_ACTIVE_FILE]),  		K(pages[LRU_INACTIVE_ANON] + pages[LRU_INACTIVE_FILE]),  		K(pages[LRU_ACTIVE_ANON]), @@ -143,13 +181,17 @@ static int meminfo_proc_show(struct seq_file *m, void *v)  		K(global_page_state(NR_UNSTABLE_NFS)),  		K(global_page_state(NR_BOUNCE)),  		K(global_page_state(NR_WRITEBACK_TEMP)), -		K(allowed), +		K(vm_commit_limit()),  		K(committed),  		(unsigned long)VMALLOC_TOTAL >> 10,  		vmi.used >> 10,  		vmi.largest_chunk >> 10  #ifdef CONFIG_MEMORY_FAILURE -		,atomic_long_read(&mce_bad_pages) << (PAGE_SHIFT - 10) +		,atomic_long_read(&num_poisoned_pages) << (PAGE_SHIFT - 10) +#endif +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +		,K(global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * +		   HPAGE_PMD_NR)  #endif  		); @@ -178,4 +220,4 @@ static int __init proc_meminfo_init(void)  	proc_create("meminfo", 0, NULL, &meminfo_proc_fops);  	return 0;  } -module_init(proc_meminfo_init); +fs_initcall(proc_meminfo_init);  | 
