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: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Jakob Bornecrantz <jakob@vmware.com> Cc: stable@vger.kernel.org
This commit is contained in:
@@ -998,24 +998,32 @@ out_unlock:
|
|||||||
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;
|
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
|
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 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,
|
|||||||
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,
|
|||||||
/*
|
/*
|
||||||
* 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,
|
|||||||
* 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);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user