aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hugetlbfs
diff options
context:
space:
mode:
authorMichel Lespinasse <walken@google.com>2012-12-11 19:02:00 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 20:22:25 -0500
commit0865935598bb112a02f40017e8aaa6bce8577f23 (patch)
tree93460e1539ba63dc3aea857e1aaf2b9fa9429ce5 /fs/hugetlbfs
parent7d025059650f1c41a427173789ac14b74212b361 (diff)
mm: use vm_unmapped_area() in hugetlbfs
Update the hugetlb_get_unmapped_area function to make use of vm_unmapped_area() instead of implementing a brute force search. Signed-off-by: Michel Lespinasse <walken@google.com> Reviewed-by: Rik van Riel <riel@redhat.com> Cc: Hugh Dickins <hughd@google.com> Cc: Russell King <linux@arm.linux.org.uk> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Paul Mundt <lethal@linux-sh.org> Cc: "David S. Miller" <davem@davemloft.net> Cc: Chris Metcalf <cmetcalf@tilera.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: "H. Peter Anvin" <hpa@zytor.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.c42
1 files changed, 8 insertions, 34 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 21b8a4875237..47e6e2f21e21 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -151,8 +151,8 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
151{ 151{
152 struct mm_struct *mm = current->mm; 152 struct mm_struct *mm = current->mm;
153 struct vm_area_struct *vma; 153 struct vm_area_struct *vma;
154 unsigned long start_addr;
155 struct hstate *h = hstate_file(file); 154 struct hstate *h = hstate_file(file);
155 struct vm_unmapped_area_info info;
156 156
157 if (len & ~huge_page_mask(h)) 157 if (len & ~huge_page_mask(h))
158 return -EINVAL; 158 return -EINVAL;
@@ -173,39 +173,13 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
173 return addr; 173 return addr;
174 } 174 }
175 175
176 if (len > mm->cached_hole_size) 176 info.flags = 0;
177 start_addr = mm->free_area_cache; 177 info.length = len;
178 else { 178 info.low_limit = TASK_UNMAPPED_BASE;
179 start_addr = TASK_UNMAPPED_BASE; 179 info.high_limit = TASK_SIZE;
180 mm->cached_hole_size = 0; 180 info.align_mask = PAGE_MASK & ~huge_page_mask(h);
181 } 181 info.align_offset = 0;
182 182 return vm_unmapped_area(&info);
183full_search:
184 addr = ALIGN(start_addr, huge_page_size(h));
185
186 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
187 /* At this point: (!vma || addr < vma->vm_end). */
188 if (TASK_SIZE - len < addr) {
189 /*
190 * Start a new search - just in case we missed
191 * some holes.
192 */
193 if (start_addr != TASK_UNMAPPED_BASE) {
194 start_addr = TASK_UNMAPPED_BASE;
195 mm->cached_hole_size = 0;
196 goto full_search;
197 }
198 return -ENOMEM;
199 }
200
201 if (!vma || addr + len <= vma->vm_start) {
202 mm->free_area_cache = addr + len;
203 return addr;
204 }
205 if (addr + mm->cached_hole_size < vma->vm_start)
206 mm->cached_hole_size = vma->vm_start - addr;
207 addr = ALIGN(vma->vm_end, huge_page_size(h));
208 }
209} 183}
210#endif 184#endif
211 185