All of lore.kernel.org
 help / color / mirror / Atom feed
* Split large VRAM allocations into smaller parts.
@ 2016-08-29  9:20 Christian König
       [not found] ` <1472462424-3052-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
  0 siblings, 1 reply; 18+ messages in thread
From: Christian König @ 2016-08-29  9:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This is still not working 100% reliable, but I thought that maybe some more
eyes on it could help find the remaining bug(s).

Valley under memory pressure (limit VRAM to only 256MB) easily shows the
problem. You get texture corruptions and lockups after a while.

Any idea what is still wrong here?

Regards,
Christian.

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/5] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_LINEAR flag v2
       [not found] ` <1472462424-3052-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
@ 2016-08-29  9:20   ` Christian König
       [not found]     ` <1472462424-3052-2-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
  2016-08-29  9:20   ` [PATCH 2/5] drm/amdgpu: use explicit limit for VRAM_LINEAR handling Christian König
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 18+ messages in thread
From: Christian König @ 2016-08-29  9:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Christian König <christian.koenig@amd.com>

Add a flag noting that a BO must be created using linear VRAM
and set this flag on all in kernel users where appropriate.

Hopefully I haven't missed anything.

v2: add it in a few more places, fix CPU mapping.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c    |  6 ++++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c     | 31 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c     |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c   |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 12 ++++++++++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c    | 10 ++++++++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c    |  9 +++++++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c     |  6 ++++--
 drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c      |  9 ++++++---
 drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c      |  6 ++++--
 include/uapi/drm/amdgpu_drm.h              |  2 ++
 14 files changed, 85 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 545789f..b2d95a9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -2499,6 +2499,7 @@ static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { }
 struct amdgpu_bo_va_mapping *
 amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
 		       uint64_t addr, struct amdgpu_bo **bo);
+int amdgpu_cs_make_bos_linear(struct amdgpu_cs_parser *parser);
 
 #if defined(CONFIG_DRM_AMD_DAL)
 int amdgpu_dm_display_resume(struct amdgpu_device *adev );
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
index 040993c..c2dfcd3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
@@ -146,7 +146,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device,
 	switch(type) {
 	case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB:
 	case CGS_GPU_MEM_TYPE__VISIBLE_FB:
-		flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
+		flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+			AMDGPU_GEM_CREATE_VRAM_LINEAR;
 		domain = AMDGPU_GEM_DOMAIN_VRAM;
 		if (max_offset > adev->mc.real_vram_size)
 			return -EINVAL;
@@ -157,7 +158,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device,
 		break;
 	case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB:
 	case CGS_GPU_MEM_TYPE__INVISIBLE_FB:
-		flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
+		flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
+			AMDGPU_GEM_CREATE_VRAM_LINEAR;
 		domain = AMDGPU_GEM_DOMAIN_VRAM;
 		if (adev->mc.visible_vram_size < adev->mc.real_vram_size) {
 			place.fpfn =
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index b0e11ca..108408b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1097,3 +1097,34 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
 
 	return NULL;
 }
+
+/**
+ * amdgpu_cs_make_bos_linear - mark all BOs in this CS as linear
+ *
+ * @parser: command submission parser context
+ *
+ * Helper for UVD/VCE VM emulation, mark all BOs in this CS as linear.
+ */
+int amdgpu_cs_make_bos_linear(struct amdgpu_cs_parser *parser)
+{
+	unsigned i;
+	int r;
+
+	if (!parser->bo_list)
+		return 0;
+
+	for (i = 0; i < parser->bo_list->num_entries; i++) {
+		struct amdgpu_bo *bo = parser->bo_list->array[i].robj;
+
+		if (bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR)
+			continue;
+
+		bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
+		amdgpu_ttm_placement_from_domain(bo, bo->allowed_domains);
+		r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
+		if (unlikely(r))
+			return r;
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 1b31a7c..38f5315 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -256,7 +256,8 @@ static int amdgpu_vram_scratch_init(struct amdgpu_device *adev)
 	if (adev->vram_scratch.robj == NULL) {
 		r = amdgpu_bo_create(adev, AMDGPU_GPU_PAGE_SIZE,
 				     PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
-				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+				     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 				     NULL, NULL, &adev->vram_scratch.robj);
 		if (r) {
 			return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index e694c99..efa9b79 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -120,7 +120,8 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
 	aligned_size = ALIGN(size, PAGE_SIZE);
 	ret = amdgpu_gem_object_create(adev, aligned_size, 0,
 				       AMDGPU_GEM_DOMAIN_VRAM,
-				       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+				       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+				       AMDGPU_GEM_CREATE_VRAM_LINEAR,
 				       true, &gobj);
 	if (ret) {
 		printk(KERN_ERR "failed to allocate framebuffer (%d)\n",
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
index 0feea34..b5982a9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
@@ -126,7 +126,8 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
 	if (adev->gart.robj == NULL) {
 		r = amdgpu_bo_create(adev, adev->gart.table_size,
 				     PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
-				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+				     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 				     NULL, NULL, &adev->gart.robj);
 		if (r) {
 			return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index b17734e..6f83909 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -247,7 +247,8 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
 	int r;
 
 	r = amdgpu_bo_create(adev, size, align, true, domain,
-			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 			     NULL, NULL, bo_ptr);
 	if (r) {
 		dev_err(adev->dev, "(%d) failed to allocate kernel bo\n", r);
@@ -617,6 +618,8 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
 
 		return 0;
 	}
+
+	bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
 	amdgpu_ttm_placement_from_domain(bo, domain);
 	for (i = 0; i < bo->placement.num_placement; i++) {
 		/* force to pin into visible video ram */
@@ -854,7 +857,9 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
 
 	size = bo->mem.num_pages << PAGE_SHIFT;
 	offset = bo->mem.start << PAGE_SHIFT;
-	if ((offset + size) <= adev->mc.visible_vram_size)
+	/* TODO: figure out how to map scattered VRAM to the CPU */
+	if ((offset + size) <= adev->mc.visible_vram_size &&
+	    (abo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR))
 		return 0;
 
 	/* Can't move a pinned BO to visible VRAM */
@@ -862,6 +867,7 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
 		return -EINVAL;
 
 	/* hurrah the memory is not visible ! */
+	abo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
 	amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM);
 	lpfn =	adev->mc.visible_vram_size >> PAGE_SHIFT;
 	for (i = 0; i < abo->placement.num_placement; i++) {
@@ -920,6 +926,8 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
 	WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM);
 	WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) &&
 		     !bo->pin_count);
+	WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM &&
+		     !(bo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR));
 
 	return bo->tbo.offset;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index e2f6a46..ea480bb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1024,7 +1024,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
 
 	r = amdgpu_bo_create(adev, 256 * 1024, PAGE_SIZE, true,
 			     AMDGPU_GEM_DOMAIN_VRAM,
-			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 			     NULL, NULL, &adev->stollen_vga_memory);
 	if (r) {
 		return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index 5888e8a..5f5380c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -891,6 +891,10 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)
 		return -EINVAL;
 	}
 
+	r = amdgpu_cs_make_bos_linear(parser);
+	if (r)
+		return r;
+
 	ctx.parser = parser;
 	ctx.buf_sizes = buf_sizes;
 	ctx.ib_idx = ib_idx;
@@ -1007,7 +1011,8 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
 
 	r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,
 			     AMDGPU_GEM_DOMAIN_VRAM,
-			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 			     NULL, NULL, &bo);
 	if (r)
 		return r;
@@ -1056,7 +1061,8 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
 
 	r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,
 			     AMDGPU_GEM_DOMAIN_VRAM,
-			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 			     NULL, NULL, &bo);
 	if (r)
 		return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index 9b71d6c..bb97a8e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -157,7 +157,8 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
 
 	r = amdgpu_bo_create(adev, size, PAGE_SIZE, true,
 			     AMDGPU_GEM_DOMAIN_VRAM,
-			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 			     NULL, NULL, &adev->vce.vcpu_bo);
 	if (r) {
 		dev_err(adev->dev, "(%d) failed to allocate VCE bo\n", r);
@@ -634,7 +635,11 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
 	uint32_t allocated = 0;
 	uint32_t tmp, handle = 0;
 	uint32_t *size = &tmp;
-	int i, r = 0, idx = 0;
+	int i, r, idx = 0;
+
+	r = amdgpu_cs_make_bos_linear(p);
+	if (r)
+		return r;
 
 	while (idx < ib->length_dw) {
 		uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 7660f82..ea1bd67 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -1398,7 +1398,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
 				     AMDGPU_GPU_PAGE_SIZE, true,
 				     AMDGPU_GEM_DOMAIN_VRAM,
 				     AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
-				     AMDGPU_GEM_CREATE_SHADOW,
+				     AMDGPU_GEM_CREATE_SHADOW |
+				     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 				     NULL, resv, &pt);
 		if (r)
 			goto error_free;
@@ -1598,7 +1599,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
 	r = amdgpu_bo_create(adev, pd_size, align, true,
 			     AMDGPU_GEM_DOMAIN_VRAM,
 			     AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
-			     AMDGPU_GEM_CREATE_SHADOW,
+			     AMDGPU_GEM_CREATE_SHADOW |
+			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 			     NULL, NULL, &vm->page_directory);
 	if (r)
 		goto error_free_sched_entity;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
index f055d49..1517a8c 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
@@ -3213,7 +3213,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
 		if (adev->gfx.rlc.save_restore_obj == NULL) {
 			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
 					     AMDGPU_GEM_DOMAIN_VRAM,
-					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 					     NULL, NULL,
 					     &adev->gfx.rlc.save_restore_obj);
 			if (r) {
@@ -3257,7 +3258,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
 		if (adev->gfx.rlc.clear_state_obj == NULL) {
 			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
 					     AMDGPU_GEM_DOMAIN_VRAM,
-					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 					     NULL, NULL,
 					     &adev->gfx.rlc.clear_state_obj);
 			if (r) {
@@ -3297,7 +3299,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
 		if (adev->gfx.rlc.cp_table_obj == NULL) {
 			r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,
 					     AMDGPU_GEM_DOMAIN_VRAM,
-					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 					     NULL, NULL,
 					     &adev->gfx.rlc.cp_table_obj);
 			if (r) {
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index 6e01392..26e614e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -1273,7 +1273,8 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
 		if (adev->gfx.rlc.clear_state_obj == NULL) {
 			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
 					     AMDGPU_GEM_DOMAIN_VRAM,
-					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 					     NULL, NULL,
 					     &adev->gfx.rlc.clear_state_obj);
 			if (r) {
@@ -1315,7 +1316,8 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
 		if (adev->gfx.rlc.cp_table_obj == NULL) {
 			r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,
 					     AMDGPU_GEM_DOMAIN_VRAM,
-					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
 					     NULL, NULL,
 					     &adev->gfx.rlc.cp_table_obj);
 			if (r) {
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 403b676..2aede6a 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -79,6 +79,8 @@
 #define AMDGPU_GEM_CREATE_VRAM_CLEARED		(1 << 3)
 /* Flag that create shadow bo(GTT) while allocating vram bo */
 #define AMDGPU_GEM_CREATE_SHADOW		(1 << 4)
+/* Flag that allocating the BO should use linear VRAM */
+#define AMDGPU_GEM_CREATE_VRAM_LINEAR		(1 << 5)
 
 struct drm_amdgpu_gem_create_in  {
 	/** the requested memory size */
-- 
2.5.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/5] drm/amdgpu: use explicit limit for VRAM_LINEAR handling
       [not found] ` <1472462424-3052-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
  2016-08-29  9:20   ` [PATCH 1/5] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_LINEAR flag v2 Christian König
@ 2016-08-29  9:20   ` Christian König
       [not found]     ` <1472462424-3052-3-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
  2016-08-29  9:20   ` [PATCH 3/5] drm/amdgpu: handle multiple MM nodes in the VMs Christian König
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 18+ messages in thread
From: Christian König @ 2016-08-29  9:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Christian König <christian.koenig@amd.com>

Split VRAM won't have a valid offset, so just set an explicit limit
when the flag is given to trigger reallocation if necessary.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 6f83909..79f6413 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -123,12 +123,17 @@ static void amdgpu_ttm_placement_init(struct amdgpu_device *adev,
 
 	if (domain & AMDGPU_GEM_DOMAIN_VRAM) {
 		unsigned visible_pfn = adev->mc.visible_vram_size >> PAGE_SHIFT;
+		unsigned lpfn = 0;
+
+		/* This forces a reallocation if the flag wasn't set before */
+		if (flags & AMDGPU_GEM_CREATE_VRAM_LINEAR)
+			lpfn = adev->mc.real_vram_size >> PAGE_SHIFT;
 
 		if (flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS &&
 		    !(flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) &&
 		    adev->mc.visible_vram_size < adev->mc.real_vram_size) {
 			places[c].fpfn = visible_pfn;
-			places[c].lpfn = 0;
+			places[c].lpfn = lpfn;
 			places[c].flags = TTM_PL_FLAG_WC |
 				TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM |
 				TTM_PL_FLAG_TOPDOWN;
@@ -136,7 +141,7 @@ static void amdgpu_ttm_placement_init(struct amdgpu_device *adev,
 		}
 
 		places[c].fpfn = 0;
-		places[c].lpfn = 0;
+		places[c].lpfn = lpfn;
 		places[c].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
 			TTM_PL_FLAG_VRAM;
 		if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
-- 
2.5.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 3/5] drm/amdgpu: handle multiple MM nodes in the VMs
       [not found] ` <1472462424-3052-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
  2016-08-29  9:20   ` [PATCH 1/5] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_LINEAR flag v2 Christian König
  2016-08-29  9:20   ` [PATCH 2/5] drm/amdgpu: use explicit limit for VRAM_LINEAR handling Christian König
@ 2016-08-29  9:20   ` Christian König
       [not found]     ` <1472462424-3052-4-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
  2016-08-29  9:20   ` [PATCH 4/5] drm/amdgpu: enable amdgpu_move_blit to handle multiple MM nodes Christian König
  2016-08-29  9:20   ` [PATCH 5/5] drm/amdgpu: add VRAM manager Christian König
  4 siblings, 1 reply; 18+ messages in thread
From: Christian König @ 2016-08-29  9:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Christian König <christian.koenig@amd.com>

This allows us to map scattered VRAM BOs to the VMs.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 79 +++++++++++++++++++---------------
 1 file changed, 44 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index ea1bd67..df6506d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -1048,8 +1048,8 @@ error_free:
  * @pages_addr: DMA addresses to use for mapping
  * @vm: requested vm
  * @mapping: mapped range and flags to use for the update
- * @addr: addr to set the area to
  * @flags: HW flags for the mapping
+ * @nodes: array of drm_mm_nodes with the MC addresses
  * @fence: optional resulting fence
  *
  * Split the mapping into smaller chunks so that each update fits
@@ -1062,12 +1062,11 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
 				      dma_addr_t *pages_addr,
 				      struct amdgpu_vm *vm,
 				      struct amdgpu_bo_va_mapping *mapping,
-				      uint32_t flags, uint64_t addr,
+				      uint32_t flags,
+				      struct drm_mm_node *nodes,
 				      struct fence **fence)
 {
-	const uint64_t max_size = 64ULL * 1024ULL * 1024ULL / AMDGPU_GPU_PAGE_SIZE;
-
-	uint64_t src = 0, start = mapping->it.start;
+	uint64_t offset, src = 0, start = mapping->it.start;
 	int r;
 
 	/* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here
@@ -1080,23 +1079,38 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
 
 	trace_amdgpu_vm_bo_update(mapping);
 
-	if (pages_addr) {
-		if (flags == gtt_flags)
-			src = adev->gart.table_addr + (addr >> 12) * 8;
-		addr = 0;
+	offset = mapping->offset;
+	if (nodes) {
+		while (offset > (nodes->size << PAGE_SHIFT)) {
+			offset -= (nodes->size << PAGE_SHIFT);
+			++nodes;
+		}
 	}
-	addr += mapping->offset;
 
-	if (!pages_addr || src)
-		return amdgpu_vm_bo_update_mapping(adev, exclusive,
-						   src, pages_addr, vm,
-						   start, mapping->it.last,
-						   flags, addr, fence);
+	do {
+		uint64_t max_entries;
+		uint64_t addr, last;
 
-	while (start != mapping->it.last + 1) {
-		uint64_t last;
+		if (nodes) {
+			addr = nodes->start << PAGE_SHIFT;
+			max_entries = nodes->size - (offset >> PAGE_SHIFT);
+		} else {
+			addr = 0;
+			max_entries = S64_MAX;
+		}
+		addr += offset;
+
+		if (pages_addr) {
+			if (flags == gtt_flags)
+				src = adev->gart.table_addr + (addr >> 12) * 8;
+			else
+				max_entries = min(max_entries, 16ull * 1024ull);
+			addr = 0;
+		} else if (flags & AMDGPU_PTE_VALID) {
+			addr += adev->vm_manager.vram_base_offset;
+		}
 
-		last = min((uint64_t)mapping->it.last, start + max_size - 1);
+		last = min((uint64_t)mapping->it.last, start + max_entries - 1);
 		r = amdgpu_vm_bo_update_mapping(adev, exclusive,
 						src, pages_addr, vm,
 						start, last, flags, addr,
@@ -1104,9 +1118,14 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
 		if (r)
 			return r;
 
+		offset += (last - start + 1) * AMDGPU_GPU_PAGE_SIZE;
+		if (nodes && nodes->size == (offset >> PAGE_SHIFT)) {
+			offset = 0;
+			++nodes;
+		}
 		start = last + 1;
-		addr += max_size * AMDGPU_GPU_PAGE_SIZE;
-	}
+
+	} while (likely(start != mapping->it.last + 1));
 
 	return 0;
 }
@@ -1130,34 +1149,24 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
 	dma_addr_t *pages_addr = NULL;
 	uint32_t gtt_flags, flags;
 	struct ttm_mem_reg *mem;
+	struct drm_mm_node *nodes;
 	struct fence *exclusive;
-	uint64_t addr;
 	int r;
 
 	if (clear) {
 		mem = NULL;
-		addr = 0;
+		nodes = NULL;
 		exclusive = NULL;
 	} else {
 		struct ttm_dma_tt *ttm;
 
 		mem = &bo_va->bo->tbo.mem;
-		addr = (u64)mem->start << PAGE_SHIFT;
-		switch (mem->mem_type) {
-		case TTM_PL_TT:
+		nodes = mem->mm_node;
+		if (mem->mem_type == TTM_PL_TT) {
 			ttm = container_of(bo_va->bo->tbo.ttm, struct
 					   ttm_dma_tt, ttm);
 			pages_addr = ttm->dma_address;
-			break;
-
-		case TTM_PL_VRAM:
-			addr += adev->vm_manager.vram_base_offset;
-			break;
-
-		default:
-			break;
 		}
-
 		exclusive = reservation_object_get_excl(bo_va->bo->tbo.resv);
 	}
 
@@ -1172,7 +1181,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
 	list_for_each_entry(mapping, &bo_va->invalids, list) {
 		r = amdgpu_vm_bo_split_mapping(adev, exclusive,
 					       gtt_flags, pages_addr, vm,
-					       mapping, flags, addr,
+					       mapping, flags, nodes,
 					       &bo_va->last_pt_update);
 		if (r)
 			return r;
-- 
2.5.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 4/5] drm/amdgpu: enable amdgpu_move_blit to handle multiple MM nodes
       [not found] ` <1472462424-3052-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
                     ` (2 preceding siblings ...)
  2016-08-29  9:20   ` [PATCH 3/5] drm/amdgpu: handle multiple MM nodes in the VMs Christian König
@ 2016-08-29  9:20   ` Christian König
       [not found]     ` <1472462424-3052-5-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
  2016-08-29  9:20   ` [PATCH 5/5] drm/amdgpu: add VRAM manager Christian König
  4 siblings, 1 reply; 18+ messages in thread
From: Christian König @ 2016-08-29  9:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Christian König <christian.koenig@amd.com>

This allows us to move scattered buffers around.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 96 ++++++++++++++++++++++-----------
 1 file changed, 64 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index ea480bb..db8638b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -239,52 +239,84 @@ static void amdgpu_move_null(struct ttm_buffer_object *bo,
 	new_mem->mm_node = NULL;
 }
 
-static int amdgpu_move_blit(struct ttm_buffer_object *bo,
-			bool evict, bool no_wait_gpu,
-			struct ttm_mem_reg *new_mem,
-			struct ttm_mem_reg *old_mem)
+static uint64_t amdgpu_mm_node_addr(struct amdgpu_device *adev,
+				    struct drm_mm_node *mm_node,
+				    struct ttm_mem_reg *mem)
 {
-	struct amdgpu_device *adev;
-	struct amdgpu_ring *ring;
-	uint64_t old_start, new_start;
-	struct fence *fence;
-	int r;
+	uint64_t addr = mm_node->start << PAGE_SHIFT;
 
-	adev = amdgpu_get_adev(bo->bdev);
-	ring = adev->mman.buffer_funcs_ring;
-	old_start = (u64)old_mem->start << PAGE_SHIFT;
-	new_start = (u64)new_mem->start << PAGE_SHIFT;
-
-	switch (old_mem->mem_type) {
+	switch (mem->mem_type) {
 	case TTM_PL_VRAM:
 	case TTM_PL_TT:
-		old_start += bo->bdev->man[old_mem->mem_type].gpu_offset;
+		addr += adev->mman.bdev.man[mem->mem_type].gpu_offset;
 		break;
 	default:
-		DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
-		return -EINVAL;
-	}
-	switch (new_mem->mem_type) {
-	case TTM_PL_VRAM:
-	case TTM_PL_TT:
-		new_start += bo->bdev->man[new_mem->mem_type].gpu_offset;
+		DRM_ERROR("Unknown placement %d\n", mem->mem_type);
 		break;
-	default:
-		DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
-		return -EINVAL;
 	}
+
+	return addr;
+}
+
+static int amdgpu_move_blit(struct ttm_buffer_object *bo,
+			    bool evict, bool no_wait_gpu,
+			    struct ttm_mem_reg *new_mem,
+			    struct ttm_mem_reg *old_mem)
+{
+	struct amdgpu_device *adev = amdgpu_get_adev(bo->bdev);
+	struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
+
+	struct drm_mm_node *old_mm, *new_mm;
+	uint64_t old_start, new_start;
+	unsigned long num_pages;
+	struct fence *fence = NULL;
+	int r;
+
+	BUILD_BUG_ON((PAGE_SIZE % AMDGPU_GPU_PAGE_SIZE) != 0);
+
 	if (!ring->ready) {
 		DRM_ERROR("Trying to move memory with ring turned off.\n");
 		return -EINVAL;
 	}
 
-	BUILD_BUG_ON((PAGE_SIZE % AMDGPU_GPU_PAGE_SIZE) != 0);
+	old_mm = old_mem->mm_node;
+	new_mm = new_mem->mm_node;
+	num_pages = new_mem->num_pages;
 
-	r = amdgpu_copy_buffer(ring, old_start, new_start,
-			       new_mem->num_pages * PAGE_SIZE, /* bytes */
-			       bo->resv, &fence, false);
-	if (r)
-		return r;
+	old_start = amdgpu_mm_node_addr(adev, old_mm, old_mem);
+	new_start = amdgpu_mm_node_addr(adev, new_mm, new_mem);
+
+	while (num_pages) {
+		unsigned long cur_pages = min(old_mm->size, new_mm->size);
+		struct fence *next;
+
+		r = amdgpu_copy_buffer(ring, old_start, new_start,
+				       cur_pages * PAGE_SIZE,
+				       bo->resv, &next, false);
+		if (r) {
+			if (fence)
+				fence_wait(fence, false);
+			fence_put(fence);
+			return r;
+		}
+		fence_put(fence);
+		fence = next;
+
+		num_pages -= cur_pages;
+		if (num_pages) {
+			old_start += cur_pages * PAGE_SIZE;
+			if (old_start == ((old_mm->start + old_mm->size) *
+				PAGE_SIZE))
+				old_start = amdgpu_mm_node_addr(adev, ++old_mm,
+								old_mem);
+
+			new_start += cur_pages * PAGE_SIZE;
+			if (new_start == ((new_mm->start + new_mm->size) *
+					  PAGE_SIZE))
+				new_start = amdgpu_mm_node_addr(adev, ++new_mm,
+								new_mem);
+		}
+	}
 
 	r = ttm_bo_pipeline_move(bo, fence, evict, new_mem);
 	fence_put(fence);
-- 
2.5.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 5/5] drm/amdgpu: add VRAM manager
       [not found] ` <1472462424-3052-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
                     ` (3 preceding siblings ...)
  2016-08-29  9:20   ` [PATCH 4/5] drm/amdgpu: enable amdgpu_move_blit to handle multiple MM nodes Christian König
@ 2016-08-29  9:20   ` Christian König
       [not found]     ` <1472462424-3052-6-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
  4 siblings, 1 reply; 18+ messages in thread
From: Christian König @ 2016-08-29  9:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Christian König <christian.koenig@amd.com>

Split VRAM allocations into 4MB blocks.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/Makefile          |   3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu.h          |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c   |   6 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c      |   4 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c   |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.h   |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c      |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h      |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 220 +++++++++++++++++++++++++++
 9 files changed, 239 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c

diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index c8d4d7c..ba12d3c 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -29,7 +29,8 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
 	amdgpu_pm.o atombios_dp.o amdgpu_afmt.o amdgpu_trace_points.o \
 	atombios_encoders.o amdgpu_sa.o atombios_i2c.o \
 	amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \
-	amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o
+	amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \
+	amdgpu_vram_mgr.o
 
 # add asic specific block
 amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index b2d95a9..7e3d341 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -96,6 +96,7 @@ extern unsigned amdgpu_cg_mask;
 extern unsigned amdgpu_pg_mask;
 extern int amdgpu_sclk_deep_sleep_en;
 extern char *amdgpu_virtual_display;
+extern int amdgpu_vram_page_split;
 
 #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS	        3000
 #define AMDGPU_MAX_USEC_TIMEOUT			100000	/* 100 ms */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 38f5315..b2dcc11 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1004,6 +1004,12 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev)
 			 amdgpu_vm_block_size);
 		amdgpu_vm_block_size = 9;
 	}
+
+	if (amdgpu_vram_page_split != -1 && amdgpu_vram_page_split < 16) {
+		dev_warn(adev->dev, "invalid VRAM page split (%d)\n",
+			 amdgpu_vram_page_split);
+		amdgpu_vram_page_split = 1024;
+	}
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 56c85e6..dcef0b4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -82,6 +82,7 @@ int amdgpu_vm_size = 64;
 int amdgpu_vm_block_size = -1;
 int amdgpu_vm_fault_stop = 0;
 int amdgpu_vm_debug = 0;
+int amdgpu_vram_page_split = 1024;
 int amdgpu_exp_hw_support = 0;
 int amdgpu_dal = -1;
 int amdgpu_sched_jobs = 32;
@@ -161,6 +162,9 @@ module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444);
 MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = enabled)");
 module_param_named(vm_debug, amdgpu_vm_debug, int, 0644);
 
+MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 1024)");
+module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444);
+
 MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))");
 module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 79f6413..d2dab28 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -933,6 +933,7 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
 		     !bo->pin_count);
 	WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM &&
 		     !(bo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR));
+	WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET);
 
 	return bo->tbo.offset;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index b6a2739..e498465 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -31,6 +31,8 @@
 #include <drm/amdgpu_drm.h>
 #include "amdgpu.h"
 
+#define AMDGPU_BO_INVALID_OFFSET	LONG_MAX
+
 /**
  * amdgpu_mem_type_to_domain - return domain corresponding to mem_type
  * @mem_type:	ttm memory type
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index db8638b..9990957 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -164,7 +164,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
 		break;
 	case TTM_PL_VRAM:
 		/* "On-card" video ram */
-		man->func = &ttm_bo_manager_func;
+		man->func = &amdgpu_vram_mgr_func;
 		man->gpu_offset = adev->mc.vram_start;
 		man->flags = TTM_MEMTYPE_FLAG_FIXED |
 			     TTM_MEMTYPE_FLAG_MAPPABLE;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index 72f6bfc..365ce9e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -65,6 +65,8 @@ struct amdgpu_mman {
 	struct amdgpu_mman_lru			guard;
 };
 
+extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func;
+
 int amdgpu_copy_buffer(struct amdgpu_ring *ring,
 		       uint64_t src_offset,
 		       uint64_t dst_offset,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
new file mode 100644
index 0000000..6c5f3ba
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Christian König
+ */
+
+#include <drm/drmP.h>
+#include "amdgpu.h"
+
+struct amdgpu_vram_mgr {
+	struct drm_mm mm;
+	spinlock_t lock;
+};
+
+/**
+ * amdgpu_vram_mgr_init - init VRAM manager and DRM MM
+ *
+ * @man: TTM memory type manager
+ * @p_size: maximum size of VRAM
+ *
+ * Allocate and initialize the VRAM manager.
+ */
+static int amdgpu_vram_mgr_init(struct ttm_mem_type_manager *man,
+				unsigned long p_size)
+{
+	struct amdgpu_vram_mgr *mgr;
+
+	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+	if (!mgr)
+		return -ENOMEM;
+
+	drm_mm_init(&mgr->mm, 0, p_size);
+	spin_lock_init(&mgr->lock);
+	man->priv = mgr;
+	return 0;
+}
+
+/**
+ * amdgpu_vram_mgr_fini - free and destroy VRAM manager
+ *
+ * @man: TTM memory type manager
+ *
+ * Destory and free the VRAM manager, returns -EBUSY if ranges are still
+ * allocated inside it.
+ */
+static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man)
+{
+	struct amdgpu_vram_mgr *mgr = man->priv;
+
+	spin_lock(&mgr->lock);
+	if (drm_mm_clean(&mgr->mm)) {
+		drm_mm_takedown(&mgr->mm);
+		spin_unlock(&mgr->lock);
+		kfree(mgr);
+		man->priv = NULL;
+		return 0;
+	}
+	spin_unlock(&mgr->lock);
+	return -EBUSY;
+}
+
+/**
+ * amdgpu_vram_mgr_new - allocate new ranges
+ *
+ * @man: TTM memory type manager
+ * @tbo: TTM BO we need this range for
+ * @place: placement flags and restrictions
+ * @mem: the resulting mem object
+ *
+ * Allocate VRAM for the given BO.
+ */
+static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
+			       struct ttm_buffer_object *tbo,
+			       const struct ttm_place *place,
+			       struct ttm_mem_reg *mem)
+{
+	struct amdgpu_bo *bo = container_of(tbo, struct amdgpu_bo, tbo);
+	struct amdgpu_vram_mgr *mgr = man->priv;
+	struct drm_mm *mm = &mgr->mm;
+	struct drm_mm_node *nodes;
+	enum drm_mm_search_flags sflags = DRM_MM_SEARCH_DEFAULT;
+	enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT;
+	unsigned long lpfn, num_nodes, pages_per_node, pages_left;
+	unsigned i;
+	int r;
+
+	lpfn = place->lpfn;
+	if (!lpfn)
+		lpfn = man->size;
+
+	if (bo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR ||
+	    amdgpu_vram_page_split == -1) {
+		pages_per_node = ~0ul;
+		num_nodes = 1;
+	} else {
+		pages_per_node = max((uint32_t)amdgpu_vram_page_split,
+				     mem->page_alignment);
+		num_nodes = DIV_ROUND_UP(mem->num_pages, pages_per_node);
+	}
+
+	nodes = kcalloc(num_nodes, sizeof(*nodes), GFP_KERNEL);
+	if (!nodes)
+		return -ENOMEM;
+
+	if (place->flags & TTM_PL_FLAG_TOPDOWN) {
+		sflags = DRM_MM_SEARCH_BELOW;
+		aflags = DRM_MM_CREATE_TOP;
+	}
+
+	pages_left = mem->num_pages;
+
+	spin_lock(&mgr->lock);
+	for (i = 0; i < num_nodes; ++i) {
+		unsigned long pages = min(pages_left, pages_per_node);
+		uint32_t alignment = mem->page_alignment;
+
+		if (pages == pages_per_node)
+			alignment = pages_per_node;
+		else
+			sflags |= DRM_MM_SEARCH_BEST;
+
+		r = drm_mm_insert_node_in_range_generic(mm, &nodes[i], pages,
+							alignment, 0,
+							place->fpfn, lpfn,
+							sflags, aflags);
+		if (unlikely(r))
+			goto error;
+
+		pages_left -= pages;
+	}
+	spin_unlock(&mgr->lock);
+
+	mem->start = num_nodes == 1 ? nodes[0].start : AMDGPU_BO_INVALID_OFFSET;
+	mem->mm_node = nodes;
+
+	return 0;
+
+error:
+	while (i--)
+		drm_mm_remove_node(&nodes[i]);
+	spin_unlock(&mgr->lock);
+
+	kfree(nodes);
+	return r == -ENOSPC ? 0 : r;
+}
+
+/**
+ * amdgpu_vram_mgr_del - free ranges
+ *
+ * @man: TTM memory type manager
+ * @tbo: TTM BO we need this range for
+ * @place: placement flags and restrictions
+ * @mem: TTM memory object
+ *
+ * Free the allocated VRAM again.
+ */
+static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,
+				struct ttm_mem_reg *mem)
+{
+	struct amdgpu_vram_mgr *mgr = man->priv;
+	struct drm_mm_node *nodes = mem->mm_node;
+	unsigned i, pages = mem->num_pages;
+
+	if (!mem->mm_node)
+		return;
+
+	spin_lock(&mgr->lock);
+	for (i = 0; pages; ++i) {
+		pages -= nodes[i].size;
+		drm_mm_remove_node(&nodes[i]);
+	}
+	spin_unlock(&mgr->lock);
+
+	kfree(mem->mm_node);
+	mem->mm_node = NULL;
+}
+
+/**
+ * amdgpu_vram_mgr_debug - dump VRAM table
+ *
+ * @man: TTM memory type manager
+ * @prefix: text prefix
+ *
+ * Dump the table content using printk.
+ */
+static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man,
+				  const char *prefix)
+{
+	struct amdgpu_vram_mgr *mgr = man->priv;
+
+	spin_lock(&mgr->lock);
+	drm_mm_debug_table(&mgr->mm, prefix);
+	spin_unlock(&mgr->lock);
+}
+
+const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = {
+	amdgpu_vram_mgr_init,
+	amdgpu_vram_mgr_fini,
+	amdgpu_vram_mgr_new,
+	amdgpu_vram_mgr_del,
+	amdgpu_vram_mgr_debug
+};
-- 
2.5.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/5] drm/amdgpu: add VRAM manager
       [not found]     ` <1472462424-3052-6-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
@ 2016-08-29 10:27       ` Edward O'Callaghan
  2016-08-30 17:37       ` William Lewis
  1 sibling, 0 replies; 18+ messages in thread
From: Edward O'Callaghan @ 2016-08-29 10:27 UTC (permalink / raw)
  To: Christian König, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW


[-- Attachment #1.1.1: Type: text/plain, Size: 13434 bytes --]

Hi,

I hope the following nitpicks are helpful.

Kind Regards,
Edward.

On 08/29/2016 07:20 PM, Christian König wrote:
> From: Christian König <christian.koenig-5C7GfCeVMHo@public.gmane.org>
> 
> Split VRAM allocations into 4MB blocks.
> 
> Signed-off-by: Christian König <christian.koenig-5C7GfCeVMHo@public.gmane.org>
> ---
>  drivers/gpu/drm/amd/amdgpu/Makefile          |   3 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h          |   1 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c   |   6 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c      |   4 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c   |   1 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_object.h   |   2 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c      |   2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h      |   2 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 220 +++++++++++++++++++++++++++
>  9 files changed, 239 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
> index c8d4d7c..ba12d3c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> @@ -29,7 +29,8 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
>  	amdgpu_pm.o atombios_dp.o amdgpu_afmt.o amdgpu_trace_points.o \
>  	atombios_encoders.o amdgpu_sa.o atombios_i2c.o \
>  	amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \
> -	amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o
> +	amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \
> +	amdgpu_vram_mgr.o
>  
>  # add asic specific block
>  amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index b2d95a9..7e3d341 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -96,6 +96,7 @@ extern unsigned amdgpu_cg_mask;
>  extern unsigned amdgpu_pg_mask;
>  extern int amdgpu_sclk_deep_sleep_en;
>  extern char *amdgpu_virtual_display;
> +extern int amdgpu_vram_page_split;
>  
>  #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS	        3000
>  #define AMDGPU_MAX_USEC_TIMEOUT			100000	/* 100 ms */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 38f5315..b2dcc11 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1004,6 +1004,12 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev)
>  			 amdgpu_vm_block_size);
>  		amdgpu_vm_block_size = 9;
>  	}
> +
> +	if (amdgpu_vram_page_split != -1 && amdgpu_vram_page_split < 16) {
> +		dev_warn(adev->dev, "invalid VRAM page split (%d)\n",
> +			 amdgpu_vram_page_split);
> +		amdgpu_vram_page_split = 1024;
> +	}
>  }
>  
>  /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 56c85e6..dcef0b4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -82,6 +82,7 @@ int amdgpu_vm_size = 64;
>  int amdgpu_vm_block_size = -1;
>  int amdgpu_vm_fault_stop = 0;
>  int amdgpu_vm_debug = 0;
> +int amdgpu_vram_page_split = 1024;
>  int amdgpu_exp_hw_support = 0;
>  int amdgpu_dal = -1;
>  int amdgpu_sched_jobs = 32;
> @@ -161,6 +162,9 @@ module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444);
>  MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = enabled)");
>  module_param_named(vm_debug, amdgpu_vm_debug, int, 0644);
>  
> +MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 1024)");
> +module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444);
> +
>  MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))");
>  module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444);
>  
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index 79f6413..d2dab28 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -933,6 +933,7 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
>  		     !bo->pin_count);
>  	WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM &&
>  		     !(bo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR));
> +	WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET);
>  
>  	return bo->tbo.offset;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
> index b6a2739..e498465 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
> @@ -31,6 +31,8 @@
>  #include <drm/amdgpu_drm.h>
>  #include "amdgpu.h"
>  
> +#define AMDGPU_BO_INVALID_OFFSET	LONG_MAX
> +
>  /**
>   * amdgpu_mem_type_to_domain - return domain corresponding to mem_type
>   * @mem_type:	ttm memory type
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index db8638b..9990957 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -164,7 +164,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
>  		break;
>  	case TTM_PL_VRAM:
>  		/* "On-card" video ram */
> -		man->func = &ttm_bo_manager_func;
> +		man->func = &amdgpu_vram_mgr_func;
>  		man->gpu_offset = adev->mc.vram_start;
>  		man->flags = TTM_MEMTYPE_FLAG_FIXED |
>  			     TTM_MEMTYPE_FLAG_MAPPABLE;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> index 72f6bfc..365ce9e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> @@ -65,6 +65,8 @@ struct amdgpu_mman {
>  	struct amdgpu_mman_lru			guard;
>  };
>  
> +extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func;
> +
>  int amdgpu_copy_buffer(struct amdgpu_ring *ring,
>  		       uint64_t src_offset,
>  		       uint64_t dst_offset,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> new file mode 100644
> index 0000000..6c5f3ba
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> @@ -0,0 +1,220 @@
> +/*
> + * Copyright 2015 Advanced Micro Devices, Inc.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + *
> + * Authors: Christian König
> + */
> +
> +#include <drm/drmP.h>
> +#include "amdgpu.h"
> +
> +struct amdgpu_vram_mgr {
> +	struct drm_mm mm;
> +	spinlock_t lock;
> +};
> +
> +/**
> + * amdgpu_vram_mgr_init - init VRAM manager and DRM MM
> + *
> + * @man: TTM memory type manager
> + * @p_size: maximum size of VRAM
> + *
> + * Allocate and initialize the VRAM manager.
> + */
> +static int amdgpu_vram_mgr_init(struct ttm_mem_type_manager *man,
> +				unsigned long p_size)
> +{
> +	struct amdgpu_vram_mgr *mgr;
> +
> +	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
> +	if (!mgr)
> +		return -ENOMEM;
> +
> +	drm_mm_init(&mgr->mm, 0, p_size);
> +	spin_lock_init(&mgr->lock);
> +	man->priv = mgr;
> +	return 0;
> +}
> +
> +/**
> + * amdgpu_vram_mgr_fini - free and destroy VRAM manager
> + *
> + * @man: TTM memory type manager
> + *
> + * Destory and free the VRAM manager, returns -EBUSY if ranges are still
> + * allocated inside it.
> + */
> +static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man)
> +{
> +	struct amdgpu_vram_mgr *mgr = man->priv;
> +
> +	spin_lock(&mgr->lock);
> +	if (drm_mm_clean(&mgr->mm)) {
> +		drm_mm_takedown(&mgr->mm);
> +		spin_unlock(&mgr->lock);
> +		kfree(mgr);
> +		man->priv = NULL;
> +		return 0;
> +	}
> +	spin_unlock(&mgr->lock);
> +	return -EBUSY;

What about taking the bulk of this out the true branch into the body of
the function as in the following:

if (!drm_mm_clean(&mgr->mm)) {
		spin_unlock(&mgr->lock);
		return -EBUSY;
}

drm_mm_takedown(&mgr->mm);
spin_unlock(&mgr->lock);
kfree(mgr);
man->priv = NULL;

return 0;


> +}
> +
> +/**
> + * amdgpu_vram_mgr_new - allocate new ranges
> + *
> + * @man: TTM memory type manager
> + * @tbo: TTM BO we need this range for
> + * @place: placement flags and restrictions
> + * @mem: the resulting mem object
> + *
> + * Allocate VRAM for the given BO.
> + */
> +static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
> +			       struct ttm_buffer_object *tbo,
> +			       const struct ttm_place *place,
> +			       struct ttm_mem_reg *mem)
> +{
> +	struct amdgpu_bo *bo = container_of(tbo, struct amdgpu_bo, tbo);
> +	struct amdgpu_vram_mgr *mgr = man->priv;
> +	struct drm_mm *mm = &mgr->mm;
> +	struct drm_mm_node *nodes;
> +	enum drm_mm_search_flags sflags = DRM_MM_SEARCH_DEFAULT;
> +	enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT;
> +	unsigned long lpfn, num_nodes, pages_per_node, pages_left;
> +	unsigned i;
> +	int r;
> +
> +	lpfn = place->lpfn;
> +	if (!lpfn)
> +		lpfn = man->size;
> +
> +	if (bo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR ||
> +	    amdgpu_vram_page_split == -1) {
> +		pages_per_node = ~0ul;
> +		num_nodes = 1;
> +	} else {
> +		pages_per_node = max((uint32_t)amdgpu_vram_page_split,
> +				     mem->page_alignment);
> +		num_nodes = DIV_ROUND_UP(mem->num_pages, pages_per_node);
> +	}
> +
> +	nodes = kcalloc(num_nodes, sizeof(*nodes), GFP_KERNEL);
> +	if (!nodes)
> +		return -ENOMEM;
> +
> +	if (place->flags & TTM_PL_FLAG_TOPDOWN) {
> +		sflags = DRM_MM_SEARCH_BELOW;
> +		aflags = DRM_MM_CREATE_TOP;
> +	}
> +
> +	pages_left = mem->num_pages;
> +
> +	spin_lock(&mgr->lock);
> +	for (i = 0; i < num_nodes; ++i) {
> +		unsigned long pages = min(pages_left, pages_per_node);
> +		uint32_t alignment = mem->page_alignment;
> +
> +		if (pages == pages_per_node)
> +			alignment = pages_per_node;
> +		else
> +			sflags |= DRM_MM_SEARCH_BEST;
> +
> +		r = drm_mm_insert_node_in_range_generic(mm, &nodes[i], pages,
> +							alignment, 0,
> +							place->fpfn, lpfn,
> +							sflags, aflags);
> +		if (unlikely(r))
> +			goto error;
> +
> +		pages_left -= pages;
> +	}
> +	spin_unlock(&mgr->lock);
> +
> +	mem->start = num_nodes == 1 ? nodes[0].start : AMDGPU_BO_INVALID_OFFSET;
> +	mem->mm_node = nodes;
> +
> +	return 0;
> +
> +error:
> +	while (i--)

Perhaps make this more explicit of intent, I feel i being negative is a
bug waiting to happen?

> +		drm_mm_remove_node(&nodes[i]);

Could be wrong but do we miss one nodes[] here?

> +	spin_unlock(&mgr->lock);
> +
> +	kfree(nodes);
> +	return r == -ENOSPC ? 0 : r;
> +}
> +
> +/**
> + * amdgpu_vram_mgr_del - free ranges
> + *
> + * @man: TTM memory type manager
> + * @tbo: TTM BO we need this range for
> + * @place: placement flags and restrictions
> + * @mem: TTM memory object
> + *
> + * Free the allocated VRAM again.
> + */
> +static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,
> +				struct ttm_mem_reg *mem)
> +{
> +	struct amdgpu_vram_mgr *mgr = man->priv;
> +	struct drm_mm_node *nodes = mem->mm_node;
> +	unsigned i, pages = mem->num_pages;
> +
> +	if (!mem->mm_node)
> +		return;
> +
> +	spin_lock(&mgr->lock);
> +	for (i = 0; pages; ++i) {

More explicit on the intent of the pages predicate.

> +		pages -= nodes[i].size;
> +		drm_mm_remove_node(&nodes[i]);
> +	}
> +	spin_unlock(&mgr->lock);
> +
> +	kfree(mem->mm_node);
> +	mem->mm_node = NULL;
> +}
> +
> +/**
> + * amdgpu_vram_mgr_debug - dump VRAM table
> + *
> + * @man: TTM memory type manager
> + * @prefix: text prefix
> + *
> + * Dump the table content using printk.
> + */
> +static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man,
> +				  const char *prefix)
> +{
> +	struct amdgpu_vram_mgr *mgr = man->priv;
> +
> +	spin_lock(&mgr->lock);
> +	drm_mm_debug_table(&mgr->mm, prefix);
> +	spin_unlock(&mgr->lock);
> +}
> +
> +const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = {
> +	amdgpu_vram_mgr_init,
> +	amdgpu_vram_mgr_fini,
> +	amdgpu_vram_mgr_new,
> +	amdgpu_vram_mgr_del,
> +	amdgpu_vram_mgr_debug
> +};
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/5] drm/amdgpu: use explicit limit for VRAM_LINEAR handling
       [not found]     ` <1472462424-3052-3-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
@ 2016-08-29 10:59       ` Edward O'Callaghan
  0 siblings, 0 replies; 18+ messages in thread
From: Edward O'Callaghan @ 2016-08-29 10:59 UTC (permalink / raw)
  To: Christian König, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW


[-- Attachment #1.1.1: Type: text/plain, Size: 1954 bytes --]



On 08/29/2016 07:20 PM, Christian König wrote:
> From: Christian König <christian.koenig-5C7GfCeVMHo@public.gmane.org>
> 
> Split VRAM won't have a valid offset, so just set an explicit limit
> when the flag is given to trigger reallocation if necessary.
> 
> Signed-off-by: Christian König <christian.koenig-5C7GfCeVMHo@public.gmane.org>
Reviewed-by: Edward O'Callaghan <funfunctor-dczkZgxz+BNUPWh3PAxdjQ@public.gmane.org>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index 6f83909..79f6413 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -123,12 +123,17 @@ static void amdgpu_ttm_placement_init(struct amdgpu_device *adev,
>  
>  	if (domain & AMDGPU_GEM_DOMAIN_VRAM) {
>  		unsigned visible_pfn = adev->mc.visible_vram_size >> PAGE_SHIFT;
> +		unsigned lpfn = 0;
> +
> +		/* This forces a reallocation if the flag wasn't set before */
> +		if (flags & AMDGPU_GEM_CREATE_VRAM_LINEAR)
> +			lpfn = adev->mc.real_vram_size >> PAGE_SHIFT;
>  
>  		if (flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS &&
>  		    !(flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) &&
>  		    adev->mc.visible_vram_size < adev->mc.real_vram_size) {
>  			places[c].fpfn = visible_pfn;
> -			places[c].lpfn = 0;
> +			places[c].lpfn = lpfn;
>  			places[c].flags = TTM_PL_FLAG_WC |
>  				TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM |
>  				TTM_PL_FLAG_TOPDOWN;
> @@ -136,7 +141,7 @@ static void amdgpu_ttm_placement_init(struct amdgpu_device *adev,
>  		}
>  
>  		places[c].fpfn = 0;
> -		places[c].lpfn = 0;
> +		places[c].lpfn = lpfn;
>  		places[c].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
>  			TTM_PL_FLAG_VRAM;
>  		if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/5] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_LINEAR flag v2
       [not found]     ` <1472462424-3052-2-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
@ 2016-08-29 11:02       ` Edward O'Callaghan
  2016-08-29 13:47       ` Deucher, Alexander
  2016-08-30 17:33       ` William Lewis
  2 siblings, 0 replies; 18+ messages in thread
From: Edward O'Callaghan @ 2016-08-29 11:02 UTC (permalink / raw)
  To: Christian König, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW


[-- Attachment #1.1.1: Type: text/plain, Size: 16257 bytes --]



On 08/29/2016 07:20 PM, Christian König wrote:
> From: Christian König <christian.koenig-5C7GfCeVMHo@public.gmane.org>
> 
> Add a flag noting that a BO must be created using linear VRAM
> and set this flag on all in kernel users where appropriate.
> 
> Hopefully I haven't missed anything.
> 
> v2: add it in a few more places, fix CPU mapping.
> 
> Signed-off-by: Christian König <christian.koenig-5C7GfCeVMHo@public.gmane.org>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  1 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c    |  6 ++++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c     | 31 ++++++++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  3 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c     |  3 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c   |  3 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 12 ++++++++++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    |  3 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c    | 10 ++++++++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c    |  9 +++++++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c     |  6 ++++--
>  drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c      |  9 ++++++---
>  drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c      |  6 ++++--
>  include/uapi/drm/amdgpu_drm.h              |  2 ++
>  14 files changed, 85 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 545789f..b2d95a9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -2499,6 +2499,7 @@ static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { }
>  struct amdgpu_bo_va_mapping *
>  amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
>  		       uint64_t addr, struct amdgpu_bo **bo);
> +int amdgpu_cs_make_bos_linear(struct amdgpu_cs_parser *parser);
>  
>  #if defined(CONFIG_DRM_AMD_DAL)
>  int amdgpu_dm_display_resume(struct amdgpu_device *adev );
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> index 040993c..c2dfcd3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> @@ -146,7 +146,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device,
>  	switch(type) {
>  	case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB:
>  	case CGS_GPU_MEM_TYPE__VISIBLE_FB:
> -		flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
> +		flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			AMDGPU_GEM_CREATE_VRAM_LINEAR;
>  		domain = AMDGPU_GEM_DOMAIN_VRAM;
>  		if (max_offset > adev->mc.real_vram_size)
>  			return -EINVAL;
> @@ -157,7 +158,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device,
>  		break;
>  	case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB:
>  	case CGS_GPU_MEM_TYPE__INVISIBLE_FB:
> -		flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
> +		flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
> +			AMDGPU_GEM_CREATE_VRAM_LINEAR;
>  		domain = AMDGPU_GEM_DOMAIN_VRAM;
>  		if (adev->mc.visible_vram_size < adev->mc.real_vram_size) {
>  			place.fpfn =
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index b0e11ca..108408b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -1097,3 +1097,34 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
>  
>  	return NULL;
>  }
> +
> +/**
> + * amdgpu_cs_make_bos_linear - mark all BOs in this CS as linear
> + *
> + * @parser: command submission parser context
> + *
> + * Helper for UVD/VCE VM emulation, mark all BOs in this CS as linear.
> + */
> +int amdgpu_cs_make_bos_linear(struct amdgpu_cs_parser *parser)
> +{
> +	unsigned i;
> +	int r;
> +
> +	if (!parser->bo_list)
> +		return 0;
> +
> +	for (i = 0; i < parser->bo_list->num_entries; i++) {
> +		struct amdgpu_bo *bo = parser->bo_list->array[i].robj;
> +
> +		if (bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR)

Isn't this always true as its an assignment with just some mutation
along the way?

> +			continue;
> +
> +		bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
> +		amdgpu_ttm_placement_from_domain(bo, bo->allowed_domains);
> +		r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
> +		if (unlikely(r))
> +			return r;
> +	}
> +
> +	return 0;
> +}
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 1b31a7c..38f5315 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -256,7 +256,8 @@ static int amdgpu_vram_scratch_init(struct amdgpu_device *adev)
>  	if (adev->vram_scratch.robj == NULL) {
>  		r = amdgpu_bo_create(adev, AMDGPU_GPU_PAGE_SIZE,
>  				     PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
> -				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +				     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  				     NULL, NULL, &adev->vram_scratch.robj);
>  		if (r) {
>  			return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> index e694c99..efa9b79 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> @@ -120,7 +120,8 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
>  	aligned_size = ALIGN(size, PAGE_SIZE);
>  	ret = amdgpu_gem_object_create(adev, aligned_size, 0,
>  				       AMDGPU_GEM_DOMAIN_VRAM,
> -				       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +				       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +				       AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  				       true, &gobj);
>  	if (ret) {
>  		printk(KERN_ERR "failed to allocate framebuffer (%d)\n",
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> index 0feea34..b5982a9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> @@ -126,7 +126,8 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
>  	if (adev->gart.robj == NULL) {
>  		r = amdgpu_bo_create(adev, adev->gart.table_size,
>  				     PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
> -				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +				     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  				     NULL, NULL, &adev->gart.robj);
>  		if (r) {
>  			return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index b17734e..6f83909 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -247,7 +247,8 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
>  	int r;
>  
>  	r = amdgpu_bo_create(adev, size, align, true, domain,
> -			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  			     NULL, NULL, bo_ptr);
>  	if (r) {
>  		dev_err(adev->dev, "(%d) failed to allocate kernel bo\n", r);
> @@ -617,6 +618,8 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
>  
>  		return 0;
>  	}
> +
> +	bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
>  	amdgpu_ttm_placement_from_domain(bo, domain);
>  	for (i = 0; i < bo->placement.num_placement; i++) {
>  		/* force to pin into visible video ram */
> @@ -854,7 +857,9 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
>  
>  	size = bo->mem.num_pages << PAGE_SHIFT;
>  	offset = bo->mem.start << PAGE_SHIFT;
> -	if ((offset + size) <= adev->mc.visible_vram_size)
> +	/* TODO: figure out how to map scattered VRAM to the CPU */
> +	if ((offset + size) <= adev->mc.visible_vram_size &&
> +	    (abo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR))
>  		return 0;
>  
>  	/* Can't move a pinned BO to visible VRAM */
> @@ -862,6 +867,7 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
>  		return -EINVAL;
>  
>  	/* hurrah the memory is not visible ! */
> +	abo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
>  	amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM);
>  	lpfn =	adev->mc.visible_vram_size >> PAGE_SHIFT;
>  	for (i = 0; i < abo->placement.num_placement; i++) {
> @@ -920,6 +926,8 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
>  	WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM);
>  	WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) &&
>  		     !bo->pin_count);
> +	WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM &&
> +		     !(bo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR));
>  
>  	return bo->tbo.offset;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index e2f6a46..ea480bb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1024,7 +1024,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>  
>  	r = amdgpu_bo_create(adev, 256 * 1024, PAGE_SIZE, true,
>  			     AMDGPU_GEM_DOMAIN_VRAM,
> -			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  			     NULL, NULL, &adev->stollen_vga_memory);
>  	if (r) {
>  		return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> index 5888e8a..5f5380c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> @@ -891,6 +891,10 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)
>  		return -EINVAL;
>  	}
>  
> +	r = amdgpu_cs_make_bos_linear(parser);
> +	if (r)
> +		return r;
> +
>  	ctx.parser = parser;
>  	ctx.buf_sizes = buf_sizes;
>  	ctx.ib_idx = ib_idx;
> @@ -1007,7 +1011,8 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
>  
>  	r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,
>  			     AMDGPU_GEM_DOMAIN_VRAM,
> -			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  			     NULL, NULL, &bo);
>  	if (r)
>  		return r;
> @@ -1056,7 +1061,8 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
>  
>  	r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,
>  			     AMDGPU_GEM_DOMAIN_VRAM,
> -			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  			     NULL, NULL, &bo);
>  	if (r)
>  		return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> index 9b71d6c..bb97a8e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> @@ -157,7 +157,8 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
>  
>  	r = amdgpu_bo_create(adev, size, PAGE_SIZE, true,
>  			     AMDGPU_GEM_DOMAIN_VRAM,
> -			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  			     NULL, NULL, &adev->vce.vcpu_bo);
>  	if (r) {
>  		dev_err(adev->dev, "(%d) failed to allocate VCE bo\n", r);
> @@ -634,7 +635,11 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
>  	uint32_t allocated = 0;
>  	uint32_t tmp, handle = 0;
>  	uint32_t *size = &tmp;
> -	int i, r = 0, idx = 0;
> +	int i, r, idx = 0;
> +
> +	r = amdgpu_cs_make_bos_linear(p);
> +	if (r)
> +		return r;
>  
>  	while (idx < ib->length_dw) {
>  		uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index 7660f82..ea1bd67 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -1398,7 +1398,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
>  				     AMDGPU_GPU_PAGE_SIZE, true,
>  				     AMDGPU_GEM_DOMAIN_VRAM,
>  				     AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
> -				     AMDGPU_GEM_CREATE_SHADOW,
> +				     AMDGPU_GEM_CREATE_SHADOW |
> +				     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  				     NULL, resv, &pt);
>  		if (r)
>  			goto error_free;
> @@ -1598,7 +1599,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
>  	r = amdgpu_bo_create(adev, pd_size, align, true,
>  			     AMDGPU_GEM_DOMAIN_VRAM,
>  			     AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
> -			     AMDGPU_GEM_CREATE_SHADOW,
> +			     AMDGPU_GEM_CREATE_SHADOW |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  			     NULL, NULL, &vm->page_directory);
>  	if (r)
>  		goto error_free_sched_entity;
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> index f055d49..1517a8c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> @@ -3213,7 +3213,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
>  		if (adev->gfx.rlc.save_restore_obj == NULL) {
>  			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
>  					     AMDGPU_GEM_DOMAIN_VRAM,
> -					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  					     NULL, NULL,
>  					     &adev->gfx.rlc.save_restore_obj);
>  			if (r) {
> @@ -3257,7 +3258,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
>  		if (adev->gfx.rlc.clear_state_obj == NULL) {
>  			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
>  					     AMDGPU_GEM_DOMAIN_VRAM,
> -					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  					     NULL, NULL,
>  					     &adev->gfx.rlc.clear_state_obj);
>  			if (r) {
> @@ -3297,7 +3299,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
>  		if (adev->gfx.rlc.cp_table_obj == NULL) {
>  			r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,
>  					     AMDGPU_GEM_DOMAIN_VRAM,
> -					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  					     NULL, NULL,
>  					     &adev->gfx.rlc.cp_table_obj);
>  			if (r) {
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> index 6e01392..26e614e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> @@ -1273,7 +1273,8 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
>  		if (adev->gfx.rlc.clear_state_obj == NULL) {
>  			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
>  					     AMDGPU_GEM_DOMAIN_VRAM,
> -					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  					     NULL, NULL,
>  					     &adev->gfx.rlc.clear_state_obj);
>  			if (r) {
> @@ -1315,7 +1316,8 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
>  		if (adev->gfx.rlc.cp_table_obj == NULL) {
>  			r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,
>  					     AMDGPU_GEM_DOMAIN_VRAM,
> -					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  					     NULL, NULL,
>  					     &adev->gfx.rlc.cp_table_obj);
>  			if (r) {
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index 403b676..2aede6a 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -79,6 +79,8 @@
>  #define AMDGPU_GEM_CREATE_VRAM_CLEARED		(1 << 3)
>  /* Flag that create shadow bo(GTT) while allocating vram bo */
>  #define AMDGPU_GEM_CREATE_SHADOW		(1 << 4)
> +/* Flag that allocating the BO should use linear VRAM */
> +#define AMDGPU_GEM_CREATE_VRAM_LINEAR		(1 << 5)
>  
>  struct drm_amdgpu_gem_create_in  {
>  	/** the requested memory size */
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/5] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_LINEAR flag v2
       [not found]     ` <1472462424-3052-2-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
  2016-08-29 11:02       ` Edward O'Callaghan
@ 2016-08-29 13:47       ` Deucher, Alexander
       [not found]         ` <MWHPR12MB1694759D47B2D6579C5D8F5BF7E10-Gy0DoCVfaSW4WA4dJ5YXGAdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
  2016-08-30 17:33       ` William Lewis
  2 siblings, 1 reply; 18+ messages in thread
From: Deucher, Alexander @ 2016-08-29 13:47 UTC (permalink / raw)
  To: 'Christian König', amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf
> Of Christian König
> Sent: Monday, August 29, 2016 5:20 AM
> To: amd-gfx@lists.freedesktop.org
> Subject: [PATCH 1/5] drm/amdgpu: add
> AMDGPU_GEM_CREATE_VRAM_LINEAR flag v2

I still think this should be renamed AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS or the anti-flag AMDGPU_GEM_CREATE_VRAM_SCATTER_GATHER to avoid confusion with linear in the tiling sense.

Alex

> 
> From: Christian König <christian.koenig@amd.com>
> 
> Add a flag noting that a BO must be created using linear VRAM
> and set this flag on all in kernel users where appropriate.
> 
> Hopefully I haven't missed anything.
> 
> v2: add it in a few more places, fix CPU mapping.
> 
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  1 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c    |  6 ++++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c     | 31
> ++++++++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  3 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c     |  3 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c   |  3 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 12 ++++++++++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    |  3 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c    | 10 ++++++++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c    |  9 +++++++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c     |  6 ++++--
>  drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c      |  9 ++++++---
>  drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c      |  6 ++++--
>  include/uapi/drm/amdgpu_drm.h              |  2 ++
>  14 files changed, 85 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 545789f..b2d95a9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -2499,6 +2499,7 @@ static inline void amdgpu_acpi_fini(struct
> amdgpu_device *adev) { }
>  struct amdgpu_bo_va_mapping *
>  amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
>  		       uint64_t addr, struct amdgpu_bo **bo);
> +int amdgpu_cs_make_bos_linear(struct amdgpu_cs_parser *parser);
> 
>  #if defined(CONFIG_DRM_AMD_DAL)
>  int amdgpu_dm_display_resume(struct amdgpu_device *adev );
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> index 040993c..c2dfcd3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> @@ -146,7 +146,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct
> cgs_device *cgs_device,
>  	switch(type) {
>  	case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB:
>  	case CGS_GPU_MEM_TYPE__VISIBLE_FB:
> -		flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
> +		flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			AMDGPU_GEM_CREATE_VRAM_LINEAR;
>  		domain = AMDGPU_GEM_DOMAIN_VRAM;
>  		if (max_offset > adev->mc.real_vram_size)
>  			return -EINVAL;
> @@ -157,7 +158,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct
> cgs_device *cgs_device,
>  		break;
>  	case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB:
>  	case CGS_GPU_MEM_TYPE__INVISIBLE_FB:
> -		flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
> +		flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
> +			AMDGPU_GEM_CREATE_VRAM_LINEAR;
>  		domain = AMDGPU_GEM_DOMAIN_VRAM;
>  		if (adev->mc.visible_vram_size < adev->mc.real_vram_size) {
>  			place.fpfn =
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index b0e11ca..108408b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -1097,3 +1097,34 @@ amdgpu_cs_find_mapping(struct
> amdgpu_cs_parser *parser,
> 
>  	return NULL;
>  }
> +
> +/**
> + * amdgpu_cs_make_bos_linear - mark all BOs in this CS as linear
> + *
> + * @parser: command submission parser context
> + *
> + * Helper for UVD/VCE VM emulation, mark all BOs in this CS as linear.
> + */
> +int amdgpu_cs_make_bos_linear(struct amdgpu_cs_parser *parser)
> +{
> +	unsigned i;
> +	int r;
> +
> +	if (!parser->bo_list)
> +		return 0;
> +
> +	for (i = 0; i < parser->bo_list->num_entries; i++) {
> +		struct amdgpu_bo *bo = parser->bo_list->array[i].robj;
> +
> +		if (bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR)
> +			continue;
> +
> +		bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
> +		amdgpu_ttm_placement_from_domain(bo, bo-
> >allowed_domains);
> +		r = ttm_bo_validate(&bo->tbo, &bo->placement, false,
> false);
> +		if (unlikely(r))
> +			return r;
> +	}
> +
> +	return 0;
> +}
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 1b31a7c..38f5315 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -256,7 +256,8 @@ static int amdgpu_vram_scratch_init(struct
> amdgpu_device *adev)
>  	if (adev->vram_scratch.robj == NULL) {
>  		r = amdgpu_bo_create(adev, AMDGPU_GPU_PAGE_SIZE,
>  				     PAGE_SIZE, true,
> AMDGPU_GEM_DOMAIN_VRAM,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +				     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  				     NULL, NULL, &adev->vram_scratch.robj);
>  		if (r) {
>  			return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> index e694c99..efa9b79 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> @@ -120,7 +120,8 @@ static int amdgpufb_create_pinned_object(struct
> amdgpu_fbdev *rfbdev,
>  	aligned_size = ALIGN(size, PAGE_SIZE);
>  	ret = amdgpu_gem_object_create(adev, aligned_size, 0,
>  				       AMDGPU_GEM_DOMAIN_VRAM,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +				       AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  				       true, &gobj);
>  	if (ret) {
>  		printk(KERN_ERR "failed to allocate framebuffer (%d)\n",
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> index 0feea34..b5982a9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> @@ -126,7 +126,8 @@ int amdgpu_gart_table_vram_alloc(struct
> amdgpu_device *adev)
>  	if (adev->gart.robj == NULL) {
>  		r = amdgpu_bo_create(adev, adev->gart.table_size,
>  				     PAGE_SIZE, true,
> AMDGPU_GEM_DOMAIN_VRAM,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +				     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  				     NULL, NULL, &adev->gart.robj);
>  		if (r) {
>  			return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index b17734e..6f83909 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -247,7 +247,8 @@ int amdgpu_bo_create_kernel(struct amdgpu_device
> *adev,
>  	int r;
> 
>  	r = amdgpu_bo_create(adev, size, align, true, domain,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED
> |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  			     NULL, NULL, bo_ptr);
>  	if (r) {
>  		dev_err(adev->dev, "(%d) failed to allocate kernel bo\n", r);
> @@ -617,6 +618,8 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo
> *bo, u32 domain,
> 
>  		return 0;
>  	}
> +
> +	bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
>  	amdgpu_ttm_placement_from_domain(bo, domain);
>  	for (i = 0; i < bo->placement.num_placement; i++) {
>  		/* force to pin into visible video ram */
> @@ -854,7 +857,9 @@ int amdgpu_bo_fault_reserve_notify(struct
> ttm_buffer_object *bo)
> 
>  	size = bo->mem.num_pages << PAGE_SHIFT;
>  	offset = bo->mem.start << PAGE_SHIFT;
> -	if ((offset + size) <= adev->mc.visible_vram_size)
> +	/* TODO: figure out how to map scattered VRAM to the CPU */
> +	if ((offset + size) <= adev->mc.visible_vram_size &&
> +	    (abo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR))
>  		return 0;
> 
>  	/* Can't move a pinned BO to visible VRAM */
> @@ -862,6 +867,7 @@ int amdgpu_bo_fault_reserve_notify(struct
> ttm_buffer_object *bo)
>  		return -EINVAL;
> 
>  	/* hurrah the memory is not visible ! */
> +	abo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
>  	amdgpu_ttm_placement_from_domain(abo,
> AMDGPU_GEM_DOMAIN_VRAM);
>  	lpfn =	adev->mc.visible_vram_size >> PAGE_SHIFT;
>  	for (i = 0; i < abo->placement.num_placement; i++) {
> @@ -920,6 +926,8 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
>  	WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM);
>  	WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) &&
>  		     !bo->pin_count);
> +	WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM &&
> +		     !(bo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR));
> 
>  	return bo->tbo.offset;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index e2f6a46..ea480bb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1024,7 +1024,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
> 
>  	r = amdgpu_bo_create(adev, 256 * 1024, PAGE_SIZE, true,
>  			     AMDGPU_GEM_DOMAIN_VRAM,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED
> |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  			     NULL, NULL, &adev->stollen_vga_memory);
>  	if (r) {
>  		return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> index 5888e8a..5f5380c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> @@ -891,6 +891,10 @@ int amdgpu_uvd_ring_parse_cs(struct
> amdgpu_cs_parser *parser, uint32_t ib_idx)
>  		return -EINVAL;
>  	}
> 
> +	r = amdgpu_cs_make_bos_linear(parser);
> +	if (r)
> +		return r;
> +
>  	ctx.parser = parser;
>  	ctx.buf_sizes = buf_sizes;
>  	ctx.ib_idx = ib_idx;
> @@ -1007,7 +1011,8 @@ int amdgpu_uvd_get_create_msg(struct
> amdgpu_ring *ring, uint32_t handle,
> 
>  	r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,
>  			     AMDGPU_GEM_DOMAIN_VRAM,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED
> |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  			     NULL, NULL, &bo);
>  	if (r)
>  		return r;
> @@ -1056,7 +1061,8 @@ int amdgpu_uvd_get_destroy_msg(struct
> amdgpu_ring *ring, uint32_t handle,
> 
>  	r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,
>  			     AMDGPU_GEM_DOMAIN_VRAM,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED
> |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  			     NULL, NULL, &bo);
>  	if (r)
>  		return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> index 9b71d6c..bb97a8e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> @@ -157,7 +157,8 @@ int amdgpu_vce_sw_init(struct amdgpu_device
> *adev, unsigned long size)
> 
>  	r = amdgpu_bo_create(adev, size, PAGE_SIZE, true,
>  			     AMDGPU_GEM_DOMAIN_VRAM,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED
> |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  			     NULL, NULL, &adev->vce.vcpu_bo);
>  	if (r) {
>  		dev_err(adev->dev, "(%d) failed to allocate VCE bo\n", r);
> @@ -634,7 +635,11 @@ int amdgpu_vce_ring_parse_cs(struct
> amdgpu_cs_parser *p, uint32_t ib_idx)
>  	uint32_t allocated = 0;
>  	uint32_t tmp, handle = 0;
>  	uint32_t *size = &tmp;
> -	int i, r = 0, idx = 0;
> +	int i, r, idx = 0;
> +
> +	r = amdgpu_cs_make_bos_linear(p);
> +	if (r)
> +		return r;
> 
>  	while (idx < ib->length_dw) {
>  		uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index 7660f82..ea1bd67 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -1398,7 +1398,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device
> *adev,
>  				     AMDGPU_GPU_PAGE_SIZE, true,
>  				     AMDGPU_GEM_DOMAIN_VRAM,
> 
> AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
> -				     AMDGPU_GEM_CREATE_SHADOW,
> +				     AMDGPU_GEM_CREATE_SHADOW |
> +				     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  				     NULL, resv, &pt);
>  		if (r)
>  			goto error_free;
> @@ -1598,7 +1599,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev,
> struct amdgpu_vm *vm)
>  	r = amdgpu_bo_create(adev, pd_size, align, true,
>  			     AMDGPU_GEM_DOMAIN_VRAM,
>  			     AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
> -			     AMDGPU_GEM_CREATE_SHADOW,
> +			     AMDGPU_GEM_CREATE_SHADOW |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  			     NULL, NULL, &vm->page_directory);
>  	if (r)
>  		goto error_free_sched_entity;
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> index f055d49..1517a8c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> @@ -3213,7 +3213,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device
> *adev)
>  		if (adev->gfx.rlc.save_restore_obj == NULL) {
>  			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE,
> true,
>  					     AMDGPU_GEM_DOMAIN_VRAM,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +
> AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  					     NULL, NULL,
>  					     &adev->gfx.rlc.save_restore_obj);
>  			if (r) {
> @@ -3257,7 +3258,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device
> *adev)
>  		if (adev->gfx.rlc.clear_state_obj == NULL) {
>  			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE,
> true,
>  					     AMDGPU_GEM_DOMAIN_VRAM,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +
> AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  					     NULL, NULL,
>  					     &adev->gfx.rlc.clear_state_obj);
>  			if (r) {
> @@ -3297,7 +3299,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device
> *adev)
>  		if (adev->gfx.rlc.cp_table_obj == NULL) {
>  			r = amdgpu_bo_create(adev, adev-
> >gfx.rlc.cp_table_size, PAGE_SIZE, true,
>  					     AMDGPU_GEM_DOMAIN_VRAM,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +
> AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  					     NULL, NULL,
>  					     &adev->gfx.rlc.cp_table_obj);
>  			if (r) {
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> index 6e01392..26e614e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> @@ -1273,7 +1273,8 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device
> *adev)
>  		if (adev->gfx.rlc.clear_state_obj == NULL) {
>  			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE,
> true,
>  					     AMDGPU_GEM_DOMAIN_VRAM,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +
> AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  					     NULL, NULL,
>  					     &adev->gfx.rlc.clear_state_obj);
>  			if (r) {
> @@ -1315,7 +1316,8 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device
> *adev)
>  		if (adev->gfx.rlc.cp_table_obj == NULL) {
>  			r = amdgpu_bo_create(adev, adev-
> >gfx.rlc.cp_table_size, PAGE_SIZE, true,
>  					     AMDGPU_GEM_DOMAIN_VRAM,
> -
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +
> AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +
> AMDGPU_GEM_CREATE_VRAM_LINEAR,
>  					     NULL, NULL,
>  					     &adev->gfx.rlc.cp_table_obj);
>  			if (r) {
> diff --git a/include/uapi/drm/amdgpu_drm.h
> b/include/uapi/drm/amdgpu_drm.h
> index 403b676..2aede6a 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -79,6 +79,8 @@
>  #define AMDGPU_GEM_CREATE_VRAM_CLEARED		(1 << 3)
>  /* Flag that create shadow bo(GTT) while allocating vram bo */
>  #define AMDGPU_GEM_CREATE_SHADOW		(1 << 4)
> +/* Flag that allocating the BO should use linear VRAM */
> +#define AMDGPU_GEM_CREATE_VRAM_LINEAR		(1 << 5)
> 
>  struct drm_amdgpu_gem_create_in  {
>  	/** the requested memory size */
> --
> 2.5.0
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/5] drm/amdgpu: enable amdgpu_move_blit to handle multiple MM nodes
       [not found]     ` <1472462424-3052-5-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
@ 2016-08-29 22:09       ` Felix Kuehling
  0 siblings, 0 replies; 18+ messages in thread
From: Felix Kuehling @ 2016-08-29 22:09 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Christian König

This requires an assumption that there is no partial overlap between the
the mm_nodes in the old and new memory. As long as BOs are always split
into fixed size portions that should work OK for copying between linear
and split BOs. But it can fail if you copy between split BOs that are
split in different size portions.

For example this won't work:

     +-------+-------+-------+
Old: |  o0   |  o1   |  o2   |
     +-------+-------+-------+

     +-----------+-----------+
New: |    n0     |    n1     |
     +-----------+-----------+


Regards,
  Felix

On 16-08-29 05:20 AM, Christian König wrote:
> From: Christian König <christian.koenig@amd.com>
>
> This allows us to move scattered buffers around.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 96 ++++++++++++++++++++++-----------
>  1 file changed, 64 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index ea480bb..db8638b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -239,52 +239,84 @@ static void amdgpu_move_null(struct ttm_buffer_object *bo,
>  	new_mem->mm_node = NULL;
>  }
>  
> -static int amdgpu_move_blit(struct ttm_buffer_object *bo,
> -			bool evict, bool no_wait_gpu,
> -			struct ttm_mem_reg *new_mem,
> -			struct ttm_mem_reg *old_mem)
> +static uint64_t amdgpu_mm_node_addr(struct amdgpu_device *adev,
> +				    struct drm_mm_node *mm_node,
> +				    struct ttm_mem_reg *mem)
>  {
> -	struct amdgpu_device *adev;
> -	struct amdgpu_ring *ring;
> -	uint64_t old_start, new_start;
> -	struct fence *fence;
> -	int r;
> +	uint64_t addr = mm_node->start << PAGE_SHIFT;
>  
> -	adev = amdgpu_get_adev(bo->bdev);
> -	ring = adev->mman.buffer_funcs_ring;
> -	old_start = (u64)old_mem->start << PAGE_SHIFT;
> -	new_start = (u64)new_mem->start << PAGE_SHIFT;
> -
> -	switch (old_mem->mem_type) {
> +	switch (mem->mem_type) {
>  	case TTM_PL_VRAM:
>  	case TTM_PL_TT:
> -		old_start += bo->bdev->man[old_mem->mem_type].gpu_offset;
> +		addr += adev->mman.bdev.man[mem->mem_type].gpu_offset;
>  		break;
>  	default:
> -		DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
> -		return -EINVAL;
> -	}
> -	switch (new_mem->mem_type) {
> -	case TTM_PL_VRAM:
> -	case TTM_PL_TT:
> -		new_start += bo->bdev->man[new_mem->mem_type].gpu_offset;
> +		DRM_ERROR("Unknown placement %d\n", mem->mem_type);
>  		break;
> -	default:
> -		DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
> -		return -EINVAL;
>  	}
> +
> +	return addr;
> +}
> +
> +static int amdgpu_move_blit(struct ttm_buffer_object *bo,
> +			    bool evict, bool no_wait_gpu,
> +			    struct ttm_mem_reg *new_mem,
> +			    struct ttm_mem_reg *old_mem)
> +{
> +	struct amdgpu_device *adev = amdgpu_get_adev(bo->bdev);
> +	struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
> +
> +	struct drm_mm_node *old_mm, *new_mm;
> +	uint64_t old_start, new_start;
> +	unsigned long num_pages;
> +	struct fence *fence = NULL;
> +	int r;
> +
> +	BUILD_BUG_ON((PAGE_SIZE % AMDGPU_GPU_PAGE_SIZE) != 0);
> +
>  	if (!ring->ready) {
>  		DRM_ERROR("Trying to move memory with ring turned off.\n");
>  		return -EINVAL;
>  	}
>  
> -	BUILD_BUG_ON((PAGE_SIZE % AMDGPU_GPU_PAGE_SIZE) != 0);
> +	old_mm = old_mem->mm_node;
> +	new_mm = new_mem->mm_node;
> +	num_pages = new_mem->num_pages;
>  
> -	r = amdgpu_copy_buffer(ring, old_start, new_start,
> -			       new_mem->num_pages * PAGE_SIZE, /* bytes */
> -			       bo->resv, &fence, false);
> -	if (r)
> -		return r;
> +	old_start = amdgpu_mm_node_addr(adev, old_mm, old_mem);
> +	new_start = amdgpu_mm_node_addr(adev, new_mm, new_mem);
> +
> +	while (num_pages) {
> +		unsigned long cur_pages = min(old_mm->size, new_mm->size);
> +		struct fence *next;
> +
> +		r = amdgpu_copy_buffer(ring, old_start, new_start,
> +				       cur_pages * PAGE_SIZE,
> +				       bo->resv, &next, false);
> +		if (r) {
> +			if (fence)
> +				fence_wait(fence, false);
> +			fence_put(fence);
> +			return r;
> +		}
> +		fence_put(fence);
> +		fence = next;
> +
> +		num_pages -= cur_pages;
> +		if (num_pages) {
> +			old_start += cur_pages * PAGE_SIZE;
> +			if (old_start == ((old_mm->start + old_mm->size) *
> +				PAGE_SIZE))
> +				old_start = amdgpu_mm_node_addr(adev, ++old_mm,
> +								old_mem);
> +
> +			new_start += cur_pages * PAGE_SIZE;
> +			if (new_start == ((new_mm->start + new_mm->size) *
> +					  PAGE_SIZE))
> +				new_start = amdgpu_mm_node_addr(adev, ++new_mm,
> +								new_mem);
> +		}
> +	}
>  
>  	r = ttm_bo_pipeline_move(bo, fence, evict, new_mem);
>  	fence_put(fence);

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/5] drm/amdgpu: handle multiple MM nodes in the VMs
       [not found]     ` <1472462424-3052-4-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
@ 2016-08-29 22:29       ` Felix Kuehling
  0 siblings, 0 replies; 18+ messages in thread
From: Felix Kuehling @ 2016-08-29 22:29 UTC (permalink / raw)
  To: Christian König, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

I looked really hard and couldn't find anything obviously broken. It
makes me a bit nervous that there is no bounds checking on the nodes
array, though.

Just one minor nit pick.

With that fixed, Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>


On 16-08-29 05:20 AM, Christian König wrote:
> From: Christian König <christian.koenig@amd.com>
>
> This allows us to map scattered VRAM BOs to the VMs.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 79 +++++++++++++++++++---------------
>  1 file changed, 44 insertions(+), 35 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index ea1bd67..df6506d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -1048,8 +1048,8 @@ error_free:
>   * @pages_addr: DMA addresses to use for mapping
>   * @vm: requested vm
>   * @mapping: mapped range and flags to use for the update
> - * @addr: addr to set the area to
>   * @flags: HW flags for the mapping
> + * @nodes: array of drm_mm_nodes with the MC addresses
>   * @fence: optional resulting fence
>   *
>   * Split the mapping into smaller chunks so that each update fits
> @@ -1062,12 +1062,11 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
>  				      dma_addr_t *pages_addr,
>  				      struct amdgpu_vm *vm,
>  				      struct amdgpu_bo_va_mapping *mapping,
> -				      uint32_t flags, uint64_t addr,
> +				      uint32_t flags,
> +				      struct drm_mm_node *nodes,
>  				      struct fence **fence)
>  {
> -	const uint64_t max_size = 64ULL * 1024ULL * 1024ULL / AMDGPU_GPU_PAGE_SIZE;
> -
> -	uint64_t src = 0, start = mapping->it.start;
> +	uint64_t offset, src = 0, start = mapping->it.start;
>  	int r;
>  
>  	/* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here
> @@ -1080,23 +1079,38 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
>  
>  	trace_amdgpu_vm_bo_update(mapping);
>  
> -	if (pages_addr) {
> -		if (flags == gtt_flags)
> -			src = adev->gart.table_addr + (addr >> 12) * 8;
> -		addr = 0;
> +	offset = mapping->offset;
> +	if (nodes) {
> +		while (offset > (nodes->size << PAGE_SHIFT)) {
> +			offset -= (nodes->size << PAGE_SHIFT);
> +			++nodes;
> +		}
>  	}
> -	addr += mapping->offset;
>  
> -	if (!pages_addr || src)
> -		return amdgpu_vm_bo_update_mapping(adev, exclusive,
> -						   src, pages_addr, vm,
> -						   start, mapping->it.last,
> -						   flags, addr, fence);
> +	do {
> +		uint64_t max_entries;
> +		uint64_t addr, last;
>  
> -	while (start != mapping->it.last + 1) {
> -		uint64_t last;
> +		if (nodes) {
> +			addr = nodes->start << PAGE_SHIFT;
> +			max_entries = nodes->size - (offset >> PAGE_SHIFT);

[FK] I think max_entries is the number of GPU page table entries. So you
should convert from the system page size to the GPU page size:
        max_entries = ((nodes->size << PAGE_SHIFT) - offset) >>
AMDGPU_GPU_PAGE_SHIFT;

> +		} else {
> +			addr = 0;
> +			max_entries = S64_MAX;
> +		}
> +		addr += offset;
> +
> +		if (pages_addr) {
> +			if (flags == gtt_flags)
> +				src = adev->gart.table_addr + (addr >> 12) * 8;
> +			else
> +				max_entries = min(max_entries, 16ull * 1024ull);
> +			addr = 0;
> +		} else if (flags & AMDGPU_PTE_VALID) {
> +			addr += adev->vm_manager.vram_base_offset;
> +		}
>  
> -		last = min((uint64_t)mapping->it.last, start + max_size - 1);
> +		last = min((uint64_t)mapping->it.last, start + max_entries - 1);
>  		r = amdgpu_vm_bo_update_mapping(adev, exclusive,
>  						src, pages_addr, vm,
>  						start, last, flags, addr,
> @@ -1104,9 +1118,14 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
>  		if (r)
>  			return r;
>  
> +		offset += (last - start + 1) * AMDGPU_GPU_PAGE_SIZE;
> +		if (nodes && nodes->size == (offset >> PAGE_SHIFT)) {
> +			offset = 0;
> +			++nodes;
> +		}
>  		start = last + 1;
> -		addr += max_size * AMDGPU_GPU_PAGE_SIZE;
> -	}
> +
> +	} while (likely(start != mapping->it.last + 1));
>  
>  	return 0;
>  }
> @@ -1130,34 +1149,24 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
>  	dma_addr_t *pages_addr = NULL;
>  	uint32_t gtt_flags, flags;
>  	struct ttm_mem_reg *mem;
> +	struct drm_mm_node *nodes;
>  	struct fence *exclusive;
> -	uint64_t addr;
>  	int r;
>  
>  	if (clear) {
>  		mem = NULL;
> -		addr = 0;
> +		nodes = NULL;
>  		exclusive = NULL;
>  	} else {
>  		struct ttm_dma_tt *ttm;
>  
>  		mem = &bo_va->bo->tbo.mem;
> -		addr = (u64)mem->start << PAGE_SHIFT;
> -		switch (mem->mem_type) {
> -		case TTM_PL_TT:
> +		nodes = mem->mm_node;
> +		if (mem->mem_type == TTM_PL_TT) {
>  			ttm = container_of(bo_va->bo->tbo.ttm, struct
>  					   ttm_dma_tt, ttm);
>  			pages_addr = ttm->dma_address;
> -			break;
> -
> -		case TTM_PL_VRAM:
> -			addr += adev->vm_manager.vram_base_offset;
> -			break;
> -
> -		default:
> -			break;
>  		}
> -
>  		exclusive = reservation_object_get_excl(bo_va->bo->tbo.resv);
>  	}
>  
> @@ -1172,7 +1181,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
>  	list_for_each_entry(mapping, &bo_va->invalids, list) {
>  		r = amdgpu_vm_bo_split_mapping(adev, exclusive,
>  					       gtt_flags, pages_addr, vm,
> -					       mapping, flags, addr,
> +					       mapping, flags, nodes,
>  					       &bo_va->last_pt_update);
>  		if (r)
>  			return r;

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/5] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_LINEAR flag v2
       [not found]         ` <MWHPR12MB1694759D47B2D6579C5D8F5BF7E10-Gy0DoCVfaSW4WA4dJ5YXGAdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
@ 2016-08-30  0:57           ` Michel Dänzer
       [not found]             ` <8221ebac-36e1-7a5b-2d02-92db63c4cc24-otUistvHUpPR7s880joybQ@public.gmane.org>
  0 siblings, 1 reply; 18+ messages in thread
From: Michel Dänzer @ 2016-08-30  0:57 UTC (permalink / raw)
  To: Deucher, Alexander, 'Christian König'
  Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 29/08/16 10:47 PM, Deucher, Alexander wrote:
>> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf
>> Of Christian König
>> Sent: Monday, August 29, 2016 5:20 AM
> 
> I still think this should be renamed AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS
> or the anti-flag AMDGPU_GEM_CREATE_VRAM_SCATTER_GATHER to avoid
> confusion with linear in the tiling sense.

Seconded.


-- 
Earthling Michel Dänzer               |               http://www.amd.com
Libre software enthusiast             |             Mesa and X developer
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/5] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_LINEAR flag v2
       [not found]             ` <8221ebac-36e1-7a5b-2d02-92db63c4cc24-otUistvHUpPR7s880joybQ@public.gmane.org>
@ 2016-08-30  1:49               ` Flora Cui
  2016-08-30  7:44                 ` Christian König
  0 siblings, 1 reply; 18+ messages in thread
From: Flora Cui @ 2016-08-30  1:49 UTC (permalink / raw)
  To: Michel Dänzer
  Cc: Deucher, Alexander, 'Christian König',
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Tue, Aug 30, 2016 at 09:57:56AM +0900, Michel Dänzer wrote:
> On 29/08/16 10:47 PM, Deucher, Alexander wrote:
> >> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf
> >> Of Christian König
> >> Sent: Monday, August 29, 2016 5:20 AM
> > 
> > I still think this should be renamed AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS
> > or the anti-flag AMDGPU_GEM_CREATE_VRAM_SCATTER_GATHER to avoid
> > confusion with linear in the tiling sense.
> 
> Seconded.
> 
and this could be the default option unless
AMDGPU_GEM_CREATE_VRAM_SCATTER_GATHER is specified.
> 
> -- 
> Earthling Michel Dänzer               |               http://www.amd.com
> Libre software enthusiast             |             Mesa and X developer
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/5] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_LINEAR flag v2
  2016-08-30  1:49               ` Flora Cui
@ 2016-08-30  7:44                 ` Christian König
  0 siblings, 0 replies; 18+ messages in thread
From: Christian König @ 2016-08-30  7:44 UTC (permalink / raw)
  To: Flora Cui, Michel Dänzer
  Cc: Deucher, Alexander, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Am 30.08.2016 um 03:49 schrieb Flora Cui:
> On Tue, Aug 30, 2016 at 09:57:56AM +0900, Michel Dänzer wrote:
>> On 29/08/16 10:47 PM, Deucher, Alexander wrote:
>>>> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf
>>>> Of Christian König
>>>> Sent: Monday, August 29, 2016 5:20 AM
>>> I still think this should be renamed AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS
>>> or the anti-flag AMDGPU_GEM_CREATE_VRAM_SCATTER_GATHER to avoid
>>> confusion with linear in the tiling sense.
>> Seconded.
>>
> and this could be the default option unless
> AMDGPU_GEM_CREATE_VRAM_SCATTER_GATHER is specified.

Yeah, but then we won't correctly use it with existing userspace.

I will just rename it to AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS.

Christian.

>> -- 
>> Earthling Michel Dänzer               |               http://www.amd.com
>> Libre software enthusiast             |             Mesa and X developer
>> _______________________________________________
>> amd-gfx mailing list
>> amd-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/5] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_LINEAR flag v2
       [not found]     ` <1472462424-3052-2-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
  2016-08-29 11:02       ` Edward O'Callaghan
  2016-08-29 13:47       ` Deucher, Alexander
@ 2016-08-30 17:33       ` William Lewis
       [not found]         ` <BY2PR17MB02955F1C52893FDD92B1D78CC8E00-x8ynOugG3EHUsavx+kKoj3+GY4YGzQ7gvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
  2 siblings, 1 reply; 18+ messages in thread
From: William Lewis @ 2016-08-30 17:33 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Question inline, probably my lack of understanding of the code.


On 08/29/16 04:20, Christian König wrote:
> From: Christian König <christian.koenig@amd.com>
>
> Add a flag noting that a BO must be created using linear VRAM
> and set this flag on all in kernel users where appropriate.
>
> Hopefully I haven't missed anything.
>
> v2: add it in a few more places, fix CPU mapping.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  1 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c    |  6 ++++--
>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c     | 31 ++++++++++++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  3 ++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c     |  3 ++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c   |  3 ++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 12 ++++++++++--
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    |  3 ++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c    | 10 ++++++++--
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c    |  9 +++++++--
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c     |  6 ++++--
>   drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c      |  9 ++++++---
>   drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c      |  6 ++++--
>   include/uapi/drm/amdgpu_drm.h              |  2 ++
>   14 files changed, 85 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 545789f..b2d95a9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -2499,6 +2499,7 @@ static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { }
>   struct amdgpu_bo_va_mapping *
>   amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
>   		       uint64_t addr, struct amdgpu_bo **bo);
> +int amdgpu_cs_make_bos_linear(struct amdgpu_cs_parser *parser);
>   
>   #if defined(CONFIG_DRM_AMD_DAL)
>   int amdgpu_dm_display_resume(struct amdgpu_device *adev );
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> index 040993c..c2dfcd3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
> @@ -146,7 +146,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device,
>   	switch(type) {
>   	case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB:
>   	case CGS_GPU_MEM_TYPE__VISIBLE_FB:
> -		flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
> +		flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			AMDGPU_GEM_CREATE_VRAM_LINEAR;
>   		domain = AMDGPU_GEM_DOMAIN_VRAM;
>   		if (max_offset > adev->mc.real_vram_size)
>   			return -EINVAL;
> @@ -157,7 +158,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device,
>   		break;
>   	case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB:
>   	case CGS_GPU_MEM_TYPE__INVISIBLE_FB:
> -		flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
> +		flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
> +			AMDGPU_GEM_CREATE_VRAM_LINEAR;
>   		domain = AMDGPU_GEM_DOMAIN_VRAM;
>   		if (adev->mc.visible_vram_size < adev->mc.real_vram_size) {
>   			place.fpfn =
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index b0e11ca..108408b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -1097,3 +1097,34 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
>   
>   	return NULL;
>   }
> +
> +/**
> + * amdgpu_cs_make_bos_linear - mark all BOs in this CS as linear
> + *
> + * @parser: command submission parser context
> + *
> + * Helper for UVD/VCE VM emulation, mark all BOs in this CS as linear.
> + */
> +int amdgpu_cs_make_bos_linear(struct amdgpu_cs_parser *parser)
> +{
> +	unsigned i;
> +	int r;
> +
> +	if (!parser->bo_list)
> +		return 0;
> +
> +	for (i = 0; i < parser->bo_list->num_entries; i++) {
> +		struct amdgpu_bo *bo = parser->bo_list->array[i].robj;
> +
> +		if (bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR)
> +			continue;
> +
> +		bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
> +		amdgpu_ttm_placement_from_domain(bo, bo->allowed_domains);
> +		r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
> +		if (unlikely(r))
> +			return r;
> +	}
> +
> +	return 0;
> +}
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 1b31a7c..38f5315 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -256,7 +256,8 @@ static int amdgpu_vram_scratch_init(struct amdgpu_device *adev)
>   	if (adev->vram_scratch.robj == NULL) {
>   		r = amdgpu_bo_create(adev, AMDGPU_GPU_PAGE_SIZE,
>   				     PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
> -				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +				     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   				     NULL, NULL, &adev->vram_scratch.robj);
>   		if (r) {
>   			return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> index e694c99..efa9b79 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> @@ -120,7 +120,8 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
>   	aligned_size = ALIGN(size, PAGE_SIZE);
>   	ret = amdgpu_gem_object_create(adev, aligned_size, 0,
>   				       AMDGPU_GEM_DOMAIN_VRAM,
> -				       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +				       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +				       AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   				       true, &gobj);
>   	if (ret) {
>   		printk(KERN_ERR "failed to allocate framebuffer (%d)\n",
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> index 0feea34..b5982a9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> @@ -126,7 +126,8 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
>   	if (adev->gart.robj == NULL) {
>   		r = amdgpu_bo_create(adev, adev->gart.table_size,
>   				     PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
> -				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +				     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   				     NULL, NULL, &adev->gart.robj);
>   		if (r) {
>   			return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index b17734e..6f83909 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -247,7 +247,8 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
>   	int r;
>   
>   	r = amdgpu_bo_create(adev, size, align, true, domain,
> -			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   			     NULL, NULL, bo_ptr);
>   	if (r) {
>   		dev_err(adev->dev, "(%d) failed to allocate kernel bo\n", r);
> @@ -617,6 +618,8 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
>   
>   		return 0;
>   	}
> +
> +	bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
>   	amdgpu_ttm_placement_from_domain(bo, domain);
>   	for (i = 0; i < bo->placement.num_placement; i++) {
>   		/* force to pin into visible video ram */
> @@ -854,7 +857,9 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
>   
>   	size = bo->mem.num_pages << PAGE_SHIFT;
>   	offset = bo->mem.start << PAGE_SHIFT;
> -	if ((offset + size) <= adev->mc.visible_vram_size)
> +	/* TODO: figure out how to map scattered VRAM to the CPU */
> +	if ((offset + size) <= adev->mc.visible_vram_size &&
> +	    (abo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR))
>   		return 0;
This is confusing.  Why are you adding the offset to the size to compare 
against the size?  Shouldn't it be size alone?
>   
>   	/* Can't move a pinned BO to visible VRAM */
> @@ -862,6 +867,7 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
>   		return -EINVAL;
>   
>   	/* hurrah the memory is not visible ! */
> +	abo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
>   	amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM);
>   	lpfn =	adev->mc.visible_vram_size >> PAGE_SHIFT;
>   	for (i = 0; i < abo->placement.num_placement; i++) {
> @@ -920,6 +926,8 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
>   	WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM);
>   	WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) &&
>   		     !bo->pin_count);
> +	WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM &&
> +		     !(bo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR));
>   
>   	return bo->tbo.offset;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index e2f6a46..ea480bb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1024,7 +1024,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>   
>   	r = amdgpu_bo_create(adev, 256 * 1024, PAGE_SIZE, true,
>   			     AMDGPU_GEM_DOMAIN_VRAM,
> -			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   			     NULL, NULL, &adev->stollen_vga_memory);
>   	if (r) {
>   		return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> index 5888e8a..5f5380c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> @@ -891,6 +891,10 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)
>   		return -EINVAL;
>   	}
>   
> +	r = amdgpu_cs_make_bos_linear(parser);
> +	if (r)
> +		return r;
> +
>   	ctx.parser = parser;
>   	ctx.buf_sizes = buf_sizes;
>   	ctx.ib_idx = ib_idx;
> @@ -1007,7 +1011,8 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
>   
>   	r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,
>   			     AMDGPU_GEM_DOMAIN_VRAM,
> -			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   			     NULL, NULL, &bo);
>   	if (r)
>   		return r;
> @@ -1056,7 +1061,8 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
>   
>   	r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,
>   			     AMDGPU_GEM_DOMAIN_VRAM,
> -			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   			     NULL, NULL, &bo);
>   	if (r)
>   		return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> index 9b71d6c..bb97a8e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> @@ -157,7 +157,8 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
>   
>   	r = amdgpu_bo_create(adev, size, PAGE_SIZE, true,
>   			     AMDGPU_GEM_DOMAIN_VRAM,
> -			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   			     NULL, NULL, &adev->vce.vcpu_bo);
>   	if (r) {
>   		dev_err(adev->dev, "(%d) failed to allocate VCE bo\n", r);
> @@ -634,7 +635,11 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
>   	uint32_t allocated = 0;
>   	uint32_t tmp, handle = 0;
>   	uint32_t *size = &tmp;
> -	int i, r = 0, idx = 0;
> +	int i, r, idx = 0;
> +
> +	r = amdgpu_cs_make_bos_linear(p);
> +	if (r)
> +		return r;
>   
>   	while (idx < ib->length_dw) {
>   		uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index 7660f82..ea1bd67 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -1398,7 +1398,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
>   				     AMDGPU_GPU_PAGE_SIZE, true,
>   				     AMDGPU_GEM_DOMAIN_VRAM,
>   				     AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
> -				     AMDGPU_GEM_CREATE_SHADOW,
> +				     AMDGPU_GEM_CREATE_SHADOW |
> +				     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   				     NULL, resv, &pt);
>   		if (r)
>   			goto error_free;
> @@ -1598,7 +1599,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
>   	r = amdgpu_bo_create(adev, pd_size, align, true,
>   			     AMDGPU_GEM_DOMAIN_VRAM,
>   			     AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
> -			     AMDGPU_GEM_CREATE_SHADOW,
> +			     AMDGPU_GEM_CREATE_SHADOW |
> +			     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   			     NULL, NULL, &vm->page_directory);
>   	if (r)
>   		goto error_free_sched_entity;
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> index f055d49..1517a8c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> @@ -3213,7 +3213,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
>   		if (adev->gfx.rlc.save_restore_obj == NULL) {
>   			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
>   					     AMDGPU_GEM_DOMAIN_VRAM,
> -					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   					     NULL, NULL,
>   					     &adev->gfx.rlc.save_restore_obj);
>   			if (r) {
> @@ -3257,7 +3258,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
>   		if (adev->gfx.rlc.clear_state_obj == NULL) {
>   			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
>   					     AMDGPU_GEM_DOMAIN_VRAM,
> -					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   					     NULL, NULL,
>   					     &adev->gfx.rlc.clear_state_obj);
>   			if (r) {
> @@ -3297,7 +3299,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
>   		if (adev->gfx.rlc.cp_table_obj == NULL) {
>   			r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,
>   					     AMDGPU_GEM_DOMAIN_VRAM,
> -					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   					     NULL, NULL,
>   					     &adev->gfx.rlc.cp_table_obj);
>   			if (r) {
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> index 6e01392..26e614e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> @@ -1273,7 +1273,8 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
>   		if (adev->gfx.rlc.clear_state_obj == NULL) {
>   			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
>   					     AMDGPU_GEM_DOMAIN_VRAM,
> -					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   					     NULL, NULL,
>   					     &adev->gfx.rlc.clear_state_obj);
>   			if (r) {
> @@ -1315,7 +1316,8 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
>   		if (adev->gfx.rlc.cp_table_obj == NULL) {
>   			r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,
>   					     AMDGPU_GEM_DOMAIN_VRAM,
> -					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
> +					     AMDGPU_GEM_CREATE_VRAM_LINEAR,
>   					     NULL, NULL,
>   					     &adev->gfx.rlc.cp_table_obj);
>   			if (r) {
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index 403b676..2aede6a 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -79,6 +79,8 @@
>   #define AMDGPU_GEM_CREATE_VRAM_CLEARED		(1 << 3)
>   /* Flag that create shadow bo(GTT) while allocating vram bo */
>   #define AMDGPU_GEM_CREATE_SHADOW		(1 << 4)
> +/* Flag that allocating the BO should use linear VRAM */
> +#define AMDGPU_GEM_CREATE_VRAM_LINEAR		(1 << 5)
>   
>   struct drm_amdgpu_gem_create_in  {
>   	/** the requested memory size */

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/5] drm/amdgpu: add VRAM manager
       [not found]     ` <1472462424-3052-6-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
  2016-08-29 10:27       ` Edward O'Callaghan
@ 2016-08-30 17:37       ` William Lewis
  1 sibling, 0 replies; 18+ messages in thread
From: William Lewis @ 2016-08-30 17:37 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

s/Destory/Destroy/.


On 08/29/16 04:20, Christian König wrote:
> From: Christian König <christian.koenig@amd.com>
>
> Split VRAM allocations into 4MB blocks.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/Makefile          |   3 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu.h          |   1 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c   |   6 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c      |   4 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.c   |   1 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.h   |   2 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c      |   2 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h      |   2 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 220 +++++++++++++++++++++++++++
>   9 files changed, 239 insertions(+), 2 deletions(-)
>   create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
> index c8d4d7c..ba12d3c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> @@ -29,7 +29,8 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
>   	amdgpu_pm.o atombios_dp.o amdgpu_afmt.o amdgpu_trace_points.o \
>   	atombios_encoders.o amdgpu_sa.o atombios_i2c.o \
>   	amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \
> -	amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o
> +	amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \
> +	amdgpu_vram_mgr.o
>   
>   # add asic specific block
>   amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index b2d95a9..7e3d341 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -96,6 +96,7 @@ extern unsigned amdgpu_cg_mask;
>   extern unsigned amdgpu_pg_mask;
>   extern int amdgpu_sclk_deep_sleep_en;
>   extern char *amdgpu_virtual_display;
> +extern int amdgpu_vram_page_split;
>   
>   #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS	        3000
>   #define AMDGPU_MAX_USEC_TIMEOUT			100000	/* 100 ms */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 38f5315..b2dcc11 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1004,6 +1004,12 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev)
>   			 amdgpu_vm_block_size);
>   		amdgpu_vm_block_size = 9;
>   	}
> +
> +	if (amdgpu_vram_page_split != -1 && amdgpu_vram_page_split < 16) {
> +		dev_warn(adev->dev, "invalid VRAM page split (%d)\n",
> +			 amdgpu_vram_page_split);
> +		amdgpu_vram_page_split = 1024;
> +	}
>   }
>   
>   /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 56c85e6..dcef0b4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -82,6 +82,7 @@ int amdgpu_vm_size = 64;
>   int amdgpu_vm_block_size = -1;
>   int amdgpu_vm_fault_stop = 0;
>   int amdgpu_vm_debug = 0;
> +int amdgpu_vram_page_split = 1024;
>   int amdgpu_exp_hw_support = 0;
>   int amdgpu_dal = -1;
>   int amdgpu_sched_jobs = 32;
> @@ -161,6 +162,9 @@ module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444);
>   MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = enabled)");
>   module_param_named(vm_debug, amdgpu_vm_debug, int, 0644);
>   
> +MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 1024)");
> +module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444);
> +
>   MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))");
>   module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444);
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index 79f6413..d2dab28 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -933,6 +933,7 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
>   		     !bo->pin_count);
>   	WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM &&
>   		     !(bo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR));
> +	WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET);
>   
>   	return bo->tbo.offset;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
> index b6a2739..e498465 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
> @@ -31,6 +31,8 @@
>   #include <drm/amdgpu_drm.h>
>   #include "amdgpu.h"
>   
> +#define AMDGPU_BO_INVALID_OFFSET	LONG_MAX
> +
>   /**
>    * amdgpu_mem_type_to_domain - return domain corresponding to mem_type
>    * @mem_type:	ttm memory type
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index db8638b..9990957 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -164,7 +164,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
>   		break;
>   	case TTM_PL_VRAM:
>   		/* "On-card" video ram */
> -		man->func = &ttm_bo_manager_func;
> +		man->func = &amdgpu_vram_mgr_func;
>   		man->gpu_offset = adev->mc.vram_start;
>   		man->flags = TTM_MEMTYPE_FLAG_FIXED |
>   			     TTM_MEMTYPE_FLAG_MAPPABLE;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> index 72f6bfc..365ce9e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> @@ -65,6 +65,8 @@ struct amdgpu_mman {
>   	struct amdgpu_mman_lru			guard;
>   };
>   
> +extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func;
> +
>   int amdgpu_copy_buffer(struct amdgpu_ring *ring,
>   		       uint64_t src_offset,
>   		       uint64_t dst_offset,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> new file mode 100644
> index 0000000..6c5f3ba
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
> @@ -0,0 +1,220 @@
> +/*
> + * Copyright 2015 Advanced Micro Devices, Inc.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + *
> + * Authors: Christian König
> + */
> +
> +#include <drm/drmP.h>
> +#include "amdgpu.h"
> +
> +struct amdgpu_vram_mgr {
> +	struct drm_mm mm;
> +	spinlock_t lock;
> +};
> +
> +/**
> + * amdgpu_vram_mgr_init - init VRAM manager and DRM MM
> + *
> + * @man: TTM memory type manager
> + * @p_size: maximum size of VRAM
> + *
> + * Allocate and initialize the VRAM manager.
> + */
> +static int amdgpu_vram_mgr_init(struct ttm_mem_type_manager *man,
> +				unsigned long p_size)
> +{
> +	struct amdgpu_vram_mgr *mgr;
> +
> +	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
> +	if (!mgr)
> +		return -ENOMEM;
> +
> +	drm_mm_init(&mgr->mm, 0, p_size);
> +	spin_lock_init(&mgr->lock);
> +	man->priv = mgr;
> +	return 0;
> +}
> +
> +/**
> + * amdgpu_vram_mgr_fini - free and destroy VRAM manager
> + *
> + * @man: TTM memory type manager
> + *
> + * Destory and free the VRAM manager, returns -EBUSY if ranges are still
> + * allocated inside it.
> + */
> +static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man)
> +{
> +	struct amdgpu_vram_mgr *mgr = man->priv;
> +
> +	spin_lock(&mgr->lock);
> +	if (drm_mm_clean(&mgr->mm)) {
> +		drm_mm_takedown(&mgr->mm);
> +		spin_unlock(&mgr->lock);
> +		kfree(mgr);
> +		man->priv = NULL;
> +		return 0;
> +	}
> +	spin_unlock(&mgr->lock);
> +	return -EBUSY;
> +}
> +
> +/**
> + * amdgpu_vram_mgr_new - allocate new ranges
> + *
> + * @man: TTM memory type manager
> + * @tbo: TTM BO we need this range for
> + * @place: placement flags and restrictions
> + * @mem: the resulting mem object
> + *
> + * Allocate VRAM for the given BO.
> + */
> +static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
> +			       struct ttm_buffer_object *tbo,
> +			       const struct ttm_place *place,
> +			       struct ttm_mem_reg *mem)
> +{
> +	struct amdgpu_bo *bo = container_of(tbo, struct amdgpu_bo, tbo);
> +	struct amdgpu_vram_mgr *mgr = man->priv;
> +	struct drm_mm *mm = &mgr->mm;
> +	struct drm_mm_node *nodes;
> +	enum drm_mm_search_flags sflags = DRM_MM_SEARCH_DEFAULT;
> +	enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT;
> +	unsigned long lpfn, num_nodes, pages_per_node, pages_left;
> +	unsigned i;
> +	int r;
> +
> +	lpfn = place->lpfn;
> +	if (!lpfn)
> +		lpfn = man->size;
> +
> +	if (bo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR ||
> +	    amdgpu_vram_page_split == -1) {
> +		pages_per_node = ~0ul;
> +		num_nodes = 1;
> +	} else {
> +		pages_per_node = max((uint32_t)amdgpu_vram_page_split,
> +				     mem->page_alignment);
> +		num_nodes = DIV_ROUND_UP(mem->num_pages, pages_per_node);
> +	}
> +
> +	nodes = kcalloc(num_nodes, sizeof(*nodes), GFP_KERNEL);
> +	if (!nodes)
> +		return -ENOMEM;
> +
> +	if (place->flags & TTM_PL_FLAG_TOPDOWN) {
> +		sflags = DRM_MM_SEARCH_BELOW;
> +		aflags = DRM_MM_CREATE_TOP;
> +	}
> +
> +	pages_left = mem->num_pages;
> +
> +	spin_lock(&mgr->lock);
> +	for (i = 0; i < num_nodes; ++i) {
> +		unsigned long pages = min(pages_left, pages_per_node);
> +		uint32_t alignment = mem->page_alignment;
> +
> +		if (pages == pages_per_node)
> +			alignment = pages_per_node;
> +		else
> +			sflags |= DRM_MM_SEARCH_BEST;
> +
> +		r = drm_mm_insert_node_in_range_generic(mm, &nodes[i], pages,
> +							alignment, 0,
> +							place->fpfn, lpfn,
> +							sflags, aflags);
> +		if (unlikely(r))
> +			goto error;
> +
> +		pages_left -= pages;
> +	}
> +	spin_unlock(&mgr->lock);
> +
> +	mem->start = num_nodes == 1 ? nodes[0].start : AMDGPU_BO_INVALID_OFFSET;
> +	mem->mm_node = nodes;
> +
> +	return 0;
> +
> +error:
> +	while (i--)
> +		drm_mm_remove_node(&nodes[i]);
> +	spin_unlock(&mgr->lock);
> +
> +	kfree(nodes);
> +	return r == -ENOSPC ? 0 : r;
> +}
> +
> +/**
> + * amdgpu_vram_mgr_del - free ranges
> + *
> + * @man: TTM memory type manager
> + * @tbo: TTM BO we need this range for
> + * @place: placement flags and restrictions
> + * @mem: TTM memory object
> + *
> + * Free the allocated VRAM again.
> + */
> +static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,
> +				struct ttm_mem_reg *mem)
> +{
> +	struct amdgpu_vram_mgr *mgr = man->priv;
> +	struct drm_mm_node *nodes = mem->mm_node;
> +	unsigned i, pages = mem->num_pages;
> +
> +	if (!mem->mm_node)
> +		return;
> +
> +	spin_lock(&mgr->lock);
> +	for (i = 0; pages; ++i) {
> +		pages -= nodes[i].size;
> +		drm_mm_remove_node(&nodes[i]);
> +	}
> +	spin_unlock(&mgr->lock);
> +
> +	kfree(mem->mm_node);
> +	mem->mm_node = NULL;
> +}
> +
> +/**
> + * amdgpu_vram_mgr_debug - dump VRAM table
> + *
> + * @man: TTM memory type manager
> + * @prefix: text prefix
> + *
> + * Dump the table content using printk.
> + */
> +static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man,
> +				  const char *prefix)
> +{
> +	struct amdgpu_vram_mgr *mgr = man->priv;
> +
> +	spin_lock(&mgr->lock);
> +	drm_mm_debug_table(&mgr->mm, prefix);
> +	spin_unlock(&mgr->lock);
> +}
> +
> +const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = {
> +	amdgpu_vram_mgr_init,
> +	amdgpu_vram_mgr_fini,
> +	amdgpu_vram_mgr_new,
> +	amdgpu_vram_mgr_del,
> +	amdgpu_vram_mgr_debug
> +};

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/5] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_LINEAR flag v2
       [not found]         ` <BY2PR17MB02955F1C52893FDD92B1D78CC8E00-x8ynOugG3EHUsavx+kKoj3+GY4YGzQ7gvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
@ 2016-08-30 18:42           ` Alex Deucher
  0 siblings, 0 replies; 18+ messages in thread
From: Alex Deucher @ 2016-08-30 18:42 UTC (permalink / raw)
  To: William Lewis; +Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Tue, Aug 30, 2016 at 1:33 PM, William Lewis
<minutemaidpark@hotmail.com> wrote:
> Question inline, probably my lack of understanding of the code.
>
>
> On 08/29/16 04:20, Christian König wrote:
>> From: Christian König <christian.koenig@amd.com>
>>
>> Add a flag noting that a BO must be created using linear VRAM
>> and set this flag on all in kernel users where appropriate.
>>
>> Hopefully I haven't missed anything.
>>
>> v2: add it in a few more places, fix CPU mapping.
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  1 +
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c    |  6 ++++--
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c     | 31 ++++++++++++++++++++++++++++++
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  3 ++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c     |  3 ++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c   |  3 ++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 12 ++++++++++--
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    |  3 ++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c    | 10 ++++++++--
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c    |  9 +++++++--
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c     |  6 ++++--
>>   drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c      |  9 ++++++---
>>   drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c      |  6 ++++--
>>   include/uapi/drm/amdgpu_drm.h              |  2 ++
>>   14 files changed, 85 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> index 545789f..b2d95a9 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> @@ -2499,6 +2499,7 @@ static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { }
>>   struct amdgpu_bo_va_mapping *
>>   amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
>>                      uint64_t addr, struct amdgpu_bo **bo);
>> +int amdgpu_cs_make_bos_linear(struct amdgpu_cs_parser *parser);
>>
>>   #if defined(CONFIG_DRM_AMD_DAL)
>>   int amdgpu_dm_display_resume(struct amdgpu_device *adev );
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
>> index 040993c..c2dfcd3 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
>> @@ -146,7 +146,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device,
>>       switch(type) {
>>       case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB:
>>       case CGS_GPU_MEM_TYPE__VISIBLE_FB:
>> -             flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
>> +             flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                     AMDGPU_GEM_CREATE_VRAM_LINEAR;
>>               domain = AMDGPU_GEM_DOMAIN_VRAM;
>>               if (max_offset > adev->mc.real_vram_size)
>>                       return -EINVAL;
>> @@ -157,7 +158,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device,
>>               break;
>>       case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB:
>>       case CGS_GPU_MEM_TYPE__INVISIBLE_FB:
>> -             flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
>> +             flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
>> +                     AMDGPU_GEM_CREATE_VRAM_LINEAR;
>>               domain = AMDGPU_GEM_DOMAIN_VRAM;
>>               if (adev->mc.visible_vram_size < adev->mc.real_vram_size) {
>>                       place.fpfn =
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> index b0e11ca..108408b 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> @@ -1097,3 +1097,34 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
>>
>>       return NULL;
>>   }
>> +
>> +/**
>> + * amdgpu_cs_make_bos_linear - mark all BOs in this CS as linear
>> + *
>> + * @parser: command submission parser context
>> + *
>> + * Helper for UVD/VCE VM emulation, mark all BOs in this CS as linear.
>> + */
>> +int amdgpu_cs_make_bos_linear(struct amdgpu_cs_parser *parser)
>> +{
>> +     unsigned i;
>> +     int r;
>> +
>> +     if (!parser->bo_list)
>> +             return 0;
>> +
>> +     for (i = 0; i < parser->bo_list->num_entries; i++) {
>> +             struct amdgpu_bo *bo = parser->bo_list->array[i].robj;
>> +
>> +             if (bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR)
>> +                     continue;
>> +
>> +             bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
>> +             amdgpu_ttm_placement_from_domain(bo, bo->allowed_domains);
>> +             r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
>> +             if (unlikely(r))
>> +                     return r;
>> +     }
>> +
>> +     return 0;
>> +}
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> index 1b31a7c..38f5315 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> @@ -256,7 +256,8 @@ static int amdgpu_vram_scratch_init(struct amdgpu_device *adev)
>>       if (adev->vram_scratch.robj == NULL) {
>>               r = amdgpu_bo_create(adev, AMDGPU_GPU_PAGE_SIZE,
>>                                    PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
>> -                                  AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                                  AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                                  AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                                    NULL, NULL, &adev->vram_scratch.robj);
>>               if (r) {
>>                       return r;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
>> index e694c99..efa9b79 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
>> @@ -120,7 +120,8 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
>>       aligned_size = ALIGN(size, PAGE_SIZE);
>>       ret = amdgpu_gem_object_create(adev, aligned_size, 0,
>>                                      AMDGPU_GEM_DOMAIN_VRAM,
>> -                                    AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                                    AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                                    AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                                      true, &gobj);
>>       if (ret) {
>>               printk(KERN_ERR "failed to allocate framebuffer (%d)\n",
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
>> index 0feea34..b5982a9 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
>> @@ -126,7 +126,8 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
>>       if (adev->gart.robj == NULL) {
>>               r = amdgpu_bo_create(adev, adev->gart.table_size,
>>                                    PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
>> -                                  AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                                  AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                                  AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                                    NULL, NULL, &adev->gart.robj);
>>               if (r) {
>>                       return r;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> index b17734e..6f83909 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> @@ -247,7 +247,8 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
>>       int r;
>>
>>       r = amdgpu_bo_create(adev, size, align, true, domain,
>> -                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                          AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                            NULL, NULL, bo_ptr);
>>       if (r) {
>>               dev_err(adev->dev, "(%d) failed to allocate kernel bo\n", r);
>> @@ -617,6 +618,8 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
>>
>>               return 0;
>>       }
>> +
>> +     bo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
>>       amdgpu_ttm_placement_from_domain(bo, domain);
>>       for (i = 0; i < bo->placement.num_placement; i++) {
>>               /* force to pin into visible video ram */
>> @@ -854,7 +857,9 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
>>
>>       size = bo->mem.num_pages << PAGE_SHIFT;
>>       offset = bo->mem.start << PAGE_SHIFT;
>> -     if ((offset + size) <= adev->mc.visible_vram_size)
>> +     /* TODO: figure out how to map scattered VRAM to the CPU */
>> +     if ((offset + size) <= adev->mc.visible_vram_size &&
>> +         (abo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR))
>>               return 0;
> This is confusing.  Why are you adding the offset to the size to compare
> against the size?  Shouldn't it be size alone?

No, you need to add the offset and size.  visible_vram_size is the
size of the cpu visible aperture to vram.  You may have multiple
buffers mapped into that aperture.  Say you have a 200M aperture an
you have a 100M buffer starting at offset 150M.  The buffer would
extend past the end of the aperture by 50M so the last 50M would not
be CPU accessible.

Alex


>>
>>       /* Can't move a pinned BO to visible VRAM */
>> @@ -862,6 +867,7 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
>>               return -EINVAL;
>>
>>       /* hurrah the memory is not visible ! */
>> +     abo->flags |= AMDGPU_GEM_CREATE_VRAM_LINEAR;
>>       amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM);
>>       lpfn =  adev->mc.visible_vram_size >> PAGE_SHIFT;
>>       for (i = 0; i < abo->placement.num_placement; i++) {
>> @@ -920,6 +926,8 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
>>       WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM);
>>       WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) &&
>>                    !bo->pin_count);
>> +     WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM &&
>> +                  !(bo->flags & AMDGPU_GEM_CREATE_VRAM_LINEAR));
>>
>>       return bo->tbo.offset;
>>   }
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index e2f6a46..ea480bb 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -1024,7 +1024,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>
>>       r = amdgpu_bo_create(adev, 256 * 1024, PAGE_SIZE, true,
>>                            AMDGPU_GEM_DOMAIN_VRAM,
>> -                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                          AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                            NULL, NULL, &adev->stollen_vga_memory);
>>       if (r) {
>>               return r;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
>> index 5888e8a..5f5380c 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
>> @@ -891,6 +891,10 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)
>>               return -EINVAL;
>>       }
>>
>> +     r = amdgpu_cs_make_bos_linear(parser);
>> +     if (r)
>> +             return r;
>> +
>>       ctx.parser = parser;
>>       ctx.buf_sizes = buf_sizes;
>>       ctx.ib_idx = ib_idx;
>> @@ -1007,7 +1011,8 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
>>
>>       r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,
>>                            AMDGPU_GEM_DOMAIN_VRAM,
>> -                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                          AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                            NULL, NULL, &bo);
>>       if (r)
>>               return r;
>> @@ -1056,7 +1061,8 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
>>
>>       r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,
>>                            AMDGPU_GEM_DOMAIN_VRAM,
>> -                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                          AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                            NULL, NULL, &bo);
>>       if (r)
>>               return r;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
>> index 9b71d6c..bb97a8e 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
>> @@ -157,7 +157,8 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
>>
>>       r = amdgpu_bo_create(adev, size, PAGE_SIZE, true,
>>                            AMDGPU_GEM_DOMAIN_VRAM,
>> -                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                          AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                            NULL, NULL, &adev->vce.vcpu_bo);
>>       if (r) {
>>               dev_err(adev->dev, "(%d) failed to allocate VCE bo\n", r);
>> @@ -634,7 +635,11 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
>>       uint32_t allocated = 0;
>>       uint32_t tmp, handle = 0;
>>       uint32_t *size = &tmp;
>> -     int i, r = 0, idx = 0;
>> +     int i, r, idx = 0;
>> +
>> +     r = amdgpu_cs_make_bos_linear(p);
>> +     if (r)
>> +             return r;
>>
>>       while (idx < ib->length_dw) {
>>               uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>> index 7660f82..ea1bd67 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>> @@ -1398,7 +1398,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
>>                                    AMDGPU_GPU_PAGE_SIZE, true,
>>                                    AMDGPU_GEM_DOMAIN_VRAM,
>>                                    AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
>> -                                  AMDGPU_GEM_CREATE_SHADOW,
>> +                                  AMDGPU_GEM_CREATE_SHADOW |
>> +                                  AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                                    NULL, resv, &pt);
>>               if (r)
>>                       goto error_free;
>> @@ -1598,7 +1599,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
>>       r = amdgpu_bo_create(adev, pd_size, align, true,
>>                            AMDGPU_GEM_DOMAIN_VRAM,
>>                            AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
>> -                          AMDGPU_GEM_CREATE_SHADOW,
>> +                          AMDGPU_GEM_CREATE_SHADOW |
>> +                          AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                            NULL, NULL, &vm->page_directory);
>>       if (r)
>>               goto error_free_sched_entity;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
>> index f055d49..1517a8c 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
>> @@ -3213,7 +3213,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
>>               if (adev->gfx.rlc.save_restore_obj == NULL) {
>>                       r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
>>                                            AMDGPU_GEM_DOMAIN_VRAM,
>> -                                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                                          AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                                            NULL, NULL,
>>                                            &adev->gfx.rlc.save_restore_obj);
>>                       if (r) {
>> @@ -3257,7 +3258,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
>>               if (adev->gfx.rlc.clear_state_obj == NULL) {
>>                       r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
>>                                            AMDGPU_GEM_DOMAIN_VRAM,
>> -                                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                                          AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                                            NULL, NULL,
>>                                            &adev->gfx.rlc.clear_state_obj);
>>                       if (r) {
>> @@ -3297,7 +3299,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
>>               if (adev->gfx.rlc.cp_table_obj == NULL) {
>>                       r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,
>>                                            AMDGPU_GEM_DOMAIN_VRAM,
>> -                                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                                          AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                                            NULL, NULL,
>>                                            &adev->gfx.rlc.cp_table_obj);
>>                       if (r) {
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
>> index 6e01392..26e614e 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
>> @@ -1273,7 +1273,8 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
>>               if (adev->gfx.rlc.clear_state_obj == NULL) {
>>                       r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
>>                                            AMDGPU_GEM_DOMAIN_VRAM,
>> -                                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                                          AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                                            NULL, NULL,
>>                                            &adev->gfx.rlc.clear_state_obj);
>>                       if (r) {
>> @@ -1315,7 +1316,8 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
>>               if (adev->gfx.rlc.cp_table_obj == NULL) {
>>                       r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,
>>                                            AMDGPU_GEM_DOMAIN_VRAM,
>> -                                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>> +                                          AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>> +                                          AMDGPU_GEM_CREATE_VRAM_LINEAR,
>>                                            NULL, NULL,
>>                                            &adev->gfx.rlc.cp_table_obj);
>>                       if (r) {
>> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
>> index 403b676..2aede6a 100644
>> --- a/include/uapi/drm/amdgpu_drm.h
>> +++ b/include/uapi/drm/amdgpu_drm.h
>> @@ -79,6 +79,8 @@
>>   #define AMDGPU_GEM_CREATE_VRAM_CLEARED              (1 << 3)
>>   /* Flag that create shadow bo(GTT) while allocating vram bo */
>>   #define AMDGPU_GEM_CREATE_SHADOW            (1 << 4)
>> +/* Flag that allocating the BO should use linear VRAM */
>> +#define AMDGPU_GEM_CREATE_VRAM_LINEAR                (1 << 5)
>>
>>   struct drm_amdgpu_gem_create_in  {
>>       /** the requested memory size */
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2016-08-30 18:42 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-29  9:20 Split large VRAM allocations into smaller parts Christian König
     [not found] ` <1472462424-3052-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2016-08-29  9:20   ` [PATCH 1/5] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_LINEAR flag v2 Christian König
     [not found]     ` <1472462424-3052-2-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2016-08-29 11:02       ` Edward O'Callaghan
2016-08-29 13:47       ` Deucher, Alexander
     [not found]         ` <MWHPR12MB1694759D47B2D6579C5D8F5BF7E10-Gy0DoCVfaSW4WA4dJ5YXGAdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2016-08-30  0:57           ` Michel Dänzer
     [not found]             ` <8221ebac-36e1-7a5b-2d02-92db63c4cc24-otUistvHUpPR7s880joybQ@public.gmane.org>
2016-08-30  1:49               ` Flora Cui
2016-08-30  7:44                 ` Christian König
2016-08-30 17:33       ` William Lewis
     [not found]         ` <BY2PR17MB02955F1C52893FDD92B1D78CC8E00-x8ynOugG3EHUsavx+kKoj3+GY4YGzQ7gvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2016-08-30 18:42           ` Alex Deucher
2016-08-29  9:20   ` [PATCH 2/5] drm/amdgpu: use explicit limit for VRAM_LINEAR handling Christian König
     [not found]     ` <1472462424-3052-3-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2016-08-29 10:59       ` Edward O'Callaghan
2016-08-29  9:20   ` [PATCH 3/5] drm/amdgpu: handle multiple MM nodes in the VMs Christian König
     [not found]     ` <1472462424-3052-4-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2016-08-29 22:29       ` Felix Kuehling
2016-08-29  9:20   ` [PATCH 4/5] drm/amdgpu: enable amdgpu_move_blit to handle multiple MM nodes Christian König
     [not found]     ` <1472462424-3052-5-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2016-08-29 22:09       ` Felix Kuehling
2016-08-29  9:20   ` [PATCH 5/5] drm/amdgpu: add VRAM manager Christian König
     [not found]     ` <1472462424-3052-6-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2016-08-29 10:27       ` Edward O'Callaghan
2016-08-30 17:37       ` William Lewis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.