Fix a hardware RTL bug in the TCP XNACK scoreboard reset path on MI300,
where a wave receiving a no-retry FAULT from UTC and subsequently
terminating may leave its scoreboard entry uncleared when reset events
arrive back-to-back.

This can cause a later, unrelated wave using the same scoreboard slot
to incorrectly inherit the XNACK error state, resulting in its VMEM
operations being dropped even though the wave never faulted.

Signed-off-by: Gang Ba <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c             | 11 ++++++-----
 drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.h             |  2 +-
 drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c     | 12 +++++++-----
 5 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c
index 4626e0b13909..ec291377302a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c
@@ -628,5 +628,6 @@ const struct kfd2kgd_calls gc_9_4_3_kfd2kgd = {
        .hqd_reset = kgd_gfx_v9_hqd_reset,
        .hqd_sdma_get_doorbell = kgd_gfx_v9_4_3_hqd_sdma_get_doorbell,
        .ptl_ctrl = kgd_v9_4_3_ptl_ctrl,
-       .hqd_sdma_get_counter = kgd_gfx_v9_4_3_hqd_sdma_get_counter
+       .hqd_sdma_get_counter = kgd_gfx_v9_4_3_hqd_sdma_get_counter,
+       .hqd_gfx_clean_fault = kgd_gfx_v9_clean_fault
 };
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
index 0d62cf475f40..0bc8d31081e6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
@@ -1234,7 +1234,7 @@ uint32_t kgd_gfx_v9_hqd_sdma_get_doorbell(struct 
amdgpu_device *adev,
 
 void kgd_gfx_v9_clean_fault(struct amdgpu_device *adev)
 {
-       gfx_v9_4_2_clean_fault(adev);
+       gfx_v9_fault_cleaner(adev);
 }
 
 const struct kfd2kgd_calls gfx_v9_kfd2kgd = {
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c
index 344156bf20ca..54bcb5fdca24 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c
@@ -714,7 +714,7 @@ static int gfx_v9_4_2_do_vgprs_init(struct amdgpu_device 
*adev)
        return r;
 }
 
-static int gfx_v9_4_2_clean_shaders(struct amdgpu_device *adev)
+static int gfx_v9_clean_shaders(struct amdgpu_device *adev)
 {
        int r;
        /* CU_ID: 0~15, SIMD_ID: 0~3, WAVE_ID: 0 ~ 9 */
@@ -763,16 +763,17 @@ static int gfx_v9_4_2_clean_shaders(struct amdgpu_device 
*adev)
        amdgpu_ib_free(&wb_ib, NULL);
 
        if (r)
-               dev_dbg(adev->dev, "Clean MI200 Failed\n");
+               dev_dbg(adev->dev, "Clean GPR Failed\n");
        else
-               dev_dbg(adev->dev, "Clean MI200 Successfully\n");
+               dev_dbg(adev->dev, "Clean GPR Successfully\n");
 
        return r;
 }
 
-void gfx_v9_4_2_clean_fault(struct amdgpu_device *adev)
+void gfx_v9_fault_cleaner(struct amdgpu_device *adev)
 {
-       gfx_v9_4_2_clean_shaders(adev);
+       /* to clean MI2XX and MI3XX */
+       gfx_v9_clean_shaders(adev);
 }
 
 int gfx_v9_4_2_do_edc_gpr_workarounds(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.h 
b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.h
index 1cbade5ed657..c8757de669ea 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.h
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.h
@@ -30,8 +30,8 @@ void gfx_v9_4_2_init_golden_registers(struct amdgpu_device 
*adev,
                                      uint32_t die_id);
 void gfx_v9_4_2_init_sq(struct amdgpu_device *adev);
 void gfx_v9_4_2_set_power_brake_sequence(struct amdgpu_device *adev);
-void gfx_v9_4_2_clean_fault(struct amdgpu_device *adev);
 int gfx_v9_4_2_do_edc_gpr_workarounds(struct amdgpu_device *adev);
+void gfx_v9_fault_cleaner(struct amdgpu_device *adev);
 
 extern struct amdgpu_gfx_ras gfx_v9_4_2_ras;
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
index 9b48fe598597..2ae1129fea55 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
@@ -359,7 +359,7 @@ static bool event_interrupt_isr_v9(struct kfd_node *dev,
                !amdgpu_no_queue_eviction_on_vm_fault);
 }
 
-static void gfx942_clean_fault(uint16_t pasid)
+static void gfx_9_clean_fault(uint16_t pasid)
 {
        struct kfd_process *p;
        struct kfd_process_device *pdd = NULL;
@@ -565,10 +565,12 @@ static void event_interrupt_wq_v9(struct kfd_node *dev,
                        return;
                }
 
-                       /* GPR cleaner shader for MI2XX */
-                       if (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2))
-                               gfx942_clean_fault(pasid);
-
+               /* GPR cleaner for GFX9 MI-series GPUs */
+               if (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2) ||
+                   KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 3) ||
+                   KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 4) ||
+                   KFD_GC_VERSION(dev) == IP_VERSION(9, 5, 0))
+                       gfx_9_clean_fault(pasid);
 
                info.vmid = vmid;
                info.mc_id = client_id;
-- 
2.55.0

Reply via email to