diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2013-10-28 05:02:19 -0400 |
---|---|---|
committer | Thomas Hellstrom <thellstrom@vmware.com> | 2013-11-06 07:36:22 -0500 |
commit | 59c8e66378fb78adbcd05f0d09783dde6fef282b (patch) | |
tree | fbae6a19cbb8c89c166b0cc151c9d5ef3376297a | |
parent | da95c788ef0c645378ffccb7060a0df1a33aee38 (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.c | 32 |
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 | ||
1001 | static int ttm_bo_mem_compat(struct ttm_placement *placement, | 1001 | static 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 | ||
1021 | int ttm_bo_validate(struct ttm_buffer_object *bo, | 1029 | int 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 | /* |