[PATCH] drm/i915: Optionally manage system memory with TTM and poolalloc
Adrian Larumbe
adrian.larumbe at collabora.com
Mon Jul 18 12:23:08 UTC 2022
Adds a module parameter that enables selection of the memory region manager
for system memory, either the legacy shmem-based one or TTM, through its
pool allocator. This could should not affect how DGFX platforms with LMEM
work.
Signed-off-by: Adrian Larumbe <adrian.larumbe at collabora.com>
---
drivers/gpu/drm/i915/gem/i915_gem_mman.c | 37 ++++++++++++++++------
drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 37 +++++++++++++++++++++-
drivers/gpu/drm/i915/gem/i915_gem_ttm.h | 6 ++++
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 6 +++-
drivers/gpu/drm/i915/i915_params.c | 6 ++++
drivers/gpu/drm/i915/i915_params.h | 4 ++-
drivers/gpu/drm/i915/intel_memory_region.c | 2 +-
drivers/gpu/drm/ttm/ttm_resource.c | 4 +--
drivers/gpu/drm/ttm/ttm_tt.c | 1 -
9 files changed, 87 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 0c5c43852e24..7f8227640d0e 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -87,7 +87,10 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
* pages from.
*/
if (!obj->base.filp) {
- addr = -ENXIO;
+ if (!i915->params.use_pool_alloc)
+ addr = -ENXIO;
+ else
+ addr = -EOPNOTSUPP;
goto err;
}
@@ -552,9 +555,11 @@ void i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
void i915_gem_object_release_mmap_offset(struct drm_i915_gem_object *obj)
{
+ struct ttm_buffer_object *bo = i915_gem_to_ttm(obj);
struct i915_mmap_offset *mmo, *mn;
- if (obj->ops->unmap_virtual)
+ if (obj->ops->unmap_virtual &&
+ bo->type == ttm_bo_type_device)
obj->ops->unmap_virtual(obj);
spin_lock(&obj->mmo.lock);
@@ -641,11 +646,13 @@ mmap_offset_attach(struct drm_i915_gem_object *obj,
enum i915_mmap_type mmap_type,
struct drm_file *file)
{
+ struct ttm_buffer_object *bo = i915_gem_to_ttm(obj);
struct drm_i915_private *i915 = to_i915(obj->base.dev);
struct i915_mmap_offset *mmo;
int err;
- GEM_BUG_ON(obj->ops->mmap_offset || obj->ops->mmap_ops);
+ GEM_BUG_ON((obj->ops->mmap_offset || obj->ops->mmap_ops) &&
+ bo->type == ttm_bo_type_device);
mmo = lookup_mmo(obj, mmap_type);
if (mmo)
@@ -694,12 +701,14 @@ __assign_mmap_offset(struct drm_i915_gem_object *obj,
enum i915_mmap_type mmap_type,
u64 *offset, struct drm_file *file)
{
+ struct ttm_buffer_object *bo = i915_gem_to_ttm(obj);
struct i915_mmap_offset *mmo;
if (i915_gem_object_never_mmap(obj))
return -ENODEV;
- if (obj->ops->mmap_offset) {
+ if (obj->ops->mmap_offset &&
+ bo->type == ttm_bo_type_device) {
if (mmap_type != I915_MMAP_TYPE_FIXED)
return -ENODEV;
@@ -731,7 +740,6 @@ __assign_mmap_offset_handle(struct drm_file *file,
{
struct drm_i915_gem_object *obj;
int err;
-
obj = i915_gem_object_lookup(file, handle);
if (!obj)
return -ENOENT;
@@ -739,6 +747,7 @@ __assign_mmap_offset_handle(struct drm_file *file,
err = i915_gem_object_lock_interruptible(obj, NULL);
if (err)
goto out_put;
+
err = __assign_mmap_offset(obj, mmap_type, offset, file);
i915_gem_object_unlock(obj);
out_put:
@@ -923,6 +932,7 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_i915_gem_object *obj = NULL;
+ struct ttm_buffer_object *bo = NULL;
struct i915_mmap_offset *mmo = NULL;
struct file *anon;
@@ -934,6 +944,7 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager,
vma->vm_pgoff,
vma_pages(vma));
+ /* TODO: need to handle this */
if (node && drm_vma_node_is_allowed(node, priv)) {
/*
* Skip 0-refcnted objects as it is in the process of being
@@ -958,6 +969,9 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
if (!obj)
return node ? -EACCES : -EINVAL;
+ if (i915_gem_object_is_ttm(obj))
+ bo = i915_gem_to_ttm(obj);
+
if (i915_gem_object_is_readonly(obj)) {
if (vma->vm_flags & VM_WRITE) {
i915_gem_object_put(obj);
@@ -987,10 +1001,15 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
fput(anon);
if (obj->ops->mmap_ops) {
- vma->vm_page_prot = pgprot_decrypted(vm_get_page_prot(vma->vm_flags));
- vma->vm_ops = obj->ops->mmap_ops;
- vma->vm_private_data = node->driver_private;
- return 0;
+ /* there could be an obj backend with mmap_ops that isn't TTM */
+ if (!i915_gem_object_is_ttm(obj) ||
+ (i915_gem_object_is_ttm(obj) &&
+ bo->type == ttm_bo_type_device)) {
+ vma->vm_page_prot = pgprot_decrypted(vm_get_page_prot(vma->vm_flags));
+ vma->vm_ops = obj->ops->mmap_ops;
+ vma->vm_private_data = node->driver_private;
+ return 0;
+ }
}
vma->vm_private_data = mmo;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index 7e1f8b83077f..be4ac97f7e2d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -3,6 +3,7 @@
* Copyright © 2021 Intel Corporation
*/
+#include "drm/ttm/ttm_bo_api.h"
#include <linux/shmem_fs.h>
#include <drm/ttm/ttm_bo_driver.h>
@@ -294,7 +295,7 @@ static struct ttm_tt *i915_ttm_tt_create(struct ttm_buffer_object *bo,
if (i915_gem_object_is_shrinkable(obj) && caching == ttm_cached) {
page_flags |= TTM_TT_FLAG_EXTERNAL |
TTM_TT_FLAG_EXTERNAL_MAPPABLE;
- i915_tt->is_shmem = true;
+ i915_tt->is_shmem = i915->params.use_pool_alloc ? false : true;
}
if (HAS_FLAT_CCS(i915) && i915_gem_object_needs_ccs_pages(obj))
@@ -1215,6 +1216,10 @@ int __i915_gem_ttm_object_init(struct intel_memory_region *mem,
bo_type = (obj->flags & I915_BO_ALLOC_USER) ? ttm_bo_type_device :
ttm_bo_type_kernel;
+ if (mem->type == INTEL_MEMORY_SYSTEM &&
+ i915->params.use_pool_alloc)
+ bo_type = ttm_bo_type_kernel;
+
obj->base.vma_node.driver_private = i915_gem_to_ttm(obj);
/* Forcing the page size is kernel internal only */
@@ -1274,3 +1279,33 @@ i915_gem_ttm_system_setup(struct drm_i915_private *i915,
intel_memory_region_set_name(mr, "system-ttm");
return mr;
}
+
+bool i915_gem_object_is_ttm(const struct drm_i915_gem_object *obj)
+{
+ return obj->ops == &i915_gem_ttm_obj_ops;
+}
+
+/* Allocate a new GEM object and fill it with the supplied data */
+struct drm_i915_gem_object *
+i915_gem_object_create_ttm_from_data(struct drm_i915_private *dev_priv,
+ const void *data, resource_size_t size)
+{
+ struct drm_i915_gem_object *obj;
+ void *vaddr;
+
+ obj = i915_gem_object_create_shmem(dev_priv, round_up(size, PAGE_SIZE));
+ if (IS_ERR(obj))
+ return obj;
+
+ vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
+ if (IS_ERR(vaddr)) {
+ i915_gem_object_put(obj);
+ return vaddr;
+ }
+
+ memcpy(vaddr, data, size);
+
+ i915_gem_object_unpin_map(obj);
+
+ return obj;
+}
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.h b/drivers/gpu/drm/i915/gem/i915_gem_ttm.h
index e4842b4296fc..d1b176336531 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.h
@@ -95,4 +95,10 @@ static inline bool i915_ttm_cpu_maps_iomem(struct ttm_resource *mem)
bool i915_ttm_resource_mappable(struct ttm_resource *res);
+bool i915_gem_object_is_ttm(const struct drm_i915_gem_object *obj);
+
+struct drm_i915_gem_object *
+i915_gem_object_create_ttm_from_data(struct drm_i915_private *dev_priv,
+ const void *data, resource_size_t size);
+
#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 27363091e1af..c40e58ae7f5c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -11,6 +11,7 @@
#include <drm/drm_print.h>
#include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_ttm.h"
#include "intel_uc_fw.h"
#include "intel_uc_fw_abi.h"
#include "i915_drv.h"
@@ -440,7 +441,10 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
if (!IS_ERR(obj))
obj->flags |= I915_BO_ALLOC_PM_EARLY;
} else {
- obj = i915_gem_object_create_shmem_from_data(i915, fw->data, fw->size);
+ if (unlikely(i915->params.use_pool_alloc))
+ obj = i915_gem_object_create_ttm_from_data(i915, fw->data, fw->size);
+ else
+ obj = i915_gem_object_create_shmem_from_data(i915, fw->data, fw->size);
}
if (IS_ERR(obj)) {
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index 701fbc98afa0..7200b1290954 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -205,6 +205,12 @@ i915_param_named_unsafe(request_timeout_ms, uint, 0600,
i915_param_named_unsafe(lmem_size, uint, 0400,
"Set the lmem size(in MiB) for each region. (default: 0, all memory)");
+i915_param_named_unsafe(use_pool_alloc, bool, 0600,
+ "Force the driver to use TTM's pool allocator API for smem objects. "
+ "This will cause TTM to take over BO allocation even in integrated platforms. "
+ "(default: false)");
+
+
static __always_inline void _print_param(struct drm_printer *p,
const char *name,
const char *type,
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index b5e7ea45d191..10e1aee43566 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -83,7 +83,9 @@ struct drm_printer;
param(bool, verbose_state_checks, true, 0) \
param(bool, nuclear_pageflip, false, 0400) \
param(bool, enable_dp_mst, true, 0600) \
- param(bool, enable_gvt, false, IS_ENABLED(CONFIG_DRM_I915_GVT) ? 0400 : 0)
+ param(bool, enable_gvt, false, IS_ENABLED(CONFIG_DRM_I915_GVT) ? 0400 : 0) \
+ param(bool, use_pool_alloc, true, 0600)
+ /* param(bool, use_pool_alloc, false, 0600) */
#define MEMBER(T, member, ...) T member;
struct i915_params {
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index 9a4a7fb55582..442687285ce6 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -321,7 +321,7 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
instance = intel_region_map[i].instance;
switch (type) {
case INTEL_MEMORY_SYSTEM:
- if (IS_DGFX(i915))
+ if (IS_DGFX(i915) || i915->params.use_pool_alloc)
mem = i915_gem_ttm_system_setup(i915, type,
instance);
else
diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c
index 20f9adcc3235..10603961a391 100644
--- a/drivers/gpu/drm/ttm/ttm_resource.c
+++ b/drivers/gpu/drm/ttm/ttm_resource.c
@@ -171,8 +171,8 @@ void ttm_resource_move_to_lru_tail(struct ttm_resource *res)
* Initialize a new resource object. Counterpart of ttm_resource_fini().
*/
void ttm_resource_init(struct ttm_buffer_object *bo,
- const struct ttm_place *place,
- struct ttm_resource *res)
+ const struct ttm_place *place,
+ struct ttm_resource *res)
{
struct ttm_resource_manager *man;
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index d505603930a7..e110db86c870 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -136,7 +136,6 @@ static void ttm_tt_init_fields(struct ttm_tt *ttm,
unsigned long extra_pages)
{
ttm->num_pages = (PAGE_ALIGN(bo->base.size) >> PAGE_SHIFT) + extra_pages;
- ttm->caching = ttm_cached;
ttm->page_flags = page_flags;
ttm->dma_address = NULL;
ttm->swap_storage = NULL;
--
2.37.0
More information about the Intel-gfx-trybot
mailing list