提交 097d5910 编写于 作者: L Linus Torvalds

vm: avoid using find_vma_prev() unnecessarily

Several users of "find_vma_prev()" were not in fact interested in the
previous vma if there was no primary vma to be found either.  And in
those cases, we're much better off just using the regular "find_vma()",
and then "prev" can be looked up by just checking vma->vm_prev.

The find_vma_prev() semantics are fairly subtle (see Mikulas' recent
commit 83cd904d: "mm: fix find_vma_prev"), and the whole "return
prev by reference" means that it generates worse code too.

Thus this "let's avoid using this inconvenient and clearly too subtle
interface when we don't really have to" patch.

Cc: Mikulas Patocka <mpatocka@redhat.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 71fece95
...@@ -333,13 +333,15 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file, ...@@ -333,13 +333,15 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
* Lookup failure means no vma is above this address, * Lookup failure means no vma is above this address,
* i.e. return with success: * i.e. return with success:
*/ */
if (!(vma = find_vma_prev(mm, addr, &prev_vma))) vma = find_vma(mm, add);
if (!vma)
return addr; return addr;
/* /*
* new region fits between prev_vma->vm_end and * new region fits between prev_vma->vm_end and
* vma->vm_start, use it: * vma->vm_start, use it:
*/ */
prev_vma = vma->vm_prev;
if (addr + len <= vma->vm_start && 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 */ /* remember the address as a hint for next time */
......
...@@ -640,10 +640,11 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, ...@@ -640,10 +640,11 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
unsigned long vmstart; unsigned long vmstart;
unsigned long vmend; unsigned long vmend;
vma = find_vma_prev(mm, start, &prev); vma = find_vma(mm, start);
if (!vma || vma->vm_start > start) if (!vma || vma->vm_start > start)
return -EFAULT; return -EFAULT;
prev = vma->vm_prev;
if (start > vma->vm_start) if (start > vma->vm_start)
prev = vma; prev = vma;
......
...@@ -385,10 +385,11 @@ static int do_mlock(unsigned long start, size_t len, int on) ...@@ -385,10 +385,11 @@ static int do_mlock(unsigned long start, size_t len, int on)
return -EINVAL; return -EINVAL;
if (end == start) if (end == start)
return 0; return 0;
vma = find_vma_prev(current->mm, start, &prev); vma = find_vma(current->mm, start);
if (!vma || vma->vm_start > start) if (!vma || vma->vm_start > start)
return -ENOMEM; return -ENOMEM;
prev = vma->vm_prev;
if (start > vma->vm_start) if (start > vma->vm_start)
prev = vma; prev = vma;
......
...@@ -262,10 +262,11 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len, ...@@ -262,10 +262,11 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
down_write(&current->mm->mmap_sem); down_write(&current->mm->mmap_sem);
vma = find_vma_prev(current->mm, start, &prev); vma = find_vma(current->mm, start);
error = -ENOMEM; error = -ENOMEM;
if (!vma) if (!vma)
goto out; goto out;
prev = vma->vm_prev;
if (unlikely(grows & PROT_GROWSDOWN)) { if (unlikely(grows & PROT_GROWSDOWN)) {
if (vma->vm_start >= end) if (vma->vm_start >= end)
goto out; goto out;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册