summaryrefslogtreecommitdiff
path: root/arch/sparc/mm/hugetlbpage.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/mm/hugetlbpage.c')
-rw-r--r--arch/sparc/mm/hugetlbpage.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index 07e14535375c..e13e85dbfcd9 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -33,7 +33,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
struct mm_struct *mm = current->mm;
struct vm_area_struct * vma;
unsigned long task_size = TASK_SIZE;
- unsigned long start_addr;
+ unsigned long start_addr, vm_start;
if (test_thread_flag(TIF_32BIT))
task_size = STACK_TOP32;
@@ -67,15 +67,17 @@ full_search:
}
return -ENOMEM;
}
- if (likely(!vma || addr + len <= vma->vm_start)) {
+ if (vma)
+ vm_start = vm_start_gap(vma);
+ if (likely(!vma || addr + len <= vm_start)) {
/*
* Remember the place where we stopped the search:
*/
mm->free_area_cache = addr + len;
return addr;
}
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
+ if (addr + mm->cached_hole_size < vm_start)
+ mm->cached_hole_size = vm_start - addr;
addr = ALIGN(vma->vm_end, HPAGE_SIZE);
}
@@ -90,6 +92,7 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
unsigned long addr = addr0;
+ unsigned long vm_start;
/* This should only ever run for 32-bit processes. */
BUG_ON(!test_thread_flag(TIF_32BIT));
@@ -106,7 +109,7 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
/* make sure it can fit in the remaining address space */
if (likely(addr > len)) {
vma = find_vma(mm, addr-len);
- if (!vma || addr <= vma->vm_start) {
+ if (!vma || addr <= vm_start_gap(vma)) {
/* remember the address as a hint for next time */
return (mm->free_area_cache = addr-len);
}
@@ -124,18 +127,20 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
* return with success:
*/
vma = find_vma(mm, addr);
- if (likely(!vma || addr+len <= vma->vm_start)) {
+ if (vma)
+ vm_start = vm_start_gap(vma);
+ if (likely(!vma || addr + len <= vm_start)) {
/* remember the address as a hint for next time */
return (mm->free_area_cache = addr);
}
/* remember the largest hole we saw so far */
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
+ if (addr + mm->cached_hole_size < vm_start)
+ mm->cached_hole_size = vm_start - addr;
/* try just below the current vma->vm_start */
- addr = (vma->vm_start-len) & HPAGE_MASK;
- } while (likely(len < vma->vm_start));
+ addr = (vm_start - len) & HPAGE_MASK;
+ } while (likely(len < vm_start));
bottomup:
/*
@@ -182,7 +187,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
addr = ALIGN(addr, HPAGE_SIZE);
vma = find_vma(mm, addr);
if (task_size - len >= addr &&
- (!vma || addr + len <= vma->vm_start))
+ (!vma || addr + len <= vm_start_gap(vma)))
return addr;
}
if (mm->get_unmapped_area == arch_get_unmapped_area)