aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorDmitry Fink <dmitry.fink@palm.com>2011-07-25 20:12:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 23:57:09 -0400
commitc15bef3099c346f2124367bff46954b59e13c3ee (patch)
treeec09c0b25eae42d6693a08decde7aee02f296978 /mm
parentc9d8c3d0896bfa5b57531ecc41a85ffbc6d87dbe (diff)
mmap: fix and tidy up overcommit page arithmetic
- shmem pages are not immediately available, but they are not potentially available either, even if we swap them out, they will just relocate from memory into swap, total amount of immediate and potentially available memory is not going to be affected, so we shouldn't count them as potentially free in the first place. - nr_free_pages() is not an expensive operation anymore, there is no need to split the decision making in two halves and repeat code. Signed-off-by: Dmitry Fink <dmitry.fink@palm.com> Reviewed-by: Minchan Kim <minchan.kim@gmail.com> Acked-by: Hugh Dickins <hughd@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/mmap.c34
-rw-r--r--mm/nommu.c34
2 files changed, 26 insertions, 42 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)
122 return 0; 122 return 0;
123 123
124 if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) { 124 if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) {
125 unsigned long n; 125 free = global_page_state(NR_FREE_PAGES);
126 free += global_page_state(NR_FILE_PAGES);
127
128 /*
129 * shmem pages shouldn't be counted as free in this
130 * case, they can't be purged, only swapped out, and
131 * that won't affect the overall amount of available
132 * memory in the system.
133 */
134 free -= global_page_state(NR_SHMEM);
126 135
127 free = global_page_state(NR_FILE_PAGES);
128 free += nr_swap_pages; 136 free += nr_swap_pages;
129 137
130 /* 138 /*
@@ -136,34 +144,18 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
136 free += global_page_state(NR_SLAB_RECLAIMABLE); 144 free += global_page_state(NR_SLAB_RECLAIMABLE);
137 145
138 /* 146 /*
139 * Leave the last 3% for root
140 */
141 if (!cap_sys_admin)
142 free -= free / 32;
143
144 if (free > pages)
145 return 0;
146
147 /*
148 * nr_free_pages() is very expensive on large systems,
149 * only call if we're about to fail.
150 */
151 n = nr_free_pages();
152
153 /*
154 * Leave reserved pages. The pages are not for anonymous pages. 147 * Leave reserved pages. The pages are not for anonymous pages.
155 */ 148 */
156 if (n <= totalreserve_pages) 149 if (free <= totalreserve_pages)
157 goto error; 150 goto error;
158 else 151 else
159 n -= totalreserve_pages; 152 free -= totalreserve_pages;
160 153
161 /* 154 /*
162 * Leave the last 3% for root 155 * Leave the last 3% for root
163 */ 156 */
164 if (!cap_sys_admin) 157 if (!cap_sys_admin)
165 n -= n / 32; 158 free -= free / 32;
166 free += n;
167 159
168 if (free > pages) 160 if (free > pages)
169 return 0; 161 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)
1884 return 0; 1884 return 0;
1885 1885
1886 if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) { 1886 if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) {
1887 unsigned long n; 1887 free = global_page_state(NR_FREE_PAGES);
1888 free += global_page_state(NR_FILE_PAGES);
1889
1890 /*
1891 * shmem pages shouldn't be counted as free in this
1892 * case, they can't be purged, only swapped out, and
1893 * that won't affect the overall amount of available
1894 * memory in the system.
1895 */
1896 free -= global_page_state(NR_SHMEM);
1888 1897
1889 free = global_page_state(NR_FILE_PAGES);
1890 free += nr_swap_pages; 1898 free += nr_swap_pages;
1891 1899
1892 /* 1900 /*
@@ -1898,34 +1906,18 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
1898 free += global_page_state(NR_SLAB_RECLAIMABLE); 1906 free += global_page_state(NR_SLAB_RECLAIMABLE);
1899 1907
1900 /* 1908 /*
1901 * Leave the last 3% for root
1902 */
1903 if (!cap_sys_admin)
1904 free -= free / 32;
1905
1906 if (free > pages)
1907 return 0;
1908
1909 /*
1910 * nr_free_pages() is very expensive on large systems,
1911 * only call if we're about to fail.
1912 */
1913 n = nr_free_pages();
1914
1915 /*
1916 * Leave reserved pages. The pages are not for anonymous pages. 1909 * Leave reserved pages. The pages are not for anonymous pages.
1917 */ 1910 */
1918 if (n <= totalreserve_pages) 1911 if (free <= totalreserve_pages)
1919 goto error; 1912 goto error;
1920 else 1913 else
1921 n -= totalreserve_pages; 1914 free -= totalreserve_pages;
1922 1915
1923 /* 1916 /*
1924 * Leave the last 3% for root 1917 * Leave the last 3% for root
1925 */ 1918 */
1926 if (!cap_sys_admin) 1919 if (!cap_sys_admin)
1927 n -= n / 32; 1920 free -= free / 32;
1928 free += n;
1929 1921
1930 if (free > pages) 1922 if (free > pages)
1931 return 0; 1923 return 0;