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; /* @@ -135,36 +143,20 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) */ free += global_page_state(NR_SLAB_RECLAIMABLE); + /* + * Leave reserved pages. The pages are not for anonymous pages. + */ + if (free <= totalreserve_pages) + goto error; + else + free -= totalreserve_pages; + /* * 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) - goto error; - else - n -= totalreserve_pages; - - /* - * Leave the last 3% for root - */ - if (!cap_sys_admin) - n -= n / 32; - free += n; - if (free > pages) return 0; diff --git a/mm/nommu.c b/mm/nommu.c index 5c5c2d4b1807..4358032566e9 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1884,9 +1884,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; /* @@ -1897,36 +1905,20 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) */ free += global_page_state(NR_SLAB_RECLAIMABLE); + /* + * Leave reserved pages. The pages are not for anonymous pages. + */ + if (free <= totalreserve_pages) + goto error; + else + free -= totalreserve_pages; + /* * 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) - goto error; - else - n -= totalreserve_pages; - - /* - * Leave the last 3% for root - */ - if (!cap_sys_admin) - n -= n / 32; - free += n; - if (free > pages) return 0;