Rev 6104 | Rev 6661 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6104 | Rev 6296 | ||
---|---|---|---|
Line 151... | Line 151... | ||
151 | } |
151 | } |
Line 152... | Line 152... | ||
152 | 152 | ||
153 | void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count, |
153 | void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count, |
154 | bool never_free) |
154 | bool never_free) |
155 | { |
155 | { |
156 | // kref_sub(&bo->list_kref, count, |
156 | kref_sub(&bo->list_kref, count, |
157 | // (never_free) ? ttm_bo_ref_bug : ttm_bo_release_list); |
157 | (never_free) ? ttm_bo_ref_bug : ttm_bo_release_list); |
Line 158... | Line 158... | ||
158 | } |
158 | } |
159 | 159 | ||
160 | void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo) |
160 | void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo) |
Line 696... | Line 696... | ||
696 | 696 | ||
697 | ret = ttm_mem_type_from_place(place, &mem_type); |
697 | ret = ttm_mem_type_from_place(place, &mem_type); |
698 | if (ret) |
698 | if (ret) |
699 | return ret; |
699 | return ret; |
- | 700 | man = &bdev->man[mem_type]; |
|
- | 701 | if (!man->has_type || !man->use_type) |
|
Line 700... | Line 702... | ||
700 | man = &bdev->man[mem_type]; |
702 | continue; |
701 | 703 | ||
Line 702... | Line 704... | ||
702 | type_ok = ttm_bo_mt_compatible(man, mem_type, place, |
704 | type_ok = ttm_bo_mt_compatible(man, mem_type, place, |
703 | &cur_flags); |
705 | &cur_flags); |
Line -... | Line 706... | ||
- | 706 | ||
704 | 707 | if (!type_ok) |
|
705 | if (!type_ok) |
708 | continue; |
706 | continue; |
709 | |
707 | 710 | type_found = true; |
|
708 | cur_flags = ttm_bo_select_caching(man, bo->mem.placement, |
711 | cur_flags = ttm_bo_select_caching(man, bo->mem.placement, |
Line 715... | Line 718... | ||
715 | ~TTM_PL_MASK_MEMTYPE); |
718 | ~TTM_PL_MASK_MEMTYPE); |
Line 716... | Line 719... | ||
716 | 719 | ||
717 | if (mem_type == TTM_PL_SYSTEM) |
720 | if (mem_type == TTM_PL_SYSTEM) |
Line 718... | Line -... | ||
718 | break; |
- | |
719 | - | ||
720 | if (man->has_type && man->use_type) { |
721 | break; |
721 | type_found = true; |
722 | |
722 | ret = (*man->func->get_node)(man, bo, place, mem); |
723 | ret = (*man->func->get_node)(man, bo, place, mem); |
723 | if (unlikely(ret)) |
724 | if (unlikely(ret)) |
724 | return ret; |
725 | return ret; |
725 | } |
726 | |
726 | if (mem->mm_node) |
727 | if (mem->mm_node) |
Line 727... | Line 728... | ||
727 | break; |
728 | break; |
728 | } |
729 | } |
729 | 730 | ||
730 | if ((type_ok && (mem_type == TTM_PL_SYSTEM)) || mem->mm_node) { |
731 | if ((type_ok && (mem_type == TTM_PL_SYSTEM)) || mem->mm_node) { |
731 | mem->mem_type = mem_type; |
732 | mem->mem_type = mem_type; |
Line 732... | Line -... | ||
732 | mem->placement = cur_flags; |
- | |
733 | return 0; |
- | |
734 | } |
- | |
735 | 733 | mem->placement = cur_flags; |
|
736 | if (!type_found) |
734 | return 0; |
Line 737... | Line 735... | ||
737 | return -EINVAL; |
735 | } |
738 | 736 | ||
739 | for (i = 0; i < placement->num_busy_placement; ++i) { |
737 | for (i = 0; i < placement->num_busy_placement; ++i) { |
740 | const struct ttm_place *place = &placement->busy_placement[i]; |
738 | const struct ttm_place *place = &placement->busy_placement[i]; |
741 | 739 | ||
742 | ret = ttm_mem_type_from_place(place, &mem_type); |
740 | ret = ttm_mem_type_from_place(place, &mem_type); |
743 | if (ret) |
741 | if (ret) |
744 | return ret; |
742 | return ret; |
Line -... | Line 743... | ||
- | 743 | man = &bdev->man[mem_type]; |
|
745 | man = &bdev->man[mem_type]; |
744 | if (!man->has_type || !man->use_type) |
746 | if (!man->has_type) |
745 | continue; |
747 | continue; |
746 | if (!ttm_bo_mt_compatible(man, mem_type, place, &cur_flags)) |
748 | if (!ttm_bo_mt_compatible(man, mem_type, place, &cur_flags)) |
747 | continue; |
749 | continue; |
748 | |
Line 771... | Line 770... | ||
771 | return 0; |
770 | return 0; |
772 | } |
771 | } |
773 | if (ret == -ERESTARTSYS) |
772 | if (ret == -ERESTARTSYS) |
774 | has_erestartsys = true; |
773 | has_erestartsys = true; |
775 | } |
774 | } |
- | 775 | ||
- | 776 | if (!type_found) { |
|
776 | ret = (has_erestartsys) ? -ERESTARTSYS : -ENOMEM; |
777 | printk(KERN_ERR TTM_PFX "No compatible memory type found.\n"); |
777 | return ret; |
778 | return -EINVAL; |
- | 779 | } |
|
- | 780 | ||
- | 781 | return (has_erestartsys) ? -ERESTARTSYS : -ENOMEM; |
|
778 | } |
782 | } |
779 | EXPORT_SYMBOL(ttm_bo_mem_space); |
783 | EXPORT_SYMBOL(ttm_bo_mem_space); |
Line 780... | Line 784... | ||
780 | 784 | ||
781 | static int ttm_bo_move_buffer(struct ttm_buffer_object *bo, |
785 | static int ttm_bo_move_buffer(struct ttm_buffer_object *bo, |
Line 1007... | Line 1011... | ||
1007 | size += ttm_round_pot(sizeof(struct ttm_dma_tt)); |
1011 | size += ttm_round_pot(sizeof(struct ttm_dma_tt)); |
1008 | return size; |
1012 | return size; |
1009 | } |
1013 | } |
1010 | EXPORT_SYMBOL(ttm_bo_dma_acc_size); |
1014 | EXPORT_SYMBOL(ttm_bo_dma_acc_size); |
Line -... | Line 1015... | ||
- | 1015 | ||
- | 1016 | int ttm_bo_create(struct ttm_bo_device *bdev, |
|
- | 1017 | unsigned long size, |
|
- | 1018 | enum ttm_bo_type type, |
|
- | 1019 | struct ttm_placement *placement, |
|
- | 1020 | uint32_t page_alignment, |
|
- | 1021 | bool interruptible, |
|
- | 1022 | struct file *persistent_swap_storage, |
|
- | 1023 | struct ttm_buffer_object **p_bo) |
|
- | 1024 | { |
|
- | 1025 | struct ttm_buffer_object *bo; |
|
- | 1026 | size_t acc_size; |
|
- | 1027 | int ret; |
|
- | 1028 | ||
- | 1029 | bo = kzalloc(sizeof(*bo), GFP_KERNEL); |
|
- | 1030 | if (unlikely(bo == NULL)) |
|
- | 1031 | return -ENOMEM; |
|
- | 1032 | ||
- | 1033 | acc_size = ttm_bo_acc_size(bdev, size, sizeof(struct ttm_buffer_object)); |
|
- | 1034 | ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment, |
|
- | 1035 | interruptible, persistent_swap_storage, acc_size, |
|
- | 1036 | NULL, NULL, NULL); |
|
- | 1037 | if (likely(ret == 0)) |
|
- | 1038 | *p_bo = bo; |
|
- | 1039 | ||
- | 1040 | return ret; |
|
- | 1041 | } |
|
- | 1042 | EXPORT_SYMBOL(ttm_bo_create); |
|
- | 1043 | ||
- | 1044 | static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, |
|
- | 1045 | unsigned mem_type, bool allow_errors) |
|
- | 1046 | { |
|
- | 1047 | struct ttm_mem_type_manager *man = &bdev->man[mem_type]; |
|
- | 1048 | struct ttm_bo_global *glob = bdev->glob; |
|
- | 1049 | int ret; |
|
- | 1050 | ||
- | 1051 | /* |
|
- | 1052 | * Can't use standard list traversal since we're unlocking. |
|
- | 1053 | */ |
|
- | 1054 | ||
- | 1055 | spin_lock(&glob->lru_lock); |
|
- | 1056 | while (!list_empty(&man->lru)) { |
|
- | 1057 | spin_unlock(&glob->lru_lock); |
|
- | 1058 | ret = ttm_mem_evict_first(bdev, mem_type, NULL, false, false); |
|
- | 1059 | if (ret) { |
|
- | 1060 | if (allow_errors) { |
|
- | 1061 | return ret; |
|
- | 1062 | } else { |
|
- | 1063 | pr_err("Cleanup eviction failed\n"); |
|
- | 1064 | } |
|
- | 1065 | } |
|
- | 1066 | spin_lock(&glob->lru_lock); |
|
- | 1067 | } |
|
- | 1068 | spin_unlock(&glob->lru_lock); |
|
- | 1069 | return 0; |
|
1011 | 1070 | } |
|
1012 | int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, |
1071 | int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, |
1013 | unsigned long p_size) |
1072 | unsigned long p_size) |
1014 | { |
1073 | { |
1015 | int ret = -EINVAL; |
1074 | int ret = -EINVAL; |
Line 1207... | Line 1266... | ||
1207 | clear_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags); |
1266 | clear_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags); |
1208 | return 0; |
1267 | return 0; |
1209 | } |
1268 | } |
1210 | EXPORT_SYMBOL(ttm_bo_wait);>>><>>>>>><>>>>>>>><>><>><>><>><>=> |
1269 | EXPORT_SYMBOL(ttm_bo_wait); |
Line -... | Line 1270... | ||
- | 1270 | ||
- | 1271 | int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait) |
|
- | 1272 | { |
|
- | 1273 | int ret = 0; |
|
- | 1274 | ||
- | 1275 | /* |
|
- | 1276 | * Using ttm_bo_reserve makes sure the lru lists are updated. |
|
Line -... | Line 1277... | ||
- | 1277 | */ |
|
- | 1278 | ||
- | 1279 | ret = ttm_bo_reserve(bo, true, no_wait, false, NULL); |
|
- | 1280 | if (unlikely(ret != 0)) |
|
- | 1281 | return ret; |
|
- | 1282 | ret = ttm_bo_wait(bo, false, true, no_wait); |
|
- | 1283 | if (likely(ret == 0)) |
|
- | 1284 | atomic_inc(&bo->cpu_writers); |
|
- | 1285 | ttm_bo_unreserve(bo); |
|
- | 1286 | return ret; |
|
- | 1287 | } |
|
- | 1288 | EXPORT_SYMBOL(ttm_bo_synccpu_write_grab); |
|
- | 1289 | ||
- | 1290 | void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo) |
|
- | 1291 | { |
|
- | 1292 | atomic_dec(&bo->cpu_writers); |
|
- | 1293 | } |
|
- | 1294 | int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo) |
|
- | 1295 | { |
|
- | 1296 | int ret; |
|
- | 1297 | ||
- | 1298 | /* |
|
- | 1299 | * In the absense of a wait_unlocked API, |
|
- | 1300 | * Use the bo::wu_mutex to avoid triggering livelocks due to |
|
- | 1301 | * concurrent use of this function. Note that this use of |
|
- | 1302 | * bo::wu_mutex can go away if we change locking order to |
|
- | 1303 | * mmap_sem -> bo::reserve. |
|
- | 1304 | */ |
|
- | 1305 | ret = mutex_lock_interruptible(&bo->wu_mutex); |
|
- | 1306 | if (unlikely(ret != 0)) |
|
- | 1307 | return -ERESTARTSYS; |
|
- | 1308 | if (!ww_mutex_is_locked(&bo->resv->lock)) |
|
- | 1309 | goto out_unlock; |
|
- | 1310 | ret = __ttm_bo_reserve(bo, true, false, false, NULL); |
|
- | 1311 | if (unlikely(ret != 0)) |
|
- | 1312 | goto out_unlock; |
|
- | 1313 | __ttm_bo_unreserve(bo); |
|
- | 1314 | ||
- | 1315 | out_unlock: |
|
- | 1316 | mutex_unlock(&bo->wu_mutex); |