Commit c6105f24 authored by Christian König's avatar Christian König

drm/radeon: remove vm_manager start/suspend

Just restore the page table instead. Addressing three
problem with this change:

1. Calling vm_manager_suspend in the suspend path is
   problematic cause it wants to wait for the VM use
   to end, which in case of a lockup never happens.

2. In case of a locked up memory controller
   unbinding the VM seems to make it even more
   unstable, creating an unrecoverable lockup
   in the end.

3. If we want to backup/restore the leftover ring
   content we must not unbind VMs in between.
Signed-off-by: default avatarChristian König <deathsimple@vodafone.de>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6f72a631
...@@ -1280,9 +1280,11 @@ static int cayman_startup(struct radeon_device *rdev) ...@@ -1280,9 +1280,11 @@ static int cayman_startup(struct radeon_device *rdev)
if (r) if (r)
return r; return r;
r = radeon_vm_manager_start(rdev); r = radeon_vm_manager_init(rdev);
if (r) if (r) {
dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
return r; return r;
}
r = r600_audio_init(rdev); r = r600_audio_init(rdev);
if (r) if (r)
...@@ -1315,7 +1317,6 @@ int cayman_resume(struct radeon_device *rdev) ...@@ -1315,7 +1317,6 @@ int cayman_resume(struct radeon_device *rdev)
int cayman_suspend(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev)
{ {
r600_audio_fini(rdev); r600_audio_fini(rdev);
radeon_vm_manager_suspend(rdev);
cayman_cp_enable(rdev, false); cayman_cp_enable(rdev, false);
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
evergreen_irq_suspend(rdev); evergreen_irq_suspend(rdev);
...@@ -1392,11 +1393,6 @@ int cayman_init(struct radeon_device *rdev) ...@@ -1392,11 +1393,6 @@ int cayman_init(struct radeon_device *rdev)
return r; return r;
rdev->accel_working = true; rdev->accel_working = true;
r = radeon_vm_manager_init(rdev);
if (r) {
dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
}
r = cayman_startup(rdev); r = cayman_startup(rdev);
if (r) { if (r) {
dev_err(rdev->dev, "disabling GPU acceleration\n"); dev_err(rdev->dev, "disabling GPU acceleration\n");
......
...@@ -1759,8 +1759,6 @@ extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size ...@@ -1759,8 +1759,6 @@ extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size
*/ */
int radeon_vm_manager_init(struct radeon_device *rdev); int radeon_vm_manager_init(struct radeon_device *rdev);
void radeon_vm_manager_fini(struct radeon_device *rdev); void radeon_vm_manager_fini(struct radeon_device *rdev);
int radeon_vm_manager_start(struct radeon_device *rdev);
int radeon_vm_manager_suspend(struct radeon_device *rdev);
int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm);
void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm);
int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm); int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm);
......
...@@ -282,27 +282,58 @@ void radeon_gart_fini(struct radeon_device *rdev) ...@@ -282,27 +282,58 @@ void radeon_gart_fini(struct radeon_device *rdev)
* *
* TODO bind a default page at vm initialization for default address * TODO bind a default page at vm initialization for default address
*/ */
int radeon_vm_manager_init(struct radeon_device *rdev) int radeon_vm_manager_init(struct radeon_device *rdev)
{ {
struct radeon_vm *vm;
struct radeon_bo_va *bo_va;
int r; int r;
rdev->vm_manager.enabled = false; if (!rdev->vm_manager.enabled) {
/* mark first vm as always in use, it's the system one */
r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager,
rdev->vm_manager.max_pfn * 8,
RADEON_GEM_DOMAIN_VRAM);
if (r) {
dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
(rdev->vm_manager.max_pfn * 8) >> 10);
return r;
}
/* mark first vm as always in use, it's the system one */ r = rdev->vm_manager.funcs->init(rdev);
r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, if (r)
rdev->vm_manager.max_pfn * 8, return r;
RADEON_GEM_DOMAIN_VRAM);
if (r) { rdev->vm_manager.enabled = true;
dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
(rdev->vm_manager.max_pfn * 8) >> 10); r = radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager);
return r; if (r)
return r;
} }
r = rdev->vm_manager.funcs->init(rdev); /* restore page table */
if (r == 0) list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) {
rdev->vm_manager.enabled = true; if (vm->id == -1)
continue;
return r; list_for_each_entry(bo_va, &vm->va, vm_list) {
struct ttm_mem_reg *mem = NULL;
if (bo_va->valid)
mem = &bo_va->bo->tbo.mem;
bo_va->valid = false;
r = radeon_vm_bo_update_pte(rdev, vm, bo_va->bo, mem);
if (r) {
DRM_ERROR("Failed to update pte for vm %d!\n", vm->id);
}
}
r = rdev->vm_manager.funcs->bind(rdev, vm, vm->id);
if (r) {
DRM_ERROR("Failed to bind vm %d!\n", vm->id);
}
}
return 0;
} }
/* global mutex must be lock */ /* global mutex must be lock */
...@@ -346,27 +377,12 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev, ...@@ -346,27 +377,12 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev,
} }
void radeon_vm_manager_fini(struct radeon_device *rdev) void radeon_vm_manager_fini(struct radeon_device *rdev)
{
if (rdev->vm_manager.sa_manager.bo == NULL)
return;
radeon_vm_manager_suspend(rdev);
rdev->vm_manager.funcs->fini(rdev);
radeon_sa_bo_manager_fini(rdev, &rdev->vm_manager.sa_manager);
rdev->vm_manager.enabled = false;
}
int radeon_vm_manager_start(struct radeon_device *rdev)
{
if (rdev->vm_manager.sa_manager.bo == NULL) {
return -EINVAL;
}
return radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager);
}
int radeon_vm_manager_suspend(struct radeon_device *rdev)
{ {
struct radeon_vm *vm, *tmp; struct radeon_vm *vm, *tmp;
if (!rdev->vm_manager.enabled)
return;
mutex_lock(&rdev->vm_manager.lock); mutex_lock(&rdev->vm_manager.lock);
/* unbind all active vm */ /* unbind all active vm */
list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) { list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) {
...@@ -374,7 +390,10 @@ int radeon_vm_manager_suspend(struct radeon_device *rdev) ...@@ -374,7 +390,10 @@ int radeon_vm_manager_suspend(struct radeon_device *rdev)
} }
rdev->vm_manager.funcs->fini(rdev); rdev->vm_manager.funcs->fini(rdev);
mutex_unlock(&rdev->vm_manager.lock); mutex_unlock(&rdev->vm_manager.lock);
return radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager);
radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager);
radeon_sa_bo_manager_fini(rdev, &rdev->vm_manager.sa_manager);
rdev->vm_manager.enabled = false;
} }
/* global mutex must be locked */ /* global mutex must be locked */
......
...@@ -3777,9 +3777,11 @@ static int si_startup(struct radeon_device *rdev) ...@@ -3777,9 +3777,11 @@ static int si_startup(struct radeon_device *rdev)
return r; return r;
} }
r = radeon_vm_manager_start(rdev); r = radeon_vm_manager_init(rdev);
if (r) if (r) {
dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
return r; return r;
}
return 0; return 0;
} }
...@@ -3809,7 +3811,6 @@ int si_resume(struct radeon_device *rdev) ...@@ -3809,7 +3811,6 @@ int si_resume(struct radeon_device *rdev)
int si_suspend(struct radeon_device *rdev) int si_suspend(struct radeon_device *rdev)
{ {
radeon_vm_manager_suspend(rdev);
si_cp_enable(rdev, false); si_cp_enable(rdev, false);
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
...@@ -3899,11 +3900,6 @@ int si_init(struct radeon_device *rdev) ...@@ -3899,11 +3900,6 @@ int si_init(struct radeon_device *rdev)
return r; return r;
rdev->accel_working = true; rdev->accel_working = true;
r = radeon_vm_manager_init(rdev);
if (r) {
dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
}
r = si_startup(rdev); r = si_startup(rdev);
if (r) { if (r) {
dev_err(rdev->dev, "disabling GPU acceleration\n"); dev_err(rdev->dev, "disabling GPU acceleration\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment