aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_vm.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_vm.c236
1 files changed, 149 insertions, 87 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index dfde266529e2..cde48c42b30a 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -125,41 +125,37 @@ void radeon_vm_manager_fini(struct radeon_device *rdev)
125 * Add the page directory to the list of BOs to 125 * Add the page directory to the list of BOs to
126 * validate for command submission (cayman+). 126 * validate for command submission (cayman+).
127 */ 127 */
128struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, 128struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev,
129 struct radeon_vm *vm, 129 struct radeon_vm *vm,
130 struct list_head *head) 130 struct list_head *head)
131{ 131{
132 struct radeon_cs_reloc *list; 132 struct radeon_bo_list *list;
133 unsigned i, idx; 133 unsigned i, idx;
134 134
135 list = drm_malloc_ab(vm->max_pde_used + 2, 135 list = drm_malloc_ab(vm->max_pde_used + 2,
136 sizeof(struct radeon_cs_reloc)); 136 sizeof(struct radeon_bo_list));
137 if (!list) 137 if (!list)
138 return NULL; 138 return NULL;
139 139
140 /* add the vm page table to the list */ 140 /* add the vm page table to the list */
141 list[0].gobj = NULL;
142 list[0].robj = vm->page_directory; 141 list[0].robj = vm->page_directory;
143 list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM; 142 list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM;
144 list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM; 143 list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
145 list[0].tv.bo = &vm->page_directory->tbo; 144 list[0].tv.bo = &vm->page_directory->tbo;
146 list[0].tv.shared = false; 145 list[0].tv.shared = true;
147 list[0].tiling_flags = 0; 146 list[0].tiling_flags = 0;
148 list[0].handle = 0;
149 list_add(&list[0].tv.head, head); 147 list_add(&list[0].tv.head, head);
150 148
151 for (i = 0, idx = 1; i <= vm->max_pde_used; i++) { 149 for (i = 0, idx = 1; i <= vm->max_pde_used; i++) {
152 if (!vm->page_tables[i].bo) 150 if (!vm->page_tables[i].bo)
153 continue; 151 continue;
154 152
155 list[idx].gobj = NULL;
156 list[idx].robj = vm->page_tables[i].bo; 153 list[idx].robj = vm->page_tables[i].bo;
157 list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM; 154 list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM;
158 list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM; 155 list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
159 list[idx].tv.bo = &list[idx].robj->tbo; 156 list[idx].tv.bo = &list[idx].robj->tbo;
160 list[idx].tv.shared = false; 157 list[idx].tv.shared = true;
161 list[idx].tiling_flags = 0; 158 list[idx].tiling_flags = 0;
162 list[idx].handle = 0;
163 list_add(&list[idx++].tv.head, head); 159 list_add(&list[idx++].tv.head, head);
164 } 160 }
165 161
@@ -182,15 +178,18 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
182 struct radeon_vm *vm, int ring) 178 struct radeon_vm *vm, int ring)
183{ 179{
184 struct radeon_fence *best[RADEON_NUM_RINGS] = {}; 180 struct radeon_fence *best[RADEON_NUM_RINGS] = {};
181 struct radeon_vm_id *vm_id = &vm->ids[ring];
182
185 unsigned choices[2] = {}; 183 unsigned choices[2] = {};
186 unsigned i; 184 unsigned i;
187 185
188 /* check if the id is still valid */ 186 /* check if the id is still valid */
189 if (vm->last_id_use && vm->last_id_use == rdev->vm_manager.active[vm->id]) 187 if (vm_id->id && vm_id->last_id_use &&
188 vm_id->last_id_use == rdev->vm_manager.active[vm_id->id])
190 return NULL; 189 return NULL;
191 190
192 /* we definately need to flush */ 191 /* we definately need to flush */
193 radeon_fence_unref(&vm->last_flush); 192 vm_id->pd_gpu_addr = ~0ll;
194 193
195 /* skip over VMID 0, since it is the system VM */ 194 /* skip over VMID 0, since it is the system VM */
196 for (i = 1; i < rdev->vm_manager.nvm; ++i) { 195 for (i = 1; i < rdev->vm_manager.nvm; ++i) {
@@ -198,8 +197,8 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
198 197
199 if (fence == NULL) { 198 if (fence == NULL) {
200 /* found a free one */ 199 /* found a free one */
201 vm->id = i; 200 vm_id->id = i;
202 trace_radeon_vm_grab_id(vm->id, ring); 201 trace_radeon_vm_grab_id(i, ring);
203 return NULL; 202 return NULL;
204 } 203 }
205 204
@@ -211,8 +210,8 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
211 210
212 for (i = 0; i < 2; ++i) { 211 for (i = 0; i < 2; ++i) {
213 if (choices[i]) { 212 if (choices[i]) {
214 vm->id = choices[i]; 213 vm_id->id = choices[i];
215 trace_radeon_vm_grab_id(vm->id, ring); 214 trace_radeon_vm_grab_id(choices[i], ring);
216 return rdev->vm_manager.active[choices[i]]; 215 return rdev->vm_manager.active[choices[i]];
217 } 216 }
218 } 217 }
@@ -228,6 +227,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
228 * @rdev: radeon_device pointer 227 * @rdev: radeon_device pointer
229 * @vm: vm we want to flush 228 * @vm: vm we want to flush
230 * @ring: ring to use for flush 229 * @ring: ring to use for flush
230 * @updates: last vm update that is waited for
231 * 231 *
232 * Flush the vm (cayman+). 232 * Flush the vm (cayman+).
233 * 233 *
@@ -235,15 +235,21 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
235 */ 235 */
236void radeon_vm_flush(struct radeon_device *rdev, 236void radeon_vm_flush(struct radeon_device *rdev,
237 struct radeon_vm *vm, 237 struct radeon_vm *vm,
238 int ring) 238 int ring, struct radeon_fence *updates)
239{ 239{
240 uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory); 240 uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory);
241 struct radeon_vm_id *vm_id = &vm->ids[ring];
242
243 if (pd_addr != vm_id->pd_gpu_addr || !vm_id->flushed_updates ||
244 radeon_fence_is_earlier(vm_id->flushed_updates, updates)) {
245
246 trace_radeon_vm_flush(pd_addr, ring, vm->ids[ring].id);
247 radeon_fence_unref(&vm_id->flushed_updates);
248 vm_id->flushed_updates = radeon_fence_ref(updates);
249 vm_id->pd_gpu_addr = pd_addr;
250 radeon_ring_vm_flush(rdev, &rdev->ring[ring],
251 vm_id->id, vm_id->pd_gpu_addr);
241 252
242 /* if we can't remember our last VM flush then flush now! */
243 if (!vm->last_flush || pd_addr != vm->pd_gpu_addr) {
244 trace_radeon_vm_flush(pd_addr, ring, vm->id);
245 vm->pd_gpu_addr = pd_addr;
246 radeon_ring_vm_flush(rdev, ring, vm);
247 } 253 }
248} 254}
249 255
@@ -263,18 +269,13 @@ void radeon_vm_fence(struct radeon_device *rdev,
263 struct radeon_vm *vm, 269 struct radeon_vm *vm,
264 struct radeon_fence *fence) 270 struct radeon_fence *fence)
265{ 271{
266 radeon_fence_unref(&vm->fence); 272 unsigned vm_id = vm->ids[fence->ring].id;
267 vm->fence = radeon_fence_ref(fence);
268
269 radeon_fence_unref(&rdev->vm_manager.active[vm->id]);
270 rdev->vm_manager.active[vm->id] = radeon_fence_ref(fence);
271 273
272 radeon_fence_unref(&vm->last_id_use); 274 radeon_fence_unref(&rdev->vm_manager.active[vm_id]);
273 vm->last_id_use = radeon_fence_ref(fence); 275 rdev->vm_manager.active[vm_id] = radeon_fence_ref(fence);
274 276
275 /* we just flushed the VM, remember that */ 277 radeon_fence_unref(&vm->ids[fence->ring].last_id_use);
276 if (!vm->last_flush) 278 vm->ids[fence->ring].last_id_use = radeon_fence_ref(fence);
277 vm->last_flush = radeon_fence_ref(fence);
278} 279}
279 280
280/** 281/**
@@ -387,35 +388,25 @@ static void radeon_vm_set_pages(struct radeon_device *rdev,
387static int radeon_vm_clear_bo(struct radeon_device *rdev, 388static int radeon_vm_clear_bo(struct radeon_device *rdev,
388 struct radeon_bo *bo) 389 struct radeon_bo *bo)
389{ 390{
390 struct ttm_validate_buffer tv;
391 struct ww_acquire_ctx ticket;
392 struct list_head head;
393 struct radeon_ib ib; 391 struct radeon_ib ib;
394 unsigned entries; 392 unsigned entries;
395 uint64_t addr; 393 uint64_t addr;
396 int r; 394 int r;
397 395
398 memset(&tv, 0, sizeof(tv)); 396 r = radeon_bo_reserve(bo, false);
399 tv.bo = &bo->tbo; 397 if (r)
400 tv.shared = false;
401
402 INIT_LIST_HEAD(&head);
403 list_add(&tv.head, &head);
404
405 r = ttm_eu_reserve_buffers(&ticket, &head, true);
406 if (r)
407 return r; 398 return r;
408 399
409 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); 400 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
410 if (r) 401 if (r)
411 goto error; 402 goto error_unreserve;
412 403
413 addr = radeon_bo_gpu_offset(bo); 404 addr = radeon_bo_gpu_offset(bo);
414 entries = radeon_bo_size(bo) / 8; 405 entries = radeon_bo_size(bo) / 8;
415 406
416 r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, 256); 407 r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, 256);
417 if (r) 408 if (r)
418 goto error; 409 goto error_unreserve;
419 410
420 ib.length_dw = 0; 411 ib.length_dw = 0;
421 412
@@ -425,15 +416,16 @@ static int radeon_vm_clear_bo(struct radeon_device *rdev,
425 416
426 r = radeon_ib_schedule(rdev, &ib, NULL, false); 417 r = radeon_ib_schedule(rdev, &ib, NULL, false);
427 if (r) 418 if (r)
428 goto error; 419 goto error_free;
429 420
430 ttm_eu_fence_buffer_objects(&ticket, &head, &ib.fence->base); 421 ib.fence->is_vm_update = true;
431 radeon_ib_free(rdev, &ib); 422 radeon_bo_fence(bo, ib.fence, false);
432 423
433 return 0; 424error_free:
425 radeon_ib_free(rdev, &ib);
434 426
435error: 427error_unreserve:
436 ttm_eu_backoff_reservation(&ticket, &head); 428 radeon_bo_unreserve(bo);
437 return r; 429 return r;
438} 430}
439 431
@@ -449,7 +441,7 @@ error:
449 * Validate and set the offset requested within the vm address space. 441 * Validate and set the offset requested within the vm address space.
450 * Returns 0 for success, error for failure. 442 * Returns 0 for success, error for failure.
451 * 443 *
452 * Object has to be reserved! 444 * Object has to be reserved and gets unreserved by this function!
453 */ 445 */
454int radeon_vm_bo_set_addr(struct radeon_device *rdev, 446int radeon_vm_bo_set_addr(struct radeon_device *rdev,
455 struct radeon_bo_va *bo_va, 447 struct radeon_bo_va *bo_va,
@@ -495,7 +487,9 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev,
495 tmp->vm = vm; 487 tmp->vm = vm;
496 tmp->addr = bo_va->addr; 488 tmp->addr = bo_va->addr;
497 tmp->bo = radeon_bo_ref(bo_va->bo); 489 tmp->bo = radeon_bo_ref(bo_va->bo);
490 spin_lock(&vm->status_lock);
498 list_add(&tmp->vm_status, &vm->freed); 491 list_add(&tmp->vm_status, &vm->freed);
492 spin_unlock(&vm->status_lock);
499 } 493 }
500 494
501 interval_tree_remove(&bo_va->it, &vm->va); 495 interval_tree_remove(&bo_va->it, &vm->va);
@@ -575,7 +569,7 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev,
575 } 569 }
576 570
577 mutex_unlock(&vm->mutex); 571 mutex_unlock(&vm->mutex);
578 return radeon_bo_reserve(bo_va->bo, false); 572 return 0;
579} 573}
580 574
581/** 575/**
@@ -699,17 +693,15 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
699 if (ib.length_dw != 0) { 693 if (ib.length_dw != 0) {
700 radeon_asic_vm_pad_ib(rdev, &ib); 694 radeon_asic_vm_pad_ib(rdev, &ib);
701 695
702 radeon_semaphore_sync_resv(rdev, ib.semaphore, pd->tbo.resv, false); 696 radeon_sync_resv(rdev, &ib.sync, pd->tbo.resv, true);
703 radeon_semaphore_sync_fence(ib.semaphore, vm->last_id_use);
704 WARN_ON(ib.length_dw > ndw); 697 WARN_ON(ib.length_dw > ndw);
705 r = radeon_ib_schedule(rdev, &ib, NULL, false); 698 r = radeon_ib_schedule(rdev, &ib, NULL, false);
706 if (r) { 699 if (r) {
707 radeon_ib_free(rdev, &ib); 700 radeon_ib_free(rdev, &ib);
708 return r; 701 return r;
709 } 702 }
710 radeon_fence_unref(&vm->fence); 703 ib.fence->is_vm_update = true;
711 vm->fence = radeon_fence_ref(ib.fence); 704 radeon_bo_fence(pd, ib.fence, false);
712 radeon_fence_unref(&vm->last_flush);
713 } 705 }
714 radeon_ib_free(rdev, &ib); 706 radeon_ib_free(rdev, &ib);
715 707
@@ -808,11 +800,11 @@ static void radeon_vm_frag_ptes(struct radeon_device *rdev,
808 * 800 *
809 * Global and local mutex must be locked! 801 * Global and local mutex must be locked!
810 */ 802 */
811static void radeon_vm_update_ptes(struct radeon_device *rdev, 803static int radeon_vm_update_ptes(struct radeon_device *rdev,
812 struct radeon_vm *vm, 804 struct radeon_vm *vm,
813 struct radeon_ib *ib, 805 struct radeon_ib *ib,
814 uint64_t start, uint64_t end, 806 uint64_t start, uint64_t end,
815 uint64_t dst, uint32_t flags) 807 uint64_t dst, uint32_t flags)
816{ 808{
817 uint64_t mask = RADEON_VM_PTE_COUNT - 1; 809 uint64_t mask = RADEON_VM_PTE_COUNT - 1;
818 uint64_t last_pte = ~0, last_dst = ~0; 810 uint64_t last_pte = ~0, last_dst = ~0;
@@ -825,8 +817,12 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
825 struct radeon_bo *pt = vm->page_tables[pt_idx].bo; 817 struct radeon_bo *pt = vm->page_tables[pt_idx].bo;
826 unsigned nptes; 818 unsigned nptes;
827 uint64_t pte; 819 uint64_t pte;
820 int r;
828 821
829 radeon_semaphore_sync_resv(rdev, ib->semaphore, pt->tbo.resv, false); 822 radeon_sync_resv(rdev, &ib->sync, pt->tbo.resv, true);
823 r = reservation_object_reserve_shared(pt->tbo.resv);
824 if (r)
825 return r;
830 826
831 if ((addr & ~mask) == (end & ~mask)) 827 if ((addr & ~mask) == (end & ~mask))
832 nptes = end - addr; 828 nptes = end - addr;
@@ -860,6 +856,33 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
860 last_pte + 8 * count, 856 last_pte + 8 * count,
861 last_dst, flags); 857 last_dst, flags);
862 } 858 }
859
860 return 0;
861}
862
863/**
864 * radeon_vm_fence_pts - fence page tables after an update
865 *
866 * @vm: requested vm
867 * @start: start of GPU address range
868 * @end: end of GPU address range
869 * @fence: fence to use
870 *
871 * Fence the page tables in the range @start - @end (cayman+).
872 *
873 * Global and local mutex must be locked!
874 */
875static void radeon_vm_fence_pts(struct radeon_vm *vm,
876 uint64_t start, uint64_t end,
877 struct radeon_fence *fence)
878{
879 unsigned i;
880
881 start >>= radeon_vm_block_size;
882 end >>= radeon_vm_block_size;
883
884 for (i = start; i <= end; ++i)
885 radeon_bo_fence(vm->page_tables[i].bo, fence, true);
863} 886}
864 887
865/** 888/**
@@ -892,7 +915,9 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
892 return -EINVAL; 915 return -EINVAL;
893 } 916 }
894 917
918 spin_lock(&vm->status_lock);
895 list_del_init(&bo_va->vm_status); 919 list_del_init(&bo_va->vm_status);
920 spin_unlock(&vm->status_lock);
896 921
897 bo_va->flags &= ~RADEON_VM_PAGE_VALID; 922 bo_va->flags &= ~RADEON_VM_PAGE_VALID;
898 bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; 923 bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM;
@@ -961,23 +986,34 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
961 return r; 986 return r;
962 ib.length_dw = 0; 987 ib.length_dw = 0;
963 988
964 radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start, 989 if (!(bo_va->flags & RADEON_VM_PAGE_VALID)) {
965 bo_va->it.last + 1, addr, 990 unsigned i;
966 radeon_vm_page_flags(bo_va->flags)); 991
992 for (i = 0; i < RADEON_NUM_RINGS; ++i)
993 radeon_sync_fence(&ib.sync, vm->ids[i].last_id_use);
994 }
995
996 r = radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start,
997 bo_va->it.last + 1, addr,
998 radeon_vm_page_flags(bo_va->flags));
999 if (r) {
1000 radeon_ib_free(rdev, &ib);
1001 return r;
1002 }
967 1003
968 radeon_asic_vm_pad_ib(rdev, &ib); 1004 radeon_asic_vm_pad_ib(rdev, &ib);
969 WARN_ON(ib.length_dw > ndw); 1005 WARN_ON(ib.length_dw > ndw);
970 1006
971 radeon_semaphore_sync_fence(ib.semaphore, vm->fence);
972 r = radeon_ib_schedule(rdev, &ib, NULL, false); 1007 r = radeon_ib_schedule(rdev, &ib, NULL, false);
973 if (r) { 1008 if (r) {
974 radeon_ib_free(rdev, &ib); 1009 radeon_ib_free(rdev, &ib);
975 return r; 1010 return r;
976 } 1011 }
977 radeon_fence_unref(&vm->fence); 1012 ib.fence->is_vm_update = true;
978 vm->fence = radeon_fence_ref(ib.fence); 1013 radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.last + 1, ib.fence);
1014 radeon_fence_unref(&bo_va->last_pt_update);
1015 bo_va->last_pt_update = radeon_fence_ref(ib.fence);
979 radeon_ib_free(rdev, &ib); 1016 radeon_ib_free(rdev, &ib);
980 radeon_fence_unref(&vm->last_flush);
981 1017
982 return 0; 1018 return 0;
983} 1019}
@@ -996,16 +1032,25 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
996int radeon_vm_clear_freed(struct radeon_device *rdev, 1032int radeon_vm_clear_freed(struct radeon_device *rdev,
997 struct radeon_vm *vm) 1033 struct radeon_vm *vm)
998{ 1034{
999 struct radeon_bo_va *bo_va, *tmp; 1035 struct radeon_bo_va *bo_va;
1000 int r; 1036 int r;
1001 1037
1002 list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { 1038 spin_lock(&vm->status_lock);
1039 while (!list_empty(&vm->freed)) {
1040 bo_va = list_first_entry(&vm->freed,
1041 struct radeon_bo_va, vm_status);
1042 spin_unlock(&vm->status_lock);
1043
1003 r = radeon_vm_bo_update(rdev, bo_va, NULL); 1044 r = radeon_vm_bo_update(rdev, bo_va, NULL);
1004 radeon_bo_unref(&bo_va->bo); 1045 radeon_bo_unref(&bo_va->bo);
1046 radeon_fence_unref(&bo_va->last_pt_update);
1005 kfree(bo_va); 1047 kfree(bo_va);
1006 if (r) 1048 if (r)
1007 return r; 1049 return r;
1050
1051 spin_lock(&vm->status_lock);
1008 } 1052 }
1053 spin_unlock(&vm->status_lock);
1009 return 0; 1054 return 0;
1010 1055
1011} 1056}
@@ -1024,14 +1069,23 @@ int radeon_vm_clear_freed(struct radeon_device *rdev,
1024int radeon_vm_clear_invalids(struct radeon_device *rdev, 1069int radeon_vm_clear_invalids(struct radeon_device *rdev,
1025 struct radeon_vm *vm) 1070 struct radeon_vm *vm)
1026{ 1071{
1027 struct radeon_bo_va *bo_va, *tmp; 1072 struct radeon_bo_va *bo_va;
1028 int r; 1073 int r;
1029 1074
1030 list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, vm_status) { 1075 spin_lock(&vm->status_lock);
1076 while (!list_empty(&vm->invalidated)) {
1077 bo_va = list_first_entry(&vm->invalidated,
1078 struct radeon_bo_va, vm_status);
1079 spin_unlock(&vm->status_lock);
1080
1031 r = radeon_vm_bo_update(rdev, bo_va, NULL); 1081 r = radeon_vm_bo_update(rdev, bo_va, NULL);
1032 if (r) 1082 if (r)
1033 return r; 1083 return r;
1084
1085 spin_lock(&vm->status_lock);
1034 } 1086 }
1087 spin_unlock(&vm->status_lock);
1088
1035 return 0; 1089 return 0;
1036} 1090}
1037 1091
@@ -1054,14 +1108,17 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev,
1054 1108
1055 mutex_lock(&vm->mutex); 1109 mutex_lock(&vm->mutex);
1056 interval_tree_remove(&bo_va->it, &vm->va); 1110 interval_tree_remove(&bo_va->it, &vm->va);
1111 spin_lock(&vm->status_lock);
1057 list_del(&bo_va->vm_status); 1112 list_del(&bo_va->vm_status);
1058 1113
1059 if (bo_va->addr) { 1114 if (bo_va->addr) {
1060 bo_va->bo = radeon_bo_ref(bo_va->bo); 1115 bo_va->bo = radeon_bo_ref(bo_va->bo);
1061 list_add(&bo_va->vm_status, &vm->freed); 1116 list_add(&bo_va->vm_status, &vm->freed);
1062 } else { 1117 } else {
1118 radeon_fence_unref(&bo_va->last_pt_update);
1063 kfree(bo_va); 1119 kfree(bo_va);
1064 } 1120 }
1121 spin_unlock(&vm->status_lock);
1065 1122
1066 mutex_unlock(&vm->mutex); 1123 mutex_unlock(&vm->mutex);
1067} 1124}
@@ -1082,10 +1139,10 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev,
1082 1139
1083 list_for_each_entry(bo_va, &bo->va, bo_list) { 1140 list_for_each_entry(bo_va, &bo->va, bo_list) {
1084 if (bo_va->addr) { 1141 if (bo_va->addr) {
1085 mutex_lock(&bo_va->vm->mutex); 1142 spin_lock(&bo_va->vm->status_lock);
1086 list_del(&bo_va->vm_status); 1143 list_del(&bo_va->vm_status);
1087 list_add(&bo_va->vm_status, &bo_va->vm->invalidated); 1144 list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
1088 mutex_unlock(&bo_va->vm->mutex); 1145 spin_unlock(&bo_va->vm->status_lock);
1089 } 1146 }
1090 } 1147 }
1091} 1148}
@@ -1103,15 +1160,17 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
1103 const unsigned align = min(RADEON_VM_PTB_ALIGN_SIZE, 1160 const unsigned align = min(RADEON_VM_PTB_ALIGN_SIZE,
1104 RADEON_VM_PTE_COUNT * 8); 1161 RADEON_VM_PTE_COUNT * 8);
1105 unsigned pd_size, pd_entries, pts_size; 1162 unsigned pd_size, pd_entries, pts_size;
1106 int r; 1163 int i, r;
1107 1164
1108 vm->id = 0;
1109 vm->ib_bo_va = NULL; 1165 vm->ib_bo_va = NULL;
1110 vm->fence = NULL; 1166 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
1111 vm->last_flush = NULL; 1167 vm->ids[i].id = 0;
1112 vm->last_id_use = NULL; 1168 vm->ids[i].flushed_updates = NULL;
1169 vm->ids[i].last_id_use = NULL;
1170 }
1113 mutex_init(&vm->mutex); 1171 mutex_init(&vm->mutex);
1114 vm->va = RB_ROOT; 1172 vm->va = RB_ROOT;
1173 spin_lock_init(&vm->status_lock);
1115 INIT_LIST_HEAD(&vm->invalidated); 1174 INIT_LIST_HEAD(&vm->invalidated);
1116 INIT_LIST_HEAD(&vm->freed); 1175 INIT_LIST_HEAD(&vm->freed);
1117 1176
@@ -1165,11 +1224,13 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
1165 if (!r) { 1224 if (!r) {
1166 list_del_init(&bo_va->bo_list); 1225 list_del_init(&bo_va->bo_list);
1167 radeon_bo_unreserve(bo_va->bo); 1226 radeon_bo_unreserve(bo_va->bo);
1227 radeon_fence_unref(&bo_va->last_pt_update);
1168 kfree(bo_va); 1228 kfree(bo_va);
1169 } 1229 }
1170 } 1230 }
1171 list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { 1231 list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) {
1172 radeon_bo_unref(&bo_va->bo); 1232 radeon_bo_unref(&bo_va->bo);
1233 radeon_fence_unref(&bo_va->last_pt_update);
1173 kfree(bo_va); 1234 kfree(bo_va);
1174 } 1235 }
1175 1236
@@ -1179,9 +1240,10 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
1179 1240
1180 radeon_bo_unref(&vm->page_directory); 1241 radeon_bo_unref(&vm->page_directory);
1181 1242
1182 radeon_fence_unref(&vm->fence); 1243 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
1183 radeon_fence_unref(&vm->last_flush); 1244 radeon_fence_unref(&vm->ids[i].flushed_updates);
1184 radeon_fence_unref(&vm->last_id_use); 1245 radeon_fence_unref(&vm->ids[i].last_id_use);
1246 }
1185 1247
1186 mutex_destroy(&vm->mutex); 1248 mutex_destroy(&vm->mutex);
1187} 1249}