diff options
author | Christian König <ckoenig.leichtzumerken@gmail.com> | 2022-09-01 13:49:30 +0100 |
---|---|---|
committer | Christian König <christian.koenig@amd.com> | 2023-01-25 09:58:38 +0100 |
commit | 516198d317d81f33839ca850e83f6717b0d80e80 (patch) | |
tree | 51d9ccb1d5ca787cbcc8d0bee61c133a30fd66a0 /drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | |
parent | 51affef35bb39f186aef7eeeb4a7f9ceccd3e65e (diff) |
drm/i915: audit bo->resource usage v3
Make sure we can at least move and alloc TT objects without backing store.
v2: clear the tt object even when no resource is allocated.
v3: add Matthews changes for i915 as well.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230124125726.13323-1-christian.koenig@amd.com
Diffstat (limited to 'drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c')
-rw-r--r-- | drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c index 2ebaaf4d663c..76dd9e5e1a8b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c @@ -103,7 +103,27 @@ void i915_ttm_adjust_gem_after_move(struct drm_i915_gem_object *obj) { struct ttm_buffer_object *bo = i915_gem_to_ttm(obj); unsigned int cache_level; + unsigned int mem_flags; unsigned int i; + int mem_type; + + /* + * We might have been purged (or swapped out) if the resource is NULL, + * in which case the SYSTEM placement is the closest match to describe + * the current domain. If the object is ever used in this state then we + * will require moving it again. + */ + if (!bo->resource) { + mem_flags = I915_BO_FLAG_STRUCT_PAGE; + mem_type = I915_PL_SYSTEM; + cache_level = I915_CACHE_NONE; + } else { + mem_flags = i915_ttm_cpu_maps_iomem(bo->resource) ? I915_BO_FLAG_IOMEM : + I915_BO_FLAG_STRUCT_PAGE; + mem_type = bo->resource->mem_type; + cache_level = i915_ttm_cache_level(to_i915(bo->base.dev), bo->resource, + bo->ttm); + } /* * If object was moved to an allowable region, update the object @@ -111,11 +131,11 @@ void i915_ttm_adjust_gem_after_move(struct drm_i915_gem_object *obj) * in an allowable region, it's evicted and we don't update the * object region. */ - if (intel_region_to_ttm_type(obj->mm.region) != bo->resource->mem_type) { + if (intel_region_to_ttm_type(obj->mm.region) != mem_type) { for (i = 0; i < obj->mm.n_placements; ++i) { struct intel_memory_region *mr = obj->mm.placements[i]; - if (intel_region_to_ttm_type(mr) == bo->resource->mem_type && + if (intel_region_to_ttm_type(mr) == mem_type && mr != obj->mm.region) { i915_gem_object_release_memory_region(obj); i915_gem_object_init_memory_region(obj, mr); @@ -125,12 +145,8 @@ void i915_ttm_adjust_gem_after_move(struct drm_i915_gem_object *obj) } obj->mem_flags &= ~(I915_BO_FLAG_STRUCT_PAGE | I915_BO_FLAG_IOMEM); + obj->mem_flags |= mem_flags; - obj->mem_flags |= i915_ttm_cpu_maps_iomem(bo->resource) ? I915_BO_FLAG_IOMEM : - I915_BO_FLAG_STRUCT_PAGE; - - cache_level = i915_ttm_cache_level(to_i915(bo->base.dev), bo->resource, - bo->ttm); i915_gem_object_set_cache_coherency(obj, cache_level); } @@ -565,6 +581,32 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict, return 0; } + if (!bo->resource) { + if (dst_mem->mem_type != TTM_PL_SYSTEM) { + hop->mem_type = TTM_PL_SYSTEM; + hop->flags = TTM_PL_FLAG_TEMPORARY; + return -EMULTIHOP; + } + + /* + * This is only reached when first creating the object, or if + * the object was purged or swapped out (pipeline-gutting). For + * the former we can safely skip all of the below since we are + * only using a dummy SYSTEM placement here. And with the latter + * we will always re-enter here with bo->resource set correctly + * (as per the above), since this is part of a multi-hop + * sequence, where at the end we can do the move for real. + * + * The special case here is when the dst_mem is TTM_PL_SYSTEM, + * which doens't require any kind of move, so it should be safe + * to skip all the below and call ttm_bo_move_null() here, where + * the caller in __i915_ttm_get_pages() will take care of the + * rest, since we should have a valid ttm_tt. + */ + ttm_bo_move_null(bo, dst_mem); + return 0; + } + ret = i915_ttm_move_notify(bo); if (ret) return ret; |