From: Alex Deucher <[email protected]> Save any unprocessed work in the queues using the new ring helper.
Signed-off-by: Alex Deucher <[email protected]> Reviewed-by: Jesse Zhang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 64 +++++++++++++++---------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 616967519869..e4d435d4a629 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -1485,6 +1485,37 @@ int vcn_set_powergating_state(struct amdgpu_ip_block *ip_block, return ret; } +static struct amdgpu_fence * +amdgpu_vcn_ring_reset_begin_helper(struct amdgpu_ring *ring, + struct amdgpu_ring *guilty_ring, + struct amdgpu_fence *timedout_fence) +{ + struct amdgpu_fence *fence; + + drm_sched_wqueue_stop(&ring->sched); + if (ring == guilty_ring) + fence = timedout_fence; + else + fence = amdgpu_ring_find_guilty_fence(ring); + amdgpu_ring_reset_helper_begin(ring, fence); + + return fence; +} + +static int +amdgpu_vcn_ring_reset_end_helper(struct amdgpu_ring *ring, + struct amdgpu_fence *fence) +{ + int r; + + r = amdgpu_ring_reset_helper_end(ring, fence); + if (r) + return r; + + drm_sched_wqueue_start(&ring->sched); + return 0; +} + /** * amdgpu_vcn_ring_reset - Reset a VCN ring * @ring: ring to reset @@ -1502,48 +1533,33 @@ int amdgpu_vcn_ring_reset(struct amdgpu_ring *ring, { struct amdgpu_device *adev = ring->adev; struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[ring->me]; + struct amdgpu_fence *dec_fence; + struct amdgpu_fence *enc_fence[AMDGPU_VCN_MAX_ENC_RINGS]; int r, i; if (adev->vcn.inst[ring->me].using_unified_queue) return -EINVAL; mutex_lock(&vinst->engine_reset_mutex); - /* Stop the scheduler's work queue for the dec and enc rings if they are running. - * This ensures that no new tasks are submitted to the queues while - * the reset is in progress. - */ - drm_sched_wqueue_stop(&vinst->ring_dec.sched); + dec_fence = amdgpu_vcn_ring_reset_begin_helper(&vinst->ring_dec, ring, + timedout_fence); for (i = 0; i < vinst->num_enc_rings; i++) - drm_sched_wqueue_stop(&vinst->ring_enc[i].sched); + enc_fence[i] = amdgpu_vcn_ring_reset_begin_helper(&vinst->ring_enc[i], ring, + timedout_fence); /* Perform the VCN reset for the specified instance */ r = vinst->reset(vinst); if (r) goto unlock; - r = amdgpu_ring_test_ring(&vinst->ring_dec); + + r = amdgpu_vcn_ring_reset_end_helper(&vinst->ring_dec, dec_fence); if (r) goto unlock; for (i = 0; i < vinst->num_enc_rings; i++) { - r = amdgpu_ring_test_ring(&vinst->ring_enc[i]); + r = amdgpu_vcn_ring_reset_end_helper(&vinst->ring_enc[i], enc_fence[i]); if (r) goto unlock; } - amdgpu_fence_driver_force_completion(&vinst->ring_dec, - (&vinst->ring_dec == ring) ? - &timedout_fence->base : NULL); - for (i = 0; i < vinst->num_enc_rings; i++) - amdgpu_fence_driver_force_completion(&vinst->ring_enc[i], - (&vinst->ring_enc[i] == ring) ? - &timedout_fence->base : NULL); - - /* Restart the scheduler's work queue for the dec and enc rings - * if they were stopped by this function. This allows new tasks - * to be submitted to the queues after the reset is complete. - */ - drm_sched_wqueue_start(&vinst->ring_dec.sched); - for (i = 0; i < vinst->num_enc_rings; i++) - drm_sched_wqueue_start(&vinst->ring_enc[i].sched); - unlock: mutex_unlock(&vinst->engine_reset_mutex); -- 2.49.0
