Commit 59c8e663 authored by Thomas Hellstrom's avatar Thomas Hellstrom

drm/ttm: Fix memory type compatibility check

Also check the busy placements before deciding to move a buffer object.
Failing to do this may result in a completely unneccessary move within a
single memory type.
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: default avatarJakob Bornecrantz <jakob@vmware.com>
Cc: stable@vger.kernel.org
parent da95c788
...@@ -998,24 +998,32 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo, ...@@ -998,24 +998,32 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
return ret; return ret;
} }
static int ttm_bo_mem_compat(struct ttm_placement *placement, static bool ttm_bo_mem_compat(struct ttm_placement *placement,
struct ttm_mem_reg *mem) struct ttm_mem_reg *mem,
uint32_t *new_flags)
{ {
int i; int i;
if (mem->mm_node && placement->lpfn != 0 && if (mem->mm_node && placement->lpfn != 0 &&
(mem->start < placement->fpfn || (mem->start < placement->fpfn ||
mem->start + mem->num_pages > placement->lpfn)) mem->start + mem->num_pages > placement->lpfn))
return -1; return false;
for (i = 0; i < placement->num_placement; i++) { for (i = 0; i < placement->num_placement; i++) {
if ((placement->placement[i] & mem->placement & *new_flags = placement->placement[i];
TTM_PL_MASK_CACHING) && if ((*new_flags & mem->placement & TTM_PL_MASK_CACHING) &&
(placement->placement[i] & mem->placement & (*new_flags & mem->placement & TTM_PL_MASK_MEM))
TTM_PL_MASK_MEM)) return true;
return i; }
for (i = 0; i < placement->num_busy_placement; i++) {
*new_flags = placement->busy_placement[i];
if ((*new_flags & mem->placement & TTM_PL_MASK_CACHING) &&
(*new_flags & mem->placement & TTM_PL_MASK_MEM))
return true;
} }
return -1;
return false;
} }
int ttm_bo_validate(struct ttm_buffer_object *bo, int ttm_bo_validate(struct ttm_buffer_object *bo,
...@@ -1024,6 +1032,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, ...@@ -1024,6 +1032,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
bool no_wait_gpu) bool no_wait_gpu)
{ {
int ret; int ret;
uint32_t new_flags;
lockdep_assert_held(&bo->resv->lock.base); lockdep_assert_held(&bo->resv->lock.base);
/* Check that range is valid */ /* Check that range is valid */
...@@ -1034,8 +1043,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, ...@@ -1034,8 +1043,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
/* /*
* Check whether we need to move buffer. * Check whether we need to move buffer.
*/ */
ret = ttm_bo_mem_compat(placement, &bo->mem); if (!ttm_bo_mem_compat(placement, &bo->mem, &new_flags)) {
if (ret < 0) {
ret = ttm_bo_move_buffer(bo, placement, interruptible, ret = ttm_bo_move_buffer(bo, placement, interruptible,
no_wait_gpu); no_wait_gpu);
if (ret) if (ret)
...@@ -1045,7 +1053,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, ...@@ -1045,7 +1053,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
* Use the access and other non-mapping-related flag bits from * Use the access and other non-mapping-related flag bits from
* the compatible memory placement flags to the active flags * the compatible memory placement flags to the active flags
*/ */
ttm_flag_masked(&bo->mem.placement, placement->placement[ret], ttm_flag_masked(&bo->mem.placement, new_flags,
~TTM_PL_MASK_MEMTYPE); ~TTM_PL_MASK_MEMTYPE);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment