[PATCH v2 20/37] drm/i915: treat stolen as a region

Matthew Auld
2019-06-27T20:57:00Z

Convert stolen memory over to a region object. Still leaves open the
question with what to do with pre-allocated objects...

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 66 +++++++++++++++++++---
drivers/gpu/drm/i915/i915_drv.h | 3 +-
drivers/gpu/drm/i915/i915_gem_gtt.c | 14 +----
drivers/gpu/drm/i915/intel_memory_region.c | 2 +-
4 files changed, 62 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index de1fab2058ec..d0b894854921 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -149,7 +149,7 @@ static int i915_adjust_stolen(struct drm_i915_private *dev_priv,
return 0;
}

-void i915_gem_cleanup_stolen(struct drm_i915_private *dev_priv)
+static void i915_gem_cleanup_stolen(struct drm_i915_private *dev_priv)
{
if (!drm_mm_initialized(&dev_priv->mm.stolen))
return;
@@ -354,7 +354,7 @@ static void icl_get_stolen_reserved(struct drm_i915_private *i915,
}
}

-int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
+static int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
{
resource_size_t reserved_base, stolen_top;
resource_size_t reserved_total, reserved_size;
@@ -533,6 +533,9 @@ i915_gem_object_release_stolen(struct drm_i915_gem_object *obj)

i915_gem_stolen_remove_node(dev_priv, stolen);
kfree(stolen);
+
+ if (obj->memory_region)
+ i915_gem_object_release_memory_region(obj);
}

static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
@@ -542,8 +545,8 @@ static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
};

static struct drm_i915_gem_object *
-_i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
- struct drm_mm_node *stolen)
+__i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
+ struct drm_mm_node *stolen)
{
struct drm_i915_gem_object *obj;
unsigned int cache_level;
@@ -570,10 +573,12 @@ _i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
return NULL;
}

-struct drm_i915_gem_object *
-i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
- resource_size_t size)
+static struct drm_i915_gem_object *
+_i915_gem_object_create_stolen(struct intel_memory_region *mem,
+ resource_size_t size,
+ unsigned int flags)
{
+ struct drm_i915_private *dev_priv = mem->i915;
struct drm_i915_gem_object *obj;
struct drm_mm_node *stolen;
int ret;
@@ -594,7 +599,7 @@ i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
return NULL;
}

- obj = _i915_gem_object_create_stolen(dev_priv, stolen);
+ obj = __i915_gem_object_create_stolen(dev_priv, stolen);
if (obj)
return obj;

@@ -603,6 +608,49 @@ i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
return NULL;
}

+struct drm_i915_gem_object *
+i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
+ resource_size_t size)
+{
+ struct drm_i915_gem_object *obj;
+
+ obj = i915_gem_object_create_region(dev_priv->regions[INTEL_MEMORY_STOLEN],
+ size, I915_BO_ALLOC_CONTIGUOUS);
+ if (IS_ERR(obj))
+ return NULL;
+
+ return obj;
+}
+
+static int init_stolen(struct intel_memory_region *mem)
+{
+ /*
+ * Initialise stolen early so that we may reserve preallocated
+ * objects for the BIOS to KMS transition.
+ */
+ return i915_gem_init_stolen(mem->i915);
+}
+
+static void release_stolen(struct intel_memory_region *mem)
+{
+ i915_gem_cleanup_stolen(mem->i915);
+}
+
+static const struct intel_memory_region_ops i915_region_stolen_ops = {
+ .init = init_stolen,
+ .release = release_stolen,
+ .create_object = _i915_gem_object_create_stolen,
+};
+
+struct intel_memory_region *i915_gem_stolen_setup(struct drm_i915_private *i915)
+{
+ return intel_memory_region_create(i915,
+ intel_graphics_stolen_res.start,
+ resource_size(&intel_graphics_stolen_res),
+ I915_GTT_PAGE_SIZE_4K, 0,
+ &i915_region_stolen_ops);
+}
+
struct drm_i915_gem_object *
i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv,
resource_size_t stolen_offset,
@@ -644,7 +692,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv
return NULL;
}

- obj = _i915_gem_object_create_stolen(dev_priv, stolen);
+ obj = __i915_gem_object_create_stolen(dev_priv, stolen);
if (obj == NULL) {
DRM_DEBUG_DRIVER("failed to allocate stolen object\n");
i915_gem_stolen_remove_node(dev_priv, stolen);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e8f41c235e70..a124d1b17773 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2622,8 +2622,7 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
u64 end);
void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv,
struct drm_mm_node *node);
-int i915_gem_init_stolen(struct drm_i915_private *dev_priv);
-void i915_gem_cleanup_stolen(struct drm_i915_private *dev_priv);
+struct intel_memory_region *i915_gem_stolen_setup(struct drm_i915_private *i915);
struct drm_i915_gem_object *
i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
resource_size_t size);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 958c61e88200..5b7e46e487bf 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2906,8 +2906,6 @@ void i915_gem_cleanup_memory_regions(struct drm_i915_private *i915)
{
int i;

- i915_gem_cleanup_stolen(i915);
-
for (i = 0; i < ARRAY_SIZE(i915->regions); ++i) {
struct intel_memory_region *region = i915->regions[i];

@@ -2923,15 +2921,6 @@ int i915_gem_init_memory_regions(struct drm_i915_private *i915)
/* All platforms currently have system memory */
GEM_BUG_ON(!HAS_REGION(i915, REGION_SMEM));

- /*
- * Initialise stolen early so that we may reserve preallocated
- * objects for the BIOS to KMS transition.
- */
- /* XXX: stolen will become a region at some point */
- err = i915_gem_init_stolen(i915);
- if (err)
- return err;
-
for (i = 0; i < ARRAY_SIZE(intel_region_map); i++) {
struct intel_memory_region *mem = NULL;
u32 type;
@@ -2944,6 +2933,9 @@ int i915_gem_init_memory_regions(struct drm_i915_private *i915)
case INTEL_SMEM:
mem = i915_gem_shmem_setup(i915);
break;
+ case INTEL_STOLEN:
+ mem = i915_gem_stolen_setup(i915);
+ break;
}

if (IS_ERR(mem)) {
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index e6bf4bc122bd..ab57b94b27a9 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -248,7 +248,7 @@ i915_gem_object_create_region(struct intel_memory_region *mem,
return ERR_PTR(-E2BIG);

obj = mem->ops->create_object(mem, size, flags);
- if (IS_ERR(obj))
+ if (IS_ERR_OR_NULL(obj))
return obj;

INIT_LIST_HEAD(&obj->blocks);
--
2.20.1