Skip to content

Commit b716ad9

Browse files
Xiao Guangrongtorvalds
authored andcommitted
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 <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Hillf Danton <[email protected]> Cc: Andrea Arcangeli <[email protected]> Cc: KAMEZAWA Hiroyuki <[email protected]> Cc: Rik van Riel <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent f44d219 commit b716ad9

File tree

2 files changed

+38
-32
lines changed

2 files changed

+38
-32
lines changed

arch/x86/kernel/sys_x86_64.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
195195
{
196196
struct vm_area_struct *vma;
197197
struct mm_struct *mm = current->mm;
198-
unsigned long addr = addr0;
198+
unsigned long addr = addr0, start_addr;
199199

200200
/* requested length too big for entire address space */
201201
if (len > TASK_SIZE)
@@ -223,25 +223,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
223223
mm->free_area_cache = mm->mmap_base;
224224
}
225225

226+
try_again:
226227
/* either no address requested or can't fit in requested address hole */
227-
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;
228+
start_addr = addr = mm->free_area_cache;
242229

243-
addr = mm->mmap_base-len;
230+
if (addr < len)
231+
goto fail;
244232

233+
addr -= len;
245234
do {
246235
addr = align_addr(addr, filp, ALIGN_TOPDOWN);
247236

@@ -263,6 +252,17 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
263252
addr = vma->vm_start-len;
264253
} while (len < vma->vm_start);
265254

255+
fail:
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+
266266
bottomup:
267267
/*
268268
* A failed mmap() very likely causes application failure,

mm/mmap.c

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,7 +1442,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
14421442
{
14431443
struct vm_area_struct *vma;
14441444
struct mm_struct *mm = current->mm;
1445-
unsigned long addr = addr0;
1445+
unsigned long addr = addr0, start_addr;
14461446

14471447
/* requested length too big for entire address space */
14481448
if (len > TASK_SIZE)
@@ -1466,22 +1466,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
14661466
mm->free_area_cache = mm->mmap_base;
14671467
}
14681468

1469+
try_again:
14691470
/* 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;
14711472

1472-
/* make sure it can fit in the remaining address space */
1473-
if (addr > len) {
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;
1473+
if (addr < len)
1474+
goto fail;
14841475

1476+
addr -= len;
14851477
do {
14861478
/*
14871479
* 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,
15011493
addr = vma->vm_start-len;
15021494
} while (len < vma->vm_start);
15031495

1504-
bottomup:
1496+
fail:
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+
15051511
/*
15061512
* A failed mmap() very likely causes application failure,
15071513
* so fall back to the bottom-up function here. This scenario

0 commit comments

Comments
 (0)