Async work (e.g., GuC queue teardowns) can call ggtt_node_remove, so the
operation must be performed under the GGTT lock to ensure the GGTT
online check remains stable. GGTT insertion and removal are heavyweight
operations (e.g., queue create/destroy), so the additional serialization
cost is negligible compared to ensuring correctness.

Fixes: 4f3a998a173b ("drm/xe: Open-code GGTT MMIO access protection")
Signed-by: Matthew Brost <[email protected]>
---
 drivers/gpu/drm/xe/xe_ggtt.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c
index 017f679ba13f..353b324f7301 100644
--- a/drivers/gpu/drm/xe/xe_ggtt.c
+++ b/drivers/gpu/drm/xe/xe_ggtt.c
@@ -482,15 +482,10 @@ static void ggtt_node_remove(struct xe_ggtt_node *node)
                xe_ggtt_clear(ggtt, xe_ggtt_node_addr(node), 
xe_ggtt_node_size(node));
        drm_mm_remove_node(&node->base);
        node->base.size = 0;
-       mutex_unlock(&ggtt->lock);
-
-       if (!bound)
-               goto free_node;
-
-       if (node->invalidate_on_remove)
+       if (bound && node->invalidate_on_remove)
                xe_ggtt_invalidate(ggtt);
+       mutex_unlock(&ggtt->lock);
 
-free_node:
        ggtt_node_fini(node);
 }
 
-- 
2.34.1

Reply via email to