diff options
author | Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com> | 2012-03-21 19:33:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-21 20:54:56 -0400 |
commit | 4bfc130d5afa28395288d1b57092906349604b41 (patch) | |
tree | 947666e26c6f1e55b3ebdf5edcefda5019a65c8f /fs/hugetlbfs | |
parent | aad6ec3777bf4930d4f7293745cc4c17a2d87947 (diff) |
hugetlbfs: fix hugetlb_get_unmapped_area()
Use/update cached_hole_size and free_area_cache properly to speedup
finding of a free region.
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>
Diffstat (limited to 'fs/hugetlbfs')
-rw-r--r-- | fs/hugetlbfs/inode.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 1e85a7ac021..b7bc7868c7b 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -154,10 +154,12 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, | |||
154 | return addr; | 154 | return addr; |
155 | } | 155 | } |
156 | 156 | ||
157 | start_addr = mm->free_area_cache; | 157 | if (len > mm->cached_hole_size) |
158 | 158 | start_addr = mm->free_area_cache; | |
159 | if (len <= mm->cached_hole_size) | 159 | else { |
160 | start_addr = TASK_UNMAPPED_BASE; | 160 | start_addr = TASK_UNMAPPED_BASE; |
161 | mm->cached_hole_size = 0; | ||
162 | } | ||
161 | 163 | ||
162 | full_search: | 164 | full_search: |
163 | addr = ALIGN(start_addr, huge_page_size(h)); | 165 | addr = ALIGN(start_addr, huge_page_size(h)); |
@@ -171,13 +173,18 @@ full_search: | |||
171 | */ | 173 | */ |
172 | if (start_addr != TASK_UNMAPPED_BASE) { | 174 | if (start_addr != TASK_UNMAPPED_BASE) { |
173 | start_addr = TASK_UNMAPPED_BASE; | 175 | start_addr = TASK_UNMAPPED_BASE; |
176 | mm->cached_hole_size = 0; | ||
174 | goto full_search; | 177 | goto full_search; |
175 | } | 178 | } |
176 | return -ENOMEM; | 179 | return -ENOMEM; |
177 | } | 180 | } |
178 | 181 | ||
179 | if (!vma || addr + len <= vma->vm_start) | 182 | if (!vma || addr + len <= vma->vm_start) { |
183 | mm->free_area_cache = addr + len; | ||
180 | return addr; | 184 | return addr; |
185 | } | ||
186 | if (addr + mm->cached_hole_size < vma->vm_start) | ||
187 | mm->cached_hole_size = vma->vm_start - addr; | ||
181 | addr = ALIGN(vma->vm_end, huge_page_size(h)); | 188 | addr = ALIGN(vma->vm_end, huge_page_size(h)); |
182 | } | 189 | } |
183 | } | 190 | } |