Skip to content

Commit 84801d4

Browse files
yunxialialexdeucher
authored andcommitted
drm/amdgpu: fix locking scope when flushing tlb
Which method is used to flush tlb does not depend on whether a reset is in progress or not. We should skip flush altogether if the GPU will get reset. So put both path under reset_domain read lock. Signed-off-by: Yunxiang Li <[email protected]> Reviewed-by: Christian König <[email protected]> Signed-off-by: Alex Deucher <[email protected]> CC: [email protected]
1 parent e2654a4 commit 84801d4

File tree

1 file changed

+34
-32
lines changed

1 file changed

+34
-32
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -684,12 +684,17 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid,
684684
struct amdgpu_ring *ring = &adev->gfx.kiq[inst].ring;
685685
struct amdgpu_kiq *kiq = &adev->gfx.kiq[inst];
686686
unsigned int ndw;
687-
signed long r;
687+
int r;
688688
uint32_t seq;
689689

690-
if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready ||
691-
!down_read_trylock(&adev->reset_domain->sem)) {
690+
/*
691+
* A GPU reset should flush all TLBs anyway, so no need to do
692+
* this while one is ongoing.
693+
*/
694+
if (!down_read_trylock(&adev->reset_domain->sem))
695+
return 0;
692696

697+
if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready) {
693698
if (adev->gmc.flush_tlb_needs_extra_type_2)
694699
adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
695700
2, all_hub,
@@ -703,43 +708,40 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid,
703708
adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
704709
flush_type, all_hub,
705710
inst);
706-
return 0;
707-
}
711+
r = 0;
712+
} else {
713+
/* 2 dwords flush + 8 dwords fence */
714+
ndw = kiq->pmf->invalidate_tlbs_size + 8;
708715

709-
/* 2 dwords flush + 8 dwords fence */
710-
ndw = kiq->pmf->invalidate_tlbs_size + 8;
716+
if (adev->gmc.flush_tlb_needs_extra_type_2)
717+
ndw += kiq->pmf->invalidate_tlbs_size;
711718

712-
if (adev->gmc.flush_tlb_needs_extra_type_2)
713-
ndw += kiq->pmf->invalidate_tlbs_size;
719+
if (adev->gmc.flush_tlb_needs_extra_type_0)
720+
ndw += kiq->pmf->invalidate_tlbs_size;
714721

715-
if (adev->gmc.flush_tlb_needs_extra_type_0)
716-
ndw += kiq->pmf->invalidate_tlbs_size;
722+
spin_lock(&adev->gfx.kiq[inst].ring_lock);
723+
amdgpu_ring_alloc(ring, ndw);
724+
if (adev->gmc.flush_tlb_needs_extra_type_2)
725+
kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub);
717726

718-
spin_lock(&adev->gfx.kiq[inst].ring_lock);
719-
amdgpu_ring_alloc(ring, ndw);
720-
if (adev->gmc.flush_tlb_needs_extra_type_2)
721-
kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub);
727+
if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0)
728+
kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub);
722729

723-
if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0)
724-
kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub);
730+
kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub);
731+
r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
732+
if (r) {
733+
amdgpu_ring_undo(ring);
734+
spin_unlock(&adev->gfx.kiq[inst].ring_lock);
735+
goto error_unlock_reset;
736+
}
725737

726-
kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub);
727-
r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
728-
if (r) {
729-
amdgpu_ring_undo(ring);
738+
amdgpu_ring_commit(ring);
730739
spin_unlock(&adev->gfx.kiq[inst].ring_lock);
731-
goto error_unlock_reset;
732-
}
733-
734-
amdgpu_ring_commit(ring);
735-
spin_unlock(&adev->gfx.kiq[inst].ring_lock);
736-
r = amdgpu_fence_wait_polling(ring, seq, usec_timeout);
737-
if (r < 1) {
738-
dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r);
739-
r = -ETIME;
740-
goto error_unlock_reset;
740+
if (amdgpu_fence_wait_polling(ring, seq, usec_timeout) < 1) {
741+
dev_err(adev->dev, "timeout waiting for kiq fence\n");
742+
r = -ETIME;
743+
}
741744
}
742-
r = 0;
743745

744746
error_unlock_reset:
745747
up_read(&adev->reset_domain->sem);

0 commit comments

Comments
 (0)