aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hugetlbfs
diff options
context:
space:
mode:
authorXiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>2012-03-21 19:33:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 20:54:56 -0400
commit4bfc130d5afa28395288d1b57092906349604b41 (patch)
tree947666e26c6f1e55b3ebdf5edcefda5019a65c8f /fs/hugetlbfs
parentaad6ec3777bf4930d4f7293745cc4c17a2d87947 (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.c15
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
162full_search: 164full_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}