aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2018-02-05 11:38:01 -0500
committerAlex Deucher <alexander.deucher@amd.com>2018-02-19 14:20:18 -0500
commitb3cd285fa68d162a53c2eb4e23bc4fc1ab7d97f6 (patch)
treebe73fc7af2f87e9ebea9e74dd654d5e6295adb77 /drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
parentc633c00bf06779ec6d5e2c01748d4753ede98f8a (diff)
drm/amdgpu: update the PASID mapping only on demand
Updating the PASID is rather heavyweight and shouldn't be done all the time. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c37
1 files changed, 28 insertions, 9 deletions
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_
591 id->oa_base != job->oa_base || 591 id->oa_base != job->oa_base ||
592 id->oa_size != job->oa_size); 592 id->oa_size != job->oa_size);
593 bool vm_flush_needed = job->vm_needs_flush; 593 bool vm_flush_needed = job->vm_needs_flush;
594 bool pasid_mapping_needed = id->pasid != job->pasid ||
595 !id->pasid_mapping ||
596 !dma_fence_is_signaled(id->pasid_mapping);
597 struct dma_fence *fence = NULL;
594 unsigned patch_offset = 0; 598 unsigned patch_offset = 0;
595 int r; 599 int r;
596 600
597 if (amdgpu_vmid_had_gpu_reset(adev, id)) { 601 if (amdgpu_vmid_had_gpu_reset(adev, id)) {
598 gds_switch_needed = true; 602 gds_switch_needed = true;
599 vm_flush_needed = true; 603 vm_flush_needed = true;
604 pasid_mapping_needed = true;
600 } 605 }
601 606
607 gds_switch_needed &= !!ring->funcs->emit_gds_switch;
608 vm_flush_needed &= !!ring->funcs->emit_vm_flush;
609 pasid_mapping_needed &= adev->gmc.gmc_funcs->emit_pasid_mapping &&
610 ring->funcs->emit_wreg;
611
602 if (!vm_flush_needed && !gds_switch_needed && !need_pipe_sync) 612 if (!vm_flush_needed && !gds_switch_needed && !need_pipe_sync)
603 return 0; 613 return 0;
604 614
@@ -608,27 +618,36 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_
608 if (need_pipe_sync) 618 if (need_pipe_sync)
609 amdgpu_ring_emit_pipeline_sync(ring); 619 amdgpu_ring_emit_pipeline_sync(ring);
610 620
611 if (ring->funcs->emit_vm_flush && vm_flush_needed) { 621 if (vm_flush_needed) {
612 struct dma_fence *fence;
613
614 trace_amdgpu_vm_flush(ring, job->vmid, job->vm_pd_addr); 622 trace_amdgpu_vm_flush(ring, job->vmid, job->vm_pd_addr);
615 amdgpu_ring_emit_vm_flush(ring, job->vmid, job->vm_pd_addr); 623 amdgpu_ring_emit_vm_flush(ring, job->vmid, job->vm_pd_addr);
616 if (adev->gmc.gmc_funcs->emit_pasid_mapping && 624 }
617 ring->funcs->emit_wreg)
618 amdgpu_gmc_emit_pasid_mapping(ring, job->vmid,
619 job->pasid);
620 625
626 if (pasid_mapping_needed)
627 amdgpu_gmc_emit_pasid_mapping(ring, job->vmid, job->pasid);
628
629 if (vm_flush_needed || pasid_mapping_needed) {
621 r = amdgpu_fence_emit(ring, &fence); 630 r = amdgpu_fence_emit(ring, &fence);
622 if (r) 631 if (r)
623 return r; 632 return r;
633 }
624 634
635 if (vm_flush_needed) {
625 mutex_lock(&id_mgr->lock); 636 mutex_lock(&id_mgr->lock);
626 dma_fence_put(id->last_flush); 637 dma_fence_put(id->last_flush);
627 id->last_flush = fence; 638 id->last_flush = dma_fence_get(fence);
628 id->current_gpu_reset_count = atomic_read(&adev->gpu_reset_counter); 639 id->current_gpu_reset_count =
640 atomic_read(&adev->gpu_reset_counter);
629 mutex_unlock(&id_mgr->lock); 641 mutex_unlock(&id_mgr->lock);
630 } 642 }
631 643
644 if (pasid_mapping_needed) {
645 id->pasid = job->pasid;
646 dma_fence_put(id->pasid_mapping);
647 id->pasid_mapping = dma_fence_get(fence);
648 }
649 dma_fence_put(fence);
650
632 if (ring->funcs->emit_gds_switch && gds_switch_needed) { 651 if (ring->funcs->emit_gds_switch && gds_switch_needed) {
633 id->gds_base = job->gds_base; 652 id->gds_base = job->gds_base;
634 id->gds_size = job->gds_size; 653 id->gds_size = job->gds_size;