summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2025-12-01 14:46:53 -0500
committerAlex Deucher <alexander.deucher@amd.com>2025-12-08 14:14:38 -0500
commitd3ff65243a52afa85166abaa8d00a44c17691dbd (patch)
tree6ae38427430b7ce215e3435ba9e734ef9202743e /drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
parenta50d32c41fb25d772cc1c47b6abed8fb811d58c2 (diff)
drm/amdgpu: add a helper for processing recoverable GPUVM faults
Add a common helper to remove the repeated logic from each gmc module. Suggested-by: Lijo Lazar <lijo.lazar@amd.com> Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index 4abed753fc2d..8ac92e7bed31 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;