Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 2449
b: refs/heads/master
c: 1363c3c
h: refs/heads/master
i:
  2447: 29da7e5
v: v3
  • Loading branch information
Wolfgang Wander authored and Linus Torvalds committed Jun 22, 2005
1 parent 1bf1ca9 commit 41083d4
Show file tree
Hide file tree
Showing 15 changed files with 148 additions and 31 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e7c8d5c9955a4d2e88e36b640563f5d6d5aba48a
refs/heads/master: 1363c3cd8603a913a27e2995dccbd70d5312d8e6
10 changes: 9 additions & 1 deletion trunk/arch/arm/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
(!vma || addr + len <= vma->vm_start))
return addr;
}
start_addr = addr = mm->free_area_cache;
if (len > mm->cached_hole_size) {
start_addr = addr = mm->free_area_cache;
} else {
start_addr = addr = TASK_UNMAPPED_BASE;
mm->cached_hole_size = 0;
}

full_search:
if (do_align)
Expand All @@ -90,6 +95,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
*/
if (start_addr != TASK_UNMAPPED_BASE) {
start_addr = addr = TASK_UNMAPPED_BASE;
mm->cached_hole_size = 0;
goto full_search;
}
return -ENOMEM;
Expand All @@ -101,6 +107,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
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;
addr = vma->vm_end;
if (do_align)
addr = COLOUR_ALIGN(addr, pgoff);
Expand Down
34 changes: 29 additions & 5 deletions trunk/arch/i386/mm/hugetlbpage.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,12 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
struct vm_area_struct *vma;
unsigned long start_addr;

start_addr = mm->free_area_cache;
if (len > mm->cached_hole_size) {
start_addr = mm->free_area_cache;
} else {
start_addr = TASK_UNMAPPED_BASE;
mm->cached_hole_size = 0;
}

full_search:
addr = ALIGN(start_addr, HPAGE_SIZE);
Expand All @@ -154,6 +159,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
*/
if (start_addr != TASK_UNMAPPED_BASE) {
start_addr = TASK_UNMAPPED_BASE;
mm->cached_hole_size = 0;
goto full_search;
}
return -ENOMEM;
Expand All @@ -162,6 +168,8 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
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;
addr = ALIGN(vma->vm_end, HPAGE_SIZE);
}
}
Expand All @@ -173,12 +181,17 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct 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 largest_hole = mm->cached_hole_size;
int first_time = 1;

/* don't allow allocations above current base */
if (mm->free_area_cache > base)
mm->free_area_cache = base;

if (len <= largest_hole) {
largest_hole = 0;
mm->free_area_cache = base;
}
try_again:
/* make sure it can fit in the remaining address space */
if (mm->free_area_cache < len)
Expand All @@ -199,13 +212,21 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
* vma->vm_start, use it:
*/
if (addr + len <= vma->vm_start &&
(!prev_vma || (addr >= prev_vma->vm_end)))
(!prev_vma || (addr >= prev_vma->vm_end))) {
/* remember the address as a hint for next time */
return (mm->free_area_cache = addr);
else
mm->cached_hole_size = largest_hole;
return (mm->free_area_cache = addr);
} else {
/* pull free_area_cache down to the first hole */
if (mm->free_area_cache == vma->vm_end)
if (mm->free_area_cache == vma->vm_end) {
mm->free_area_cache = vma->vm_start;
mm->cached_hole_size = largest_hole;
}
}

/* remember the largest hole we saw so far */
if (addr + largest_hole < vma->vm_start)
largest_hole = vma->vm_start - addr;

/* try just below the current vma->vm_start */
addr = (vma->vm_start - len) & HPAGE_MASK;
Expand All @@ -218,6 +239,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
*/
if (first_time) {
mm->free_area_cache = base;
largest_hole = 0;
first_time = 0;
goto try_again;
}
Expand All @@ -228,13 +250,15 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
* allocations.
*/
mm->free_area_cache = TASK_UNMAPPED_BASE;
mm->cached_hole_size = ~0UL;
addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
len, pgoff, flags);

/*
* Restore the topdown base:
*/
mm->free_area_cache = base;
mm->cached_hole_size = ~0UL;

return addr;
}
Expand Down
34 changes: 29 additions & 5 deletions trunk/arch/ppc64/mm/hugetlbpage.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,12 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
&& !is_hugepage_only_range(mm, addr,len))
return addr;
}
start_addr = addr = mm->free_area_cache;
if (len > mm->cached_hole_size) {
start_addr = addr = mm->free_area_cache;
} else {
start_addr = addr = TASK_UNMAPPED_BASE;
mm->cached_hole_size = 0;
}

full_search:
vma = find_vma(mm, addr);
Expand All @@ -316,13 +321,16 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
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;
addr = vma->vm_end;
vma = vma->vm_next;
}

/* Make sure we didn't miss any holes */
if (start_addr != TASK_UNMAPPED_BASE) {
start_addr = addr = TASK_UNMAPPED_BASE;
mm->cached_hole_size = 0;
goto full_search;
}
return -ENOMEM;
Expand All @@ -344,6 +352,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
struct vm_area_struct *vma, *prev_vma;
struct mm_struct *mm = current->mm;
unsigned long base = mm->mmap_base, addr = addr0;
unsigned long largest_hole = mm->cached_hole_size;
int first_time = 1;

/* requested length too big for entire address space */
Expand All @@ -364,6 +373,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return addr;
}

if (len <= largest_hole) {
largest_hole = 0;
mm->free_area_cache = base;
}
try_again:
/* make sure it can fit in the remaining address space */
if (mm->free_area_cache < len)
Expand Down Expand Up @@ -392,13 +405,21 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
* vma->vm_start, use it:
*/
if (addr+len <= vma->vm_start &&
(!prev_vma || (addr >= prev_vma->vm_end)))
(!prev_vma || (addr >= prev_vma->vm_end))) {
/* remember the address as a hint for next time */
return (mm->free_area_cache = addr);
else
mm->cached_hole_size = largest_hole;
return (mm->free_area_cache = addr);
} else {
/* pull free_area_cache down to the first hole */
if (mm->free_area_cache == vma->vm_end)
if (mm->free_area_cache == vma->vm_end) {
mm->free_area_cache = vma->vm_start;
mm->cached_hole_size = largest_hole;
}
}

/* remember the largest hole we saw so far */
if (addr + largest_hole < vma->vm_start)
largest_hole = vma->vm_start - addr;

/* try just below the current vma->vm_start */
addr = vma->vm_start-len;
Expand All @@ -411,6 +432,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
*/
if (first_time) {
mm->free_area_cache = base;
largest_hole = 0;
first_time = 0;
goto try_again;
}
Expand All @@ -421,11 +443,13 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
* allocations.
*/
mm->free_area_cache = TASK_UNMAPPED_BASE;
mm->cached_hole_size = ~0UL;
addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
/*
* Restore the topdown base:
*/
mm->free_area_cache = base;
mm->cached_hole_size = ~0UL;

return addr;
}
Expand Down
8 changes: 8 additions & 0 deletions trunk/arch/sh/kernel/sys_sh.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
(!vma || addr + len <= vma->vm_start))
return addr;
}
if (len <= mm->cached_hole_size) {
mm->cached_hole_size = 0;
mm->free_area_cache = TASK_UNMAPPED_BASE;
}
if (flags & MAP_PRIVATE)
addr = PAGE_ALIGN(mm->free_area_cache);
else
Expand All @@ -95,6 +99,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
*/
if (start_addr != TASK_UNMAPPED_BASE) {
start_addr = addr = TASK_UNMAPPED_BASE;
mm->cached_hole_size = 0;
goto full_search;
}
return -ENOMEM;
Expand All @@ -106,6 +111,9 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
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;

addr = vma->vm_end;
if (!(flags & MAP_PRIVATE))
addr = COLOUR_ALIGN(addr);
Expand Down
8 changes: 8 additions & 0 deletions trunk/arch/sparc64/kernel/sys_sparc.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
return addr;
}

if (len <= mm->cached_hole_size) {
mm->cached_hole_size = 0;
mm->free_area_cache = TASK_UNMAPPED_BASE;
}
start_addr = addr = mm->free_area_cache;

task_size -= len;
Expand All @@ -103,6 +107,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
if (task_size < addr) {
if (start_addr != TASK_UNMAPPED_BASE) {
start_addr = addr = TASK_UNMAPPED_BASE;
mm->cached_hole_size = 0;
goto full_search;
}
return -ENOMEM;
Expand All @@ -114,6 +119,9 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
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;

addr = vma->vm_end;
if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff);
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/x86_64/ia32/ia32_aout.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current->mm->brk = ex.a_bss +
(current->mm->start_brk = N_BSSADDR(ex));
current->mm->free_area_cache = TASK_UNMAPPED_BASE;
current->mm->cached_hole_size = 0;

set_mm_counter(current->mm, rss, 0);
current->mm->mmap = NULL;
Expand Down
9 changes: 9 additions & 0 deletions trunk/arch/x86_64/kernel/sys_x86_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
(!vma || addr + len <= vma->vm_start))
return addr;
}
if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32))
&& len <= mm->cached_hole_size) {
mm->cached_hole_size = 0;
mm->free_area_cache = begin;
}
addr = mm->free_area_cache;
if (addr < begin)
addr = begin;
Expand All @@ -120,6 +125,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
*/
if (start_addr != begin) {
start_addr = addr = begin;
mm->cached_hole_size = 0;
goto full_search;
}
return -ENOMEM;
Expand All @@ -131,6 +137,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
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;

addr = vma->vm_end;
}
}
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/binfmt_aout.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current->mm->brk = ex.a_bss +
(current->mm->start_brk = N_BSSADDR(ex));
current->mm->free_area_cache = current->mm->mmap_base;
current->mm->cached_hole_size = 0;

set_mm_counter(current->mm, rss, 0);
current->mm->mmap = NULL;
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/binfmt_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
change some of these later */
set_mm_counter(current->mm, rss, 0);
current->mm->free_area_cache = current->mm->mmap_base;
current->mm->cached_hole_size = 0;
retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP),
executable_stack);
if (retval < 0) {
Expand Down
3 changes: 3 additions & 0 deletions trunk/fs/hugetlbfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,

start_addr = mm->free_area_cache;

if (len <= mm->cached_hole_size)
start_addr = TASK_UNMAPPED_BASE;

full_search:
addr = ALIGN(start_addr, HPAGE_SIZE);

Expand Down
11 changes: 6 additions & 5 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ extern unsigned long
arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff,
unsigned long flags);
extern void arch_unmap_area(struct vm_area_struct *area);
extern void arch_unmap_area_topdown(struct vm_area_struct *area);
extern void arch_unmap_area(struct mm_struct *, unsigned long);
extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long);

#define set_mm_counter(mm, member, value) (mm)->_##member = (value)
#define get_mm_counter(mm, member) ((mm)->_##member)
Expand All @@ -218,9 +218,10 @@ struct mm_struct {
unsigned long (*get_unmapped_area) (struct file *filp,
unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags);
void (*unmap_area) (struct vm_area_struct *area);
unsigned long mmap_base; /* base of mmap area */
unsigned long free_area_cache; /* first hole */
void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
unsigned long mmap_base; /* base of mmap area */
unsigned long cached_hole_size; /* if non-zero, the largest hole below free_area_cache */
unsigned long free_area_cache; /* first hole of size cached_hole_size or larger */
pgd_t * pgd;
atomic_t mm_users; /* How many users with user space? */
atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */
Expand Down
2 changes: 2 additions & 0 deletions trunk/kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
mm->mmap = NULL;
mm->mmap_cache = NULL;
mm->free_area_cache = oldmm->mmap_base;
mm->cached_hole_size = ~0UL;
mm->map_count = 0;
set_mm_counter(mm, rss, 0);
set_mm_counter(mm, anon_rss, 0);
Expand Down Expand Up @@ -322,6 +323,7 @@ static struct mm_struct * mm_init(struct mm_struct * mm)
mm->ioctx_list = NULL;
mm->default_kioctx = (struct kioctx)INIT_KIOCTX(mm->default_kioctx, *mm);
mm->free_area_cache = TASK_UNMAPPED_BASE;
mm->cached_hole_size = ~0UL;

if (likely(!mm_alloc_pgd(mm))) {
mm->def_flags = 0;
Expand Down
Loading

0 comments on commit 41083d4

Please sign in to comment.