Updating the PASID is rather heavyweight and shouldn't be done all the
time.

Signed-off-by: Christian König <christian.koe...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h |  3 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c  | 37 +++++++++++++++++++++++++--------
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
index 7d2805729c20..6f44734dd35f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
@@ -606,6 +606,7 @@ void amdgpu_vmid_mgr_fini(struct amdgpu_device *adev)
                        amdgpu_sync_free(&id->active);
                        dma_fence_put(id->flushed_updates);
                        dma_fence_put(id->last_flush);
+                       dma_fence_put(id->pasid_mapping);
                }
        }
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
index 20d4eca6cd6a..7625419f0fc2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
@@ -57,6 +57,9 @@ struct amdgpu_vmid {
        uint32_t                gws_size;
        uint32_t                oa_base;
        uint32_t                oa_size;
+
+       unsigned                pasid;
+       struct dma_fence        *pasid_mapping;
 };
 
 struct amdgpu_vmid_mgr {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index afa16a862eaa..0b237e027cab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -591,14 +591,24 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct 
amdgpu_job *job, bool need_
                id->oa_base != job->oa_base ||
                id->oa_size != job->oa_size);
        bool vm_flush_needed = job->vm_needs_flush;
+       bool pasid_mapping_needed = id->pasid != job->pasid ||
+               !id->pasid_mapping ||
+               !dma_fence_is_signaled(id->pasid_mapping);
+       struct dma_fence *fence = NULL;
        unsigned patch_offset = 0;
        int r;
 
        if (amdgpu_vmid_had_gpu_reset(adev, id)) {
                gds_switch_needed = true;
                vm_flush_needed = true;
+               pasid_mapping_needed = true;
        }
 
+       gds_switch_needed &= !!ring->funcs->emit_gds_switch;
+       vm_flush_needed &= !!ring->funcs->emit_vm_flush;
+       pasid_mapping_needed &= adev->gmc.gmc_funcs->emit_pasid_mapping &&
+               ring->funcs->emit_wreg;
+
        if (!vm_flush_needed && !gds_switch_needed && !need_pipe_sync)
                return 0;
 
@@ -608,27 +618,36 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct 
amdgpu_job *job, bool need_
        if (need_pipe_sync)
                amdgpu_ring_emit_pipeline_sync(ring);
 
-       if (ring->funcs->emit_vm_flush && vm_flush_needed) {
-               struct dma_fence *fence;
-
+       if (vm_flush_needed) {
                trace_amdgpu_vm_flush(ring, job->vmid, job->vm_pd_addr);
                amdgpu_ring_emit_vm_flush(ring, job->vmid, job->vm_pd_addr);
-               if (adev->gmc.gmc_funcs->emit_pasid_mapping &&
-                   ring->funcs->emit_wreg)
-                       amdgpu_gmc_emit_pasid_mapping(ring, job->vmid,
-                                                     job->pasid);
+       }
 
+       if (pasid_mapping_needed)
+               amdgpu_gmc_emit_pasid_mapping(ring, job->vmid, job->pasid);
+
+       if (vm_flush_needed || pasid_mapping_needed) {
                r = amdgpu_fence_emit(ring, &fence);
                if (r)
                        return r;
+       }
 
+       if (vm_flush_needed) {
                mutex_lock(&id_mgr->lock);
                dma_fence_put(id->last_flush);
-               id->last_flush = fence;
-               id->current_gpu_reset_count = 
atomic_read(&adev->gpu_reset_counter);
+               id->last_flush = dma_fence_get(fence);
+               id->current_gpu_reset_count =
+                       atomic_read(&adev->gpu_reset_counter);
                mutex_unlock(&id_mgr->lock);
        }
 
+       if (pasid_mapping_needed) {
+               id->pasid = job->pasid;
+               dma_fence_put(id->pasid_mapping);
+               id->pasid_mapping = dma_fence_get(fence);
+       }
+       dma_fence_put(fence);
+
        if (ring->funcs->emit_gds_switch && gds_switch_needed) {
                id->gds_base = job->gds_base;
                id->gds_size = job->gds_size;
-- 
2.14.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to