On 2025. december 19., péntek 12:22:00 középső államokbeli zónaidő Alex 
Deucher wrote:
> GFX ring resets work differently on pre-GFX10 hardware since
> there is no MQD managed by the scheduler.
> For ring reset, you need issue the reset via CP_VMID_RESET
> via KIQ or MMIO and submit the following to the gfx ring to
> complete the reset:
> 1. EOP packet with EXEC bit set
> 2. WAIT_REG_MEM to wait for the fence
> 3. Clear CP_VMID_RESET to 0
> 4. EVENT_WRITE ENABLE_LEGACY_PIPELINE
> 5. EOP packet with EXEC bit set
> 6. WAIT_REG_MEM to wait for the fence
> Once those commands have completed the reset should
> be complete and the ring can accept new packets.
> 
> Tested-by: Jiqian Chen <[email protected]> (v1)
> Signed-off-by: Alex Deucher <[email protected]>

Hi Alex,

Thank you for working on this.
For the entire series,
Reviewed-by: Timur Kristóf <[email protected]>

I can't test it at the moment but can give it a try in January or so.

Best regards,
Timur

> ---
>  drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 92 ++++++++++++++++++++++++++-
>  1 file changed, 89 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 0d8e797d59b8a..7e9d753f4a808
> 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> @@ -2411,8 +2411,10 @@ static int gfx_v9_0_sw_init(struct amdgpu_ip_block
> *ip_block) amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]);
>       adev->gfx.compute_supported_reset =
>               amdgpu_get_soft_full_reset_mask(&adev-
>gfx.compute_ring[0]);
> -     if (!amdgpu_sriov_vf(adev) && !adev->debug_disable_gpu_ring_reset)
> +     if (!amdgpu_sriov_vf(adev) && !adev->debug_disable_gpu_ring_reset) 
{
>               adev->gfx.compute_supported_reset |= 
AMDGPU_RESET_TYPE_PER_QUEUE;
> +             adev->gfx.gfx_supported_reset |= 
AMDGPU_RESET_TYPE_PER_QUEUE;
> +     }
> 
>       r = amdgpu_gfx_kiq_init(adev, GFX9_MEC_HPD_SIZE, 0);
>       if (r) {
> @@ -7172,6 +7174,91 @@ static void gfx_v9_ring_insert_nop(struct amdgpu_ring
> *ring, uint32_t num_nop) amdgpu_ring_insert_nop(ring, num_nop - 1);
>  }
> 
> +static void gfx_v9_0_ring_emit_wreg_me(struct amdgpu_ring *ring,
> +                                    uint32_t reg,
> +                                    uint32_t val)
> +{
> +     uint32_t cmd = 0;
> +
> +     switch (ring->funcs->type) {
> +     case AMDGPU_RING_TYPE_KIQ:
> +             cmd = (1 << 16); /* no inc addr */
> +             break;
> +     default:
> +             cmd = WR_CONFIRM;
> +             break;
> +     }
> +     amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
> +     amdgpu_ring_write(ring, cmd);
> +     amdgpu_ring_write(ring, reg);
> +     amdgpu_ring_write(ring, 0);
> +     amdgpu_ring_write(ring, val);
> +}
> +
> +static int gfx_v9_0_reset_kgq(struct amdgpu_ring *ring,
> +                           unsigned int vmid,
> +                           struct amdgpu_fence *timedout_fence)
> +{
> +     struct amdgpu_device *adev = ring->adev;
> +     struct amdgpu_kiq *kiq = &adev->gfx.kiq[0];
> +     struct amdgpu_ring *kiq_ring = &kiq->ring;
> +     unsigned long flags;
> +     u32 tmp;
> +     int r;
> +
> +     amdgpu_ring_reset_helper_begin(ring, timedout_fence);
> +
> +     spin_lock_irqsave(&kiq->ring_lock, flags);
> +
> +     if (amdgpu_ring_alloc(kiq_ring, 5)) {
> +             spin_unlock_irqrestore(&kiq->ring_lock, flags);
> +             return -ENOMEM;
> +     }
> +
> +     /* send the reset - 5 */
> +     tmp = REG_SET_FIELD(0, CP_VMID_RESET, RESET_REQUEST, 1 << vmid);
> +     gfx_v9_0_ring_emit_wreg(kiq_ring,
> +                             SOC15_REG_OFFSET(GC, 0, 
mmCP_VMID_RESET), tmp);
> +     amdgpu_ring_commit(kiq_ring);
> +     r = amdgpu_ring_test_ring(kiq_ring);
> +     spin_unlock_irqrestore(&kiq->ring_lock, flags);
> +     if (r)
> +             return r;
> +
> +     if (amdgpu_ring_alloc(ring, 8 + 7 + 5 + 2 + 8 + 7))
> +             return -ENOMEM;
> +     /* emit the fence to finish the reset - 8 */
> +     ring->trail_seq++;
> +     gfx_v9_0_ring_emit_fence(ring, ring->trail_fence_gpu_addr,
> +                              ring->trail_seq, 
AMDGPU_FENCE_FLAG_EXEC);
> +     /* wait for the fence - 7 */
> +     gfx_v9_0_wait_reg_mem(ring, 0, 1, 0,
> +                           lower_32_bits(ring-
>trail_fence_gpu_addr),
> +                           upper_32_bits(ring-
>trail_fence_gpu_addr),
> +                           ring->trail_seq, 0xffffffff, 4);
> +     /* clear mmCP_VMID_RESET - 5 */
> +     gfx_v9_0_ring_emit_wreg_me(ring,
> +                                SOC15_REG_OFFSET(GC, 0, 
mmCP_VMID_RESET), 0);
> +     /* event write ENABLE_LEGACY_PIPELINE - 2 */
> +     gfx_v9_0_ring_emit_event_write(ring, ENABLE_LEGACY_PIPELINE, 0);
> +     /* emit a regular fence - 8 */
> +     ring->trail_seq++;
> +     gfx_v9_0_ring_emit_fence(ring, ring->trail_fence_gpu_addr,
> +                              ring->trail_seq, 
AMDGPU_FENCE_FLAG_EXEC);
> +     /* wait for the fence - 7 */
> +     gfx_v9_0_wait_reg_mem(ring, 1, 1, 0,
> +                           lower_32_bits(ring-
>trail_fence_gpu_addr),
> +                           upper_32_bits(ring-
>trail_fence_gpu_addr),
> +                           ring->trail_seq, 0xffffffff, 4);
> +     amdgpu_ring_commit(ring);
> +     /* wait for the commands to complete */
> +     r = amdgpu_ring_test_ring(ring);
> +     if (r)
> +             return r;
> +
> +     return amdgpu_ring_reset_helper_end(ring, timedout_fence);
> +}
> +
>  static int gfx_v9_0_reset_kcq(struct amdgpu_ring *ring,
>                             unsigned int vmid,
>                             struct amdgpu_fence *timedout_fence)
> @@ -7450,9 +7537,9 @@ static const struct amdgpu_ring_funcs
> gfx_v9_0_ring_funcs_gfx = { .emit_wreg = gfx_v9_0_ring_emit_wreg,
>       .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait,
>       .emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait,
> -     .soft_recovery = gfx_v9_0_ring_soft_recovery,
>       .emit_mem_sync = gfx_v9_0_emit_mem_sync,
>       .emit_cleaner_shader = gfx_v9_0_ring_emit_cleaner_shader,
> +     .reset = gfx_v9_0_reset_kgq,
>       .begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
>       .end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
>  };
> @@ -7551,7 +7638,6 @@ static const struct amdgpu_ring_funcs
> gfx_v9_0_ring_funcs_compute = { .emit_wreg = gfx_v9_0_ring_emit_wreg,
>       .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait,
>       .emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait,
> -     .soft_recovery = gfx_v9_0_ring_soft_recovery,
>       .emit_mem_sync = gfx_v9_0_emit_mem_sync,
>       .emit_wave_limit = gfx_v9_0_emit_wave_limit,
>       .reset = gfx_v9_0_reset_kcq,




Reply via email to