Commit 2edc0409 authored by David S. Miller's avatar David S. Miller

[SPARC64]: Use mm->free_area_cache.

parent 5576c776
...@@ -46,8 +46,10 @@ asmlinkage unsigned long sys_getpagesize(void) ...@@ -46,8 +46,10 @@ asmlinkage unsigned long sys_getpagesize(void)
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
{ {
struct vm_area_struct * vmm; struct mm_struct *mm = current->mm;
struct vm_area_struct * vma;
unsigned long task_size = TASK_SIZE; unsigned long task_size = TASK_SIZE;
unsigned long start_addr;
int do_color_align; int do_color_align;
if (flags & MAP_FIXED) { if (flags & MAP_FIXED) {
...@@ -63,30 +65,54 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi ...@@ -63,30 +65,54 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
task_size = 0xf0000000UL; task_size = 0xf0000000UL;
if (len > task_size || len > -PAGE_OFFSET) if (len > task_size || len > -PAGE_OFFSET)
return -ENOMEM; return -ENOMEM;
if (!addr)
addr = TASK_UNMAPPED_BASE;
do_color_align = 0; do_color_align = 0;
if (filp || (flags & MAP_SHARED)) if (filp || (flags & MAP_SHARED))
do_color_align = 1; do_color_align = 1;
if (addr) {
if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff);
else
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
if (task_size - len >= addr &&
(!vma || addr + len <= vma->vm_start))
return addr;
}
start_addr = addr = mm->free_area_cache;
task_size -= len;
full_search:
if (do_color_align) if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff); addr = COLOUR_ALIGN(addr, pgoff);
else else
addr = PAGE_ALIGN(addr); addr = PAGE_ALIGN(addr);
task_size -= len;
for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
/* At this point: (!vmm || addr < vmm->vm_end). */ /* At this point: (!vma || addr < vma->vm_end). */
if (addr < PAGE_OFFSET && -PAGE_OFFSET - len < addr) { if (addr < PAGE_OFFSET && -PAGE_OFFSET - len < addr) {
addr = PAGE_OFFSET; addr = PAGE_OFFSET;
vmm = find_vma(current->mm, PAGE_OFFSET); vma = find_vma(mm, PAGE_OFFSET);
} }
if (task_size < addr) if (task_size < addr) {
if (start_addr != TASK_UNMAPPED_BASE) {
start_addr = addr = TASK_UNMAPPED_BASE;
goto full_search;
}
return -ENOMEM; return -ENOMEM;
if (!vmm || addr + len <= vmm->vm_start) }
if (!vma || addr + len <= vma->vm_start) {
/*
* Remember the place where we stopped the search:
*/
mm->free_area_cache = addr + len;
return addr; return addr;
addr = vmm->vm_end; }
addr = vma->vm_end;
if (do_color_align) if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff); addr = COLOUR_ALIGN(addr, pgoff);
} }
......
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