drm/i915: add i915_gem_object_create_region_at()
Add a generic interface for allocating an object at some specific offset, and convert stolen over. Later we will want to hook this up to different backends. Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com> Reviewed-by: Nirmoy Das <nirmoy.das@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20220315181425.576828-4-matthew.auld@intel.com
This commit is contained in:
parent
d511d013e2
commit
9b78b5dade
|
@ -3,6 +3,7 @@
|
||||||
* Copyright © 2021 Intel Corporation
|
* Copyright © 2021 Intel Corporation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "gem/i915_gem_region.h"
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
#include "intel_atomic_plane.h"
|
#include "intel_atomic_plane.h"
|
||||||
#include "intel_display.h"
|
#include "intel_display.h"
|
||||||
|
@ -69,7 +70,8 @@ initial_plane_vma(struct drm_i915_private *i915,
|
||||||
size * 2 > i915->stolen_usable_size)
|
size * 2 > i915->stolen_usable_size)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
obj = i915_gem_object_create_stolen_for_preallocated(i915, base, size);
|
obj = i915_gem_object_create_region_at(i915->mm.stolen_region,
|
||||||
|
base, size, 0);
|
||||||
if (IS_ERR(obj))
|
if (IS_ERR(obj))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ __i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
|
||||||
*/
|
*/
|
||||||
flags = I915_BO_ALLOC_USER;
|
flags = I915_BO_ALLOC_USER;
|
||||||
|
|
||||||
ret = mr->ops->init_object(mr, obj, size, 0, flags);
|
ret = mr->ops->init_object(mr, obj, I915_BO_INVALID_OFFSET, size, 0, flags);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto object_free;
|
goto object_free;
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,12 @@ void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj)
|
||||||
mutex_unlock(&mem->objects.lock);
|
mutex_unlock(&mem->objects.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drm_i915_gem_object *
|
static struct drm_i915_gem_object *
|
||||||
i915_gem_object_create_region(struct intel_memory_region *mem,
|
__i915_gem_object_create_region(struct intel_memory_region *mem,
|
||||||
resource_size_t size,
|
resource_size_t offset,
|
||||||
resource_size_t page_size,
|
resource_size_t size,
|
||||||
unsigned int flags)
|
resource_size_t page_size,
|
||||||
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
struct drm_i915_gem_object *obj;
|
struct drm_i915_gem_object *obj;
|
||||||
resource_size_t default_page_size;
|
resource_size_t default_page_size;
|
||||||
|
@ -86,7 +87,7 @@ i915_gem_object_create_region(struct intel_memory_region *mem,
|
||||||
if (default_page_size < mem->min_page_size)
|
if (default_page_size < mem->min_page_size)
|
||||||
flags |= I915_BO_ALLOC_PM_EARLY;
|
flags |= I915_BO_ALLOC_PM_EARLY;
|
||||||
|
|
||||||
err = mem->ops->init_object(mem, obj, size, page_size, flags);
|
err = mem->ops->init_object(mem, obj, offset, size, page_size, flags);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_object_free;
|
goto err_object_free;
|
||||||
|
|
||||||
|
@ -98,6 +99,40 @@ err_object_free:
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct drm_i915_gem_object *
|
||||||
|
i915_gem_object_create_region(struct intel_memory_region *mem,
|
||||||
|
resource_size_t size,
|
||||||
|
resource_size_t page_size,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
return __i915_gem_object_create_region(mem, I915_BO_INVALID_OFFSET,
|
||||||
|
size, page_size, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct drm_i915_gem_object *
|
||||||
|
i915_gem_object_create_region_at(struct intel_memory_region *mem,
|
||||||
|
resource_size_t offset,
|
||||||
|
resource_size_t size,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
GEM_BUG_ON(offset == I915_BO_INVALID_OFFSET);
|
||||||
|
|
||||||
|
if (GEM_WARN_ON(!IS_ALIGNED(size, mem->min_page_size)) ||
|
||||||
|
GEM_WARN_ON(!IS_ALIGNED(offset, mem->min_page_size)))
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
if (range_overflows(offset, size, resource_size(&mem->region)))
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
if (!(flags & I915_BO_ALLOC_GPU_ONLY) &&
|
||||||
|
offset + size > mem->io_size &&
|
||||||
|
!i915_ggtt_has_aperture(to_gt(mem->i915)->ggtt))
|
||||||
|
return ERR_PTR(-ENOSPC);
|
||||||
|
|
||||||
|
return __i915_gem_object_create_region(mem, offset, size, 0,
|
||||||
|
flags | I915_BO_ALLOC_CONTIGUOUS);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i915_gem_process_region - Iterate over all objects of a region using ops
|
* i915_gem_process_region - Iterate over all objects of a region using ops
|
||||||
* to process and optionally skip objects
|
* to process and optionally skip objects
|
||||||
|
|
|
@ -14,6 +14,8 @@ struct sg_table;
|
||||||
|
|
||||||
struct i915_gem_apply_to_region;
|
struct i915_gem_apply_to_region;
|
||||||
|
|
||||||
|
#define I915_BO_INVALID_OFFSET ((resource_size_t)-1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct i915_gem_apply_to_region_ops - ops to use when iterating over all
|
* struct i915_gem_apply_to_region_ops - ops to use when iterating over all
|
||||||
* region objects.
|
* region objects.
|
||||||
|
@ -56,6 +58,11 @@ i915_gem_object_create_region(struct intel_memory_region *mem,
|
||||||
resource_size_t size,
|
resource_size_t size,
|
||||||
resource_size_t page_size,
|
resource_size_t page_size,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
struct drm_i915_gem_object *
|
||||||
|
i915_gem_object_create_region_at(struct intel_memory_region *mem,
|
||||||
|
resource_size_t offset,
|
||||||
|
resource_size_t size,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
int i915_gem_process_region(struct intel_memory_region *mr,
|
int i915_gem_process_region(struct intel_memory_region *mr,
|
||||||
struct i915_gem_apply_to_region *apply);
|
struct i915_gem_apply_to_region *apply);
|
||||||
|
|
|
@ -552,6 +552,7 @@ static int __create_shmem(struct drm_i915_private *i915,
|
||||||
|
|
||||||
static int shmem_object_init(struct intel_memory_region *mem,
|
static int shmem_object_init(struct intel_memory_region *mem,
|
||||||
struct drm_i915_gem_object *obj,
|
struct drm_i915_gem_object *obj,
|
||||||
|
resource_size_t offset,
|
||||||
resource_size_t size,
|
resource_size_t size,
|
||||||
resource_size_t page_size,
|
resource_size_t page_size,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
|
|
|
@ -681,6 +681,7 @@ static int __i915_gem_object_create_stolen(struct intel_memory_region *mem,
|
||||||
|
|
||||||
static int _i915_gem_object_stolen_init(struct intel_memory_region *mem,
|
static int _i915_gem_object_stolen_init(struct intel_memory_region *mem,
|
||||||
struct drm_i915_gem_object *obj,
|
struct drm_i915_gem_object *obj,
|
||||||
|
resource_size_t offset,
|
||||||
resource_size_t size,
|
resource_size_t size,
|
||||||
resource_size_t page_size,
|
resource_size_t page_size,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
|
@ -707,8 +708,20 @@ static int _i915_gem_object_stolen_init(struct intel_memory_region *mem,
|
||||||
if (!stolen)
|
if (!stolen)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = i915_gem_stolen_insert_node(i915, stolen, size,
|
if (offset != I915_BO_INVALID_OFFSET) {
|
||||||
mem->min_page_size);
|
drm_dbg(&i915->drm,
|
||||||
|
"creating preallocated stolen object: stolen_offset=%pa, size=%pa\n",
|
||||||
|
&offset, &size);
|
||||||
|
|
||||||
|
stolen->start = offset;
|
||||||
|
stolen->size = size;
|
||||||
|
mutex_lock(&i915->mm.stolen_lock);
|
||||||
|
ret = drm_mm_reserve_node(&i915->mm.stolen, stolen);
|
||||||
|
mutex_unlock(&i915->mm.stolen_lock);
|
||||||
|
} else {
|
||||||
|
ret = i915_gem_stolen_insert_node(i915, stolen, size,
|
||||||
|
mem->min_page_size);
|
||||||
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
|
|
||||||
|
@ -882,63 +895,6 @@ i915_gem_stolen_smem_setup(struct drm_i915_private *i915, u16 type,
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drm_i915_gem_object *
|
|
||||||
i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *i915,
|
|
||||||
resource_size_t stolen_offset,
|
|
||||||
resource_size_t size)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
drm_dbg(&i915->drm,
|
|
||||||
"creating preallocated stolen object: stolen_offset=%pa, size=%pa\n",
|
|
||||||
&stolen_offset, &size);
|
|
||||||
|
|
||||||
/* 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(stolen_offset, mem->min_page_size)))
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
|
|
||||||
stolen = kzalloc(sizeof(*stolen), GFP_KERNEL);
|
|
||||||
if (!stolen)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
|
|
||||||
stolen->start = stolen_offset;
|
|
||||||
stolen->size = size;
|
|
||||||
mutex_lock(&i915->mm.stolen_lock);
|
|
||||||
ret = drm_mm_reserve_node(&i915->mm.stolen, stolen);
|
|
||||||
mutex_unlock(&i915->mm.stolen_lock);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj)
|
bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj)
|
||||||
{
|
{
|
||||||
return obj->ops == &i915_gem_object_stolen_ops;
|
return obj->ops == &i915_gem_object_stolen_ops;
|
||||||
|
|
|
@ -31,10 +31,6 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type,
|
||||||
struct drm_i915_gem_object *
|
struct drm_i915_gem_object *
|
||||||
i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
|
i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
|
||||||
resource_size_t size);
|
resource_size_t size);
|
||||||
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);
|
|
||||||
|
|
||||||
bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj);
|
bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj);
|
||||||
|
|
||||||
|
|
|
@ -1142,6 +1142,7 @@ void i915_ttm_bo_destroy(struct ttm_buffer_object *bo)
|
||||||
*/
|
*/
|
||||||
int __i915_gem_ttm_object_init(struct intel_memory_region *mem,
|
int __i915_gem_ttm_object_init(struct intel_memory_region *mem,
|
||||||
struct drm_i915_gem_object *obj,
|
struct drm_i915_gem_object *obj,
|
||||||
|
resource_size_t offset,
|
||||||
resource_size_t size,
|
resource_size_t size,
|
||||||
resource_size_t page_size,
|
resource_size_t page_size,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
|
|
|
@ -45,6 +45,7 @@ i915_ttm_to_gem(struct ttm_buffer_object *bo)
|
||||||
|
|
||||||
int __i915_gem_ttm_object_init(struct intel_memory_region *mem,
|
int __i915_gem_ttm_object_init(struct intel_memory_region *mem,
|
||||||
struct drm_i915_gem_object *obj,
|
struct drm_i915_gem_object *obj,
|
||||||
|
resource_size_t offset,
|
||||||
resource_size_t size,
|
resource_size_t size,
|
||||||
resource_size_t page_size,
|
resource_size_t page_size,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
|
|
||||||
|
#include "gem/i915_gem_region.h"
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
#include "i915_reg.h"
|
#include "i915_reg.h"
|
||||||
#include "i915_vgpu.h"
|
#include "i915_vgpu.h"
|
||||||
|
@ -324,9 +325,10 @@ static int vlv_rc6_init(struct intel_rc6 *rc6)
|
||||||
resource_size_t pcbr_offset;
|
resource_size_t pcbr_offset;
|
||||||
|
|
||||||
pcbr_offset = (pcbr & ~4095) - i915->dsm.start;
|
pcbr_offset = (pcbr & ~4095) - i915->dsm.start;
|
||||||
pctx = i915_gem_object_create_stolen_for_preallocated(i915,
|
pctx = i915_gem_object_create_region_at(i915->mm.stolen_region,
|
||||||
pcbr_offset,
|
pcbr_offset,
|
||||||
pctx_size);
|
pctx_size,
|
||||||
|
0);
|
||||||
if (IS_ERR(pctx))
|
if (IS_ERR(pctx))
|
||||||
return PTR_ERR(pctx);
|
return PTR_ERR(pctx);
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ struct intel_memory_region_ops {
|
||||||
|
|
||||||
int (*init_object)(struct intel_memory_region *mem,
|
int (*init_object)(struct intel_memory_region *mem,
|
||||||
struct drm_i915_gem_object *obj,
|
struct drm_i915_gem_object *obj,
|
||||||
|
resource_size_t offset,
|
||||||
resource_size_t size,
|
resource_size_t size,
|
||||||
resource_size_t page_size,
|
resource_size_t page_size,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
|
@ -57,6 +57,7 @@ static const struct drm_i915_gem_object_ops mock_region_obj_ops = {
|
||||||
|
|
||||||
static int mock_object_init(struct intel_memory_region *mem,
|
static int mock_object_init(struct intel_memory_region *mem,
|
||||||
struct drm_i915_gem_object *obj,
|
struct drm_i915_gem_object *obj,
|
||||||
|
resource_size_t offset,
|
||||||
resource_size_t size,
|
resource_size_t size,
|
||||||
resource_size_t page_size,
|
resource_size_t page_size,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
|
|
Loading…
Reference in New Issue