[PATCH 4/5] drm/xe/display: Prevent overwriting original GGTT when taking over initial FB.

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Thu Apr 18 16:55:18 UTC 2024


Instead of overwriting the original GGTT mapping accidentally, allocate
a new GGTT mapping above the original GGTT mapping.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
---
 drivers/gpu/drm/xe/display/xe_fb_pin.c        | 40 ++++++++++++-------
 drivers/gpu/drm/xe/display/xe_fb_pin.h        | 20 ++++++++++
 drivers/gpu/drm/xe/display/xe_plane_initial.c | 15 ++++---
 drivers/gpu/drm/xe/xe_ggtt.c                  |  9 +++--
 drivers/gpu/drm/xe/xe_ggtt.h                  |  3 +-
 5 files changed, 63 insertions(+), 24 deletions(-)
 create mode 100644 drivers/gpu/drm/xe/display/xe_fb_pin.h

diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c
index 16a287cbebc5..dd7a1c4a9430 100644
--- a/drivers/gpu/drm/xe/display/xe_fb_pin.c
+++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c
@@ -8,6 +8,7 @@
 #include "intel_dpt.h"
 #include "intel_fb.h"
 #include "intel_fb_pin.h"
+#include "xe_fb_pin.h"
 #include "xe_ggtt.h"
 #include "xe_gt.h"
 
@@ -119,12 +120,11 @@ static void xe_fb_dpt_free(struct i915_vma *vma, struct intel_framebuffer *fb)
 	vma->dpt = NULL;
 }
 
-static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt)
+static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt, u64 ggtt_start)
 {
 	struct xe_device *xe = xe_bo_device(dpt);
 	struct xe_tile *tile0 = xe_device_get_root_tile(xe);
 	struct xe_ggtt *ggtt = tile0->mem.ggtt;
-	u64 start = 0, end = U64_MAX;
 	u64 alignment = XE_PAGE_SIZE;
 	int err;
 
@@ -139,8 +139,9 @@ static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt)
 	if (err)
 		goto out_put;
 
-	err = drm_mm_insert_node_in_range(&ggtt->mm, &dpt->ggtt_node, dpt->size,
-					  alignment, 0, start, end, 0);
+	err = xe_ggtt_insert_special_node_locked(ggtt, &dpt->ggtt_node, dpt->size,
+						 alignment, ggtt_start, U64_MAX,
+						 ggtt_start ? DRM_MM_INSERT_HIGH : 0);
 	if (!err)
 		xe_ggtt_map_bo(ggtt, dpt);
 	mutex_unlock(&ggtt->lock);
@@ -188,7 +189,7 @@ static void xe_fb_dpt_unpin_free(struct i915_vma *vma, struct intel_framebuffer
 
 static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb,
 			       const struct i915_gtt_view *view,
-			       struct i915_vma *vma)
+			       struct i915_vma *vma, u64 ggtt_start)
 {
 	struct xe_device *xe = to_xe_device(fb->base.dev);
 	struct xe_tile *tile0 = xe_device_get_root_tile(xe);
@@ -237,7 +238,7 @@ static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb,
 					  rot_info->plane[i].dst_stride);
 	}
 
-	ret = xe_fb_dpt_map_ggtt(dpt);
+	ret = xe_fb_dpt_map_ggtt(dpt, ggtt_start);
 	if (ret)
 		xe_fb_dpt_unpin_free(vma, fb);
 	return ret;
@@ -269,7 +270,7 @@ write_ggtt_rotated(struct xe_bo *bo, struct xe_ggtt *ggtt, u32 *ggtt_ofs, u32 bo
 
 static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb,
 				const struct i915_gtt_view *view,
-				struct i915_vma *vma)
+				struct i915_vma *vma, u64 ggtt_start)
 {
 	struct xe_bo *bo = intel_fb_obj(&fb->base);
 	struct xe_device *xe = to_xe_device(fb->base.dev);
@@ -295,7 +296,8 @@ static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb,
 		u32 x, size = bo->ttm.base.size;
 
 		ret = xe_ggtt_insert_special_node_locked(ggtt, &vma->node, size,
-							 align, 0);
+							 align, ggtt_start, U64_MAX,
+							 ggtt_start ? DRM_MM_INSERT_HIGH : 0);
 		if (ret)
 			goto out_unlock;
 
@@ -313,7 +315,7 @@ static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb,
 		u32 size = intel_rotation_info_size(rot_info) * XE_PAGE_SIZE;
 
 		ret = xe_ggtt_insert_special_node_locked(ggtt, &vma->node, size,
-							 align, 0);
+							 align, ggtt_start, U64_MAX, 0);
 		if (ret)
 			goto out_unlock;
 
@@ -336,7 +338,8 @@ static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb,
 }
 
 static struct i915_vma *__xe_pin_fb_vma(struct intel_framebuffer *fb,
-					const struct i915_gtt_view *view)
+					const struct i915_gtt_view *view,
+					u64 ggtt_start)
 {
 	struct drm_device *dev = fb->base.dev;
 	struct xe_device *xe = to_xe_device(dev);
@@ -384,9 +387,9 @@ static struct i915_vma *__xe_pin_fb_vma(struct intel_framebuffer *fb,
 
 	vma->bo = bo;
 	if (intel_fb_uses_dpt(&fb->base))
-		ret = __xe_pin_fb_vma_dpt(fb, view, vma);
+		ret = __xe_pin_fb_vma_dpt(fb, view, vma, ggtt_start);
 	else
-		ret = __xe_pin_fb_vma_ggtt(fb, view, vma);
+		ret = __xe_pin_fb_vma_ggtt(fb, view, vma, ggtt_start);
 	if (ret)
 		goto err_unpin;
 
@@ -430,7 +433,16 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
 {
 	*out_flags = 0;
 
-	return __xe_pin_fb_vma(to_intel_framebuffer(fb), view);
+	return __xe_pin_fb_vma(to_intel_framebuffer(fb), view, 0);
+}
+
+
+struct i915_vma *
+xe_pin_and_fence_fb_obj_initial(struct drm_framebuffer *fb,
+				const struct i915_gtt_view *view,
+				u64 ggtt_start)
+{
+	return __xe_pin_fb_vma(to_intel_framebuffer(fb), view, ggtt_start);
 }
 
 void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags)
@@ -447,7 +459,7 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state)
 	/* We reject creating !SCANOUT fb's, so this is weird.. */
 	drm_WARN_ON(bo->ttm.base.dev, !(bo->flags & XE_BO_FLAG_SCANOUT));
 
-	vma = __xe_pin_fb_vma(to_intel_framebuffer(fb), &plane_state->view.gtt);
+	vma = __xe_pin_fb_vma(to_intel_framebuffer(fb), &plane_state->view.gtt, 0);
 	if (IS_ERR(vma))
 		return PTR_ERR(vma);
 
diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.h b/drivers/gpu/drm/xe/display/xe_fb_pin.h
new file mode 100644
index 000000000000..f22960138691
--- /dev/null
+++ b/drivers/gpu/drm/xe/display/xe_fb_pin.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __XE_FB_PIN_H__
+#define __XE_FB_PIN_H__
+
+#include <linux/types.h>
+
+struct i915_vma;
+struct drm_framebuffer;
+struct i915_gtt_view;
+
+struct i915_vma *
+xe_pin_and_fence_fb_obj_initial(struct drm_framebuffer *fb,
+				const struct i915_gtt_view *view,
+				u64 ggtt_start);
+
+#endif
diff --git a/drivers/gpu/drm/xe/display/xe_plane_initial.c b/drivers/gpu/drm/xe/display/xe_plane_initial.c
index 9693c56d386b..fdb05043add1 100644
--- a/drivers/gpu/drm/xe/display/xe_plane_initial.c
+++ b/drivers/gpu/drm/xe/display/xe_plane_initial.c
@@ -18,6 +18,7 @@
 #include "intel_fb_pin.h"
 #include "intel_frontbuffer.h"
 #include "intel_plane_initial.h"
+#include "xe_fb_pin.h"
 
 static bool
 intel_reuse_initial_plane_obj(struct intel_crtc *this,
@@ -63,7 +64,7 @@ initial_plane_bo(struct xe_device *xe,
 	if (plane_config->size == 0)
 		return NULL;
 
-	flags = XE_BO_FLAG_PINNED | XE_BO_FLAG_SCANOUT | XE_BO_FLAG_GGTT;
+	flags = XE_BO_FLAG_PINNED | XE_BO_FLAG_SCANOUT;
 
 	base = round_down(plane_config->base, page_size);
 	if (IS_DGFX(xe)) {
@@ -193,6 +194,7 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
 		to_intel_crtc_state(crtc->base.state);
 	struct drm_framebuffer *fb;
 	struct i915_vma *vma;
+	u64 ggtt_start = 0;
 
 	/*
 	 * TODO:
@@ -202,17 +204,20 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
 	if (!plane_config->fb)
 		return;
 
-	if (intel_alloc_initial_plane_obj(crtc, plane_config))
+	if (intel_alloc_initial_plane_obj(crtc, plane_config)) {
 		fb = &plane_config->fb->base;
-	else if (!intel_reuse_initial_plane_obj(crtc, plane_configs, &fb))
+
+		/* Ensure that new GGTT mapping is not overwriting the original mapping */
+		ggtt_start = plane_config->base + intel_fb_obj(fb)->ttm.base.size;
+	} else if (!intel_reuse_initial_plane_obj(crtc, plane_configs, &fb)) {
 		goto nofb;
+	}
 
 	plane_state->uapi.rotation = plane_config->rotation;
 	intel_fb_fill_view(to_intel_framebuffer(fb),
 			   plane_state->uapi.rotation, &plane_state->view);
 
-	vma = intel_pin_and_fence_fb_obj(fb, false, &plane_state->view.gtt,
-					 false, &plane_state->flags);
+	vma = xe_pin_and_fence_fb_obj_initial(fb, &plane_state->view.gtt, ggtt_start);
 	if (IS_ERR(vma))
 		goto nofb;
 
diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c
index 38f6c94c722d..281301f85aba 100644
--- a/drivers/gpu/drm/xe/xe_ggtt.c
+++ b/drivers/gpu/drm/xe/xe_ggtt.c
@@ -352,10 +352,10 @@ void xe_ggtt_deballoon(struct xe_ggtt *ggtt, struct drm_mm_node *node)
 }
 
 int xe_ggtt_insert_special_node_locked(struct xe_ggtt *ggtt, struct drm_mm_node *node,
-				       u32 size, u32 align, u32 mm_flags)
+				       u32 size, u32 align, u64 start, u64 end, u32 mm_flags)
 {
-	return drm_mm_insert_node_generic(&ggtt->mm, node, size, align, 0,
-					  mm_flags);
+	return drm_mm_insert_node_in_range(&ggtt->mm, node, size, align, 0,
+					   start, end, mm_flags);
 }
 
 int xe_ggtt_insert_special_node(struct xe_ggtt *ggtt, struct drm_mm_node *node,
@@ -365,7 +365,8 @@ int xe_ggtt_insert_special_node(struct xe_ggtt *ggtt, struct drm_mm_node *node,
 
 	mutex_lock(&ggtt->lock);
 	ret = xe_ggtt_insert_special_node_locked(ggtt, node, size,
-						 align, DRM_MM_INSERT_HIGH);
+						 align, 0, U64_MAX,
+						 DRM_MM_INSERT_HIGH);
 	mutex_unlock(&ggtt->lock);
 
 	return ret;
diff --git a/drivers/gpu/drm/xe/xe_ggtt.h b/drivers/gpu/drm/xe/xe_ggtt.h
index 4a41a1762358..6fdd7c58f37f 100644
--- a/drivers/gpu/drm/xe/xe_ggtt.h
+++ b/drivers/gpu/drm/xe/xe_ggtt.h
@@ -22,7 +22,8 @@ int xe_ggtt_insert_special_node(struct xe_ggtt *ggtt, struct drm_mm_node *node,
 				u32 size, u32 align);
 int xe_ggtt_insert_special_node_locked(struct xe_ggtt *ggtt,
 				       struct drm_mm_node *node,
-				       u32 size, u32 align, u32 mm_flags);
+				       u32 size, u32 align,
+				       u64 start, u64 end, u32 mm_flags);
 void xe_ggtt_remove_node(struct xe_ggtt *ggtt, struct drm_mm_node *node,
 			 bool invalidate);
 void xe_ggtt_map_bo(struct xe_ggtt *ggtt, struct xe_bo *bo);
-- 
2.43.0



More information about the Intel-gfx mailing list