aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_gart.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_gart.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index 79db56e6c2ac..84b648a7ddd8 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -289,8 +289,9 @@ int radeon_vm_manager_init(struct radeon_device *rdev)
289 rdev->vm_manager.enabled = false; 289 rdev->vm_manager.enabled = false;
290 290
291 /* mark first vm as always in use, it's the system one */ 291 /* mark first vm as always in use, it's the system one */
292 /* allocate enough for 2 full VM pts */
292 r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, 293 r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager,
293 rdev->vm_manager.max_pfn * 8, 294 rdev->vm_manager.max_pfn * 8 * 2,
294 RADEON_GEM_DOMAIN_VRAM); 295 RADEON_GEM_DOMAIN_VRAM);
295 if (r) { 296 if (r) {
296 dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", 297 dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
@@ -476,12 +477,18 @@ int radeon_vm_bo_add(struct radeon_device *rdev,
476 477
477 mutex_lock(&vm->mutex); 478 mutex_lock(&vm->mutex);
478 if (last_pfn > vm->last_pfn) { 479 if (last_pfn > vm->last_pfn) {
479 /* grow va space 32M by 32M */ 480 /* release mutex and lock in right order */
480 unsigned align = ((32 << 20) >> 12) - 1; 481 mutex_unlock(&vm->mutex);
481 radeon_mutex_lock(&rdev->cs_mutex); 482 radeon_mutex_lock(&rdev->cs_mutex);
482 radeon_vm_unbind_locked(rdev, vm); 483 mutex_lock(&vm->mutex);
484 /* and check again */
485 if (last_pfn > vm->last_pfn) {
486 /* grow va space 32M by 32M */
487 unsigned align = ((32 << 20) >> 12) - 1;
488 radeon_vm_unbind_locked(rdev, vm);
489 vm->last_pfn = (last_pfn + align) & ~align;
490 }
483 radeon_mutex_unlock(&rdev->cs_mutex); 491 radeon_mutex_unlock(&rdev->cs_mutex);
484 vm->last_pfn = (last_pfn + align) & ~align;
485 } 492 }
486 head = &vm->va; 493 head = &vm->va;
487 last_offset = 0; 494 last_offset = 0;
@@ -595,8 +602,8 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev,
595 if (bo_va == NULL) 602 if (bo_va == NULL)
596 return 0; 603 return 0;
597 604
598 mutex_lock(&vm->mutex);
599 radeon_mutex_lock(&rdev->cs_mutex); 605 radeon_mutex_lock(&rdev->cs_mutex);
606 mutex_lock(&vm->mutex);
600 radeon_vm_bo_update_pte(rdev, vm, bo, NULL); 607 radeon_vm_bo_update_pte(rdev, vm, bo, NULL);
601 radeon_mutex_unlock(&rdev->cs_mutex); 608 radeon_mutex_unlock(&rdev->cs_mutex);
602 list_del(&bo_va->vm_list); 609 list_del(&bo_va->vm_list);
@@ -627,7 +634,15 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
627 mutex_init(&vm->mutex); 634 mutex_init(&vm->mutex);
628 INIT_LIST_HEAD(&vm->list); 635 INIT_LIST_HEAD(&vm->list);
629 INIT_LIST_HEAD(&vm->va); 636 INIT_LIST_HEAD(&vm->va);
630 vm->last_pfn = 0; 637 /* SI requires equal sized PTs for all VMs, so always set
638 * last_pfn to max_pfn. cayman allows variable sized
639 * pts so we can grow then as needed. Once we switch
640 * to two level pts we can unify this again.
641 */
642 if (rdev->family >= CHIP_TAHITI)
643 vm->last_pfn = rdev->vm_manager.max_pfn;
644 else
645 vm->last_pfn = 0;
631 /* map the ib pool buffer at 0 in virtual address space, set 646 /* map the ib pool buffer at 0 in virtual address space, set
632 * read only 647 * read only
633 */ 648 */
@@ -641,9 +656,8 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
641 struct radeon_bo_va *bo_va, *tmp; 656 struct radeon_bo_va *bo_va, *tmp;
642 int r; 657 int r;
643 658
644 mutex_lock(&vm->mutex);
645
646 radeon_mutex_lock(&rdev->cs_mutex); 659 radeon_mutex_lock(&rdev->cs_mutex);
660 mutex_lock(&vm->mutex);
647 radeon_vm_unbind_locked(rdev, vm); 661 radeon_vm_unbind_locked(rdev, vm);
648 radeon_mutex_unlock(&rdev->cs_mutex); 662 radeon_mutex_unlock(&rdev->cs_mutex);
649 663