On device removal reroute all CPU mappings to dummy page
per drm_file instance or imported GEM object.

v3:
Remove loop to find DRM file and instead access it
by vma->vm_file->private_data. Move dummy page installation
into a separate function.

Signed-off-by: Andrey Grodzovsky <andrey.grodzov...@amd.com>
---
 drivers/gpu/drm/ttm/ttm_bo_vm.c | 54 +++++++++++++++++++++++++++++++++++------
 1 file changed, 46 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index 01693e8..f2dbb93 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -35,6 +35,8 @@
 #include <drm/ttm/ttm_bo_driver.h>
 #include <drm/ttm/ttm_placement.h>
 #include <drm/drm_vma_manager.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_file.h>
 #include <linux/mm.h>
 #include <linux/pfn_t.h>
 #include <linux/rbtree.h>
@@ -420,23 +422,59 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
 }
 EXPORT_SYMBOL(ttm_bo_vm_fault_reserved);
 
+vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf)
+{
+       struct vm_area_struct *vma = vmf->vma;
+       struct ttm_buffer_object *bo = vma->vm_private_data;
+       struct drm_file *file = NULL;
+       struct page *dummy_page = NULL;
+
+       /* We are faulting on imported BO from dma_buf */
+       if (bo->base.dma_buf && bo->base.import_attach) {
+               dummy_page = bo->base.dummy_page;
+       /* We are faulting on local BO */
+       } else {
+               file = vma->vm_file->private_data;
+               dummy_page = file->dummy_page;
+       }
+
+       /* Let do_fault complete the PTE install e.t.c using vmf->page */
+       get_page(dummy_page);
+       vmf->page = dummy_page;
+
+       return 0;
+}
+
 vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        pgprot_t prot;
        struct ttm_buffer_object *bo = vma->vm_private_data;
        vm_fault_t ret;
+       int idx;
+       struct drm_device *ddev = bo->base.dev;
 
-       ret = ttm_bo_vm_reserve(bo, vmf);
-       if (ret)
-               return ret;
 
-       prot = vma->vm_page_prot;
-       ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT, 1);
-       if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
-               return ret;
+       if (!drm_dev_enter(ddev, &idx)) {
+               ret = ttm_bo_vm_dummy_page(vmf);
+               if (ret)
+                       return ret;
+       } else {
+               ret = ttm_bo_vm_reserve(bo, vmf);
+               if (ret)
+                       goto exit;
 
-       dma_resv_unlock(bo->base.resv);
+               prot = vma->vm_page_prot;
+
+               ret = ttm_bo_vm_fault_reserved(vmf, prot, 
TTM_BO_VM_NUM_PREFAULT, 1);
+               if (ret == VM_FAULT_RETRY && !(vmf->flags & 
FAULT_FLAG_RETRY_NOWAIT))
+                       goto exit;
+
+               dma_resv_unlock(bo->base.resv);
+
+exit:
+               drm_dev_exit(idx);
+       }
 
        return ret;
 }
-- 
2.7.4

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

Reply via email to