All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robert Beckett <bob.beckett@collabora.com>
To: intel-gfx@lists.freedesktop.org,
	Jani Nikula <jani.nikula@linux.intel.com>,
	Joonas Lahtinen <joonas.lahtinen@linux.intel.com>,
	Rodrigo Vivi <rodrigo.vivi@intel.com>,
	Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>,
	David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>
Cc: Robert Beckett <bob.beckett@collabora.com>,
	linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org
Subject: [RFC PATCH 3/7] drm/i915: use gem objects to track stolen nodes
Date: Tue, 15 Mar 2022 18:04:40 +0000	[thread overview]
Message-ID: <20220315180444.3327283-4-bob.beckett@collabora.com> (raw)
In-Reply-To: <20220315180444.3327283-1-bob.beckett@collabora.com>

Construct gem objects around stolen nodes.
This stops the abuse of interfaces and aids future patches that done use
drm nodes for stolen areas.

Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
---
 drivers/gpu/drm/i915/display/intel_fbc.c   | 72 ++++++++++++----------
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 60 ++++++++++++++++++
 drivers/gpu/drm/i915/gem/i915_gem_stolen.h |  7 +++
 3 files changed, 106 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 142280b6ce6d..9df64ecab70e 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -92,8 +92,8 @@ struct intel_fbc {
 	unsigned int possible_framebuffer_bits;
 	unsigned int busy_bits;
 
-	struct drm_mm_node compressed_fb;
-	struct drm_mm_node compressed_llb;
+	struct drm_i915_gem_object *compressed_fb;
+	struct drm_i915_gem_object *compressed_llb;
 
 	enum intel_fbc_id id;
 
@@ -331,16 +331,18 @@ static void i8xx_fbc_nuke(struct intel_fbc *fbc)
 static void i8xx_fbc_program_cfb(struct intel_fbc *fbc)
 {
 	struct drm_i915_private *i915 = fbc->i915;
+	u64 fb_offset = i915_gem_object_stolen_offset(fbc->compressed_fb);
+	u64 llb_offset = i915_gem_object_stolen_offset(fbc->compressed_llb);
 
 	GEM_BUG_ON(range_overflows_end_t(u64, i915->dsm.start,
-					 fbc->compressed_fb.start, U32_MAX));
+					 fb_offset, U32_MAX));
 	GEM_BUG_ON(range_overflows_end_t(u64, i915->dsm.start,
-					 fbc->compressed_llb.start, U32_MAX));
+					 llb_offset, U32_MAX));
 
 	intel_de_write(i915, FBC_CFB_BASE,
-		       i915->dsm.start + fbc->compressed_fb.start);
+		       i915->dsm.start + fb_offset);
 	intel_de_write(i915, FBC_LL_BASE,
-		       i915->dsm.start + fbc->compressed_llb.start);
+		       i915->dsm.start + llb_offset);
 }
 
 static const struct intel_fbc_funcs i8xx_fbc_funcs = {
@@ -449,7 +451,8 @@ static void g4x_fbc_program_cfb(struct intel_fbc *fbc)
 {
 	struct drm_i915_private *i915 = fbc->i915;
 
-	intel_de_write(i915, DPFC_CB_BASE, fbc->compressed_fb.start);
+	intel_de_write(i915, DPFC_CB_BASE,
+		       i915_gem_object_stolen_offset(fbc->compressed_fb));
 }
 
 static const struct intel_fbc_funcs g4x_fbc_funcs = {
@@ -500,7 +503,8 @@ static void ilk_fbc_program_cfb(struct intel_fbc *fbc)
 {
 	struct drm_i915_private *i915 = fbc->i915;
 
-	intel_de_write(i915, ILK_DPFC_CB_BASE(fbc->id), fbc->compressed_fb.start);
+	intel_de_write(i915, ILK_DPFC_CB_BASE(fbc->id),
+			i915_gem_object_stolen_offset(fbc->compressed_fb));
 }
 
 static const struct intel_fbc_funcs ilk_fbc_funcs = {
@@ -740,21 +744,24 @@ static int find_compression_limit(struct intel_fbc *fbc,
 {
 	struct drm_i915_private *i915 = fbc->i915;
 	u64 end = intel_fbc_stolen_end(i915);
-	int ret, limit = min_limit;
+	int limit = min_limit;
+	struct drm_i915_gem_object *obj;
 
 	size /= limit;
 
 	/* Try to over-allocate to reduce reallocations and fragmentation. */
-	ret = i915_gem_stolen_insert_node_in_range(i915, &fbc->compressed_fb,
-						   size <<= 1, 4096, 0, end);
-	if (ret == 0)
+	obj = i915_gem_object_create_stolen_in_range(i915, size <<= 1, 4096, 0, end);
+	if (!IS_ERR(obj)) {
+		fbc->compressed_fb = obj;
 		return limit;
+	}
 
 	for (; limit <= intel_fbc_max_limit(i915); limit <<= 1) {
-		ret = i915_gem_stolen_insert_node_in_range(i915, &fbc->compressed_fb,
-							   size >>= 1, 4096, 0, end);
-		if (ret == 0)
+		obj = i915_gem_object_create_stolen_in_range(i915, size >>= 1, 4096, 0, end);
+		if (!IS_ERR(obj)) {
+			fbc->compressed_fb = obj;
 			return limit;
+		}
 	}
 
 	return 0;
@@ -765,17 +772,19 @@ static int intel_fbc_alloc_cfb(struct intel_fbc *fbc,
 {
 	struct drm_i915_private *i915 = fbc->i915;
 	int ret;
+	struct drm_i915_gem_object *obj;
 
-	drm_WARN_ON(&i915->drm,
-		    drm_mm_node_allocated(&fbc->compressed_fb));
-	drm_WARN_ON(&i915->drm,
-		    drm_mm_node_allocated(&fbc->compressed_llb));
+	drm_WARN_ON(&i915->drm, fbc->compressed_fb);
+	drm_WARN_ON(&i915->drm, fbc->compressed_llb);
 
 	if (DISPLAY_VER(i915) < 5 && !IS_G4X(i915)) {
-		ret = i915_gem_stolen_insert_node(i915, &fbc->compressed_llb,
-						  4096, 4096);
-		if (ret)
+		obj = i915_gem_object_create_stolen_in_range(i915, 4096, 4096,
+							     I915_GEM_STOLEN_BIAS, U64_MAX);
+		if (IS_ERR(obj)) {
+			ret = PTR_ERR(obj);
 			goto err;
+		}
+		fbc->compressed_llb = obj;
 	}
 
 	ret = find_compression_limit(fbc, size, min_limit);
@@ -788,14 +797,13 @@ static int intel_fbc_alloc_cfb(struct intel_fbc *fbc,
 	fbc->limit = ret;
 
 	drm_dbg_kms(&i915->drm,
-		    "reserved %llu bytes of contiguous stolen space for FBC, limit: %d\n",
-		    fbc->compressed_fb.size, fbc->limit);
+		    "reserved %lu bytes of contiguous stolen space for FBC, limit: %d\n",
+		    fbc->compressed_fb->base.size, fbc->limit);
 
 	return 0;
 
 err_llb:
-	if (drm_mm_node_allocated(&fbc->compressed_llb))
-		i915_gem_stolen_remove_node(i915, &fbc->compressed_llb);
+	i915_gem_object_put(fetch_and_zero(&fbc->compressed_llb));
 err:
 	if (drm_mm_initialized(&i915->mm.stolen))
 		drm_info_once(&i915->drm, "not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
@@ -809,15 +817,13 @@ static void intel_fbc_program_cfb(struct intel_fbc *fbc)
 
 static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
 {
-	struct drm_i915_private *i915 = fbc->i915;
-
 	if (WARN_ON(intel_fbc_hw_is_active(fbc)))
 		return;
 
-	if (drm_mm_node_allocated(&fbc->compressed_llb))
-		i915_gem_stolen_remove_node(i915, &fbc->compressed_llb);
-	if (drm_mm_node_allocated(&fbc->compressed_fb))
-		i915_gem_stolen_remove_node(i915, &fbc->compressed_fb);
+	if (fbc->compressed_llb)
+		i915_gem_object_put(fetch_and_zero(&fbc->compressed_llb));
+	if (fbc->compressed_fb)
+		i915_gem_object_put(fetch_and_zero(&fbc->compressed_fb));
 }
 
 void intel_fbc_cleanup(struct drm_i915_private *i915)
@@ -1023,7 +1029,7 @@ static bool intel_fbc_is_cfb_ok(const struct intel_plane_state *plane_state)
 	struct intel_fbc *fbc = plane->fbc;
 
 	return intel_fbc_min_limit(plane_state) <= fbc->limit &&
-		intel_fbc_cfb_size(plane_state) <= fbc->compressed_fb.size * fbc->limit;
+		intel_fbc_cfb_size(plane_state) <= fbc->compressed_fb->base.size * fbc->limit;
 }
 
 static bool intel_fbc_is_ok(const struct intel_plane_state *plane_state)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index 0bf8f61134af..265133cb2a47 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -907,6 +907,66 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *i915,
 	return ERR_PTR(ret);
 }
 
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen_in_range(struct drm_i915_private *i915,
+				       resource_size_t size,
+				       resource_size_t alignment,
+				       u64 start, u64 end)
+{
+	struct intel_memory_region *mem = i915->mm.stolen_region;
+	struct drm_i915_gem_object *obj;
+	struct drm_mm_node *stolen;
+	int ret;
+
+	if (!drm_mm_initialized(&i915->mm.stolen))
+		return ERR_PTR(-ENODEV);
+
+	/* KISS and expect everything to be page-aligned */
+	if (GEM_WARN_ON(size == 0) ||
+	    GEM_WARN_ON(!IS_ALIGNED(size, mem->min_page_size)) ||
+	    GEM_WARN_ON(!IS_ALIGNED(alignment, mem->min_page_size)))
+		return ERR_PTR(-EINVAL);
+
+	stolen = kzalloc(sizeof(*stolen), GFP_KERNEL);
+	if (!stolen)
+		return ERR_PTR(-ENOMEM);
+
+	ret = i915_gem_stolen_insert_node_in_range(i915, stolen, size,
+						   alignment, start, end);
+	if (ret)
+		goto err_free;
+
+	obj = i915_gem_object_alloc();
+	if (!obj) {
+		ret = -ENOMEM;
+		goto err_stolen;
+	}
+
+	ret = __i915_gem_object_create_stolen(mem, obj, stolen);
+	if (ret)
+		goto err_object_free;
+
+	i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
+	return obj;
+
+err_object_free:
+	i915_gem_object_free(obj);
+err_stolen:
+	i915_gem_stolen_remove_node(i915, stolen);
+err_free:
+	kfree(stolen);
+	return ERR_PTR(ret);
+}
+
+u64 i915_gem_object_stolen_offset(const struct drm_i915_gem_object *obj)
+{
+	if (!obj || !i915_gem_object_is_stolen(obj))
+		return 0;
+
+	return obj->stolen->start;
+}
+
+
 bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj)
 {
 	return obj->ops == &i915_gem_object_stolen_ops;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.h b/drivers/gpu/drm/i915/gem/i915_gem_stolen.h
index ccdf7befc571..494e90f130f4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.h
@@ -35,6 +35,13 @@ struct drm_i915_gem_object *
 i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv,
 					       resource_size_t stolen_offset,
 					       resource_size_t size);
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen_in_range(struct drm_i915_private *i915,
+				       resource_size_t size,
+				       resource_size_t alignment,
+				       u64 start, u64 end);
+u64 i915_gem_object_stolen_offset(const struct drm_i915_gem_object *obj);
+
 
 bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj);
 
-- 
2.25.1


WARNING: multiple messages have this Message-ID (diff)
From: Robert Beckett <bob.beckett@collabora.com>
To: intel-gfx@lists.freedesktop.org,
	Jani Nikula <jani.nikula@linux.intel.com>,
	Joonas Lahtinen <joonas.lahtinen@linux.intel.com>,
	Rodrigo Vivi <rodrigo.vivi@intel.com>,
	Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>,
	David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>
Cc: Robert Beckett <bob.beckett@collabora.com>,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH 3/7] drm/i915: use gem objects to track stolen nodes
Date: Tue, 15 Mar 2022 18:04:40 +0000	[thread overview]
Message-ID: <20220315180444.3327283-4-bob.beckett@collabora.com> (raw)
In-Reply-To: <20220315180444.3327283-1-bob.beckett@collabora.com>

Construct gem objects around stolen nodes.
This stops the abuse of interfaces and aids future patches that done use
drm nodes for stolen areas.

Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
---
 drivers/gpu/drm/i915/display/intel_fbc.c   | 72 ++++++++++++----------
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 60 ++++++++++++++++++
 drivers/gpu/drm/i915/gem/i915_gem_stolen.h |  7 +++
 3 files changed, 106 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 142280b6ce6d..9df64ecab70e 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -92,8 +92,8 @@ struct intel_fbc {
 	unsigned int possible_framebuffer_bits;
 	unsigned int busy_bits;
 
-	struct drm_mm_node compressed_fb;
-	struct drm_mm_node compressed_llb;
+	struct drm_i915_gem_object *compressed_fb;
+	struct drm_i915_gem_object *compressed_llb;
 
 	enum intel_fbc_id id;
 
@@ -331,16 +331,18 @@ static void i8xx_fbc_nuke(struct intel_fbc *fbc)
 static void i8xx_fbc_program_cfb(struct intel_fbc *fbc)
 {
 	struct drm_i915_private *i915 = fbc->i915;
+	u64 fb_offset = i915_gem_object_stolen_offset(fbc->compressed_fb);
+	u64 llb_offset = i915_gem_object_stolen_offset(fbc->compressed_llb);
 
 	GEM_BUG_ON(range_overflows_end_t(u64, i915->dsm.start,
-					 fbc->compressed_fb.start, U32_MAX));
+					 fb_offset, U32_MAX));
 	GEM_BUG_ON(range_overflows_end_t(u64, i915->dsm.start,
-					 fbc->compressed_llb.start, U32_MAX));
+					 llb_offset, U32_MAX));
 
 	intel_de_write(i915, FBC_CFB_BASE,
-		       i915->dsm.start + fbc->compressed_fb.start);
+		       i915->dsm.start + fb_offset);
 	intel_de_write(i915, FBC_LL_BASE,
-		       i915->dsm.start + fbc->compressed_llb.start);
+		       i915->dsm.start + llb_offset);
 }
 
 static const struct intel_fbc_funcs i8xx_fbc_funcs = {
@@ -449,7 +451,8 @@ static void g4x_fbc_program_cfb(struct intel_fbc *fbc)
 {
 	struct drm_i915_private *i915 = fbc->i915;
 
-	intel_de_write(i915, DPFC_CB_BASE, fbc->compressed_fb.start);
+	intel_de_write(i915, DPFC_CB_BASE,
+		       i915_gem_object_stolen_offset(fbc->compressed_fb));
 }
 
 static const struct intel_fbc_funcs g4x_fbc_funcs = {
@@ -500,7 +503,8 @@ static void ilk_fbc_program_cfb(struct intel_fbc *fbc)
 {
 	struct drm_i915_private *i915 = fbc->i915;
 
-	intel_de_write(i915, ILK_DPFC_CB_BASE(fbc->id), fbc->compressed_fb.start);
+	intel_de_write(i915, ILK_DPFC_CB_BASE(fbc->id),
+			i915_gem_object_stolen_offset(fbc->compressed_fb));
 }
 
 static const struct intel_fbc_funcs ilk_fbc_funcs = {
@@ -740,21 +744,24 @@ static int find_compression_limit(struct intel_fbc *fbc,
 {
 	struct drm_i915_private *i915 = fbc->i915;
 	u64 end = intel_fbc_stolen_end(i915);
-	int ret, limit = min_limit;
+	int limit = min_limit;
+	struct drm_i915_gem_object *obj;
 
 	size /= limit;
 
 	/* Try to over-allocate to reduce reallocations and fragmentation. */
-	ret = i915_gem_stolen_insert_node_in_range(i915, &fbc->compressed_fb,
-						   size <<= 1, 4096, 0, end);
-	if (ret == 0)
+	obj = i915_gem_object_create_stolen_in_range(i915, size <<= 1, 4096, 0, end);
+	if (!IS_ERR(obj)) {
+		fbc->compressed_fb = obj;
 		return limit;
+	}
 
 	for (; limit <= intel_fbc_max_limit(i915); limit <<= 1) {
-		ret = i915_gem_stolen_insert_node_in_range(i915, &fbc->compressed_fb,
-							   size >>= 1, 4096, 0, end);
-		if (ret == 0)
+		obj = i915_gem_object_create_stolen_in_range(i915, size >>= 1, 4096, 0, end);
+		if (!IS_ERR(obj)) {
+			fbc->compressed_fb = obj;
 			return limit;
+		}
 	}
 
 	return 0;
@@ -765,17 +772,19 @@ static int intel_fbc_alloc_cfb(struct intel_fbc *fbc,
 {
 	struct drm_i915_private *i915 = fbc->i915;
 	int ret;
+	struct drm_i915_gem_object *obj;
 
-	drm_WARN_ON(&i915->drm,
-		    drm_mm_node_allocated(&fbc->compressed_fb));
-	drm_WARN_ON(&i915->drm,
-		    drm_mm_node_allocated(&fbc->compressed_llb));
+	drm_WARN_ON(&i915->drm, fbc->compressed_fb);
+	drm_WARN_ON(&i915->drm, fbc->compressed_llb);
 
 	if (DISPLAY_VER(i915) < 5 && !IS_G4X(i915)) {
-		ret = i915_gem_stolen_insert_node(i915, &fbc->compressed_llb,
-						  4096, 4096);
-		if (ret)
+		obj = i915_gem_object_create_stolen_in_range(i915, 4096, 4096,
+							     I915_GEM_STOLEN_BIAS, U64_MAX);
+		if (IS_ERR(obj)) {
+			ret = PTR_ERR(obj);
 			goto err;
+		}
+		fbc->compressed_llb = obj;
 	}
 
 	ret = find_compression_limit(fbc, size, min_limit);
@@ -788,14 +797,13 @@ static int intel_fbc_alloc_cfb(struct intel_fbc *fbc,
 	fbc->limit = ret;
 
 	drm_dbg_kms(&i915->drm,
-		    "reserved %llu bytes of contiguous stolen space for FBC, limit: %d\n",
-		    fbc->compressed_fb.size, fbc->limit);
+		    "reserved %lu bytes of contiguous stolen space for FBC, limit: %d\n",
+		    fbc->compressed_fb->base.size, fbc->limit);
 
 	return 0;
 
 err_llb:
-	if (drm_mm_node_allocated(&fbc->compressed_llb))
-		i915_gem_stolen_remove_node(i915, &fbc->compressed_llb);
+	i915_gem_object_put(fetch_and_zero(&fbc->compressed_llb));
 err:
 	if (drm_mm_initialized(&i915->mm.stolen))
 		drm_info_once(&i915->drm, "not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
@@ -809,15 +817,13 @@ static void intel_fbc_program_cfb(struct intel_fbc *fbc)
 
 static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
 {
-	struct drm_i915_private *i915 = fbc->i915;
-
 	if (WARN_ON(intel_fbc_hw_is_active(fbc)))
 		return;
 
-	if (drm_mm_node_allocated(&fbc->compressed_llb))
-		i915_gem_stolen_remove_node(i915, &fbc->compressed_llb);
-	if (drm_mm_node_allocated(&fbc->compressed_fb))
-		i915_gem_stolen_remove_node(i915, &fbc->compressed_fb);
+	if (fbc->compressed_llb)
+		i915_gem_object_put(fetch_and_zero(&fbc->compressed_llb));
+	if (fbc->compressed_fb)
+		i915_gem_object_put(fetch_and_zero(&fbc->compressed_fb));
 }
 
 void intel_fbc_cleanup(struct drm_i915_private *i915)
@@ -1023,7 +1029,7 @@ static bool intel_fbc_is_cfb_ok(const struct intel_plane_state *plane_state)
 	struct intel_fbc *fbc = plane->fbc;
 
 	return intel_fbc_min_limit(plane_state) <= fbc->limit &&
-		intel_fbc_cfb_size(plane_state) <= fbc->compressed_fb.size * fbc->limit;
+		intel_fbc_cfb_size(plane_state) <= fbc->compressed_fb->base.size * fbc->limit;
 }
 
 static bool intel_fbc_is_ok(const struct intel_plane_state *plane_state)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index 0bf8f61134af..265133cb2a47 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -907,6 +907,66 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *i915,
 	return ERR_PTR(ret);
 }
 
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen_in_range(struct drm_i915_private *i915,
+				       resource_size_t size,
+				       resource_size_t alignment,
+				       u64 start, u64 end)
+{
+	struct intel_memory_region *mem = i915->mm.stolen_region;
+	struct drm_i915_gem_object *obj;
+	struct drm_mm_node *stolen;
+	int ret;
+
+	if (!drm_mm_initialized(&i915->mm.stolen))
+		return ERR_PTR(-ENODEV);
+
+	/* KISS and expect everything to be page-aligned */
+	if (GEM_WARN_ON(size == 0) ||
+	    GEM_WARN_ON(!IS_ALIGNED(size, mem->min_page_size)) ||
+	    GEM_WARN_ON(!IS_ALIGNED(alignment, mem->min_page_size)))
+		return ERR_PTR(-EINVAL);
+
+	stolen = kzalloc(sizeof(*stolen), GFP_KERNEL);
+	if (!stolen)
+		return ERR_PTR(-ENOMEM);
+
+	ret = i915_gem_stolen_insert_node_in_range(i915, stolen, size,
+						   alignment, start, end);
+	if (ret)
+		goto err_free;
+
+	obj = i915_gem_object_alloc();
+	if (!obj) {
+		ret = -ENOMEM;
+		goto err_stolen;
+	}
+
+	ret = __i915_gem_object_create_stolen(mem, obj, stolen);
+	if (ret)
+		goto err_object_free;
+
+	i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
+	return obj;
+
+err_object_free:
+	i915_gem_object_free(obj);
+err_stolen:
+	i915_gem_stolen_remove_node(i915, stolen);
+err_free:
+	kfree(stolen);
+	return ERR_PTR(ret);
+}
+
+u64 i915_gem_object_stolen_offset(const struct drm_i915_gem_object *obj)
+{
+	if (!obj || !i915_gem_object_is_stolen(obj))
+		return 0;
+
+	return obj->stolen->start;
+}
+
+
 bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj)
 {
 	return obj->ops == &i915_gem_object_stolen_ops;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.h b/drivers/gpu/drm/i915/gem/i915_gem_stolen.h
index ccdf7befc571..494e90f130f4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.h
@@ -35,6 +35,13 @@ struct drm_i915_gem_object *
 i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv,
 					       resource_size_t stolen_offset,
 					       resource_size_t size);
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen_in_range(struct drm_i915_private *i915,
+				       resource_size_t size,
+				       resource_size_t alignment,
+				       u64 start, u64 end);
+u64 i915_gem_object_stolen_offset(const struct drm_i915_gem_object *obj);
+
 
 bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj);
 
-- 
2.25.1


WARNING: multiple messages have this Message-ID (diff)
From: Robert Beckett <bob.beckett@collabora.com>
To: intel-gfx@lists.freedesktop.org,
	Jani Nikula <jani.nikula@linux.intel.com>,
	Joonas Lahtinen <joonas.lahtinen@linux.intel.com>,
	Rodrigo Vivi <rodrigo.vivi@intel.com>,
	Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>,
	David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>
Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org
Subject: [Intel-gfx] [RFC PATCH 3/7] drm/i915: use gem objects to track stolen nodes
Date: Tue, 15 Mar 2022 18:04:40 +0000	[thread overview]
Message-ID: <20220315180444.3327283-4-bob.beckett@collabora.com> (raw)
In-Reply-To: <20220315180444.3327283-1-bob.beckett@collabora.com>

Construct gem objects around stolen nodes.
This stops the abuse of interfaces and aids future patches that done use
drm nodes for stolen areas.

Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
---
 drivers/gpu/drm/i915/display/intel_fbc.c   | 72 ++++++++++++----------
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 60 ++++++++++++++++++
 drivers/gpu/drm/i915/gem/i915_gem_stolen.h |  7 +++
 3 files changed, 106 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 142280b6ce6d..9df64ecab70e 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -92,8 +92,8 @@ struct intel_fbc {
 	unsigned int possible_framebuffer_bits;
 	unsigned int busy_bits;
 
-	struct drm_mm_node compressed_fb;
-	struct drm_mm_node compressed_llb;
+	struct drm_i915_gem_object *compressed_fb;
+	struct drm_i915_gem_object *compressed_llb;
 
 	enum intel_fbc_id id;
 
@@ -331,16 +331,18 @@ static void i8xx_fbc_nuke(struct intel_fbc *fbc)
 static void i8xx_fbc_program_cfb(struct intel_fbc *fbc)
 {
 	struct drm_i915_private *i915 = fbc->i915;
+	u64 fb_offset = i915_gem_object_stolen_offset(fbc->compressed_fb);
+	u64 llb_offset = i915_gem_object_stolen_offset(fbc->compressed_llb);
 
 	GEM_BUG_ON(range_overflows_end_t(u64, i915->dsm.start,
-					 fbc->compressed_fb.start, U32_MAX));
+					 fb_offset, U32_MAX));
 	GEM_BUG_ON(range_overflows_end_t(u64, i915->dsm.start,
-					 fbc->compressed_llb.start, U32_MAX));
+					 llb_offset, U32_MAX));
 
 	intel_de_write(i915, FBC_CFB_BASE,
-		       i915->dsm.start + fbc->compressed_fb.start);
+		       i915->dsm.start + fb_offset);
 	intel_de_write(i915, FBC_LL_BASE,
-		       i915->dsm.start + fbc->compressed_llb.start);
+		       i915->dsm.start + llb_offset);
 }
 
 static const struct intel_fbc_funcs i8xx_fbc_funcs = {
@@ -449,7 +451,8 @@ static void g4x_fbc_program_cfb(struct intel_fbc *fbc)
 {
 	struct drm_i915_private *i915 = fbc->i915;
 
-	intel_de_write(i915, DPFC_CB_BASE, fbc->compressed_fb.start);
+	intel_de_write(i915, DPFC_CB_BASE,
+		       i915_gem_object_stolen_offset(fbc->compressed_fb));
 }
 
 static const struct intel_fbc_funcs g4x_fbc_funcs = {
@@ -500,7 +503,8 @@ static void ilk_fbc_program_cfb(struct intel_fbc *fbc)
 {
 	struct drm_i915_private *i915 = fbc->i915;
 
-	intel_de_write(i915, ILK_DPFC_CB_BASE(fbc->id), fbc->compressed_fb.start);
+	intel_de_write(i915, ILK_DPFC_CB_BASE(fbc->id),
+			i915_gem_object_stolen_offset(fbc->compressed_fb));
 }
 
 static const struct intel_fbc_funcs ilk_fbc_funcs = {
@@ -740,21 +744,24 @@ static int find_compression_limit(struct intel_fbc *fbc,
 {
 	struct drm_i915_private *i915 = fbc->i915;
 	u64 end = intel_fbc_stolen_end(i915);
-	int ret, limit = min_limit;
+	int limit = min_limit;
+	struct drm_i915_gem_object *obj;
 
 	size /= limit;
 
 	/* Try to over-allocate to reduce reallocations and fragmentation. */
-	ret = i915_gem_stolen_insert_node_in_range(i915, &fbc->compressed_fb,
-						   size <<= 1, 4096, 0, end);
-	if (ret == 0)
+	obj = i915_gem_object_create_stolen_in_range(i915, size <<= 1, 4096, 0, end);
+	if (!IS_ERR(obj)) {
+		fbc->compressed_fb = obj;
 		return limit;
+	}
 
 	for (; limit <= intel_fbc_max_limit(i915); limit <<= 1) {
-		ret = i915_gem_stolen_insert_node_in_range(i915, &fbc->compressed_fb,
-							   size >>= 1, 4096, 0, end);
-		if (ret == 0)
+		obj = i915_gem_object_create_stolen_in_range(i915, size >>= 1, 4096, 0, end);
+		if (!IS_ERR(obj)) {
+			fbc->compressed_fb = obj;
 			return limit;
+		}
 	}
 
 	return 0;
@@ -765,17 +772,19 @@ static int intel_fbc_alloc_cfb(struct intel_fbc *fbc,
 {
 	struct drm_i915_private *i915 = fbc->i915;
 	int ret;
+	struct drm_i915_gem_object *obj;
 
-	drm_WARN_ON(&i915->drm,
-		    drm_mm_node_allocated(&fbc->compressed_fb));
-	drm_WARN_ON(&i915->drm,
-		    drm_mm_node_allocated(&fbc->compressed_llb));
+	drm_WARN_ON(&i915->drm, fbc->compressed_fb);
+	drm_WARN_ON(&i915->drm, fbc->compressed_llb);
 
 	if (DISPLAY_VER(i915) < 5 && !IS_G4X(i915)) {
-		ret = i915_gem_stolen_insert_node(i915, &fbc->compressed_llb,
-						  4096, 4096);
-		if (ret)
+		obj = i915_gem_object_create_stolen_in_range(i915, 4096, 4096,
+							     I915_GEM_STOLEN_BIAS, U64_MAX);
+		if (IS_ERR(obj)) {
+			ret = PTR_ERR(obj);
 			goto err;
+		}
+		fbc->compressed_llb = obj;
 	}
 
 	ret = find_compression_limit(fbc, size, min_limit);
@@ -788,14 +797,13 @@ static int intel_fbc_alloc_cfb(struct intel_fbc *fbc,
 	fbc->limit = ret;
 
 	drm_dbg_kms(&i915->drm,
-		    "reserved %llu bytes of contiguous stolen space for FBC, limit: %d\n",
-		    fbc->compressed_fb.size, fbc->limit);
+		    "reserved %lu bytes of contiguous stolen space for FBC, limit: %d\n",
+		    fbc->compressed_fb->base.size, fbc->limit);
 
 	return 0;
 
 err_llb:
-	if (drm_mm_node_allocated(&fbc->compressed_llb))
-		i915_gem_stolen_remove_node(i915, &fbc->compressed_llb);
+	i915_gem_object_put(fetch_and_zero(&fbc->compressed_llb));
 err:
 	if (drm_mm_initialized(&i915->mm.stolen))
 		drm_info_once(&i915->drm, "not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
@@ -809,15 +817,13 @@ static void intel_fbc_program_cfb(struct intel_fbc *fbc)
 
 static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
 {
-	struct drm_i915_private *i915 = fbc->i915;
-
 	if (WARN_ON(intel_fbc_hw_is_active(fbc)))
 		return;
 
-	if (drm_mm_node_allocated(&fbc->compressed_llb))
-		i915_gem_stolen_remove_node(i915, &fbc->compressed_llb);
-	if (drm_mm_node_allocated(&fbc->compressed_fb))
-		i915_gem_stolen_remove_node(i915, &fbc->compressed_fb);
+	if (fbc->compressed_llb)
+		i915_gem_object_put(fetch_and_zero(&fbc->compressed_llb));
+	if (fbc->compressed_fb)
+		i915_gem_object_put(fetch_and_zero(&fbc->compressed_fb));
 }
 
 void intel_fbc_cleanup(struct drm_i915_private *i915)
@@ -1023,7 +1029,7 @@ static bool intel_fbc_is_cfb_ok(const struct intel_plane_state *plane_state)
 	struct intel_fbc *fbc = plane->fbc;
 
 	return intel_fbc_min_limit(plane_state) <= fbc->limit &&
-		intel_fbc_cfb_size(plane_state) <= fbc->compressed_fb.size * fbc->limit;
+		intel_fbc_cfb_size(plane_state) <= fbc->compressed_fb->base.size * fbc->limit;
 }
 
 static bool intel_fbc_is_ok(const struct intel_plane_state *plane_state)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index 0bf8f61134af..265133cb2a47 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -907,6 +907,66 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *i915,
 	return ERR_PTR(ret);
 }
 
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen_in_range(struct drm_i915_private *i915,
+				       resource_size_t size,
+				       resource_size_t alignment,
+				       u64 start, u64 end)
+{
+	struct intel_memory_region *mem = i915->mm.stolen_region;
+	struct drm_i915_gem_object *obj;
+	struct drm_mm_node *stolen;
+	int ret;
+
+	if (!drm_mm_initialized(&i915->mm.stolen))
+		return ERR_PTR(-ENODEV);
+
+	/* KISS and expect everything to be page-aligned */
+	if (GEM_WARN_ON(size == 0) ||
+	    GEM_WARN_ON(!IS_ALIGNED(size, mem->min_page_size)) ||
+	    GEM_WARN_ON(!IS_ALIGNED(alignment, mem->min_page_size)))
+		return ERR_PTR(-EINVAL);
+
+	stolen = kzalloc(sizeof(*stolen), GFP_KERNEL);
+	if (!stolen)
+		return ERR_PTR(-ENOMEM);
+
+	ret = i915_gem_stolen_insert_node_in_range(i915, stolen, size,
+						   alignment, start, end);
+	if (ret)
+		goto err_free;
+
+	obj = i915_gem_object_alloc();
+	if (!obj) {
+		ret = -ENOMEM;
+		goto err_stolen;
+	}
+
+	ret = __i915_gem_object_create_stolen(mem, obj, stolen);
+	if (ret)
+		goto err_object_free;
+
+	i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
+	return obj;
+
+err_object_free:
+	i915_gem_object_free(obj);
+err_stolen:
+	i915_gem_stolen_remove_node(i915, stolen);
+err_free:
+	kfree(stolen);
+	return ERR_PTR(ret);
+}
+
+u64 i915_gem_object_stolen_offset(const struct drm_i915_gem_object *obj)
+{
+	if (!obj || !i915_gem_object_is_stolen(obj))
+		return 0;
+
+	return obj->stolen->start;
+}
+
+
 bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj)
 {
 	return obj->ops == &i915_gem_object_stolen_ops;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.h b/drivers/gpu/drm/i915/gem/i915_gem_stolen.h
index ccdf7befc571..494e90f130f4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.h
@@ -35,6 +35,13 @@ struct drm_i915_gem_object *
 i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv,
 					       resource_size_t stolen_offset,
 					       resource_size_t size);
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen_in_range(struct drm_i915_private *i915,
+				       resource_size_t size,
+				       resource_size_t alignment,
+				       u64 start, u64 end);
+u64 i915_gem_object_stolen_offset(const struct drm_i915_gem_object *obj);
+
 
 bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj);
 
-- 
2.25.1


  parent reply	other threads:[~2022-03-15 18:05 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-15 18:04 [Intel-gfx] [RFC PATCH 0/7] drm/i915: ttm for stolen Robert Beckett
2022-03-15 18:04 ` [RFC PATCH 1/7] drm/i915: instantiate ttm ranger manager for stolen memory Robert Beckett
2022-03-15 18:04   ` [Intel-gfx] " Robert Beckett
2022-03-15 18:04   ` Robert Beckett
2022-03-15 18:04 ` [RFC PATCH 2/7] drm/i915: add ability to create memory region object in place Robert Beckett
2022-03-15 18:04   ` [Intel-gfx] " Robert Beckett
2022-03-15 18:04   ` Robert Beckett
2022-03-15 18:04 ` Robert Beckett [this message]
2022-03-15 18:04   ` [Intel-gfx] [RFC PATCH 3/7] drm/i915: use gem objects to track stolen nodes Robert Beckett
2022-03-15 18:04   ` Robert Beckett
2022-03-15 18:04 ` [RFC PATCH 4/7] drm/i915: stolen memory use ttm backend Robert Beckett
2022-03-15 18:04   ` [Intel-gfx] " Robert Beckett
2022-03-15 18:04   ` Robert Beckett
2022-03-15 18:04 ` [RFC PATCH 5/7] drm/ttm: add range busy check for range manager Robert Beckett
2022-03-15 18:04   ` [Intel-gfx] " Robert Beckett
2022-03-15 18:04   ` Robert Beckett
2022-03-16  9:54   ` Christian König
2022-03-16  9:54     ` Christian König
2022-03-16  9:54     ` [Intel-gfx] " Christian König
2022-03-16 13:19     ` Robert Beckett
2022-03-16 13:19       ` Robert Beckett
2022-03-16 13:19       ` [Intel-gfx] " Robert Beckett
2022-03-16 13:43       ` Christian König
2022-03-16 13:43         ` [Intel-gfx] " Christian König
2022-03-16 13:43         ` Christian König
2022-03-16 14:26         ` Robert Beckett
2022-03-16 14:26           ` [Intel-gfx] " Robert Beckett
2022-03-16 14:26           ` Robert Beckett
2022-03-16 14:39           ` Christian König
2022-03-16 14:39             ` [Intel-gfx] " Christian König
2022-03-16 14:39             ` Christian König
2022-03-16 15:28             ` Robert Beckett
2022-03-16 15:28               ` [Intel-gfx] " Robert Beckett
2022-03-17  7:00               ` Christian König
2022-03-17  7:00                 ` [Intel-gfx] " Christian König
2022-03-15 18:04 ` [RFC PATCH 6/7] drm/i915: add range busy check for ttm region Robert Beckett
2022-03-15 18:04   ` [Intel-gfx] " Robert Beckett
2022-03-15 18:04   ` Robert Beckett
2022-03-15 18:04 ` [RFC PATCH 7/7] drm/i915: cleanup old stolen state Robert Beckett
2022-03-15 18:04   ` [Intel-gfx] " Robert Beckett
2022-03-15 18:04   ` Robert Beckett
2022-03-15 19:28 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: ttm for stolen Patchwork
2022-03-15 19:30 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2022-03-15 20:09 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2022-03-15 20:09 ` [Intel-gfx] ✗ Fi.CI.BUILD: warning " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220315180444.3327283-4-bob.beckett@collabora.com \
    --to=bob.beckett@collabora.com \
    --cc=airlied@linux.ie \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jani.nikula@linux.intel.com \
    --cc=joonas.lahtinen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rodrigo.vivi@intel.com \
    --cc=tvrtko.ursulin@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.