[PATCH v3 03/12] drm/ttm: Remap all page faults to per process dummy page.
Andrey Grodzovsky
andrey.grodzovsky at amd.com
Sat Nov 21 05:21:13 UTC 2020
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.grodzovsky at 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
More information about the dri-devel
mailing list