[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 Intel-gfx mailing list