hugetlb: try to search again if it is really needed
authorXiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Wed, 21 Mar 2012 23:33:55 +0000 (16:33 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 22 Mar 2012 00:54:56 +0000 (17:54 -0700)
Search again only if some holes may be skipped in the first pass.

[akpm@linux-foundation.org: clean up crazy compound definition]
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>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/x86/mm/hugetlbpage.c

index 8ecbb4bba4b3b44241b64b46079476ad90f7aad4..c20e81c3425d629ef554fce50dad8e6c80279219 100644 (file)
@@ -309,9 +309,10 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
        struct hstate *h = hstate_file(file);
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma, *prev_vma;
-       unsigned long base = mm->mmap_base, addr = addr0;
+       unsigned long base = mm->mmap_base;
+       unsigned long addr = addr0;
        unsigned long largest_hole = mm->cached_hole_size;
-       int first_time = 1;
+       unsigned long start_addr;
 
        /* don't allow allocations above current base */
        if (mm->free_area_cache > base)
@@ -322,6 +323,8 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
                mm->free_area_cache  = base;
        }
 try_again:
+       start_addr = mm->free_area_cache;
+
        /* make sure it can fit in the remaining address space */
        if (mm->free_area_cache < len)
                goto fail;
@@ -368,10 +371,9 @@ fail:
         * if hint left us with no space for the requested
         * mapping then try again:
         */
-       if (first_time) {
+       if (start_addr != base) {
                mm->free_area_cache = base;
                largest_hole = 0;
-               first_time = 0;
                goto try_again;
        }
        /*