On 4/12/19 9:04 AM, Thomas Hellstrom wrote:
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 <a...@linux-foundation.org>
Cc: Matthew Wilcox <wi...@infradead.org>
Cc: Will Deacon <will.dea...@arm.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Rik van Riel <r...@surriel.com>
Cc: Minchan Kim <minc...@kernel.org>
Cc: Michal Hocko <mho...@suse.com>
Cc: Huang Ying <ying.hu...@intel.com>
Cc: Souptick Joarder <jrdr.li...@gmail.com>
Cc: "Jérôme Glisse" <jgli...@redhat.com>
Cc: linux...@kvack.org
Cc: linux-ker...@vger.kernel.org

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>

Reviewed-by: Ralph Campbell <rcampb...@nvidia.com>

---
  mm/memory.c | 10 ++++++----
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index e11ca9dd823f..a95b4a3b1ae2 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2144,7 +2144,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_RETRY | VM_FAULT_NOPAGE)))

A very minor nit, for consistency elsewhere in mm/memory.c,
could you make this be:
        (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)

                return ret;
        if (unlikely(!(ret & VM_FAULT_LOCKED))) {
                lock_page(page);
@@ -2419,7 +2419,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_RETRY | VM_FAULT_NOPAGE))
                        return ret;
                return finish_mkwrite_fault(vmf);
        }
@@ -2440,7 +2440,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_RETRY |
+                                      VM_FAULT_NOPAGE)))) {
                        put_page(vmf->page);
                        return tmp;
                }
@@ -3494,7 +3495,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_RETRY |
+                                       VM_FAULT_NOPAGE)))) {
                        put_page(vmf->page);
                        return tmp;
                }

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to