[PATCH] drm/nv50-: fix tiled memory layout checks

Maarten Lankhorst maarten.lankhorst at canonical.com
Mon Sep 2 07:31:18 PDT 2013


nv50_bo_move_m2mf might copy to tiled gart, in which case linear copy is not appropriate.
---
 drivers/gpu/drm/nouveau/nouveau_bo.c | 42 ++++++++++++++++++++----------------
 1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 88f0c45..0daf3f0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -176,8 +176,8 @@ nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags,
 			*size = roundup(*size, 32 * nvbo->tile_mode);
 		}
 	} else {
-		*size = roundup(*size, (1 << nvbo->page_shift));
-		*align = max((1 <<  nvbo->page_shift), *align);
+		*align = 1 << nvbo->page_shift;
+		*size = roundup(*size, *align);
 	}
 
 	*size = roundup(*size, PAGE_SIZE);
@@ -713,6 +713,8 @@ nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
 	u32 page_count = new_mem->num_pages;
 	int ret, last_count = 0;
 
+	nv_error(chan->drm, "Evicting %#x bytes from %u/%#Lx to %u/%#Lx\n", page_count << PAGE_SHIFT, old_mem->mem_type, src_offset, new_mem->mem_type, dst_offset);
+
 	ret = RING_SPACE(chan, (page_count + 2046) / 2047 * 7 + 2);
 	if (ret)
 		return ret;
@@ -834,19 +836,17 @@ static int
 nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
 		  struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
 {
-	struct nouveau_mem *node = old_mem->mm_node;
+	struct nouveau_mem *old_node = old_mem->mm_node;
+	struct nouveau_mem *new_node = new_mem->mm_node;
 	struct nouveau_bo *nvbo = nouveau_bo(bo);
 	u64 length = (new_mem->num_pages << PAGE_SHIFT);
-	u64 src_offset = node->vma[0].offset;
-	u64 dst_offset = node->vma[1].offset;
+	u64 src_offset = old_node->vma[0].offset;
+	u64 dst_offset = old_node->vma[1].offset;
 	u32 size;
 	int ret;
 
 	size = 18;
-	if (nouveau_bo_tile_layout(nvbo)) {
-		size += 6 * (old_mem->mem_type == TTM_PL_VRAM);
-		size += 6 * (new_mem->mem_type == TTM_PL_VRAM);
-	}
+	size += 6 * (!!old_node->memtype + !!new_node->memtype);
 	size *= (length + (4 * 1024 * 1024) - 1) / (4 * 1024 * 1024);
 	ret = RING_SPACE(chan, size);
 	if (ret)
@@ -859,8 +859,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
 		stride  = 16 * 4;
 		height  = amount / stride;
 
-		if (old_mem->mem_type == TTM_PL_VRAM &&
-		    nouveau_bo_tile_layout(nvbo)) {
+		if (old_node->memtype) {
 			BEGIN_NV04(chan, NvSubCopy, 0x0200, 7);
 			OUT_RING  (chan, 0);
 			OUT_RING  (chan, 0);
@@ -873,8 +872,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
 			BEGIN_NV04(chan, NvSubCopy, 0x0200, 1);
 			OUT_RING  (chan, 1);
 		}
-		if (new_mem->mem_type == TTM_PL_VRAM &&
-		    nouveau_bo_tile_layout(nvbo)) {
+		if (new_node->memtype) {
 			BEGIN_NV04(chan, NvSubCopy, 0x021c, 7);
 			OUT_RING  (chan, 0);
 			OUT_RING  (chan, 0);
@@ -1051,8 +1049,8 @@ nouveau_bo_move_init(struct nouveau_drm *drm)
 	} _methods[] = {
 		{  "COPY", 4, 0xa0b5, nve0_bo_move_copy, nve0_bo_move_init },
 		{  "GRCE", 0, 0xa0b5, nve0_bo_move_copy, nve0_bo_move_init },
-		{ "COPY1", 5, 0x90b8, nvc0_bo_move_copy, nvc0_bo_copy_init },
-		{ "COPY0", 4, 0x90b5, nvc0_bo_move_copy, nvc0_bo_copy_init },
+//		{ "COPY1", 5, 0x90b8, nvc0_bo_move_copy, nvc0_bo_copy_init },
+//		{ "COPY0", 4, 0x90b5, nvc0_bo_move_copy, nvc0_bo_copy_init },
 		{  "COPY", 0, 0x85b5, nva3_bo_move_copy, nv50_bo_move_init },
 		{ "CRYPT", 0, 0x74c1, nv84_bo_move_exec, nv50_bo_move_init },
 		{  "M2MF", 0, 0x9039, nvc0_bo_move_m2mf, nvc0_bo_m2mf_init },
@@ -1166,13 +1164,23 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
 {
 	struct nouveau_bo *nvbo = nouveau_bo(bo);
 	struct nouveau_vma *vma;
+	struct ttm_mem_reg *old_mem = &bo->mem;
 
 	/* ttm can now (stupidly) pass the driver bos it didn't create... */
 	if (bo->destroy != nouveau_bo_del_ttm)
 		return;
 
 	list_for_each_entry(vma, &nvbo->vma_list, head) {
-		if (new_mem && new_mem->mem_type == TTM_PL_VRAM) {
+		if (!new_mem ||
+		    old_mem->mem_type == TTM_PL_VRAM ||
+		    (old_mem->mem_type == TTM_PL_TT &&
+		     nvbo->page_shift == vma->vm->vmm->spg_shift))
+		    nouveau_vm_unmap(vma);
+
+		if (!new_mem)
+			continue;
+
+		if (new_mem->mem_type == TTM_PL_VRAM) {
 			nouveau_vm_map(vma, new_mem->mm_node);
 		} else
 		if (new_mem && new_mem->mem_type == TTM_PL_TT &&
@@ -1185,8 +1193,6 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
 				nouveau_vm_map_sg(vma, 0, new_mem->
 						  num_pages << PAGE_SHIFT,
 						  new_mem->mm_node);
-		} else {
-			nouveau_vm_unmap(vma);
 		}
 	}
 }
-- 
1.8.3.4



More information about the dri-devel mailing list