Commit 9fe1f5e6 authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds

[PATCH] simpler topdown mmap layout allocator

1. typos/spelling ;-)

2. removed prev_vma and find_vma_prev because the condition checked
   later was always true

3. moved the free_area_cache/mmap_base check into arch_unmap_area_topdown
   where i think it belongs.

4. removed the extra free_area_cache setting code in the while loop
   as it only has to be set when we actually (and successfully) return
   from this function.

The only visible change to the layout should be the following:

   
parent 26eecbf3
...@@ -1218,19 +1218,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, ...@@ -1218,19 +1218,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
const unsigned long len, const unsigned long pgoff, const unsigned long len, const unsigned long pgoff,
const unsigned long flags) const unsigned long flags)
{ {
struct vm_area_struct *vma, *prev_vma; struct vm_area_struct *vma;
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
unsigned long base = mm->mmap_base, addr = addr0; unsigned long addr = addr0;
int first_time = 1;
/* requested length too big for entire address space */ /* requested length too big for entire address space */
if (len > TASK_SIZE) if (len > TASK_SIZE)
return -ENOMEM; return -ENOMEM;
/* dont allow allocations above current base */
if (mm->free_area_cache > base)
mm->free_area_cache = base;
/* requesting a specific address */ /* requesting a specific address */
if (addr) { if (addr) {
addr = PAGE_ALIGN(addr); addr = PAGE_ALIGN(addr);
...@@ -1240,48 +1235,34 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, ...@@ -1240,48 +1235,34 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return addr; return addr;
} }
try_again: /* either no address requested or can't fit in requested address hole */
addr = mm->free_area_cache;
/* make sure it can fit in the remaining address space */ /* make sure it can fit in the remaining address space */
if (mm->free_area_cache < len) if (addr >= len) {
goto fail; vma = find_vma(mm, addr-len);
if (!vma || addr <= vma->vm_start)
/* remember the address as a hint for next time */
return (mm->free_area_cache = addr-len);
}
addr = mm->mmap_base-len;
/* either no address requested or cant fit in requested address hole */
addr = (mm->free_area_cache - len) & PAGE_MASK;
do { do {
/* /*
* Lookup failure means no vma is above this address, * Lookup failure means no vma is above this address,
* i.e. return with success: * else if new region fits below vma->vm_start,
*/ * return with success:
if (!(vma = find_vma_prev(mm, addr, &prev_vma)))
return addr;
/*
* new region fits between prev_vma->vm_end and
* vma->vm_start, use it:
*/ */
if (addr+len <= vma->vm_start && vma = find_vma(mm, addr);
(!prev_vma || (addr >= prev_vma->vm_end))) if (!vma || addr+len <= vma->vm_start)
/* remember the address as a hint for next time */ /* remember the address as a hint for next time */
return (mm->free_area_cache = addr); return (mm->free_area_cache = addr);
else
/* pull free_area_cache down to the first hole */
if (mm->free_area_cache == vma->vm_end)
mm->free_area_cache = vma->vm_start;
/* try just below the current vma->vm_start */ /* try just below the current vma->vm_start */
addr = vma->vm_start-len; addr = vma->vm_start-len;
} while (len <= vma->vm_start); } while (len <= vma->vm_start);
fail:
/*
* if hint left us with no space for the requested
* mapping then try again:
*/
if (first_time) {
mm->free_area_cache = base;
first_time = 0;
goto try_again;
}
/* /*
* A failed mmap() very likely causes application failure, * A failed mmap() very likely causes application failure,
* so fall back to the bottom-up function here. This scenario * so fall back to the bottom-up function here. This scenario
...@@ -1293,7 +1274,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, ...@@ -1293,7 +1274,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
/* /*
* Restore the topdown base: * Restore the topdown base:
*/ */
mm->free_area_cache = base; mm->free_area_cache = mm->mmap_base;
return addr; return addr;
} }
...@@ -1306,6 +1287,10 @@ void arch_unmap_area_topdown(struct vm_area_struct *area) ...@@ -1306,6 +1287,10 @@ void arch_unmap_area_topdown(struct vm_area_struct *area)
*/ */
if (area->vm_end > area->vm_mm->free_area_cache) if (area->vm_end > area->vm_mm->free_area_cache)
area->vm_mm->free_area_cache = area->vm_end; area->vm_mm->free_area_cache = area->vm_end;
/* dont allow allocations above current base */
if (area->vm_mm->free_area_cache > area->vm_mm->mmap_base)
area->vm_mm->free_area_cache = area->vm_mm->mmap_base;
} }
unsigned long unsigned long
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment