ANDROID: mm: Fix sleeping while atomic during speculative page fault
A speculative page fault may race with a call to free_pagetables. If free_pagetables is called first, *(vmf->pmd) may be empty. __might_sleep() __alloc_pages_nodemask() pte_alloc_one(inline) __pte_alloc() pte_alloc_one_map(inline) alloc_set_pte() filemap_map_pages() do_fault_around(inline) do_read_fault(inline) do_fault(inline) handle_pte_fault() mem_cgroup_exit_user_fault(inline) __handle_speculative_fault() do_page_fault() As filemap_map_pages() holds an rcu_lock(), this triggers a sleeping-while-atomic BUG(). As free_pagetables has already been called, it is also a memory leak. Fix this by skipping to pte_map_lock() to allow spf to detect that the vma has changed, and a normal page fault should be taken instead. Change-Id: I121ca4be99c908656db3a1dc88cfb3b64f01e2fb Bug: 161210518 Signed-off-by: Patrick Daly <pdaly@codeaurora.org> Signed-off-by: Vinayak Menon <vinmenon@codeaurora.org>
This commit is contained in:
committed by
Suren Baghdasaryan
parent
14624d3dc3
commit
531f65ae67
@@ -3877,7 +3877,7 @@ static vm_fault_t pte_alloc_one_map(struct vm_fault *vmf)
|
||||
{
|
||||
struct vm_area_struct *vma = vmf->vma;
|
||||
|
||||
if (!pmd_none(*vmf->pmd))
|
||||
if (!pmd_none(*vmf->pmd) || (vmf->flags & FAULT_FLAG_SPECULATIVE))
|
||||
goto map_pte;
|
||||
if (vmf->prealloc_pte) {
|
||||
vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd);
|
||||
|
||||
Reference in New Issue
Block a user