aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2013-10-28 05:02:19 -0400
committerThomas Hellstrom <thellstrom@vmware.com>2013-11-06 07:36:22 -0500
commit59c8e66378fb78adbcd05f0d09783dde6fef282b (patch)
treefbae6a19cbb8c89c166b0cc151c9d5ef3376297a
parentda95c788ef0c645378ffccb7060a0df1a33aee38 (diff)
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
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 6c1a38f53066..8d5a646ebe6a 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -998,24 +998,32 @@ out_unlock:
998 return ret; 998 return ret;
999} 999}
1000 1000
1001static int ttm_bo_mem_compat(struct ttm_placement *placement, 1001static bool ttm_bo_mem_compat(struct ttm_placement *placement,
1002 struct ttm_mem_reg *mem) 1002 struct ttm_mem_reg *mem,
1003 uint32_t *new_flags)
1003{ 1004{
1004 int i; 1005 int i;
1005 1006
1006 if (mem->mm_node && placement->lpfn != 0 && 1007 if (mem->mm_node && placement->lpfn != 0 &&
1007 (mem->start < placement->fpfn || 1008 (mem->start < placement->fpfn ||
1008 mem->start + mem->num_pages > placement->lpfn)) 1009 mem->start + mem->num_pages > placement->lpfn))
1009 return -1; 1010 return false;
1010 1011
1011 for (i = 0; i < placement->num_placement; i++) { 1012 for (i = 0; i < placement->num_placement; i++) {
1012 if ((placement->placement[i] & mem->placement & 1013 *new_flags = placement->placement[i];
1013 TTM_PL_MASK_CACHING) && 1014 if ((*new_flags & mem->placement & TTM_PL_MASK_CACHING) &&
1014 (placement->placement[i] & mem->placement & 1015 (*new_flags & mem->placement & TTM_PL_MASK_MEM))
1015 TTM_PL_MASK_MEM)) 1016 return true;
1016 return i; 1017 }
1018
1019 for (i = 0; i < placement->num_busy_placement; i++) {
1020 *new_flags = placement->busy_placement[i];
1021 if ((*new_flags & mem->placement & TTM_PL_MASK_CACHING) &&
1022 (*new_flags & mem->placement & TTM_PL_MASK_MEM))
1023 return true;
1017 } 1024 }
1018 return -1; 1025
1026 return false;
1019} 1027}
1020 1028
1021int ttm_bo_validate(struct ttm_buffer_object *bo, 1029int ttm_bo_validate(struct ttm_buffer_object *bo,
@@ -1024,6 +1032,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
1024 bool no_wait_gpu) 1032 bool no_wait_gpu)
1025{ 1033{
1026 int ret; 1034 int ret;
1035 uint32_t new_flags;
1027 1036
1028 lockdep_assert_held(&bo->resv->lock.base); 1037 lockdep_assert_held(&bo->resv->lock.base);
1029 /* Check that range is valid */ 1038 /* Check that range is valid */
@@ -1034,8 +1043,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
1034 /* 1043 /*
1035 * Check whether we need to move buffer. 1044 * Check whether we need to move buffer.
1036 */ 1045 */
1037 ret = ttm_bo_mem_compat(placement, &bo->mem); 1046 if (!ttm_bo_mem_compat(placement, &bo->mem, &new_flags)) {
1038 if (ret < 0) {
1039 ret = ttm_bo_move_buffer(bo, placement, interruptible, 1047 ret = ttm_bo_move_buffer(bo, placement, interruptible,
1040 no_wait_gpu); 1048 no_wait_gpu);
1041 if (ret) 1049 if (ret)
@@ -1045,7 +1053,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
1045 * Use the access and other non-mapping-related flag bits from 1053 * Use the access and other non-mapping-related flag bits from
1046 * the compatible memory placement flags to the active flags 1054 * the compatible memory placement flags to the active flags
1047 */ 1055 */
1048 ttm_flag_masked(&bo->mem.placement, placement->placement[ret], 1056 ttm_flag_masked(&bo->mem.placement, new_flags,
1049 ~TTM_PL_MASK_MEMTYPE); 1057 ~TTM_PL_MASK_MEMTYPE);
1050 } 1058 }
1051 /* 1059 /*