]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe/ggtt: use drm_dev_enter to mark device section
authorMatthew Auld <matthew.auld@intel.com>
Wed, 22 May 2024 10:21:46 +0000 (11:21 +0100)
committerMatthew Auld <matthew.auld@intel.com>
Wed, 22 May 2024 12:22:39 +0000 (13:22 +0100)
Device can be hotunplugged before we start destroying gem objects. In
such a case don't touch the GGTT entries, trigger any invalidations or
mess around with rpm.  This should already be taken care of when
removing the device, we just need to take care of dealing with the
software state, like removing the mm node.

v2: (Andrzej)
  - Avoid some duplication by tracking the bound status and checking
    that instead.

References: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/1717
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
Reviewed-by: Jagmeet Randhawa <jagmeet.randhawa@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240522102143.128069-21-matthew.auld@intel.com
drivers/gpu/drm/xe/xe_ggtt.c

index 0d541f55b4fcf9701a0ff2a88c18a3de0e90d5d4..17e5066763dbd47fd545ff7988676e961f868877 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/sizes.h>
 
+#include <drm/drm_drv.h>
 #include <drm/drm_managed.h>
 #include <drm/i915_drm.h>
 
@@ -433,18 +434,29 @@ int xe_ggtt_insert_bo(struct xe_ggtt *ggtt, struct xe_bo *bo)
 void xe_ggtt_remove_node(struct xe_ggtt *ggtt, struct drm_mm_node *node,
                         bool invalidate)
 {
-       xe_pm_runtime_get_noresume(tile_to_xe(ggtt->tile));
+       struct xe_device *xe = tile_to_xe(ggtt->tile);
+       bool bound;
+       int idx;
+
+       bound = drm_dev_enter(&xe->drm, &idx);
+       if (bound)
+               xe_pm_runtime_get_noresume(xe);
 
        mutex_lock(&ggtt->lock);
-       xe_ggtt_clear(ggtt, node->start, node->size);
+       if (bound)
+               xe_ggtt_clear(ggtt, node->start, node->size);
        drm_mm_remove_node(node);
        node->size = 0;
        mutex_unlock(&ggtt->lock);
 
+       if (!bound)
+               return;
+
        if (invalidate)
                xe_ggtt_invalidate(ggtt);
 
-       xe_pm_runtime_put(tile_to_xe(ggtt->tile));
+       xe_pm_runtime_put(xe);
+       drm_dev_exit(idx);
 }
 
 void xe_ggtt_remove_bo(struct xe_ggtt *ggtt, struct xe_bo *bo)