diff options
author | Jerome Glisse <jglisse@redhat.com> | 2009-12-10 11:16:27 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-12-10 23:09:05 -0500 |
commit | 09855acb1c2e3779f25317ec9a8ffe1b1784a4a8 (patch) | |
tree | 4a96a67c6bc9694036a95aafd4004c9e9b89eadc /drivers/gpu | |
parent | 4361e52ad0372e6fd2240a2207b49a4de1f45ca9 (diff) |
drm/ttm: Convert ttm_buffer_object_init to use ttm_placement
Convert ttm_buffer_object_init to use struct ttm_placement and
rename to ttm_bo_init for consistency with function naming. This
allow to give more complex placement at buffer creation. For
instance you ask to allocate bo into vram first but if there is
not enough vram you can give system as a second possible
placement. It also allow to create buffer in a specific range.
Also rename ttm_buffer_object_validate to ttm_bo_validate.
Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo.c | 130 |
1 files changed, 57 insertions, 73 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index a835b6fe42a1..fae5c158351c 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -1002,9 +1002,9 @@ static int ttm_bo_mem_compat(struct ttm_placement *placement, | |||
1002 | return -1; | 1002 | return -1; |
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | int ttm_buffer_object_validate(struct ttm_buffer_object *bo, | 1005 | int ttm_bo_validate(struct ttm_buffer_object *bo, |
1006 | struct ttm_placement *placement, | 1006 | struct ttm_placement *placement, |
1007 | bool interruptible, bool no_wait) | 1007 | bool interruptible, bool no_wait) |
1008 | { | 1008 | { |
1009 | int ret; | 1009 | int ret; |
1010 | 1010 | ||
@@ -1040,55 +1040,57 @@ int ttm_buffer_object_validate(struct ttm_buffer_object *bo, | |||
1040 | } | 1040 | } |
1041 | return 0; | 1041 | return 0; |
1042 | } | 1042 | } |
1043 | EXPORT_SYMBOL(ttm_buffer_object_validate); | 1043 | EXPORT_SYMBOL(ttm_bo_validate); |
1044 | 1044 | ||
1045 | int | 1045 | int ttm_bo_check_placement(struct ttm_buffer_object *bo, |
1046 | ttm_bo_check_placement(struct ttm_buffer_object *bo, | 1046 | struct ttm_placement *placement) |
1047 | uint32_t set_flags, uint32_t clr_flags) | ||
1048 | { | 1047 | { |
1049 | uint32_t new_mask = set_flags | clr_flags; | 1048 | int i; |
1050 | |||
1051 | if ((bo->type == ttm_bo_type_user) && | ||
1052 | (clr_flags & TTM_PL_FLAG_CACHED)) { | ||
1053 | printk(KERN_ERR TTM_PFX | ||
1054 | "User buffers require cache-coherent memory.\n"); | ||
1055 | return -EINVAL; | ||
1056 | } | ||
1057 | 1049 | ||
1058 | if (!capable(CAP_SYS_ADMIN)) { | 1050 | if (placement->fpfn || placement->lpfn) { |
1059 | if (new_mask & TTM_PL_FLAG_NO_EVICT) { | 1051 | if (bo->mem.num_pages > (placement->lpfn - placement->fpfn)) { |
1060 | printk(KERN_ERR TTM_PFX "Need to be root to modify" | 1052 | printk(KERN_ERR TTM_PFX "Page number range to small " |
1061 | " NO_EVICT status.\n"); | 1053 | "Need %lu pages, range is [%u, %u]\n", |
1054 | bo->mem.num_pages, placement->fpfn, | ||
1055 | placement->lpfn); | ||
1062 | return -EINVAL; | 1056 | return -EINVAL; |
1063 | } | 1057 | } |
1064 | 1058 | } | |
1065 | if ((clr_flags & bo->mem.placement & TTM_PL_MASK_MEMTYPE) && | 1059 | for (i = 0; i < placement->num_placement; i++) { |
1066 | (bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) { | 1060 | if (!capable(CAP_SYS_ADMIN)) { |
1067 | printk(KERN_ERR TTM_PFX | 1061 | if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) { |
1068 | "Incompatible memory specification" | 1062 | printk(KERN_ERR TTM_PFX "Need to be root to " |
1069 | " for NO_EVICT buffer.\n"); | 1063 | "modify NO_EVICT status.\n"); |
1070 | return -EINVAL; | 1064 | return -EINVAL; |
1065 | } | ||
1066 | } | ||
1067 | } | ||
1068 | for (i = 0; i < placement->num_busy_placement; i++) { | ||
1069 | if (!capable(CAP_SYS_ADMIN)) { | ||
1070 | if (placement->busy_placement[i] & TTM_PL_FLAG_NO_EVICT) { | ||
1071 | printk(KERN_ERR TTM_PFX "Need to be root to " | ||
1072 | "modify NO_EVICT status.\n"); | ||
1073 | return -EINVAL; | ||
1074 | } | ||
1071 | } | 1075 | } |
1072 | } | 1076 | } |
1073 | return 0; | 1077 | return 0; |
1074 | } | 1078 | } |
1075 | 1079 | ||
1076 | int ttm_buffer_object_init(struct ttm_bo_device *bdev, | 1080 | int ttm_bo_init(struct ttm_bo_device *bdev, |
1077 | struct ttm_buffer_object *bo, | 1081 | struct ttm_buffer_object *bo, |
1078 | unsigned long size, | 1082 | unsigned long size, |
1079 | enum ttm_bo_type type, | 1083 | enum ttm_bo_type type, |
1080 | uint32_t flags, | 1084 | struct ttm_placement *placement, |
1081 | uint32_t page_alignment, | 1085 | uint32_t page_alignment, |
1082 | unsigned long buffer_start, | 1086 | unsigned long buffer_start, |
1083 | bool interruptible, | 1087 | bool interruptible, |
1084 | struct file *persistant_swap_storage, | 1088 | struct file *persistant_swap_storage, |
1085 | size_t acc_size, | 1089 | size_t acc_size, |
1086 | void (*destroy) (struct ttm_buffer_object *)) | 1090 | void (*destroy) (struct ttm_buffer_object *)) |
1087 | { | 1091 | { |
1088 | int i, c, ret = 0; | 1092 | int ret = 0; |
1089 | unsigned long num_pages; | 1093 | unsigned long num_pages; |
1090 | uint32_t placements[8]; | ||
1091 | struct ttm_placement placement; | ||
1092 | 1094 | ||
1093 | size += buffer_start & ~PAGE_MASK; | 1095 | size += buffer_start & ~PAGE_MASK; |
1094 | num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | 1096 | num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
@@ -1123,38 +1125,21 @@ int ttm_buffer_object_init(struct ttm_bo_device *bdev, | |||
1123 | bo->acc_size = acc_size; | 1125 | bo->acc_size = acc_size; |
1124 | atomic_inc(&bo->glob->bo_count); | 1126 | atomic_inc(&bo->glob->bo_count); |
1125 | 1127 | ||
1126 | ret = ttm_bo_check_placement(bo, flags, 0ULL); | 1128 | ret = ttm_bo_check_placement(bo, placement); |
1127 | if (unlikely(ret != 0)) | 1129 | if (unlikely(ret != 0)) |
1128 | goto out_err; | 1130 | goto out_err; |
1129 | 1131 | ||
1130 | /* | 1132 | /* |
1131 | * If no caching attributes are set, accept any form of caching. | ||
1132 | */ | ||
1133 | |||
1134 | if ((flags & TTM_PL_MASK_CACHING) == 0) | ||
1135 | flags |= TTM_PL_MASK_CACHING; | ||
1136 | |||
1137 | /* | ||
1138 | * For ttm_bo_type_device buffers, allocate | 1133 | * For ttm_bo_type_device buffers, allocate |
1139 | * address space from the device. | 1134 | * address space from the device. |
1140 | */ | 1135 | */ |
1141 | |||
1142 | if (bo->type == ttm_bo_type_device) { | 1136 | if (bo->type == ttm_bo_type_device) { |
1143 | ret = ttm_bo_setup_vm(bo); | 1137 | ret = ttm_bo_setup_vm(bo); |
1144 | if (ret) | 1138 | if (ret) |
1145 | goto out_err; | 1139 | goto out_err; |
1146 | } | 1140 | } |
1147 | 1141 | ||
1148 | placement.fpfn = 0; | 1142 | ret = ttm_bo_validate(bo, placement, interruptible, false); |
1149 | placement.lpfn = 0; | ||
1150 | for (i = 0, c = 0; i <= TTM_PL_PRIV5; i++) | ||
1151 | if (flags & (1 << i)) | ||
1152 | placements[c++] = (flags & ~TTM_PL_MASK_MEM) | (1 << i); | ||
1153 | placement.placement = placements; | ||
1154 | placement.num_placement = c; | ||
1155 | placement.busy_placement = placements; | ||
1156 | placement.num_busy_placement = c; | ||
1157 | ret = ttm_buffer_object_validate(bo, &placement, interruptible, false); | ||
1158 | if (ret) | 1143 | if (ret) |
1159 | goto out_err; | 1144 | goto out_err; |
1160 | 1145 | ||
@@ -1167,7 +1152,7 @@ out_err: | |||
1167 | 1152 | ||
1168 | return ret; | 1153 | return ret; |
1169 | } | 1154 | } |
1170 | EXPORT_SYMBOL(ttm_buffer_object_init); | 1155 | EXPORT_SYMBOL(ttm_bo_init); |
1171 | 1156 | ||
1172 | static inline size_t ttm_bo_size(struct ttm_bo_global *glob, | 1157 | static inline size_t ttm_bo_size(struct ttm_bo_global *glob, |
1173 | unsigned long num_pages) | 1158 | unsigned long num_pages) |
@@ -1178,15 +1163,15 @@ static inline size_t ttm_bo_size(struct ttm_bo_global *glob, | |||
1178 | return glob->ttm_bo_size + 2 * page_array_size; | 1163 | return glob->ttm_bo_size + 2 * page_array_size; |
1179 | } | 1164 | } |
1180 | 1165 | ||
1181 | int ttm_buffer_object_create(struct ttm_bo_device *bdev, | 1166 | int ttm_bo_create(struct ttm_bo_device *bdev, |
1182 | unsigned long size, | 1167 | unsigned long size, |
1183 | enum ttm_bo_type type, | 1168 | enum ttm_bo_type type, |
1184 | uint32_t flags, | 1169 | struct ttm_placement *placement, |
1185 | uint32_t page_alignment, | 1170 | uint32_t page_alignment, |
1186 | unsigned long buffer_start, | 1171 | unsigned long buffer_start, |
1187 | bool interruptible, | 1172 | bool interruptible, |
1188 | struct file *persistant_swap_storage, | 1173 | struct file *persistant_swap_storage, |
1189 | struct ttm_buffer_object **p_bo) | 1174 | struct ttm_buffer_object **p_bo) |
1190 | { | 1175 | { |
1191 | struct ttm_buffer_object *bo; | 1176 | struct ttm_buffer_object *bo; |
1192 | struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; | 1177 | struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; |
@@ -1205,10 +1190,9 @@ int ttm_buffer_object_create(struct ttm_bo_device *bdev, | |||
1205 | return -ENOMEM; | 1190 | return -ENOMEM; |
1206 | } | 1191 | } |
1207 | 1192 | ||
1208 | ret = ttm_buffer_object_init(bdev, bo, size, type, flags, | 1193 | ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment, |
1209 | page_alignment, buffer_start, | 1194 | buffer_start, interruptible, |
1210 | interruptible, | 1195 | persistant_swap_storage, acc_size, NULL); |
1211 | persistant_swap_storage, acc_size, NULL); | ||
1212 | if (likely(ret == 0)) | 1196 | if (likely(ret == 0)) |
1213 | *p_bo = bo; | 1197 | *p_bo = bo; |
1214 | 1198 | ||