Commit 3dc7216c authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/amdgpu: fix concurrent VM flushes on Vega/Navi v2

Starting with Vega the hardware supports concurrent flushes
of VMID which can be used to implement per process VMID
allocation.

But concurrent flushes are mutual exclusive with back to
back VMID allocations, fix this to avoid a VMID used in
two ways at the same time.

v2: don't set ring to NULL
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarJames Zhu <James.Zhu@amd.com>
Tested-by: default avatarJames Zhu <James.Zhu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 42daecfc
...@@ -215,7 +215,11 @@ static int amdgpu_vmid_grab_idle(struct amdgpu_vm *vm, ...@@ -215,7 +215,11 @@ static int amdgpu_vmid_grab_idle(struct amdgpu_vm *vm,
/* Check if we have an idle VMID */ /* Check if we have an idle VMID */
i = 0; i = 0;
list_for_each_entry((*idle), &id_mgr->ids_lru, list) { list_for_each_entry((*idle), &id_mgr->ids_lru, list) {
fences[i] = amdgpu_sync_peek_fence(&(*idle)->active, ring); /* Don't use per engine and per process VMID at the same time */
struct amdgpu_ring *r = adev->vm_manager.concurrent_flush ?
NULL : ring;
fences[i] = amdgpu_sync_peek_fence(&(*idle)->active, r);
if (!fences[i]) if (!fences[i])
break; break;
++i; ++i;
...@@ -281,7 +285,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm, ...@@ -281,7 +285,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
if (updates && (*id)->flushed_updates && if (updates && (*id)->flushed_updates &&
updates->context == (*id)->flushed_updates->context && updates->context == (*id)->flushed_updates->context &&
!dma_fence_is_later(updates, (*id)->flushed_updates)) !dma_fence_is_later(updates, (*id)->flushed_updates))
updates = NULL; updates = NULL;
if ((*id)->owner != vm->immediate.fence_context || if ((*id)->owner != vm->immediate.fence_context ||
job->vm_pd_addr != (*id)->pd_gpu_addr || job->vm_pd_addr != (*id)->pd_gpu_addr ||
...@@ -290,6 +294,10 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm, ...@@ -290,6 +294,10 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
!dma_fence_is_signaled((*id)->last_flush))) { !dma_fence_is_signaled((*id)->last_flush))) {
struct dma_fence *tmp; struct dma_fence *tmp;
/* Don't use per engine and per process VMID at the same time */
if (adev->vm_manager.concurrent_flush)
ring = NULL;
/* to prevent one context starved by another context */ /* to prevent one context starved by another context */
(*id)->pd_gpu_addr = 0; (*id)->pd_gpu_addr = 0;
tmp = amdgpu_sync_peek_fence(&(*id)->active, ring); tmp = amdgpu_sync_peek_fence(&(*id)->active, ring);
...@@ -365,12 +373,7 @@ static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm, ...@@ -365,12 +373,7 @@ static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
if (updates && (!flushed || dma_fence_is_later(updates, flushed))) if (updates && (!flushed || dma_fence_is_later(updates, flushed)))
needs_flush = true; needs_flush = true;
/* Concurrent flushes are only possible starting with Vega10 and if (needs_flush && !adev->vm_manager.concurrent_flush)
* are broken on Navi10 and Navi14.
*/
if (needs_flush && (adev->asic_type < CHIP_VEGA10 ||
adev->asic_type == CHIP_NAVI10 ||
adev->asic_type == CHIP_NAVI14))
continue; continue;
/* Good, we can use this VMID. Remember this submission as /* Good, we can use this VMID. Remember this submission as
......
...@@ -3160,6 +3160,12 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev) ...@@ -3160,6 +3160,12 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
{ {
unsigned i; unsigned i;
/* Concurrent flushes are only possible starting with Vega10 and
* are broken on Navi10 and Navi14.
*/
adev->vm_manager.concurrent_flush = !(adev->asic_type < CHIP_VEGA10 ||
adev->asic_type == CHIP_NAVI10 ||
adev->asic_type == CHIP_NAVI14);
amdgpu_vmid_mgr_init(adev); amdgpu_vmid_mgr_init(adev);
adev->vm_manager.fence_context = adev->vm_manager.fence_context =
......
...@@ -328,6 +328,7 @@ struct amdgpu_vm_manager { ...@@ -328,6 +328,7 @@ struct amdgpu_vm_manager {
/* Handling of VMIDs */ /* Handling of VMIDs */
struct amdgpu_vmid_mgr id_mgr[AMDGPU_MAX_VMHUBS]; struct amdgpu_vmid_mgr id_mgr[AMDGPU_MAX_VMHUBS];
unsigned int first_kfd_vmid; unsigned int first_kfd_vmid;
bool concurrent_flush;
/* Handling of VM fences */ /* Handling of VM fences */
u64 fence_context; u64 fence_context;
......
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