From: Monk Liu Date: Mon, 19 Jun 2017 10:19:41 -0400 Subject: drm/amdgpu:fix gfx fence allocate size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Git-commit: 0915fdbc69f58644f437730fbc9e1f1ab426fe18 Patch-mainline: v4.14-rc1 References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166 1, for sriov, we need 8dw for the gfx fence due to CP behaviour 2, cleanup wrong logic in wptr/rptr wb alloc and free Change-Id: Ifbfed17a4621dae57244942ffac7de1743de0294 Signed-off-by: Monk Liu Signed-off-by: Xiangliang Yu Reviewed-by: Alex Deucher Reviewed-by: Christian König Signed-off-by: Alex Deucher Acked-by: Petr Tesarik --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 32 +++++++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 26 ++++++++++++++++------- 3 files changed, 52 insertions(+), 8 deletions(-) --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1192,7 +1192,9 @@ struct amdgpu_wb { int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb); void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb); int amdgpu_wb_get_64bit(struct amdgpu_device *adev, u32 *wb); +int amdgpu_wb_get_256Bit(struct amdgpu_device *adev, u32 *wb); void amdgpu_wb_free_64bit(struct amdgpu_device *adev, u32 wb); +void amdgpu_wb_free_256bit(struct amdgpu_device *adev, u32 wb); void amdgpu_get_pcie_info(struct amdgpu_device *adev); --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -602,6 +602,21 @@ int amdgpu_wb_get_64bit(struct amdgpu_de } } +int amdgpu_wb_get_256Bit(struct amdgpu_device *adev, u32 *wb) +{ + int i = 0; + unsigned long offset = bitmap_find_next_zero_area_off(adev->wb.used, + adev->wb.num_wb, 0, 8, 63, 0); + if ((offset + 7) < adev->wb.num_wb) { + for (i = 0; i < 8; i++) + __set_bit(offset + i, adev->wb.used); + *wb = offset; + return 0; + } else { + return -EINVAL; + } +} + /** * amdgpu_wb_free - Free a wb entry * @@ -633,6 +648,23 @@ void amdgpu_wb_free_64bit(struct amdgpu_ } /** + * amdgpu_wb_free_256bit - Free a wb entry + * + * @adev: amdgpu_device pointer + * @wb: wb index + * + * Free a wb slot allocated for use by the driver (all asics) + */ +void amdgpu_wb_free_256bit(struct amdgpu_device *adev, u32 wb) +{ + int i = 0; + + if ((wb + 7) < adev->wb.num_wb) + for (i = 0; i < 8; i++) + __clear_bit(wb + i, adev->wb.used); +} + +/** * amdgpu_vram_location - try to find VRAM location * @adev: amdgpu device structure holding all necessary informations * @mc: memory controller structure holding memory informations --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -212,10 +212,19 @@ int amdgpu_ring_init(struct amdgpu_devic } - r = amdgpu_wb_get(adev, &ring->fence_offs); - if (r) { - dev_err(adev->dev, "(%d) ring fence_offs wb alloc failed\n", r); - return r; + if (amdgpu_sriov_vf(adev) && ring->funcs->type == AMDGPU_RING_TYPE_GFX) { + r = amdgpu_wb_get_256Bit(adev, &ring->fence_offs); + if (r) { + dev_err(adev->dev, "(%d) ring fence_offs wb alloc failed\n", r); + return r; + } + + } else { + r = amdgpu_wb_get(adev, &ring->fence_offs); + if (r) { + dev_err(adev->dev, "(%d) ring fence_offs wb alloc failed\n", r); + return r; + } } r = amdgpu_wb_get(adev, &ring->cond_exe_offs); @@ -278,17 +287,18 @@ void amdgpu_ring_fini(struct amdgpu_ring ring->ready = false; if (ring->funcs->support_64bit_ptrs) { - amdgpu_wb_free_64bit(ring->adev, ring->cond_exe_offs); - amdgpu_wb_free_64bit(ring->adev, ring->fence_offs); amdgpu_wb_free_64bit(ring->adev, ring->rptr_offs); amdgpu_wb_free_64bit(ring->adev, ring->wptr_offs); } else { - amdgpu_wb_free(ring->adev, ring->cond_exe_offs); - amdgpu_wb_free(ring->adev, ring->fence_offs); amdgpu_wb_free(ring->adev, ring->rptr_offs); amdgpu_wb_free(ring->adev, ring->wptr_offs); } + amdgpu_wb_free(ring->adev, ring->cond_exe_offs); + if (amdgpu_sriov_vf(ring->adev) && ring->funcs->type == AMDGPU_RING_TYPE_GFX) + amdgpu_wb_free_256bit(ring->adev, ring->fence_offs); + else + amdgpu_wb_free(ring->adev, ring->fence_offs); amdgpu_bo_free_kernel(&ring->ring_obj, &ring->gpu_addr,