xe_bo_vm_access() may acquire a runtime PM reference and access a BO
during PCI error recovery, after a permanent wedge or during device
unplug.

Return -EIO when device I/O is blocked. Use drm_dev_enter() to protect
against concurrent unplug and keep that protection until the runtime PM
reference has been released.

Use the same SRCU domain as CPU faults so wedge isolation waits for a BO
access that started before the wedge.

Cc: Matthew Brost <[email protected]>
Cc: Thomas Hellström <[email protected]>
Cc: Himal Prasad Ghimiray <[email protected]>
Cc: Rodrigo Vivi <[email protected]>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Arvind Yadav <[email protected]>
---
 drivers/gpu/drm/xe/xe_bo.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index 1eabece56f6c..717d318c7072 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -2245,9 +2245,25 @@ static int xe_bo_vm_access(struct vm_area_struct *vma, 
unsigned long addr,
        struct ttm_buffer_object *ttm_bo = vma->vm_private_data;
        struct xe_bo *bo = ttm_to_xe_bo(ttm_bo);
        struct xe_device *xe = xe_bo_device(bo);
+       int idx, srcu_idx, ret = -EIO;
 
-       guard(xe_pm_runtime)(xe);
-       return ttm_bo_vm_access(vma, addr, buf, len, write);
+       srcu_idx = srcu_read_lock(&xe->mem_access.vram_userfault.srcu);
+
+       if (xe_device_io_blocked(xe) || !drm_dev_enter(&xe->drm, &idx))
+               goto out_srcu;
+
+       /*
+        * Keep the drm_dev_enter() protection until the runtime PM
+        * reference has been released.
+        */
+       scoped_guard(xe_pm_runtime, xe)
+               ret = ttm_bo_vm_access(vma, addr, buf, len, write);
+
+       drm_dev_exit(idx);
+
+out_srcu:
+       srcu_read_unlock(&xe->mem_access.vram_userfault.srcu, srcu_idx);
+       return ret;
 }
 
 /**
-- 
2.43.0

Reply via email to