mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 21:07:02 +09:00
FROMLIST: mm: implement speculative handling in do_anonymous_page()
Change do_anonymous_page() to handle the speculative case. This involves aborting speculative faults if they have to allocate a new anon_vma, and using pte_map_lock() instead of pte_offset_map_lock() to complete the page fault. Signed-off-by: Michel Lespinasse <michel@lespinasse.org> Link: https://lore.kernel.org/all/20220128131006.67712-19-michel@lespinasse.org/ Bug: 161210518 Signed-off-by: Suren Baghdasaryan <surenb@google.com> Change-Id: I5ad955323faabc142c21f62415db039ac889066a
This commit is contained in:
committed by
Todd Kjos
parent
6e6766ab76
commit
31cf1fd564
17
mm/memory.c
17
mm/memory.c
@@ -3839,8 +3839,12 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
|
||||
vma->vm_page_prot));
|
||||
} else {
|
||||
/* Allocate our own private page. */
|
||||
if (unlikely(anon_vma_prepare(vma)))
|
||||
goto oom;
|
||||
if (unlikely(!vma->anon_vma)) {
|
||||
if (vmf->flags & FAULT_FLAG_SPECULATIVE)
|
||||
return VM_FAULT_RETRY;
|
||||
if (__anon_vma_prepare(vma))
|
||||
goto oom;
|
||||
}
|
||||
page = alloc_zeroed_user_highpage_movable(vma, vmf->address);
|
||||
if (!page)
|
||||
goto oom;
|
||||
@@ -3862,8 +3866,10 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
|
||||
entry = pte_mkwrite(pte_mkdirty(entry));
|
||||
}
|
||||
|
||||
vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd, vmf->address,
|
||||
&vmf->ptl);
|
||||
if (!pte_map_lock(vmf)) {
|
||||
ret = VM_FAULT_RETRY;
|
||||
goto release;
|
||||
}
|
||||
if (!pte_none(*vmf->pte)) {
|
||||
update_mmu_tlb(vma, vmf->address, vmf->pte);
|
||||
goto unlock;
|
||||
@@ -3878,6 +3884,8 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
|
||||
pte_unmap_unlock(vmf->pte, vmf->ptl);
|
||||
if (page)
|
||||
put_page(page);
|
||||
if (vmf->flags & FAULT_FLAG_SPECULATIVE)
|
||||
return VM_FAULT_RETRY;
|
||||
return handle_userfault(vmf, VM_UFFD_MISSING);
|
||||
}
|
||||
|
||||
@@ -3895,6 +3903,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
|
||||
return 0;
|
||||
unlock:
|
||||
pte_unmap_unlock(vmf->pte, vmf->ptl);
|
||||
release:
|
||||
if (page)
|
||||
put_page(page);
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user