Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b716ad95 authored by Xiao Guangrong's avatar Xiao Guangrong Committed by Linus Torvalds
Browse files

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: default avatarXiao 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>
Cc: Rik van Riel <riel@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f44d2198
Loading
Loading
Loading
Loading
+17 −17
Original line number Diff line number Diff line
@@ -195,7 +195,7 @@ arch_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 addr = addr0, start_addr;

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

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 */
	if (addr > len) {
		unsigned long tmp_addr = align_addr(addr - len, filp,
						    ALIGN_TOPDOWN);

		vma = find_vma(mm, tmp_addr);
		if (!vma || tmp_addr + len <= vma->vm_start)
			/* remember the address as a hint for next time */
			return mm->free_area_cache = tmp_addr;
	}

	if (mm->mmap_base < len)
		goto bottomup;
	start_addr = addr = mm->free_area_cache;

	addr = mm->mmap_base-len;
	if (addr < len)
		goto fail;

	addr -= len;
	do {
		addr = align_addr(addr, filp, ALIGN_TOPDOWN);

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

fail:
	/*
	 * if hint left us with no space for the requested
	 * mapping then try again:
	 */
	if (start_addr != mm->mmap_base) {
		mm->free_area_cache = mm->mmap_base;
		mm->cached_hole_size = 0;
		goto try_again;
	}

bottomup:
	/*
	 * A failed mmap() very likely causes application failure,
+21 −15
Original line number Diff line number Diff line
@@ -1442,7 +1442,7 @@ arch_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 addr = addr0, start_addr;

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

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 */
	if (addr > len) {
		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);
	}

	if (mm->mmap_base < len)
		goto bottomup;
	start_addr = addr = mm->free_area_cache;

	addr = mm->mmap_base-len;
	if (addr < len)
		goto fail;

	addr -= len;
	do {
		/*
		 * 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,
		addr = vma->vm_start-len;
	} while (len < vma->vm_start);

bottomup:
fail:
	/*
	 * if hint left us with no space for the requested
	 * mapping then try again:
	 *
	 * Note: this is different with the case of bottomup
	 * which does the fully line-search, but we use find_vma
	 * here that causes some holes skipped.
	 */
	if (start_addr != mm->mmap_base) {
		mm->free_area_cache = mm->mmap_base;
		mm->cached_hole_size = 0;
		goto try_again;
	}

	/*
	 * A failed mmap() very likely causes application failure,
	 * so fall back to the bottom-up function here. This scenario