forked from luck/tmp_suning_uos_patched
drm/amdgpu: fix fundamental suspend/resume issue
Reinitializing the VM manager during suspend/resume is a very very bad idea since all the VMs are still active and kicking. This can lead to random VM faults after resume when new processes become the same client ID assigned. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org
This commit is contained in:
parent
d51aff16e8
commit
b3c85a0fb2
|
@ -672,6 +672,7 @@ void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vmhub,
|
|||
struct amdgpu_vm_id_manager *id_mgr = &adev->vm_manager.id_mgr[vmhub];
|
||||
struct amdgpu_vm_id *id = &id_mgr->ids[vmid];
|
||||
|
||||
atomic64_set(&id->owner, 0);
|
||||
id->gds_base = 0;
|
||||
id->gds_size = 0;
|
||||
id->gws_base = 0;
|
||||
|
@ -680,6 +681,26 @@ void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vmhub,
|
|||
id->oa_size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_reset_all_id - reset VMID to zero
|
||||
*
|
||||
* @adev: amdgpu device structure
|
||||
*
|
||||
* Reset VMID to force flush on next use
|
||||
*/
|
||||
void amdgpu_vm_reset_all_ids(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) {
|
||||
struct amdgpu_vm_id_manager *id_mgr =
|
||||
&adev->vm_manager.id_mgr[i];
|
||||
|
||||
for (j = 1; j < id_mgr->num_ids; ++j)
|
||||
amdgpu_vm_reset_id(adev, i, j);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_bo_find - find the bo_va for a specific vm & bo
|
||||
*
|
||||
|
@ -2270,7 +2291,6 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
|
|||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
|
||||
adev->vm_manager.seqno[i] = 0;
|
||||
|
||||
|
||||
atomic_set(&adev->vm_manager.vm_pte_next_ring, 0);
|
||||
atomic64_set(&adev->vm_manager.client_counter, 0);
|
||||
spin_lock_init(&adev->vm_manager.prt_lock);
|
||||
|
|
|
@ -204,6 +204,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
|||
int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job);
|
||||
void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vmhub,
|
||||
unsigned vmid);
|
||||
void amdgpu_vm_reset_all_ids(struct amdgpu_device *adev);
|
||||
int amdgpu_vm_update_directories(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm);
|
||||
int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
|
||||
|
|
|
@ -950,10 +950,6 @@ static int gmc_v6_0_suspend(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (adev->vm_manager.enabled) {
|
||||
gmc_v6_0_vm_fini(adev);
|
||||
adev->vm_manager.enabled = false;
|
||||
}
|
||||
gmc_v6_0_hw_fini(adev);
|
||||
|
||||
return 0;
|
||||
|
@ -968,16 +964,9 @@ static int gmc_v6_0_resume(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
if (!adev->vm_manager.enabled) {
|
||||
r = gmc_v6_0_vm_init(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "vm manager initialization failed (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
adev->vm_manager.enabled = true;
|
||||
}
|
||||
amdgpu_vm_reset_all_ids(adev);
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool gmc_v6_0_is_idle(void *handle)
|
||||
|
|
|
@ -1117,10 +1117,6 @@ static int gmc_v7_0_suspend(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (adev->vm_manager.enabled) {
|
||||
gmc_v7_0_vm_fini(adev);
|
||||
adev->vm_manager.enabled = false;
|
||||
}
|
||||
gmc_v7_0_hw_fini(adev);
|
||||
|
||||
return 0;
|
||||
|
@ -1135,16 +1131,9 @@ static int gmc_v7_0_resume(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
if (!adev->vm_manager.enabled) {
|
||||
r = gmc_v7_0_vm_init(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "vm manager initialization failed (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
adev->vm_manager.enabled = true;
|
||||
}
|
||||
amdgpu_vm_reset_all_ids(adev);
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool gmc_v7_0_is_idle(void *handle)
|
||||
|
|
|
@ -1209,10 +1209,6 @@ static int gmc_v8_0_suspend(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (adev->vm_manager.enabled) {
|
||||
gmc_v8_0_vm_fini(adev);
|
||||
adev->vm_manager.enabled = false;
|
||||
}
|
||||
gmc_v8_0_hw_fini(adev);
|
||||
|
||||
return 0;
|
||||
|
@ -1227,16 +1223,9 @@ static int gmc_v8_0_resume(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
if (!adev->vm_manager.enabled) {
|
||||
r = gmc_v8_0_vm_init(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "vm manager initialization failed (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
adev->vm_manager.enabled = true;
|
||||
}
|
||||
amdgpu_vm_reset_all_ids(adev);
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool gmc_v8_0_is_idle(void *handle)
|
||||
|
|
|
@ -791,10 +791,6 @@ static int gmc_v9_0_suspend(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (adev->vm_manager.enabled) {
|
||||
gmc_v9_0_vm_fini(adev);
|
||||
adev->vm_manager.enabled = false;
|
||||
}
|
||||
gmc_v9_0_hw_fini(adev);
|
||||
|
||||
return 0;
|
||||
|
@ -809,17 +805,9 @@ static int gmc_v9_0_resume(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
if (!adev->vm_manager.enabled) {
|
||||
r = gmc_v9_0_vm_init(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev,
|
||||
"vm manager initialization failed (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
adev->vm_manager.enabled = true;
|
||||
}
|
||||
amdgpu_vm_reset_all_ids(adev);
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool gmc_v9_0_is_idle(void *handle)
|
||||
|
|
Loading…
Reference in New Issue
Block a user