[Intel-xe] [PATCH v2 24/31] drm/xe: Userptr refactor

Matthew Brost matthew.brost at intel.com
Tue May 2 00:17:20 UTC 2023


Add GPUVA userptr flag, add GPUVA userptr sub-struct, and drop sg
pointer. A larger follow on cleanup may push more of userptr
implementation to GPUVA.

Signed-off-by: Matthew Brost <matthew.brost at intel.com>
---
 drivers/gpu/drm/xe/xe_pt.c       |  6 +--
 drivers/gpu/drm/xe/xe_vm.c       | 41 +++++++++++----------
 drivers/gpu/drm/xe/xe_vm.h       | 23 +++++++-----
 drivers/gpu/drm/xe/xe_vm_types.h | 20 +++++-----
 include/drm/drm_gpuva_mgr.h      | 63 +++++++++++++++++++++-----------
 5 files changed, 89 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index 0f40f1950686..964baa24eba3 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -92,8 +92,8 @@ static dma_addr_t vma_addr(struct xe_vma *vma, u64 offset,
 		page = offset >> PAGE_SHIFT;
 		offset &= (PAGE_SIZE - 1);
 
-		xe_res_first_sg(vma->userptr.sg, page << PAGE_SHIFT, page_size,
-				&cur);
+		xe_res_first_sg(&vma->userptr.sgt, page << PAGE_SHIFT,
+				page_size, &cur);
 		return xe_res_dma(&cur) + offset;
 	} else {
 		return xe_bo_addr(xe_vma_bo(vma), offset, page_size, is_vram);
@@ -813,7 +813,7 @@ xe_pt_stage_bind(struct xe_gt *gt, struct xe_vma *vma,
 	xe_bo_assert_held(bo);
 	if (!xe_vma_is_null(vma)) {
 		if (xe_vma_is_userptr(vma))
-			xe_res_first_sg(vma->userptr.sg, 0, xe_vma_size(vma),
+			xe_res_first_sg(&vma->userptr.sgt, 0, xe_vma_size(vma),
 					&curs);
 		else if (xe_bo_is_vram(bo) || xe_bo_is_stolen(bo))
 			xe_res_first(bo->ttm.resource, xe_vma_bo_offset(vma),
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 336e21c710a5..4d734ec4d6ab 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -73,13 +73,13 @@ int xe_vma_userptr_pin_pages(struct xe_vma *vma)
 	if (!pages)
 		return -ENOMEM;
 
-	if (vma->userptr.sg) {
+	if (xe_vma_userptr_sg_mapped(vma)) {
 		dma_unmap_sgtable(xe->drm.dev,
-				  vma->userptr.sg,
+				  &vma->userptr.sgt,
 				  read_only ? DMA_TO_DEVICE :
 				  DMA_BIDIRECTIONAL, 0);
-		sg_free_table(vma->userptr.sg);
-		vma->userptr.sg = NULL;
+		sg_free_table(&vma->userptr.sgt);
+		vma->gpuva.flags &= ~XE_VMA_USERPTR_SG_MAPPED;
 	}
 
 	pinned = ret = 0;
@@ -119,19 +119,19 @@ int xe_vma_userptr_pin_pages(struct xe_vma *vma)
 					0, (u64)pinned << PAGE_SHIFT,
 					GFP_KERNEL);
 	if (ret) {
-		vma->userptr.sg = NULL;
+		vma->gpuva.flags &= ~XE_VMA_USERPTR_SG_MAPPED;
 		goto out;
 	}
-	vma->userptr.sg = &vma->userptr.sgt;
+	vma->gpuva.flags |= XE_VMA_USERPTR_SG_MAPPED;
 
-	ret = dma_map_sgtable(xe->drm.dev, vma->userptr.sg,
+	ret = dma_map_sgtable(xe->drm.dev, &vma->userptr.sgt,
 			      read_only ? DMA_TO_DEVICE :
 			      DMA_BIDIRECTIONAL,
 			      DMA_ATTR_SKIP_CPU_SYNC |
 			      DMA_ATTR_NO_KERNEL_MAPPING);
 	if (ret) {
-		sg_free_table(vma->userptr.sg);
-		vma->userptr.sg = NULL;
+		sg_free_table(&vma->userptr.sgt);
+		vma->gpuva.flags &= ~XE_VMA_USERPTR_SG_MAPPED;
 		goto out;
 	}
 
@@ -820,15 +820,13 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
 	 */
 	INIT_LIST_HEAD(&vma->rebind_link);
 
-	INIT_LIST_HEAD(&vma->gpuva.gem.entry);
-	INIT_LIST_HEAD(&vma->gpuva.gem.extobj_link);
 	vma->gpuva.mgr = &vm->mgr;
 	vma->gpuva.va.addr = start;
 	vma->gpuva.va.range = end - start + 1;
 	if (read_only)
 		vma->gpuva.flags |= XE_VMA_READ_ONLY;
 	if (null)
-		vma->gpuva.flags |= XE_VMA_NULL;
+		vma->gpuva.flags |= DRM_GPUVA_SPARSE;
 
 	if (gt_mask) {
 		vma->gt_mask = gt_mask;
@@ -845,6 +843,8 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
 		xe_bo_assert_held(bo);
 
 		drm_gem_object_get(&bo->ttm.base);
+		INIT_LIST_HEAD(&vma->gpuva.gem.entry);
+		INIT_LIST_HEAD(&vma->gpuva.gem.extobj_link);
 		vma->gpuva.gem.obj = &bo->ttm.base;
 		vma->gpuva.gem.offset = bo_offset_or_userptr;
 		if (!bo->vm)
@@ -855,7 +855,8 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
 			u64 size = end - start + 1;
 			int err;
 
-			vma->gpuva.gem.offset = bo_offset_or_userptr;
+			vma->gpuva.flags |= DRM_GPUVA_USERPTR;
+			vma->gpuva.userptr.address= bo_offset_or_userptr;
 			err = mmu_interval_notifier_insert(&vma->userptr.notifier,
 							   current->mm,
 							   xe_vma_userptr(vma),
@@ -883,13 +884,13 @@ static void xe_vma_destroy_late(struct xe_vma *vma)
 	bool read_only = xe_vma_read_only(vma);
 
 	if (xe_vma_is_userptr(vma)) {
-		if (vma->userptr.sg) {
+		if (xe_vma_userptr_sg_mapped(vma)) {
 			dma_unmap_sgtable(xe->drm.dev,
-					  vma->userptr.sg,
+					  &vma->userptr.sgt,
 					  read_only ? DMA_TO_DEVICE :
 					  DMA_BIDIRECTIONAL, 0);
-			sg_free_table(vma->userptr.sg);
-			vma->userptr.sg = NULL;
+			sg_free_table(&vma->userptr.sgt);
+			vma->gpuva.flags &= ~XE_VMA_USERPTR_SG_MAPPED;
 		}
 
 		/*
@@ -2309,7 +2310,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct xe_engine *e,
 						XE_VMA_READ_ONLY;
 					bool null =
 						op->base.remap.unmap->va->flags &
-						XE_VMA_NULL;
+						DRM_GPUVA_SPARSE;
 
 					vma = new_vma(vm, op->base.remap.prev,
 						      op->gt_mask, read_only,
@@ -2344,7 +2345,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct xe_engine *e,
 
 					bool null =
 						op->base.remap.unmap->va->flags &
-						XE_VMA_NULL;
+						DRM_GPUVA_SPARSE;
 
 					vma = new_vma(vm, op->base.remap.next,
 						      op->gt_mask, read_only,
@@ -3320,7 +3321,7 @@ int xe_analyze_vm(struct drm_printer *p, struct xe_vm *vm, int gt_id)
 		} else if (is_userptr) {
 			struct xe_res_cursor cur;
 
-			xe_res_first_sg(vma->userptr.sg, 0, XE_PAGE_SIZE, &cur);
+			xe_res_first_sg(&vma->userptr.sgt, 0, XE_PAGE_SIZE, &cur);
 			addr = xe_res_dma(&cur);
 		} else {
 			addr = xe_bo_addr(xe_vma_bo(vma), 0, XE_PAGE_SIZE, &is_vram);
diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
index 12de652d8d1c..f279fa622260 100644
--- a/drivers/gpu/drm/xe/xe_vm.h
+++ b/drivers/gpu/drm/xe/xe_vm.h
@@ -101,12 +101,6 @@ static inline u64 xe_vma_bo_offset(struct xe_vma *vma)
 	return vma->gpuva.gem.offset;
 }
 
-static inline struct xe_bo *xe_vma_bo(struct xe_vma *vma)
-{
-	return !vma->gpuva.gem.obj ? NULL :
-		container_of(vma->gpuva.gem.obj, struct xe_bo, ttm.base);
-}
-
 static inline struct xe_vm *xe_vma_vm(struct xe_vma *vma)
 {
 	return container_of(vma->gpuva.mgr, struct xe_vm, mgr);
@@ -129,7 +123,7 @@ static inline bool xe_vma_read_only(struct xe_vma *vma)
 
 static inline u64 xe_vma_userptr(struct xe_vma *vma)
 {
-	return vma->gpuva.gem.offset;
+	return vma->gpuva.userptr.address;
 }
 
 #define xe_vm_assert_held(vm) dma_resv_assert_held(&(vm)->mgr.resv)
@@ -197,12 +191,18 @@ static inline void xe_vm_reactivate_rebind(struct xe_vm *vm)
 
 static inline bool xe_vma_is_null(struct xe_vma *vma)
 {
-	return vma->gpuva.flags & XE_VMA_NULL;
+	return vma->gpuva.flags & DRM_GPUVA_SPARSE;
 }
 
 static inline bool xe_vma_is_userptr(struct xe_vma *vma)
 {
-	return !xe_vma_bo(vma) && !xe_vma_is_null(vma);
+	return vma->gpuva.flags & DRM_GPUVA_USERPTR;
+}
+
+static inline struct xe_bo *xe_vma_bo(struct xe_vma *vma)
+{
+	return xe_vma_is_null(vma) || xe_vma_is_userptr(vma) ? NULL :
+		container_of(vma->gpuva.gem.obj, struct xe_bo, ttm.base);
 }
 
 static inline bool xe_vma_has_no_bo(struct xe_vma *vma)
@@ -210,6 +210,11 @@ static inline bool xe_vma_has_no_bo(struct xe_vma *vma)
 	return !xe_vma_bo(vma);
 }
 
+static inline bool xe_vma_userptr_sg_mapped(struct xe_vma *vma)
+{
+	return vma->gpuva.flags & XE_VMA_USERPTR_SG_MAPPED;
+}
+
 int xe_vma_userptr_pin_pages(struct xe_vma *vma);
 
 int xe_vma_userptr_check_repin(struct xe_vma *vma);
diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h
index 0b59bde3bc4e..ce1260b8d3ef 100644
--- a/drivers/gpu/drm/xe/xe_vm_types.h
+++ b/drivers/gpu/drm/xe/xe_vm_types.h
@@ -23,15 +23,15 @@ struct xe_vm;
 #define TEST_VM_ASYNC_OPS_ERROR
 #define FORCE_ASYNC_OP_ERROR	BIT(31)
 
-#define XE_VMA_READ_ONLY	DRM_GPUVA_USERBITS
-#define XE_VMA_DESTROYED	(DRM_GPUVA_USERBITS << 1)
-#define XE_VMA_ATOMIC_PTE_BIT	(DRM_GPUVA_USERBITS << 2)
-#define XE_VMA_FIRST_REBIND	(DRM_GPUVA_USERBITS << 3)
-#define XE_VMA_LAST_REBIND	(DRM_GPUVA_USERBITS << 4)
-#define XE_VMA_NULL		(DRM_GPUVA_USERBITS << 5)
-#define XE_VMA_PTE_4K		(DRM_GPUVA_USERBITS << 6)
-#define XE_VMA_PTE_2M		(DRM_GPUVA_USERBITS << 7)
-#define XE_VMA_PTE_1G		(DRM_GPUVA_USERBITS << 8)
+#define XE_VMA_READ_ONLY		DRM_GPUVA_USERBITS
+#define XE_VMA_DESTROYED		(DRM_GPUVA_USERBITS << 1)
+#define XE_VMA_ATOMIC_PTE_BIT		(DRM_GPUVA_USERBITS << 2)
+#define XE_VMA_FIRST_REBIND		(DRM_GPUVA_USERBITS << 3)
+#define XE_VMA_LAST_REBIND		(DRM_GPUVA_USERBITS << 4)
+#define XE_VMA_USERPTR_SG_MAPPED	(DRM_GPUVA_USERBITS << 5)
+#define XE_VMA_PTE_4K			(DRM_GPUVA_USERBITS << 6)
+#define XE_VMA_PTE_2M			(DRM_GPUVA_USERBITS << 7)
+#define XE_VMA_PTE_1G			(DRM_GPUVA_USERBITS << 8)
 
 /** struct xe_userptr - User pointer */
 struct xe_userptr {
@@ -41,8 +41,6 @@ struct xe_userptr {
 	struct mmu_interval_notifier notifier;
 	/** @sgt: storage for a scatter gather table */
 	struct sg_table sgt;
-	/** @sg: allocated scatter gather table */
-	struct sg_table *sg;
 	/** @notifier_seq: notifier sequence number */
 	unsigned long notifier_seq;
 	/**
diff --git a/include/drm/drm_gpuva_mgr.h b/include/drm/drm_gpuva_mgr.h
index 57861a7ed504..943c8fcda533 100644
--- a/include/drm/drm_gpuva_mgr.h
+++ b/include/drm/drm_gpuva_mgr.h
@@ -62,10 +62,17 @@ enum drm_gpuva_flags {
 	 */
 	DRM_GPUVA_EXTOBJ = (1 << 2),
 
+	/**
+	 * @DRM_GPUVA_USERPTR:
+	 *
+	 * Flag indicating that the &drm_gpuva is a user pointer mapping.
+	 */
+	DRM_GPUVA_USERPTR = (1 << 3),
+
 	/**
 	 * @DRM_GPUVA_USERBITS: user defined bits
 	 */
-	DRM_GPUVA_USERBITS = (1 << 3),
+	DRM_GPUVA_USERBITS = (1 << 4),
 };
 
 /**
@@ -102,31 +109,45 @@ struct drm_gpuva {
 		u64 range;
 	} va;
 
-	/**
-	 * @gem: structure containing the &drm_gem_object and it's offset
-	 */
-	struct {
-		/**
-		 * @offset: the offset within the &drm_gem_object
-		 */
-		u64 offset;
-
-		/**
-		 * @obj: the mapped &drm_gem_object
-		 */
-		struct drm_gem_object *obj;
-
+	union {
 		/**
-		 * @entry: the &list_head to attach this object to a &drm_gem_object
+		 * @gem: structure containing the &drm_gem_object and it's
+		 * offset
 		 */
-		struct list_head entry;
+		struct {
+			/**
+			 * @offset: the offset within the &drm_gem_object
+			 */
+			u64 offset;
+
+			/**
+			 * @obj: the mapped &drm_gem_object
+			 */
+			struct drm_gem_object *obj;
+
+			/**
+			 * @entry: the &list_head to attach this object to a
+			 * &drm_gem_object
+			 */
+			struct list_head entry;
+
+			/**
+			 * @extobj_link: the &list_head to attach this object to
+			 * a @drm_gpuva_manager.extobj.list
+			 */
+			struct list_head extobj_link;
+		} gem;
 
 		/**
-		 * @extobj_link: the &list_head to attach this object to a
-		 * @drm_gpuva_manager.extobj.list
+		 * @userptr: structure containing user pointer state
 		 */
-		struct list_head extobj_link;
-	} gem;
+		struct {
+			/**
+			 * @address: user pointer address
+			 */
+			u64 address;
+		} userptr;
+	};
 };
 
 void drm_gpuva_link(struct drm_gpuva *va);
-- 
2.34.1



More information about the Intel-xe mailing list