[PATCH 2/5] ppgtt

Matthew Auld matthew.auld at intel.com
Fri Nov 29 10:49:29 UTC 2019


---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 114 ++++++++++++++++++++--------
 drivers/gpu/drm/i915/i915_gem_gtt.h |   8 ++
 2 files changed, 92 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 6239a9adbf14..cf061160e920 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -576,9 +576,19 @@ static void i915_address_space_init(struct i915_address_space *vm, int subclass)
 	INIT_LIST_HEAD(&vm->bound_list);
 }
 
-static int __setup_page_dma(struct i915_address_space *vm,
-			    struct i915_page_dma *p,
-			    gfp_t gfp)
+static void *kmap_page_dma_system(const struct i915_page_dma *p)
+{
+	return kmap_atomic(p->page);
+}
+
+static void kunmap_page_dma_system(void *vaddr)
+{
+	kunmap_atomic(vaddr);
+}
+
+static int setup_page_dma_system(struct i915_address_space *vm,
+				 struct i915_page_dma *p,
+				 gfp_t gfp)
 {
 	p->page = vm_alloc_page(vm, gfp | I915_GFP_ALLOW_FAIL);
 	if (unlikely(!p->page))
@@ -594,28 +604,54 @@ static int __setup_page_dma(struct i915_address_space *vm,
 		return -ENOMEM;
 	}
 
+	p->kmap = kmap_page_dma_system;
+	p->kunmap = kunmap_page_dma_system;
+
 	return 0;
 }
 
+static void cleanup_page_dma_system(struct i915_address_space *vm,
+				    struct i915_page_dma *p)
+{
+	dma_unmap_page(vm->dma, p->daddr, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+	vm_free_page(vm, p->page);
+}
+
+static int __setup_page_dma(struct i915_address_space *vm,
+			    struct i915_page_dma *p)
+{
+	return vm->setup_page_dma(vm, p, __GFP_HIGHMEM);
+}
+
 static int setup_page_dma(struct i915_address_space *vm,
 			  struct i915_page_dma *p)
 {
-	return __setup_page_dma(vm, p, __GFP_HIGHMEM);
+	return __setup_page_dma(vm, p);
 }
 
 static void cleanup_page_dma(struct i915_address_space *vm,
 			     struct i915_page_dma *p)
 {
-	dma_unmap_page(vm->dma, p->daddr, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
-	vm_free_page(vm, p->page);
+	vm->cleanup_page_dma(vm, p);
 }
 
-#define kmap_atomic_px(px) kmap_atomic(px_base(px)->page)
+static void kunmap_page_dma(const struct i915_page_dma *p, void *vaddr)
+{
+	p->kunmap(vaddr);
+}
+
+static void *kmap_page_dma(const struct i915_page_dma *p)
+{
+	return p->kmap(p);
+}
+
+#define kmap_atomic_base(base) kmap_page_dma(base)
+#define kunmap_atomic_base(base, vaddr) kunmap_page_dma(base, vaddr)
 
 static void
 fill_page_dma(const struct i915_page_dma *p, const u64 val, unsigned int count)
 {
-	kunmap_atomic(memset64(kmap_atomic(p->page), val, count));
+	kunmap_atomic_base(p, memset64(kmap_atomic_base(p), val, count));
 }
 
 #define fill_px(px, v) fill_page_dma(px_base(px), (v), PAGE_SIZE / sizeof(u64))
@@ -716,7 +752,7 @@ static struct i915_page_table *alloc_pt(struct i915_address_space *vm)
 {
 	struct i915_page_table *pt;
 
-	pt = kmalloc(sizeof(*pt), I915_GFP_ALLOW_FAIL);
+	pt = kzalloc(sizeof(*pt), I915_GFP_ALLOW_FAIL);
 	if (unlikely(!pt))
 		return ERR_PTR(-ENOMEM);
 
@@ -770,10 +806,10 @@ write_dma_entry(struct i915_page_dma * const pdma,
 		const unsigned short idx,
 		const u64 encoded_entry)
 {
-	u64 * const vaddr = kmap_atomic(pdma->page);
+	u64 * const vaddr = kmap_atomic_base(pdma);
 
 	vaddr[idx] = encoded_entry;
-	kunmap_atomic(vaddr);
+	kunmap_atomic_base(pdma, vaddr);
 }
 
 static inline void
@@ -1001,11 +1037,11 @@ static u64 __gen8_ppgtt_clear(struct i915_address_space * const vm,
 			    atomic_read(&pt->used));
 			GEM_BUG_ON(!count || count >= atomic_read(&pt->used));
 
-			vaddr = kmap_atomic_px(pt);
+			vaddr = kmap_atomic_base(&pt->base);
 			memset64(vaddr + gen8_pd_index(start, 0),
 				 vm->scratch[0].encode,
 				 count);
-			kunmap_atomic(vaddr);
+			kunmap_atomic_base(&pt->base, vaddr);
 
 			atomic_sub(count, &pt->used);
 			start += count;
@@ -1172,10 +1208,12 @@ gen8_ppgtt_insert_pte(struct i915_ppgtt *ppgtt,
 {
 	struct i915_page_directory *pd;
 	const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level, flags);
+	struct i915_page_table *pt;
 	gen8_pte_t *vaddr;
 
 	pd = i915_pd_entry(pdp, gen8_pd_index(idx, 2));
-	vaddr = kmap_atomic_px(i915_pt_entry(pd, gen8_pd_index(idx, 1)));
+	pt = i915_pt_entry(pd, gen8_pd_index(idx, 1));
+	vaddr = kmap_atomic_base(&pt->base);
 	do {
 		vaddr[gen8_pd_index(idx, 0)] = pte_encode | iter->dma;
 
@@ -1200,11 +1238,12 @@ gen8_ppgtt_insert_pte(struct i915_ppgtt *ppgtt,
 				pd = pdp->entry[gen8_pd_index(idx, 2)];
 			}
 
-			kunmap_atomic(vaddr);
-			vaddr = kmap_atomic_px(i915_pt_entry(pd, gen8_pd_index(idx, 1)));
+			kunmap_atomic_base(&pt->base, vaddr);
+			pt = i915_pt_entry(pd, gen8_pd_index(idx, 1));
+			vaddr = kmap_atomic_base(&pt->base);
 		}
 	} while (1);
-	kunmap_atomic(vaddr);
+	kunmap_atomic_base(&pt->base, vaddr);
 
 	return idx;
 }
@@ -1225,6 +1264,7 @@ static void gen8_ppgtt_insert_huge(struct i915_vma *vma,
 			gen8_pdp_for_page_address(vma->vm, start);
 		struct i915_page_directory * const pd =
 			i915_pd_entry(pdp, __gen8_pte_index(start, 2));
+		struct i915_page_dma *base;
 		gen8_pte_t encode = pte_encode;
 		unsigned int maybe_64K = -1;
 		unsigned int page_size;
@@ -1239,7 +1279,7 @@ static void gen8_ppgtt_insert_huge(struct i915_vma *vma,
 			encode |= GEN8_PDE_PS_2M;
 			page_size = I915_GTT_PAGE_SIZE_2M;
 
-			vaddr = kmap_atomic_px(pd);
+			base = &pd->pt.base;
 		} else {
 			struct i915_page_table *pt =
 				i915_pt_entry(pd, __gen8_pte_index(start, 1));
@@ -1254,9 +1294,11 @@ static void gen8_ppgtt_insert_huge(struct i915_vma *vma,
 			     rem >= (I915_PDES - index) * I915_GTT_PAGE_SIZE))
 				maybe_64K = __gen8_pte_index(start, 1);
 
-			vaddr = kmap_atomic_px(pt);
+			base = &pt->base;
 		}
 
+		vaddr = kmap_atomic_base(base);
+
 		do {
 			GEM_BUG_ON(iter->sg->length < page_size);
 			vaddr[index++] = encode | iter->dma;
@@ -1284,7 +1326,7 @@ static void gen8_ppgtt_insert_huge(struct i915_vma *vma,
 			}
 		} while (rem >= page_size && index < I915_PDES);
 
-		kunmap_atomic(vaddr);
+		kunmap_atomic_base(base, vaddr);
 
 		/*
 		 * Is it safe to mark the 2M block as 64K? -- Either we have
@@ -1298,9 +1340,9 @@ static void gen8_ppgtt_insert_huge(struct i915_vma *vma,
 		      !iter->sg && IS_ALIGNED(vma->node.start +
 					      vma->node.size,
 					      I915_GTT_PAGE_SIZE_2M)))) {
-			vaddr = kmap_atomic_px(pd);
+			vaddr = kmap_atomic_base(&pd->pt.base);
 			vaddr[maybe_64K] |= GEN8_PDE_IPS_64K;
-			kunmap_atomic(vaddr);
+			kunmap_atomic_base(&pd->pt.base, vaddr);
 			page_size = I915_GTT_PAGE_SIZE_64K;
 
 			/*
@@ -1313,15 +1355,17 @@ static void gen8_ppgtt_insert_huge(struct i915_vma *vma,
 			 * selftests.
 			 */
 			if (I915_SELFTEST_ONLY(vma->vm->scrub_64K)) {
+				struct i915_page_table *pt =
+						i915_pt_entry(pd, maybe_64K);
 				u16 i;
 
 				encode = vma->vm->scratch[0].encode;
-				vaddr = kmap_atomic_px(i915_pt_entry(pd, maybe_64K));
+				vaddr = kmap_atomic_base(&pt->base);
 
 				for (i = 1; i < index; i += 16)
 					memset64(vaddr + i, encode, 15);
 
-				kunmap_atomic(vaddr);
+				kunmap_atomic_base(&pt->base, vaddr);
 			}
 		}
 
@@ -1502,6 +1546,9 @@ static struct i915_ppgtt *gen8_ppgtt_create(struct drm_i915_private *i915)
 	if (IS_CHERRYVIEW(i915) || IS_BROXTON(i915))
 		ppgtt->vm.pt_kmap_wc = true;
 
+	ppgtt->vm.setup_page_dma = setup_page_dma_system;
+	ppgtt->vm.cleanup_page_dma = cleanup_page_dma_system;
+
 	err = gen8_init_scratch(&ppgtt->vm);
 	if (err)
 		goto err_free;
@@ -1634,9 +1681,9 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
 		 * entries back to scratch.
 		 */
 
-		vaddr = kmap_atomic_px(pt);
+		vaddr = kmap_atomic_base(&pt->base);
 		memset32(vaddr + pte, scratch_pte, count);
-		kunmap_atomic(vaddr);
+		kunmap_atomic_base(&pt->base, vaddr);
 
 		pte = 0;
 	}
@@ -1654,11 +1701,13 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
 	unsigned act_pte = first_entry % GEN6_PTES;
 	const u32 pte_encode = vm->pte_encode(0, cache_level, flags);
 	struct sgt_dma iter = sgt_dma(vma);
+	struct i915_page_table *pt;
 	gen6_pte_t *vaddr;
 
 	GEM_BUG_ON(pd->entry[act_pt] == &vm->scratch[1]);
 
-	vaddr = kmap_atomic_px(i915_pt_entry(pd, act_pt));
+	pt = i915_pt_entry(pd, act_pt);
+	vaddr = kmap_atomic_base(&pt->base);
 	do {
 		vaddr[act_pte] = pte_encode | GEN6_PTE_ADDR_ENCODE(iter.dma);
 
@@ -1673,12 +1722,14 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
 		}
 
 		if (++act_pte == GEN6_PTES) {
-			kunmap_atomic(vaddr);
-			vaddr = kmap_atomic_px(i915_pt_entry(pd, ++act_pt));
+			kunmap_atomic_base(&pt->base, vaddr);
+
+			pt = i915_pt_entry(pd, ++act_pt);
+			vaddr = kmap_atomic_base(&pt->base);
 			act_pte = 0;
 		}
 	} while (1);
-	kunmap_atomic(vaddr);
+	kunmap_atomic_base(&pt->base, vaddr);
 
 	vma->page_sizes.gtt = I915_GTT_PAGE_SIZE;
 }
@@ -1971,6 +2022,9 @@ static struct i915_ppgtt *gen6_ppgtt_create(struct drm_i915_private *i915)
 
 	ppgtt->base.vm.pte_encode = ggtt->vm.pte_encode;
 
+	ppgtt->base.vm.setup_page_dma = setup_page_dma_system;
+	ppgtt->base.vm.cleanup_page_dma = cleanup_page_dma_system;
+
 	ppgtt->base.pd = __alloc_pd(sizeof(*ppgtt->base.pd));
 	if (!ppgtt->base.pd) {
 		err = -ENOMEM;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 402283ce2864..4356cd546796 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -226,6 +226,9 @@ struct i915_page_dma {
 		 */
 		u32 ggtt_offset;
 	};
+
+	void *(*kmap)(const struct i915_page_dma *p);
+	void (*kunmap)(void *vaddr);
 };
 
 struct i915_page_scratch {
@@ -345,6 +348,11 @@ struct i915_address_space {
 			  u32 flags); /* Create a valid PTE */
 #define PTE_READ_ONLY	(1<<0)
 
+	int (*setup_page_dma)(struct i915_address_space *vm,
+			      struct i915_page_dma *p,
+			      gfp_t gfp);
+	void (*cleanup_page_dma)(struct i915_address_space *vm,
+				 struct i915_page_dma *p);
 	int (*allocate_va_range)(struct i915_address_space *vm,
 				 u64 start, u64 length);
 	void (*clear_range)(struct i915_address_space *vm,
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list