Add a common helper to remove the repeated logic from each
gmc module.

Suggested-by: Lijo Lazar <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 48 +++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  6 ++++
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 23 ++----------
 drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c  | 23 ++----------
 drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c  | 23 ++----------
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 43 ++++------------------
 6 files changed, 69 insertions(+), 97 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index 4abed753fc2df..8ac92e7bed315 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -524,6 +524,54 @@ void amdgpu_gmc_filter_faults_remove(struct amdgpu_device 
*adev, uint64_t addr,
        } while (fault->timestamp < tmp);
 }
 
+int amdgpu_gmc_handle_retry_fault(struct amdgpu_device *adev,
+                                 struct amdgpu_iv_entry *entry,
+                                 u64 addr,
+                                 u32 cam_index,
+                                 u32 node_id,
+                                 bool write_fault)
+{
+       int ret;
+
+       if (adev->irq.retry_cam_enabled) {
+               /* Delegate it to a different ring if the hardware hasn't
+                * already done it.
+                */
+               if (entry->ih == &adev->irq.ih) {
+                       amdgpu_irq_delegate(adev, entry, 8);
+                       return 1;
+               }
+
+               ret = amdgpu_vm_handle_fault(adev, entry->pasid, entry->vmid, 
node_id,
+                                            addr, entry->timestamp, 
write_fault);
+               WDOORBELL32(adev->irq.retry_cam_doorbell_index, cam_index);
+               if (ret)
+                       return 1;
+       } else {
+               /* Process it only if it's the first fault for this address */
+               if (entry->ih != &adev->irq.ih_soft &&
+                   amdgpu_gmc_filter_faults(adev, entry->ih, addr, 
entry->pasid,
+                                            entry->timestamp))
+                       return 1;
+
+               /* Delegate it to a different ring if the hardware hasn't
+                * already done it.
+                */
+               if (entry->ih == &adev->irq.ih) {
+                       amdgpu_irq_delegate(adev, entry, 8);
+                       return 1;
+               }
+
+               /* Try to handle the recoverable page faults by filling page
+                * tables
+                */
+               if (amdgpu_vm_handle_fault(adev, entry->pasid, entry->vmid, 
node_id,
+                                          addr, entry->timestamp, write_fault))
+                       return 1;
+       }
+       return 0;
+}
+
 int amdgpu_gmc_ras_sw_init(struct amdgpu_device *adev)
 {
        int r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index b62fa7e92c79d..e8e8bfa098c3e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -425,6 +425,12 @@ bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev,
                              uint16_t pasid, uint64_t timestamp);
 void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr,
                                     uint16_t pasid);
+int amdgpu_gmc_handle_retry_fault(struct amdgpu_device *adev,
+                                 struct amdgpu_iv_entry *entry,
+                                 u64 addr,
+                                 u32 cam_index,
+                                 u32 node_id,
+                                 bool write_fault);
 int amdgpu_gmc_ras_sw_init(struct amdgpu_device *adev);
 int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev);
 void amdgpu_gmc_ras_fini(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index 47558e572553a..0b385a15194d9 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -115,27 +115,10 @@ static int gmc_v10_0_process_interrupt(struct 
amdgpu_device *adev,
        addr |= ((u64)entry->src_data[1] & 0xf) << 44;
 
        if (retry_fault) {
+               int ret = amdgpu_gmc_handle_retry_fault(adev, entry, addr, 0, 0,
+                                                       write_fault);
                /* Returning 1 here also prevents sending the IV to the KFD */
-
-               /* Process it only if it's the first fault for this address */
-               if (entry->ih != &adev->irq.ih_soft &&
-                   amdgpu_gmc_filter_faults(adev, entry->ih, addr, 
entry->pasid,
-                                            entry->timestamp))
-                       return 1;
-
-               /* Delegate it to a different ring if the hardware hasn't
-                * already done it.
-                */
-               if (entry->ih == &adev->irq.ih) {
-                       amdgpu_irq_delegate(adev, entry, 8);
-                       return 1;
-               }
-
-               /* Try to handle the recoverable page faults by filling page
-                * tables
-                */
-               if (amdgpu_vm_handle_fault(adev, entry->pasid, 0, 0, addr,
-                                          entry->timestamp, write_fault))
+               if (ret == 1)
                        return 1;
        }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
index ba59ee8e398a8..7a1f0742754a6 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
@@ -114,27 +114,10 @@ static int gmc_v11_0_process_interrupt(struct 
amdgpu_device *adev,
        addr |= ((u64)entry->src_data[1] & 0xf) << 44;
 
        if (retry_fault) {
+               int ret = amdgpu_gmc_handle_retry_fault(adev, entry, addr, 0, 0,
+                                                       write_fault);
                /* Returning 1 here also prevents sending the IV to the KFD */
-
-               /* Process it only if it's the first fault for this address */
-               if (entry->ih != &adev->irq.ih_soft &&
-                   amdgpu_gmc_filter_faults(adev, entry->ih, addr, 
entry->pasid,
-                                            entry->timestamp))
-                       return 1;
-
-               /* Delegate it to a different ring if the hardware hasn't
-                * already done it.
-                */
-               if (entry->ih == &adev->irq.ih) {
-                       amdgpu_irq_delegate(adev, entry, 8);
-                       return 1;
-               }
-
-               /* Try to handle the recoverable page faults by filling page
-                * tables
-                */
-               if (amdgpu_vm_handle_fault(adev, entry->pasid, 0, 0, addr,
-                                          entry->timestamp, write_fault))
+               if (ret == 1)
                        return 1;
        }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c
index dfb06baea1ff1..145fcefd1c783 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c
@@ -110,27 +110,10 @@ static int gmc_v12_0_process_interrupt(struct 
amdgpu_device *adev,
                hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
 
        if (retry_fault) {
+               int ret = amdgpu_gmc_handle_retry_fault(adev, entry, addr, 0, 0,
+                                                       write_fault);
                /* Returning 1 here also prevents sending the IV to the KFD */
-
-               /* Process it only if it's the first fault for this address */
-               if (entry->ih != &adev->irq.ih_soft &&
-                   amdgpu_gmc_filter_faults(adev, entry->ih, addr, 
entry->pasid,
-                                            entry->timestamp))
-                       return 1;
-
-               /* Delegate it to a different ring if the hardware hasn't
-                * already done it.
-                */
-               if (entry->ih == &adev->irq.ih) {
-                       amdgpu_irq_delegate(adev, entry, 8);
-                       return 1;
-               }
-
-               /* Try to handle the recoverable page faults by filling page
-                * tables
-                */
-               if (amdgpu_vm_handle_fault(adev, entry->pasid, 0, 0, addr,
-                                          entry->timestamp, write_fault))
+               if (ret == 1)
                        return 1;
        }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 778ad7ac6d086..97a04e3171f2d 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -583,44 +583,13 @@ static int gmc_v9_0_process_interrupt(struct 
amdgpu_device *adev,
        hub = &adev->vmhub[vmhub];
 
        if (retry_fault) {
-               if (adev->irq.retry_cam_enabled) {
-                       /* Delegate it to a different ring if the hardware 
hasn't
-                        * already done it.
-                        */
-                       if (entry->ih == &adev->irq.ih) {
-                               amdgpu_irq_delegate(adev, entry, 8);
-                               return 1;
-                       }
-
-                       cam_index = entry->src_data[2] & 0x3ff;
+               cam_index = entry->src_data[2] & 0x3ff;
 
-                       ret = amdgpu_vm_handle_fault(adev, entry->pasid, 
entry->vmid, node_id,
-                                                    addr, entry->timestamp, 
write_fault);
-                       WDOORBELL32(adev->irq.retry_cam_doorbell_index, 
cam_index);
-                       if (ret)
-                               return 1;
-               } else {
-                       /* Process it only if it's the first fault for this 
address */
-                       if (entry->ih != &adev->irq.ih_soft &&
-                           amdgpu_gmc_filter_faults(adev, entry->ih, addr, 
entry->pasid,
-                                            entry->timestamp))
-                               return 1;
-
-                       /* Delegate it to a different ring if the hardware 
hasn't
-                        * already done it.
-                        */
-                       if (entry->ih == &adev->irq.ih) {
-                               amdgpu_irq_delegate(adev, entry, 8);
-                               return 1;
-                       }
-
-                       /* Try to handle the recoverable page faults by filling 
page
-                        * tables
-                        */
-                       if (amdgpu_vm_handle_fault(adev, entry->pasid, 
entry->vmid, node_id,
-                                                  addr, entry->timestamp, 
write_fault))
-                               return 1;
-               }
+               ret = amdgpu_gmc_handle_retry_fault(adev, entry, addr, 
cam_index, node_id,
+                                                   write_fault);
+               /* Returning 1 here also prevents sending the IV to the KFD */
+               if (ret == 1)
+                       return 1;
        }
 
        if (kgd2kfd_vmfault_fast_path(adev, entry, retry_fault))
-- 
2.51.1

Reply via email to