mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29:37 +00:00
mm: Allow the [page|pfn]_mkwrite callbacks to drop the mmap_sem
Driver fault callbacks are allowed to drop the mmap_sem when expecting long hardware waits to avoid blocking other mm users. Allow the mkwrite callbacks to do the same by returning early on VM_FAULT_RETRY. In particular we want to be able to drop the mmap_sem when waiting for a reservation object lock on a GPU buffer object. These locks may be held while waiting for the GPU. Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Matthew Wilcox <willy@infradead.org> Cc: Will Deacon <will.deacon@arm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rik van Riel <riel@surriel.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Huang Ying <ying.huang@intel.com> Cc: Souptick Joarder <jrdr.linux@gmail.com> Cc: "Jérôme Glisse" <jglisse@redhat.com> Cc: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Ralph Campbell <rcampbell@nvidia.com>
This commit is contained in:
parent
4251fa5fc3
commit
c9e5f41f73
1 changed files with 6 additions and 4 deletions
10
mm/memory.c
10
mm/memory.c
|
@ -2238,7 +2238,7 @@ static vm_fault_t do_page_mkwrite(struct vm_fault *vmf)
|
|||
ret = vmf->vma->vm_ops->page_mkwrite(vmf);
|
||||
/* Restore original flags so that caller is not surprised */
|
||||
vmf->flags = old_flags;
|
||||
if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))
|
||||
if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)))
|
||||
return ret;
|
||||
if (unlikely(!(ret & VM_FAULT_LOCKED))) {
|
||||
lock_page(page);
|
||||
|
@ -2515,7 +2515,7 @@ static vm_fault_t wp_pfn_shared(struct vm_fault *vmf)
|
|||
pte_unmap_unlock(vmf->pte, vmf->ptl);
|
||||
vmf->flags |= FAULT_FLAG_MKWRITE;
|
||||
ret = vma->vm_ops->pfn_mkwrite(vmf);
|
||||
if (ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE))
|
||||
if (ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY))
|
||||
return ret;
|
||||
return finish_mkwrite_fault(vmf);
|
||||
}
|
||||
|
@ -2536,7 +2536,8 @@ static vm_fault_t wp_page_shared(struct vm_fault *vmf)
|
|||
pte_unmap_unlock(vmf->pte, vmf->ptl);
|
||||
tmp = do_page_mkwrite(vmf);
|
||||
if (unlikely(!tmp || (tmp &
|
||||
(VM_FAULT_ERROR | VM_FAULT_NOPAGE)))) {
|
||||
(VM_FAULT_ERROR | VM_FAULT_NOPAGE |
|
||||
VM_FAULT_RETRY)))) {
|
||||
put_page(vmf->page);
|
||||
return tmp;
|
||||
}
|
||||
|
@ -3601,7 +3602,8 @@ static vm_fault_t do_shared_fault(struct vm_fault *vmf)
|
|||
unlock_page(vmf->page);
|
||||
tmp = do_page_mkwrite(vmf);
|
||||
if (unlikely(!tmp ||
|
||||
(tmp & (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))) {
|
||||
(tmp & (VM_FAULT_ERROR | VM_FAULT_NOPAGE |
|
||||
VM_FAULT_RETRY)))) {
|
||||
put_page(vmf->page);
|
||||
return tmp;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue