[Intel-gfx] [PATCH 1/5] drm/i915: Update object placement flags to be mutable
Matthew Auld
matthew.william.auld at gmail.com
Thu Jun 3 11:17:01 UTC 2021
On Wed, 2 Jun 2021 at 18:08, Thomas Hellström
<thomas.hellstrom at linux.intel.com> wrote:
>
> The object ops i915_GEM_OBJECT_HAS_IOMEM and the object
> I915_BO_ALLOC_STRUCT_PAGE flags are considered immutable by
> much of our code. Introduce a new mem_flags member to hold these
> and make sure checks for these flags being set are either done
> under the object lock or with pages properly pinned. The flags
> will change during migration under the object lock.
What are the rules for the gem_object_ops flags? Like is_shrinkable?
Can't we just move these there(IOMEM vs PAGE)?
>
> Signed-off-by: Thomas Hellström <thomas.hellstrom at linux.intel.com>
> ---
> drivers/gpu/drm/i915/gem/i915_gem_internal.c | 4 +-
> drivers/gpu/drm/i915/gem/i915_gem_mman.c | 7 +++-
> drivers/gpu/drm/i915/gem/i915_gem_object.c | 38 +++++++++++++++++++
> drivers/gpu/drm/i915/gem/i915_gem_object.h | 14 ++-----
> .../gpu/drm/i915/gem/i915_gem_object_types.h | 20 +++++-----
> drivers/gpu/drm/i915/gem/i915_gem_pages.c | 2 +-
> drivers/gpu/drm/i915/gem/i915_gem_phys.c | 2 +-
> drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 10 +++--
> drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +-
> drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 4 +-
> .../drm/i915/gem/selftests/huge_gem_object.c | 4 +-
> .../gpu/drm/i915/gem/selftests/huge_pages.c | 5 +--
> .../drm/i915/gem/selftests/i915_gem_mman.c | 4 +-
> .../drm/i915/gem/selftests/i915_gem_phys.c | 3 +-
> 14 files changed, 78 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
> index ce6b664b10aa..13b217f75055 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
> @@ -177,8 +177,8 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
> return ERR_PTR(-ENOMEM);
>
> drm_gem_private_object_init(&i915->drm, &obj->base, size);
> - i915_gem_object_init(obj, &i915_gem_object_internal_ops, &lock_class,
> - I915_BO_ALLOC_STRUCT_PAGE);
> + i915_gem_object_init(obj, &i915_gem_object_internal_ops, &lock_class, 0);
> + obj->mem_flags |= I915_BO_FLAG_STRUCT_PAGE;
>
> /*
> * Mark the object as volatile, such that the pages are marked as
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> index d1de97e4adfd..171a21ca930c 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> @@ -683,7 +683,7 @@ __assign_mmap_offset(struct drm_i915_gem_object *obj,
>
> if (mmap_type != I915_MMAP_TYPE_GTT &&
> !i915_gem_object_has_struct_page(obj) &&
> - !i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM))
> + !i915_gem_object_has_iomem(obj))
> return -ENODEV;
>
> mmo = mmap_offset_attach(obj, mmap_type, file);
> @@ -707,7 +707,12 @@ __assign_mmap_offset_handle(struct drm_file *file,
> if (!obj)
> return -ENOENT;
>
> + 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:
> i915_gem_object_put(obj);
> return err;
> }
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> index cf18c430d51f..07e8ff9a8aae 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> @@ -475,6 +475,44 @@ bool i915_gem_object_migratable(struct drm_i915_gem_object *obj)
> return obj->mm.n_placements > 1;
> }
>
> +/**
> + * i915_gem_object_has_struct_page - Whether the object is page-backed
> + * @obj: The object to query.
> + *
> + * This function should only be called while the object is locked or pinned,
> + * otherwise the page backing may change under the caller.
> + *
> + * Return: True if page-backed, false otherwise.
> + */
> +bool i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj)
> +{
> +#ifdef CONFIG_LOCKDEP
> + if (IS_DGFX(to_i915(obj->base.dev)) &&
> + i915_gem_object_evictable((void __force *)obj))
> + assert_object_held_shared(obj);
> +#endif
> + return obj->mem_flags & I915_BO_FLAG_STRUCT_PAGE;
> +}
> +
> +/**
> + * i915_gem_object_has_iomem - Whether the object is iomem-backed
> + * @obj: The object to query.
> + *
> + * This function should only be called while the object is locked or pinned,
> + * otherwise the iomem backing may change under the caller.
> + *
> + * Return: True if iomem-backed, false otherwise.
> + */
> +bool i915_gem_object_has_iomem(const struct drm_i915_gem_object *obj)
> +{
> +#ifdef CONFIG_LOCKDEP
> + if (IS_DGFX(to_i915(obj->base.dev)) &&
> + i915_gem_object_evictable((void __force *)obj))
> + assert_object_held_shared(obj);
> +#endif
> + return obj->mem_flags & I915_BO_FLAG_IOMEM;
> +}
> +
> void i915_gem_init__objects(struct drm_i915_private *i915)
> {
> INIT_WORK(&i915->mm.free_work, __i915_gem_free_work);
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> index ff59e6c640e6..23e26f6b1db9 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> @@ -147,7 +147,7 @@ i915_gem_object_put(struct drm_i915_gem_object *obj)
> /*
> * If more than one potential simultaneous locker, assert held.
> */
> -static inline void assert_object_held_shared(struct drm_i915_gem_object *obj)
> +static inline void assert_object_held_shared(const struct drm_i915_gem_object *obj)
> {
> /*
> * Note mm list lookup is protected by
> @@ -261,17 +261,9 @@ i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
> return obj->ops->flags & flags;
> }
>
> -static inline bool
> -i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj)
> -{
> - return obj->flags & I915_BO_ALLOC_STRUCT_PAGE;
> -}
> +bool i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj);
>
> -static inline bool
> -i915_gem_object_has_iomem(const struct drm_i915_gem_object *obj)
> -{
> - return i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM);
> -}
> +bool i915_gem_object_has_iomem(const struct drm_i915_gem_object *obj);
>
> static inline bool
> i915_gem_object_is_shrinkable(const struct drm_i915_gem_object *obj)
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> index 2a23b77424b3..fb9ccc3f50e7 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> @@ -33,10 +33,9 @@ struct i915_lut_handle {
>
> struct drm_i915_gem_object_ops {
> unsigned int flags;
> -#define I915_GEM_OBJECT_HAS_IOMEM BIT(1)
> -#define I915_GEM_OBJECT_IS_SHRINKABLE BIT(2)
> -#define I915_GEM_OBJECT_IS_PROXY BIT(3)
> -#define I915_GEM_OBJECT_NO_MMAP BIT(4)
> +#define I915_GEM_OBJECT_IS_SHRINKABLE BIT(1)
> +#define I915_GEM_OBJECT_IS_PROXY BIT(2)
> +#define I915_GEM_OBJECT_NO_MMAP BIT(3)
>
> /* Interface between the GEM object and its backing storage.
> * get_pages() is called once prior to the use of the associated set
> @@ -201,17 +200,18 @@ struct drm_i915_gem_object {
> unsigned long flags;
> #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
> #define I915_BO_ALLOC_VOLATILE BIT(1)
> -#define I915_BO_ALLOC_STRUCT_PAGE BIT(2)
> -#define I915_BO_ALLOC_CPU_CLEAR BIT(3)
> -#define I915_BO_ALLOC_USER BIT(4)
> +#define I915_BO_ALLOC_CPU_CLEAR BIT(2)
> +#define I915_BO_ALLOC_USER BIT(3)
> #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
> I915_BO_ALLOC_VOLATILE | \
> - I915_BO_ALLOC_STRUCT_PAGE | \
> I915_BO_ALLOC_CPU_CLEAR | \
> I915_BO_ALLOC_USER)
> -#define I915_BO_READONLY BIT(5)
> -#define I915_TILING_QUIRK_BIT 6 /* unknown swizzling; do not release! */
> +#define I915_BO_READONLY BIT(4)
> +#define I915_TILING_QUIRK_BIT 5 /* unknown swizzling; do not release! */
>
> + unsigned int mem_flags:2;
> +#define I915_BO_FLAG_STRUCT_PAGE BIT(0)
> +#define I915_BO_FLAG_IOMEM BIT(1)
> /*
> * Is the object to be mapped as read-only to the GPU
> * Only honoured if hardware has relevant pte bit
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> index 086005c1c7ea..f2f850e31b8e 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> @@ -351,7 +351,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
> int err;
>
> if (!i915_gem_object_has_struct_page(obj) &&
> - !i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM))
> + !i915_gem_object_has_iomem(obj))
> return ERR_PTR(-ENXIO);
>
> assert_object_held(obj);
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_phys.c b/drivers/gpu/drm/i915/gem/i915_gem_phys.c
> index be72ad0634ba..7986612f48fa 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_phys.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_phys.c
> @@ -76,7 +76,7 @@ static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
> intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt);
>
> /* We're no longer struct page backed */
> - obj->flags &= ~I915_BO_ALLOC_STRUCT_PAGE;
> + obj->mem_flags &= ~I915_BO_FLAG_STRUCT_PAGE;
> __i915_gem_object_set_pages(obj, st, sg->length);
>
> return 0;
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
> index 5d16c4462fda..3648ae1d6628 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
> @@ -284,6 +284,7 @@ __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,
> bool needs_clflush)
> {
> GEM_BUG_ON(obj->mm.madv == __I915_MADV_PURGED);
> + GEM_WARN_ON(IS_DGFX(to_i915(obj->base.dev)));
>
> if (obj->mm.madv == I915_MADV_DONTNEED)
> obj->mm.dirty = false;
> @@ -302,6 +303,7 @@ void i915_gem_object_put_pages_shmem(struct drm_i915_gem_object *obj, struct sg_
> struct pagevec pvec;
> struct page *page;
>
> + GEM_WARN_ON(IS_DGFX(to_i915(obj->base.dev)));
> __i915_gem_object_release_shmem(obj, pages, true);
>
> i915_gem_gtt_finish_pages(obj, pages);
> @@ -444,7 +446,7 @@ shmem_pread(struct drm_i915_gem_object *obj,
>
> static void shmem_release(struct drm_i915_gem_object *obj)
> {
> - if (obj->flags & I915_BO_ALLOC_STRUCT_PAGE)
> + if (i915_gem_object_has_struct_page(obj))
> i915_gem_object_release_memory_region(obj);
>
> fput(obj->base.filp);
> @@ -513,9 +515,8 @@ static int shmem_object_init(struct intel_memory_region *mem,
> mapping_set_gfp_mask(mapping, mask);
> GEM_BUG_ON(!(mapping_gfp_mask(mapping) & __GFP_RECLAIM));
>
> - i915_gem_object_init(obj, &i915_gem_shmem_ops, &lock_class,
> - I915_BO_ALLOC_STRUCT_PAGE);
> -
> + i915_gem_object_init(obj, &i915_gem_shmem_ops, &lock_class, 0);
> + obj->mem_flags |= I915_BO_FLAG_STRUCT_PAGE;
> obj->write_domain = I915_GEM_DOMAIN_CPU;
> obj->read_domains = I915_GEM_DOMAIN_CPU;
>
> @@ -561,6 +562,7 @@ i915_gem_object_create_shmem_from_data(struct drm_i915_private *dev_priv,
> resource_size_t offset;
> int err;
>
> + GEM_WARN_ON(IS_DGFX(dev_priv));
> obj = i915_gem_object_create_shmem(dev_priv, round_up(size, PAGE_SIZE));
> if (IS_ERR(obj))
> return obj;
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> index 3748098b42d5..ae12a2be11a2 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> @@ -563,7 +563,6 @@ static u64 i915_ttm_mmap_offset(struct drm_i915_gem_object *obj)
>
> const struct drm_i915_gem_object_ops i915_gem_ttm_obj_ops = {
> .name = "i915_gem_object_ttm",
> - .flags = I915_GEM_OBJECT_HAS_IOMEM,
>
> .get_pages = i915_ttm_get_pages,
> .put_pages = i915_ttm_put_pages,
> @@ -620,6 +619,7 @@ int __i915_gem_ttm_object_init(struct intel_memory_region *mem,
> i915_gem_object_init_memory_region(obj, mem);
> i915_gem_object_make_unshrinkable(obj);
> obj->read_domains = I915_GEM_DOMAIN_WC | I915_GEM_DOMAIN_GTT;
> + obj->mem_flags |= I915_BO_FLAG_IOMEM;
> i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
> INIT_RADIX_TREE(&obj->ttm.get_io_page.radix, GFP_KERNEL | __GFP_NOWARN);
> mutex_init(&obj->ttm.get_io_page.lock);
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> index 602f0ed983ec..41dfcb75f05b 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> @@ -538,8 +538,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev,
> return -ENOMEM;
>
> drm_gem_private_object_init(dev, &obj->base, args->user_size);
> - i915_gem_object_init(obj, &i915_gem_userptr_ops, &lock_class,
> - I915_BO_ALLOC_STRUCT_PAGE);
> + i915_gem_object_init(obj, &i915_gem_userptr_ops, &lock_class, 0);
> + obj->mem_flags = I915_BO_FLAG_STRUCT_PAGE;
> obj->read_domains = I915_GEM_DOMAIN_CPU;
> obj->write_domain = I915_GEM_DOMAIN_CPU;
> i915_gem_object_set_cache_coherency(obj, I915_CACHE_LLC);
> diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c b/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c
> index 0c8ecfdf5405..f963b8e1e37b 100644
> --- a/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c
> +++ b/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c
> @@ -114,8 +114,8 @@ huge_gem_object(struct drm_i915_private *i915,
> return ERR_PTR(-ENOMEM);
>
> drm_gem_private_object_init(&i915->drm, &obj->base, dma_size);
> - i915_gem_object_init(obj, &huge_ops, &lock_class,
> - I915_BO_ALLOC_STRUCT_PAGE);
> + i915_gem_object_init(obj, &huge_ops, &lock_class, 0);
> + obj->mem_flags |= I915_BO_FLAG_STRUCT_PAGE;
>
> obj->read_domains = I915_GEM_DOMAIN_CPU;
> obj->write_domain = I915_GEM_DOMAIN_CPU;
> diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
> index dadd485bc52f..ccc67ed1a84b 100644
> --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
> +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
> @@ -167,9 +167,8 @@ huge_pages_object(struct drm_i915_private *i915,
> return ERR_PTR(-ENOMEM);
>
> drm_gem_private_object_init(&i915->drm, &obj->base, size);
> - i915_gem_object_init(obj, &huge_page_ops, &lock_class,
> - I915_BO_ALLOC_STRUCT_PAGE);
> -
> + i915_gem_object_init(obj, &huge_page_ops, &lock_class, 0);
> + obj->mem_flags |= I915_BO_FLAG_STRUCT_PAGE;
> i915_gem_object_set_volatile(obj);
>
> obj->write_domain = I915_GEM_DOMAIN_CPU;
> diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
> index ca69a29b7f2a..bfb35270a1f0 100644
> --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
> +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
> @@ -837,7 +837,7 @@ static bool can_mmap(struct drm_i915_gem_object *obj, enum i915_mmap_type type)
>
> if (type != I915_MMAP_TYPE_GTT &&
> !i915_gem_object_has_struct_page(obj) &&
> - !i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM))
> + !i915_gem_object_has_iomem(obj))
> return false;
>
> return true;
> @@ -991,7 +991,7 @@ static const char *repr_mmap_type(enum i915_mmap_type type)
> static bool can_access(const struct drm_i915_gem_object *obj)
> {
> return i915_gem_object_has_struct_page(obj) ||
> - i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM);
> + i915_gem_object_has_iomem(obj);
> }
>
> static int __igt_mmap_access(struct drm_i915_private *i915,
> diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c
> index 3a6ce87f8b52..d43d8dae0f69 100644
> --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c
> +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c
> @@ -25,13 +25,14 @@ static int mock_phys_object(void *arg)
> goto out;
> }
>
> + i915_gem_object_lock(obj, NULL);
> if (!i915_gem_object_has_struct_page(obj)) {
> + i915_gem_object_unlock(obj);
> err = -EINVAL;
> pr_err("shmem has no struct page\n");
> goto out_obj;
> }
>
> - i915_gem_object_lock(obj, NULL);
> err = i915_gem_object_attach_phys(obj, PAGE_SIZE);
> i915_gem_object_unlock(obj);
> if (err) {
> --
> 2.31.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
More information about the dri-devel
mailing list