]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
drm/amdgpu: fix concurrent VM flushes on Vega/Navi v2
authorChristian König <christian.koenig@amd.com>
Thu, 22 Apr 2021 11:11:39 +0000 (13:11 +0200)
committerKelsey Skunberg <kelsey.skunberg@canonical.com>
Mon, 24 May 2021 23:46:14 +0000 (17:46 -0600)
BugLink: https://bugs.launchpad.net/bugs/1929455
commit 20a5f5a98e1bb3d40acd97e89299e8c2d22784be upstream.

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: Christian König <christian.koenig@amd.com>
Reviewed-by: James Zhu <James.Zhu@amd.com>
Tested-by: James Zhu <James.Zhu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Kelsey Skunberg <kelsey.skunberg@canonical.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h

index 94b069630db3652009f7003700be3f668e33c5d5..b4971e90b98cfc613506e4729d02f6d3cf8f30cd 100644 (file)
@@ -215,7 +215,11 @@ static int amdgpu_vmid_grab_idle(struct amdgpu_vm *vm,
        /* Check if we have an idle VMID */
        i = 0;
        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])
                        break;
                ++i;
@@ -281,7 +285,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
        if (updates && (*id)->flushed_updates &&
            updates->context == (*id)->flushed_updates->context &&
            !dma_fence_is_later(updates, (*id)->flushed_updates))
-           updates = NULL;
+               updates = NULL;
 
        if ((*id)->owner != vm->immediate.fence_context ||
            job->vm_pd_addr != (*id)->pd_gpu_addr ||
@@ -290,6 +294,10 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
             !dma_fence_is_signaled((*id)->last_flush))) {
                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 */
                (*id)->pd_gpu_addr = 0;
                tmp = amdgpu_sync_peek_fence(&(*id)->active, ring);
@@ -365,12 +373,7 @@ static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
                if (updates && (!flushed || dma_fence_is_later(updates, flushed)))
                        needs_flush = true;
 
-               /* Concurrent flushes are only possible starting with Vega10 and
-                * are broken on Navi10 and Navi14.
-                */
-               if (needs_flush && (adev->asic_type < CHIP_VEGA10 ||
-                                   adev->asic_type == CHIP_NAVI10 ||
-                                   adev->asic_type == CHIP_NAVI14))
+               if (needs_flush && !adev->vm_manager.concurrent_flush)
                        continue;
 
                /* Good, we can use this VMID. Remember this submission as
index 8090c1e7a3bac853a571dd8afb1d55495f878ded..d0bb5198945c9d332322e194c67bb591b28a7432 100644 (file)
@@ -3145,6 +3145,12 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
 {
        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);
 
        adev->vm_manager.fence_context =
index 976a12e5a8b92fcaa1232ae85f9781c1ecb1c462..4e140288159cd5f82295b3d57e57f9167e875796 100644 (file)
@@ -331,6 +331,7 @@ struct amdgpu_vm_manager {
        /* Handling of VMIDs */
        struct amdgpu_vmid_mgr                  id_mgr[AMDGPU_MAX_VMHUBS];
        unsigned int                            first_kfd_vmid;
+       bool                                    concurrent_flush;
 
        /* Handling of VM fences */
        u64                                     fence_context;