uprobes: Clean up and document write_opcode()->lock_page(old_page)
The comment above write_opcode()->lock_page(old_page) tells
about the race with do_wp_page(). I don't really understand
which exactly race it means, but afaics this lock_page() was not
enough to close all races with do_wp_page().
Anyway, since:
77fc4af1b5
uprobes: Change register_for_each_vma() to take mm->mmap_sem for writing
this code is always called with ->mmap_sem held for writing,
so we can forget about do_wp_page().
However, we can't simply remove this lock_page(), and the only
(afaics) reason is __replace_page()->try_to_free_swap().
Nothing in write_opcode() needs it, move it into
__replace_page() and fix the comment.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Srikar Dronamraju <srikar.vnet.ibm.com>
Cc: Anton Arapov <anton@redhat.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Link: http://lkml.kernel.org/r/20120729182220.GA20322@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
089ba999dc
commit
9f92448cee
|
@ -139,10 +139,15 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
|
|||
struct mm_struct *mm = vma->vm_mm;
|
||||
spinlock_t *ptl;
|
||||
pte_t *ptep;
|
||||
int err;
|
||||
|
||||
/* freeze PageSwapCache() for try_to_free_swap() below */
|
||||
lock_page(page);
|
||||
|
||||
err = -EAGAIN;
|
||||
ptep = page_check_address(page, mm, addr, &ptl, 0);
|
||||
if (!ptep)
|
||||
return -EAGAIN;
|
||||
goto unlock;
|
||||
|
||||
get_page(kpage);
|
||||
page_add_new_anon_rmap(kpage, vma, addr);
|
||||
|
@ -162,7 +167,10 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
|
|||
put_page(page);
|
||||
pte_unmap_unlock(ptep, ptl);
|
||||
|
||||
return 0;
|
||||
err = 0;
|
||||
unlock:
|
||||
unlock_page(page);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -216,15 +224,10 @@ retry:
|
|||
ret = -ENOMEM;
|
||||
new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr);
|
||||
if (!new_page)
|
||||
goto put_out;
|
||||
goto put_old;
|
||||
|
||||
__SetPageUptodate(new_page);
|
||||
|
||||
/*
|
||||
* lock page will serialize against do_wp_page()'s
|
||||
* PageAnon() handling
|
||||
*/
|
||||
lock_page(old_page);
|
||||
/* copy the page now that we've got it stable */
|
||||
vaddr_old = kmap_atomic(old_page);
|
||||
vaddr_new = kmap_atomic(new_page);
|
||||
|
@ -237,15 +240,13 @@ retry:
|
|||
|
||||
ret = anon_vma_prepare(vma);
|
||||
if (ret)
|
||||
goto unlock_out;
|
||||
goto put_new;
|
||||
|
||||
ret = __replace_page(vma, vaddr, old_page, new_page);
|
||||
|
||||
unlock_out:
|
||||
unlock_page(old_page);
|
||||
put_new:
|
||||
page_cache_release(new_page);
|
||||
|
||||
put_out:
|
||||
put_old:
|
||||
put_page(old_page);
|
||||
|
||||
if (unlikely(ret == -EAGAIN))
|
||||
|
|
Loading…
Reference in a new issue