Commit ae3e8122 authored by Thomas Hellstrom's avatar Thomas Hellstrom Committed by Dave Airlie

ttm: Fix caching mode selection.

A bug caused a new caching state to be selected on each buffer object
validation regardless of the current caching state.
Moreover, a caching state could be selected that wasn't supported by
the memory type.
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent d1724078
...@@ -655,31 +655,52 @@ static int ttm_bo_mem_force_space(struct ttm_bo_device *bdev, ...@@ -655,31 +655,52 @@ static int ttm_bo_mem_force_space(struct ttm_bo_device *bdev,
return 0; return 0;
} }
static uint32_t ttm_bo_select_caching(struct ttm_mem_type_manager *man,
uint32_t cur_placement,
uint32_t proposed_placement)
{
uint32_t caching = proposed_placement & TTM_PL_MASK_CACHING;
uint32_t result = proposed_placement & ~TTM_PL_MASK_CACHING;
/**
* Keep current caching if possible.
*/
if ((cur_placement & caching) != 0)
result |= (cur_placement & caching);
else if ((man->default_caching & caching) != 0)
result |= man->default_caching;
else if ((TTM_PL_FLAG_CACHED & caching) != 0)
result |= TTM_PL_FLAG_CACHED;
else if ((TTM_PL_FLAG_WC & caching) != 0)
result |= TTM_PL_FLAG_WC;
else if ((TTM_PL_FLAG_UNCACHED & caching) != 0)
result |= TTM_PL_FLAG_UNCACHED;
return result;
}
static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man, static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man,
bool disallow_fixed, bool disallow_fixed,
uint32_t mem_type, uint32_t mem_type,
uint32_t mask, uint32_t *res_mask) uint32_t proposed_placement,
uint32_t *masked_placement)
{ {
uint32_t cur_flags = ttm_bo_type_flags(mem_type); uint32_t cur_flags = ttm_bo_type_flags(mem_type);
if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && disallow_fixed) if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && disallow_fixed)
return false; return false;
if ((cur_flags & mask & TTM_PL_MASK_MEM) == 0) if ((cur_flags & proposed_placement & TTM_PL_MASK_MEM) == 0)
return false; return false;
if ((mask & man->available_caching) == 0) if ((proposed_placement & man->available_caching) == 0)
return false; return false;
if (mask & man->default_caching)
cur_flags |= man->default_caching;
else if (mask & TTM_PL_FLAG_CACHED)
cur_flags |= TTM_PL_FLAG_CACHED;
else if (mask & TTM_PL_FLAG_WC)
cur_flags |= TTM_PL_FLAG_WC;
else
cur_flags |= TTM_PL_FLAG_UNCACHED;
*res_mask = cur_flags; cur_flags |= (proposed_placement & man->available_caching);
*masked_placement = cur_flags;
return true; return true;
} }
...@@ -723,6 +744,9 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, ...@@ -723,6 +744,9 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
if (!type_ok) if (!type_ok)
continue; continue;
cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
cur_flags);
if (mem_type == TTM_PL_SYSTEM) if (mem_type == TTM_PL_SYSTEM)
break; break;
...@@ -779,6 +803,9 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, ...@@ -779,6 +803,9 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
proposed_placement, &cur_flags)) proposed_placement, &cur_flags))
continue; continue;
cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
cur_flags);
ret = ttm_bo_mem_force_space(bdev, mem, mem_type, ret = ttm_bo_mem_force_space(bdev, mem, mem_type,
interruptible, no_wait); interruptible, no_wait);
......
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