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 83cd904d271b: "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: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
71fece9511
Коммит
097d59106a
|
@ -333,13 +333,15 @@ try_again:
|
|||
* Lookup failure means no vma is above this address,
|
||||
* i.e. return with success:
|
||||
*/
|
||||
if (!(vma = find_vma_prev(mm, addr, &prev_vma)))
|
||||
vma = find_vma(mm, add);
|
||||
if (!vma)
|
||||
return addr;
|
||||
|
||||
/*
|
||||
* new region fits between prev_vma->vm_end and
|
||||
* vma->vm_start, use it:
|
||||
*/
|
||||
prev_vma = vma->vm_prev;
|
||||
if (addr + len <= vma->vm_start &&
|
||||
(!prev_vma || (addr >= prev_vma->vm_end))) {
|
||||
/* remember the address as a hint for next time */
|
||||
|
|
|
@ -640,10 +640,11 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
|
|||
unsigned long vmstart;
|
||||
unsigned long vmend;
|
||||
|
||||
vma = find_vma_prev(mm, start, &prev);
|
||||
vma = find_vma(mm, start);
|
||||
if (!vma || vma->vm_start > start)
|
||||
return -EFAULT;
|
||||
|
||||
prev = vma->vm_prev;
|
||||
if (start > vma->vm_start)
|
||||
prev = vma;
|
||||
|
||||
|
|
|
@ -385,10 +385,11 @@ static int do_mlock(unsigned long start, size_t len, int on)
|
|||
return -EINVAL;
|
||||
if (end == start)
|
||||
return 0;
|
||||
vma = find_vma_prev(current->mm, start, &prev);
|
||||
vma = find_vma(current->mm, start);
|
||||
if (!vma || vma->vm_start > start)
|
||||
return -ENOMEM;
|
||||
|
||||
prev = vma->vm_prev;
|
||||
if (start > vma->vm_start)
|
||||
prev = vma;
|
||||
|
||||
|
|
|
@ -262,10 +262,11 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
|
|||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
|
||||
vma = find_vma_prev(current->mm, start, &prev);
|
||||
vma = find_vma(current->mm, start);
|
||||
error = -ENOMEM;
|
||||
if (!vma)
|
||||
goto out;
|
||||
prev = vma->vm_prev;
|
||||
if (unlikely(grows & PROT_GROWSDOWN)) {
|
||||
if (vma->vm_start >= end)
|
||||
goto out;
|
||||
|
|
Загрузка…
Ссылка в новой задаче