aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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