aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>2012-03-21 19:33:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 20:54:56 -0400
commitb716ad953a2bc4a543143c1d9836b7007a4b182f (patch)
tree99791c6c857b1ff7b922eaa0163ec3c912549009
parentf44d21985eb6af7361d3785e26923355172147bd (diff)
mm: search from free_area_cache for the bigger size
If the required size is bigger than cached_hole_size it is better to search from free_area_cache - it is easier to get a free region, specifically for the 64 bit process whose address space is large enough Do it just as hugetlb_get_unmapped_area_topdown() in arch/x86/mm/hugetlbpage.c Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Michal Hocko <mhocko@suse.cz> Cc: Hillf Danton <dhillf@gmail.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Rik van Riel <riel@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/x86/kernel/sys_x86_64.c34
-rw-r--r--mm/mmap.c36
2 files changed, 38 insertions, 32 deletions
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 051489082d59..ef59642ff1bf 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -195,7 +195,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
195{ 195{
196 struct vm_area_struct *vma; 196 struct vm_area_struct *vma;
197 struct mm_struct *mm = current->mm; 197 struct mm_struct *mm = current->mm;
198 unsigned long addr = addr0; 198 unsigned long addr = addr0, start_addr;
199 199
200 /* requested length too big for entire address space */ 200 /* requested length too big for entire address space */
201 if (len > TASK_SIZE) 201 if (len > TASK_SIZE)
@@ -223,25 +223,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
223 mm->free_area_cache = mm->mmap_base; 223 mm->free_area_cache = mm->mmap_base;
224 } 224 }
225 225
226try_again:
226 /* either no address requested or can't fit in requested address hole */ 227 /* either no address requested or can't fit in requested address hole */
227 addr = mm->free_area_cache; 228 start_addr = addr = mm->free_area_cache;
228
229 /* make sure it can fit in the remaining address space */
230 if (addr > len) {
231 unsigned long tmp_addr = align_addr(addr - len, filp,
232 ALIGN_TOPDOWN);
233
234 vma = find_vma(mm, tmp_addr);
235 if (!vma || tmp_addr + len <= vma->vm_start)
236 /* remember the address as a hint for next time */
237 return mm->free_area_cache = tmp_addr;
238 }
239
240 if (mm->mmap_base < len)
241 goto bottomup;
242 229
243 addr = mm->mmap_base-len; 230 if (addr < len)
231 goto fail;
244 232
233 addr -= len;
245 do { 234 do {
246 addr = align_addr(addr, filp, ALIGN_TOPDOWN); 235 addr = align_addr(addr, filp, ALIGN_TOPDOWN);
247 236
@@ -263,6 +252,17 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
263 addr = vma->vm_start-len; 252 addr = vma->vm_start-len;
264 } while (len < vma->vm_start); 253 } while (len < vma->vm_start);
265 254
255fail:
256 /*
257 * if hint left us with no space for the requested
258 * mapping then try again:
259 */
260 if (start_addr != mm->mmap_base) {
261 mm->free_area_cache = mm->mmap_base;
262 mm->cached_hole_size = 0;
263 goto try_again;
264 }
265
266bottomup: 266bottomup:
267 /* 267 /*
268 * A failed mmap() very likely causes application failure, 268 * A failed mmap() very likely causes application failure,
diff --git a/mm/mmap.c b/mm/mmap.c
index 4f31764d838f..9e0c0de2e7e3 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1442,7 +1442,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
1442{ 1442{
1443 struct vm_area_struct *vma; 1443 struct vm_area_struct *vma;
1444 struct mm_struct *mm = current->mm; 1444 struct mm_struct *mm = current->mm;
1445 unsigned long addr = addr0; 1445 unsigned long addr = addr0, start_addr;
1446 1446
1447 /* requested length too big for entire address space */ 1447 /* requested length too big for entire address space */
1448 if (len > TASK_SIZE) 1448 if (len > TASK_SIZE)
@@ -1466,22 +1466,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
1466 mm->free_area_cache = mm->mmap_base; 1466 mm->free_area_cache = mm->mmap_base;
1467 } 1467 }
1468 1468
1469try_again:
1469 /* either no address requested or can't fit in requested address hole */ 1470 /* either no address requested or can't fit in requested address hole */
1470 addr = mm->free_area_cache; 1471 start_addr = addr = mm->free_area_cache;
1471 1472
1472 /* make sure it can fit in the remaining address space */ 1473 if (addr < len)
1473 if (addr > len) { 1474 goto fail;
1474 vma = find_vma(mm, addr-len);
1475 if (!vma || addr <= vma->vm_start)
1476 /* remember the address as a hint for next time */
1477 return (mm->free_area_cache = addr-len);
1478 }
1479
1480 if (mm->mmap_base < len)
1481 goto bottomup;
1482
1483 addr = mm->mmap_base-len;
1484 1475
1476 addr -= len;
1485 do { 1477 do {
1486 /* 1478 /*
1487 * Lookup failure means no vma is above this address, 1479 * Lookup failure means no vma is above this address,
@@ -1501,7 +1493,21 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
1501 addr = vma->vm_start-len; 1493 addr = vma->vm_start-len;
1502 } while (len < vma->vm_start); 1494 } while (len < vma->vm_start);
1503 1495
1504bottomup: 1496fail:
1497 /*
1498 * if hint left us with no space for the requested
1499 * mapping then try again:
1500 *
1501 * Note: this is different with the case of bottomup
1502 * which does the fully line-search, but we use find_vma
1503 * here that causes some holes skipped.
1504 */
1505 if (start_addr != mm->mmap_base) {
1506 mm->free_area_cache = mm->mmap_base;
1507 mm->cached_hole_size = 0;
1508 goto try_again;
1509 }
1510
1505 /* 1511 /*
1506 * A failed mmap() very likely causes application failure, 1512 * A failed mmap() very likely causes application failure,
1507 * so fall back to the bottom-up function here. This scenario 1513 * so fall back to the bottom-up function here. This scenario