drm/amdgpu: Fix a bug in amdgpu_fill_buffer()
authorYong Zhao <yong.zhao@amd.com>
Fri, 15 Sep 2017 22:20:37 +0000 (18:20 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 Sep 2017 19:14:21 +0000 (15:14 -0400)
When max_bytes is not 8 bytes aligned and bo size is larger than
max_bytes, the last 8 bytes in a ttm node may be left unchanged.
For example, on pre SDMA 4.0, max_bytes = 0x1fffff, and the bo size
is 0x200000, the problem will happen.

In order to fix the problem, we separately store the max nums of
PTEs/PDEs a single operation can set in amdgpu_vm_pte_funcs
structure, rather than inferring it from bytes limit of SDMA
constant fill, i.e. fill_max_bytes.

Together with the fix, we replace the hard code value "10" in
amdgpu_vm_bo_update_mapping() with the corresponding values from
structure amdgpu_vm_pte_funcs.

Signed-off-by: Yong Zhao <yong.zhao@amd.com>
Reviewed-by: Christian K├Ânig <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/cik_sdma.c
drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
drivers/gpu/drm/amd/amdgpu/si_dma.c

index f085c8c..1bf42a8 100644 (file)
@@ -302,6 +302,13 @@ struct amdgpu_vm_pte_funcs {
        void (*write_pte)(struct amdgpu_ib *ib, uint64_t pe,
                          uint64_t value, unsigned count,
                          uint32_t incr);
+
+       /* maximum nums of PTEs/PDEs in a single operation */
+       uint32_t        set_max_nums_pte_pde;
+
+       /* number of dw to reserve per operation */
+       unsigned        set_pte_pde_num_dw;
+
        /* for linear pte/pde updates without addr mapping */
        void (*set_pte_pde)(struct amdgpu_ib *ib,
                            uint64_t pe,
index ce435db..1086f03 100644 (file)
@@ -1527,8 +1527,8 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
                       struct dma_fence **fence)
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
-       /* max_bytes applies to SDMA_OP_PTEPDE as well as SDMA_OP_CONST_FILL*/
-       uint32_t max_bytes = adev->mman.buffer_funcs->fill_max_bytes;
+       uint32_t max_bytes = 8 *
+                       adev->vm_manager.vm_pte_funcs->set_max_nums_pte_pde;
        struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
 
        struct drm_mm_node *mm_node;
@@ -1560,8 +1560,8 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
                ++mm_node;
        }
 
-       /* 10 double words for each SDMA_OP_PTEPDE cmd */
-       num_dw = num_loops * 10;
+       /* num of dwords for each SDMA_OP_PTEPDE cmd */
+       num_dw = num_loops * adev->vm_manager.vm_pte_funcs->set_pte_pde_num_dw;
 
        /* for IB padding */
        num_dw += 64;
index 6c11332..28d1678 100644 (file)
@@ -1606,10 +1606,11 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
 
        } else {
                /* set page commands needed */
-               ndw += ncmds * 10;
+               ndw += ncmds * adev->vm_manager.vm_pte_funcs->set_pte_pde_num_dw;
 
                /* extra commands for begin/end fragments */
-               ndw += 2 * 10 * adev->vm_manager.fragment_size;
+               ndw += 2 * adev->vm_manager.vm_pte_funcs->set_pte_pde_num_dw
+                               * adev->vm_manager.fragment_size;
 
                params.func = amdgpu_vm_do_set_ptes;
        }
index f508f4d..c64dcd1 100644 (file)
@@ -1389,6 +1389,9 @@ static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev)
 static const struct amdgpu_vm_pte_funcs cik_sdma_vm_pte_funcs = {
        .copy_pte = cik_sdma_vm_copy_pte,
        .write_pte = cik_sdma_vm_write_pte,
+
+       .set_max_nums_pte_pde = 0x1fffff >> 3,
+       .set_pte_pde_num_dw = 10,
        .set_pte_pde = cik_sdma_vm_set_pte_pde,
 };
 
index f2d0710..c05eb74 100644 (file)
@@ -1326,6 +1326,9 @@ static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev)
 static const struct amdgpu_vm_pte_funcs sdma_v2_4_vm_pte_funcs = {
        .copy_pte = sdma_v2_4_vm_copy_pte,
        .write_pte = sdma_v2_4_vm_write_pte,
+
+       .set_max_nums_pte_pde = 0x1fffff >> 3,
+       .set_pte_pde_num_dw = 10,
        .set_pte_pde = sdma_v2_4_vm_set_pte_pde,
 };
 
index 4858c99..2079340 100644 (file)
@@ -1750,6 +1750,10 @@ static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev)
 static const struct amdgpu_vm_pte_funcs sdma_v3_0_vm_pte_funcs = {
        .copy_pte = sdma_v3_0_vm_copy_pte,
        .write_pte = sdma_v3_0_vm_write_pte,
+
+       /* not 0x3fffff due to HW limitation */
+       .set_max_nums_pte_pde = 0x3fffe0 >> 3,
+       .set_pte_pde_num_dw = 10,
        .set_pte_pde = sdma_v3_0_vm_set_pte_pde,
 };
 
index 3524060..2605faf 100644 (file)
@@ -1716,6 +1716,9 @@ static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev)
 static const struct amdgpu_vm_pte_funcs sdma_v4_0_vm_pte_funcs = {
        .copy_pte = sdma_v4_0_vm_copy_pte,
        .write_pte = sdma_v4_0_vm_write_pte,
+
+       .set_max_nums_pte_pde = 0x400000 >> 3,
+       .set_pte_pde_num_dw = 10,
        .set_pte_pde = sdma_v4_0_vm_set_pte_pde,
 };
 
index 112969f..adb6ae7 100644 (file)
@@ -889,6 +889,9 @@ static void si_dma_set_buffer_funcs(struct amdgpu_device *adev)
 static const struct amdgpu_vm_pte_funcs si_dma_vm_pte_funcs = {
        .copy_pte = si_dma_vm_copy_pte,
        .write_pte = si_dma_vm_write_pte,
+
+       .set_max_nums_pte_pde = 0xffff8 >> 3,
+       .set_pte_pde_num_dw = 9,
        .set_pte_pde = si_dma_vm_set_pte_pde,
 };