summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorMatthew Auld <matthew.auld@intel.com>2023-03-31 11:46:26 +0300
committerRodrigo Vivi <rodrigo.vivi@intel.com>2023-12-21 19:37:54 +0300
commit6a024f1bfdfe3b535786780f67c38429df17e857 (patch)
treeffe6f5ef62db5ffa705090bc47fb85998c9379c8 /drivers/gpu
parent2a6d871bd97722e899780a8e429b0fb5f11dadc6 (diff)
downloadlinux-6a024f1bfdfe3b535786780f67c38429df17e857.tar.xz
drm/xe/bo: support tiered vram allocation for small-bar
Add the new flag XE_BO_NEEDS_CPU_ACCESS, to force allocating in the mappable part of vram. If no flag is specified we do a topdown allocation, to limit the chances of stealing the precious mappable part, if we don't need it. If this is a full-bar system, then this all gets nooped. For kernel users, it looks like xe_bo_create_pin_map() is the central place which users should call if they want CPU access to the object, so add the flag there. We still need to plumb this through for userspace allocations. Also it looks like page-tables are using pin_map(), which is less than ideal. If we can already use the GPU to do page-table management, then maybe we should just force that for small-bar. Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com> Cc: Lucas De Marchi <lucas.demarchi@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/xe/tests/xe_migrate.c3
-rw-r--r--drivers/gpu/drm/xe/xe_bo.c48
-rw-r--r--drivers/gpu/drm/xe/xe_bo.h1
-rw-r--r--drivers/gpu/drm/xe/xe_ttm_vram_mgr.c4
4 files changed, 40 insertions, 16 deletions
diff --git a/drivers/gpu/drm/xe/tests/xe_migrate.c b/drivers/gpu/drm/xe/tests/xe_migrate.c
index 30e5fdf6ca63..c332dc54cb70 100644
--- a/drivers/gpu/drm/xe/tests/xe_migrate.c
+++ b/drivers/gpu/drm/xe/tests/xe_migrate.c
@@ -111,7 +111,8 @@ static void test_copy(struct xe_migrate *m, struct xe_bo *bo,
struct xe_bo *sysmem = xe_bo_create_locked(xe, m->tile, NULL,
bo->size,
ttm_bo_type_kernel,
- XE_BO_CREATE_SYSTEM_BIT);
+ XE_BO_CREATE_SYSTEM_BIT |
+ XE_BO_NEEDS_CPU_ACCESS);
if (IS_ERR(sysmem)) {
KUNIT_FAIL(test, "Failed to allocate sysmem bo for %s: %li\n",
str, PTR_ERR(sysmem));
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index 4b7678db88f3..fa3fc825b730 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -124,19 +124,28 @@ static void add_vram(struct xe_device *xe, struct xe_bo *bo,
struct ttm_place *places, u32 bo_flags, u32 mem_type, u32 *c)
{
struct xe_tile *tile = mem_type_to_tile(xe, mem_type);
+ struct ttm_place place = { .mem_type = mem_type };
+ u64 io_size = tile->mem.vram.io_size;
XE_BUG_ON(!tile->mem.vram.usable_size);
- places[*c] = (struct ttm_place) {
- .mem_type = mem_type,
- /*
- * For eviction / restore on suspend / resume objects
- * pinned in VRAM must be contiguous
- */
- .flags = bo_flags & (XE_BO_CREATE_PINNED_BIT |
- XE_BO_CREATE_GGTT_BIT) ?
- TTM_PL_FLAG_CONTIGUOUS : 0,
- };
+ /*
+ * For eviction / restore on suspend / resume objects
+ * pinned in VRAM must be contiguous
+ */
+ if (bo_flags & (XE_BO_CREATE_PINNED_BIT |
+ XE_BO_CREATE_GGTT_BIT))
+ place.flags |= TTM_PL_FLAG_CONTIGUOUS;
+
+ if (io_size < tile->mem.vram.usable_size) {
+ if (bo_flags & XE_BO_NEEDS_CPU_ACCESS) {
+ place.fpfn = 0;
+ place.lpfn = io_size >> PAGE_SHIFT;
+ } else {
+ place.flags |= TTM_PL_FLAG_TOPDOWN;
+ }
+ }
+ places[*c] = place;
*c += 1;
if (bo->props.preferred_mem_type == XE_BO_PROPS_INVALID)
@@ -385,15 +394,20 @@ static int xe_ttm_io_mem_reserve(struct ttm_device *bdev,
struct ttm_resource *mem)
{
struct xe_device *xe = ttm_to_xe_device(bdev);
- struct xe_tile *tile;
switch (mem->mem_type) {
case XE_PL_SYSTEM:
case XE_PL_TT:
return 0;
case XE_PL_VRAM0:
- case XE_PL_VRAM1:
- tile = mem_type_to_tile(xe, mem->mem_type);
+ case XE_PL_VRAM1: {
+ struct xe_tile *tile = mem_type_to_tile(xe, mem->mem_type);
+ struct xe_ttm_vram_mgr_resource *vres =
+ to_xe_ttm_vram_mgr_resource(mem);
+
+ if (vres->used_visible_size < mem->size)
+ return -EINVAL;
+
mem->bus.offset = mem->start << PAGE_SHIFT;
if (tile->mem.vram.mapping &&
@@ -408,7 +422,7 @@ static int xe_ttm_io_mem_reserve(struct ttm_device *bdev,
mem->bus.caching = ttm_write_combined;
#endif
return 0;
- case XE_PL_STOLEN:
+ } case XE_PL_STOLEN:
return xe_ttm_stolen_io_mem_reserve(xe, mem);
default:
return -EINVAL;
@@ -1376,7 +1390,8 @@ struct xe_bo *xe_bo_create_pin_map_at(struct xe_device *xe, struct xe_tile *tile
xe_ttm_stolen_cpu_access_needs_ggtt(xe))
flags |= XE_BO_CREATE_GGTT_BIT;
- bo = xe_bo_create_locked_range(xe, tile, vm, size, start, end, type, flags);
+ bo = xe_bo_create_locked_range(xe, tile, vm, size, start, end, type,
+ flags | XE_BO_NEEDS_CPU_ACCESS);
if (IS_ERR(bo))
return bo;
@@ -1685,6 +1700,9 @@ int xe_bo_vmap(struct xe_bo *bo)
xe_bo_assert_held(bo);
+ if (!(bo->flags & XE_BO_NEEDS_CPU_ACCESS))
+ return -EINVAL;
+
if (!iosys_map_is_null(&bo->vmap))
return 0;
diff --git a/drivers/gpu/drm/xe/xe_bo.h b/drivers/gpu/drm/xe/xe_bo.h
index 12a291925fa9..e231b2829bef 100644
--- a/drivers/gpu/drm/xe/xe_bo.h
+++ b/drivers/gpu/drm/xe/xe_bo.h
@@ -41,6 +41,7 @@
#define XE_BO_SCANOUT_BIT BIT(10)
#define XE_BO_FIXED_PLACEMENT_BIT BIT(11)
#define XE_BO_PAGETABLE BIT(12)
+#define XE_BO_NEEDS_CPU_ACCESS BIT(13)
/* this one is trigger internally only */
#define XE_BO_INTERNAL_TEST BIT(30)
#define XE_BO_INTERNAL_64K BIT(31)
diff --git a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
index a10fd0366da3..27e0d40daca8 100644
--- a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
+++ b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
@@ -373,11 +373,15 @@ int xe_ttm_vram_mgr_alloc_sgt(struct xe_device *xe,
struct sg_table **sgt)
{
struct xe_tile *tile = &xe->tiles[res->mem_type - XE_PL_VRAM0];
+ struct xe_ttm_vram_mgr_resource *vres = to_xe_ttm_vram_mgr_resource(res);
struct xe_res_cursor cursor;
struct scatterlist *sg;
int num_entries = 0;
int i, r;
+ if (vres->used_visible_size < res->size)
+ return -EOPNOTSUPP;
+
*sgt = kmalloc(sizeof(**sgt), GFP_KERNEL);
if (!*sgt)
return -ENOMEM;