aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2009-12-10 11:16:27 -0500
committerDave Airlie <airlied@redhat.com>2009-12-10 23:09:05 -0500
commit09855acb1c2e3779f25317ec9a8ffe1b1784a4a8 (patch)
tree4a96a67c6bc9694036a95aafd4004c9e9b89eadc
parent4361e52ad0372e6fd2240a2207b49a4de1f45ca9 (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>
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c130
-rw-r--r--include/drm/ttm/ttm_bo_api.h63
2 files changed, 87 insertions, 106 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
1005int ttm_buffer_object_validate(struct ttm_buffer_object *bo, 1005int 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}
1043EXPORT_SYMBOL(ttm_buffer_object_validate); 1043EXPORT_SYMBOL(ttm_bo_validate);
1044 1044
1045int 1045int ttm_bo_check_placement(struct ttm_buffer_object *bo,
1046ttm_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
1076int ttm_buffer_object_init(struct ttm_bo_device *bdev, 1080int 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}
1170EXPORT_SYMBOL(ttm_buffer_object_init); 1155EXPORT_SYMBOL(ttm_bo_init);
1171 1156
1172static inline size_t ttm_bo_size(struct ttm_bo_global *glob, 1157static 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
1181int ttm_buffer_object_create(struct ttm_bo_device *bdev, 1166int 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
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
index 4fd498523ce3..81eb9f45883c 100644
--- a/include/drm/ttm/ttm_bo_api.h
+++ b/include/drm/ttm/ttm_bo_api.h
@@ -308,7 +308,7 @@ ttm_bo_reference(struct ttm_buffer_object *bo)
308extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy, 308extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
309 bool interruptible, bool no_wait); 309 bool interruptible, bool no_wait);
310/** 310/**
311 * ttm_buffer_object_validate 311 * ttm_bo_validate
312 * 312 *
313 * @bo: The buffer object. 313 * @bo: The buffer object.
314 * @placement: Proposed placement for the buffer object. 314 * @placement: Proposed placement for the buffer object.
@@ -323,9 +323,9 @@ extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
323 * -EBUSY if no_wait is true and buffer busy. 323 * -EBUSY if no_wait is true and buffer busy.
324 * -ERESTARTSYS if interrupted by a signal. 324 * -ERESTARTSYS if interrupted by a signal.
325 */ 325 */
326extern int ttm_buffer_object_validate(struct ttm_buffer_object *bo, 326extern int ttm_bo_validate(struct ttm_buffer_object *bo,
327 struct ttm_placement *placement, 327 struct ttm_placement *placement,
328 bool interruptible, bool no_wait); 328 bool interruptible, bool no_wait);
329 329
330/** 330/**
331 * ttm_bo_unref 331 * ttm_bo_unref
@@ -362,7 +362,7 @@ ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait);
362extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo); 362extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo);
363 363
364/** 364/**
365 * ttm_buffer_object_init 365 * ttm_bo_init
366 * 366 *
367 * @bdev: Pointer to a ttm_bo_device struct. 367 * @bdev: Pointer to a ttm_bo_device struct.
368 * @bo: Pointer to a ttm_buffer_object to be initialized. 368 * @bo: Pointer to a ttm_buffer_object to be initialized.
@@ -393,17 +393,17 @@ extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo);
393 * -ERESTARTSYS: Interrupted by signal while sleeping waiting for resources. 393 * -ERESTARTSYS: Interrupted by signal while sleeping waiting for resources.
394 */ 394 */
395 395
396extern int ttm_buffer_object_init(struct ttm_bo_device *bdev, 396extern int ttm_bo_init(struct ttm_bo_device *bdev,
397 struct ttm_buffer_object *bo, 397 struct ttm_buffer_object *bo,
398 unsigned long size, 398 unsigned long size,
399 enum ttm_bo_type type, 399 enum ttm_bo_type type,
400 uint32_t flags, 400 struct ttm_placement *placement,
401 uint32_t page_alignment, 401 uint32_t page_alignment,
402 unsigned long buffer_start, 402 unsigned long buffer_start,
403 bool interrubtible, 403 bool interrubtible,
404 struct file *persistant_swap_storage, 404 struct file *persistant_swap_storage,
405 size_t acc_size, 405 size_t acc_size,
406 void (*destroy) (struct ttm_buffer_object *)); 406 void (*destroy) (struct ttm_buffer_object *));
407/** 407/**
408 * ttm_bo_synccpu_object_init 408 * ttm_bo_synccpu_object_init
409 * 409 *
@@ -424,40 +424,37 @@ extern int ttm_buffer_object_init(struct ttm_bo_device *bdev,
424 * GEM user interface. 424 * GEM user interface.
425 * @p_bo: On successful completion *p_bo points to the created object. 425 * @p_bo: On successful completion *p_bo points to the created object.
426 * 426 *
427 * This function allocates a ttm_buffer_object, and then calls 427 * This function allocates a ttm_buffer_object, and then calls ttm_bo_init
428 * ttm_buffer_object_init on that object. 428 * on that object. The destroy function is set to kfree().
429 * The destroy function is set to kfree().
430 * Returns 429 * Returns
431 * -ENOMEM: Out of memory. 430 * -ENOMEM: Out of memory.
432 * -EINVAL: Invalid placement flags. 431 * -EINVAL: Invalid placement flags.
433 * -ERESTARTSYS: Interrupted by signal while waiting for resources. 432 * -ERESTARTSYS: Interrupted by signal while waiting for resources.
434 */ 433 */
435 434
436extern int ttm_buffer_object_create(struct ttm_bo_device *bdev, 435extern int ttm_bo_create(struct ttm_bo_device *bdev,
437 unsigned long size, 436 unsigned long size,
438 enum ttm_bo_type type, 437 enum ttm_bo_type type,
439 uint32_t flags, 438 struct ttm_placement *placement,
440 uint32_t page_alignment, 439 uint32_t page_alignment,
441 unsigned long buffer_start, 440 unsigned long buffer_start,
442 bool interruptible, 441 bool interruptible,
443 struct file *persistant_swap_storage, 442 struct file *persistant_swap_storage,
444 struct ttm_buffer_object **p_bo); 443 struct ttm_buffer_object **p_bo);
445 444
446/** 445/**
447 * ttm_bo_check_placement 446 * ttm_bo_check_placement
448 * 447 *
449 * @bo: the buffer object. 448 * @bo: the buffer object.
450 * @set_flags: placement flags to set. 449 * @placement: placements
451 * @clr_flags: placement flags to clear.
452 * 450 *
453 * Performs minimal validity checking on an intended change of 451 * Performs minimal validity checking on an intended change of
454 * placement flags. 452 * placement flags.
455 * Returns 453 * Returns
456 * -EINVAL: Intended change is invalid or not allowed. 454 * -EINVAL: Intended change is invalid or not allowed.
457 */ 455 */
458
459extern int ttm_bo_check_placement(struct ttm_buffer_object *bo, 456extern int ttm_bo_check_placement(struct ttm_buffer_object *bo,
460 uint32_t set_flags, uint32_t clr_flags); 457 struct ttm_placement *placement);
461 458
462/** 459/**
463 * ttm_bo_init_mm 460 * ttm_bo_init_mm