Commit 63034aee authored by Thomas Hellstrom's avatar Thomas Hellstrom Committed by Greg Kroah-Hartman

drm/ttm: Fix memory type compatibility check

commit 59c8e663 upstream.

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>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
Cc: Weng Meiling <wengmeiling.weng@huawei.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 465282b3
...@@ -1091,24 +1091,32 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo, ...@@ -1091,24 +1091,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,
...@@ -1117,6 +1125,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, ...@@ -1117,6 +1125,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;
BUG_ON(!atomic_read(&bo->reserved)); BUG_ON(!atomic_read(&bo->reserved));
/* Check that range is valid */ /* Check that range is valid */
...@@ -1127,8 +1136,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, ...@@ -1127,8 +1136,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, no_wait_reserve, no_wait_gpu); ret = ttm_bo_move_buffer(bo, placement, interruptible, no_wait_reserve, no_wait_gpu);
if (ret) if (ret)
return ret; return ret;
...@@ -1137,7 +1145,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, ...@@ -1137,7 +1145,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