mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
mm: introduce __page_add_new_anon_rmap()
When dealing with speculative page fault handler, we may race with VMA being split or merged. In this case the vma->vm_start and vm->vm_end fields may not match the address the page fault is occurring. This can only happens when the VMA is split but in that case, the anon_vma pointer of the new VMA will be the same as the original one, because in __split_vma the new->anon_vma is set to src->anon_vma when *new = *vma. So even if the VMA boundaries are not correct, the anon_vma pointer is still valid. If the VMA has been merged, then the VMA in which it has been merged must have the same anon_vma pointer otherwise the merge can't be done. So in all the case we know that the anon_vma is valid, since we have checked before starting the speculative page fault that the anon_vma pointer is valid for this VMA and since there is an anon_vma this means that at one time a page has been backed and that before the VMA is cleaned, the page table lock would have to be grab to clean the PTE, and the anon_vma field is checked once the PTE is locked. This patch introduce a new __page_add_new_anon_rmap() service which doesn't check for the VMA boundaries, and create a new inline one which do the check. When called from a page fault handler, if this is not a speculative one, there is a guarantee that vm_start and vm_end match the faulting address, so this check is useless. In the context of the speculative page fault handler, this check may be wrong but anon_vma is still valid as explained above. Change-Id: I72c47830181579f8c9618df879077d321653b5f1 Signed-off-by: Laurent Dufour <[email protected]> Patch-mainline: linux-mm @ Tue, 17 Apr 2018 16:33:22 [[email protected]: trivial merge conflict fixes + checkpatch fixes] Signed-off-by: Vinayak Menon <[email protected]>
This commit is contained in:
parent
ec5147dea1
commit
d56126780c
3 changed files with 16 additions and 9 deletions
|
|
@ -1138,7 +1138,7 @@ void do_page_add_anon_rmap(struct page *page,
|
|||
}
|
||||
|
||||
/**
|
||||
* page_add_new_anon_rmap - add pte mapping to a new anonymous page
|
||||
* __page_add_new_anon_rmap - add pte mapping to a new anonymous page
|
||||
* @page: the page to add the mapping to
|
||||
* @vma: the vm area in which the mapping is added
|
||||
* @address: the user virtual address mapped
|
||||
|
|
@ -1148,12 +1148,11 @@ void do_page_add_anon_rmap(struct page *page,
|
|||
* This means the inc-and-test can be bypassed.
|
||||
* Page does not have to be locked.
|
||||
*/
|
||||
void page_add_new_anon_rmap(struct page *page,
|
||||
void __page_add_new_anon_rmap(struct page *page,
|
||||
struct vm_area_struct *vma, unsigned long address, bool compound)
|
||||
{
|
||||
int nr = compound ? hpage_nr_pages(page) : 1;
|
||||
|
||||
VM_BUG_ON_VMA(address < vma->vm_start || address >= vma->vm_end, vma);
|
||||
__SetPageSwapBacked(page);
|
||||
if (compound) {
|
||||
VM_BUG_ON_PAGE(!PageTransHuge(page), page);
|
||||
|
|
|
|||
Loading…
Reference in a new issue