diff options
Diffstat (limited to 'mm/mmap.c')
| -rw-r--r-- | mm/mmap.c | 34 | 
1 files changed, 13 insertions, 21 deletions
diff --git a/mm/mmap.c b/mm/mmap.c index d49736ff8a8d..a65efd4db3e1 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -122,9 +122,17 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)  		return 0;  	if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) { -		unsigned long n; +		free = global_page_state(NR_FREE_PAGES); +		free += global_page_state(NR_FILE_PAGES); + +		/* +		 * shmem pages shouldn't be counted as free in this +		 * case, they can't be purged, only swapped out, and +		 * that won't affect the overall amount of available +		 * memory in the system. +		 */ +		free -= global_page_state(NR_SHMEM); -		free = global_page_state(NR_FILE_PAGES);  		free += nr_swap_pages;  		/* @@ -136,34 +144,18 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)  		free += global_page_state(NR_SLAB_RECLAIMABLE);  		/* -		 * Leave the last 3% for root -		 */ -		if (!cap_sys_admin) -			free -= free / 32; - -		if (free > pages) -			return 0; - -		/* -		 * nr_free_pages() is very expensive on large systems, -		 * only call if we're about to fail. -		 */ -		n = nr_free_pages(); - -		/*  		 * Leave reserved pages. The pages are not for anonymous pages.  		 */ -		if (n <= totalreserve_pages) +		if (free <= totalreserve_pages)  			goto error;  		else -			n -= totalreserve_pages; +			free -= totalreserve_pages;  		/*  		 * Leave the last 3% for root  		 */  		if (!cap_sys_admin) -			n -= n / 32; -		free += n; +			free -= free / 32;  		if (free > pages)  			return 0;  |