[Intel-gfx] [PATCH 7/7] drm/i915/lmem: Verify checks for lmem residency
Matthew Auld
matthew.william.auld at gmail.com
Wed May 12 07:58:30 UTC 2021
On Tue, 11 May 2021 at 14:26, Thomas Hellström
<thomas.hellstrom at linux.intel.com> wrote:
>
> Since objects can be migrated or evicted when not pinned or locked,
> update the checks for lmem residency or future residency so that
> the value returned is not immediately stale.
>
> Signed-off-by: Thomas Hellström <thomas.hellstrom at linux.intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_display.c | 2 +-
> drivers/gpu/drm/i915/gem/i915_gem_lmem.c | 42 +++++++++++++++++++-
> drivers/gpu/drm/i915/gem/i915_gem_object.c | 29 ++++++++++++++
> drivers/gpu/drm/i915/gem/i915_gem_object.h | 4 ++
> 4 files changed, 75 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index de1f13d203b5..b95def2d5af3 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -11615,7 +11615,7 @@ intel_user_framebuffer_create(struct drm_device *dev,
>
> /* object is backed with LMEM for discrete */
> i915 = to_i915(obj->base.dev);
> - if (HAS_LMEM(i915) && !i915_gem_object_is_lmem(obj)) {
> + if (HAS_LMEM(i915) && !i915_gem_object_validates_to_lmem(obj)) {
> /* object is "remote", not in local memory */
> i915_gem_object_put(obj);
> return ERR_PTR(-EREMOTE);
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
> index 2b8cd15de1d9..d539dffa1554 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
> @@ -23,10 +23,50 @@ i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
> return io_mapping_map_wc(&obj->mm.region->iomap, offset, size);
> }
>
> +/**
> + * i915_gem_object_validates_to_lmem - Whether the object is resident in
> + * lmem when pages are present.
> + * @obj: The object to check.
> + *
> + * Migratable objects residency may change from under us if the object is
> + * not pinned or locked. This function is intended to be used to check whether
> + * the object can only reside in lmem when pages are present.
> + *
> + * Return: Whether the object is always resident in lmem when pages are
> + * present.
> + */
> +bool i915_gem_object_validates_to_lmem(struct drm_i915_gem_object *obj)
> +{
> + struct intel_memory_region *mr = READ_ONCE(obj->mm.region);
> +
> + return !i915_gem_object_migratable(obj) &&
> + mr && (mr->type == INTEL_MEMORY_LOCAL ||
> + mr->type == INTEL_MEMORY_STOLEN_LOCAL);
> +}
> +
> +/**
> + * i915_gem_object_is_lmem - Whether the object is resident in
> + * lmem
> + * @obj: The object to check.
> + *
> + * Even if an object is allowed to migrate and change memory region,
> + * this function checks whether it will always be present in lmem when
> + * valid *or* if that's not the case, whether it's currently resident in lmem.
> + * For migratable and evictable objects, the latter only makes sense when
> + * the object is locked.
> + *
> + * Return: Whether the object migratable but resident in lmem, or not
> + * migratable and will be present in lmem when valid.
> + */
> bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
> {
> - struct intel_memory_region *mr = obj->mm.region;
> + struct intel_memory_region *mr = READ_ONCE(obj->mm.region);
>
> +#ifdef CONFIG_LOCKDEP
> + if (i915_gem_object_migratable(obj) &&
> + i915_gem_object_evictable(obj))
> + assert_object_held(obj);
> +#endif
> return mr && (mr->type == INTEL_MEMORY_LOCAL ||
> mr->type == INTEL_MEMORY_STOLEN_LOCAL);
> }
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> index c53488f391dd..0475b1c94454 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> @@ -458,6 +458,35 @@ bool i915_gem_object_evictable(struct drm_i915_gem_object *obj)
> return pin_count == 0;
> }
>
> +/**
> + * i915_gem_object_migratable - Whether the object is migratable out of the
> + * current region.
> + * @obj: Pointer to the object.
> + *
> + * Return: Whether the object is allowed to be resident in other
> + * regions than the current while pages are present.
> + */
> +bool i915_gem_object_migratable(struct drm_i915_gem_object *obj)
> +{
> + struct intel_memory_region *mr = READ_ONCE(obj->mm.region);
> + struct intel_memory_region *placement;
> + int i;
> +
> + if (!mr)
> + return false;
> +
> + if (!obj->mm.n_placements)
> + return false;
> +
> + for (i = 0; i < obj->mm.n_placements; ++i) {
> + placement = obj->mm.placements[i];
> + if (placement != mr)
> + return true;
> + }
Maybe this can simply be:
return obj->mm.n_placements > 1;
?
The uAPI guarantees that mm.placements are each unique.
> +
> + return false;
> +}
> +
> 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 ae5930e307d5..a3ad8cf4eefd 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> @@ -596,6 +596,10 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj);
>
> bool i915_gem_object_evictable(struct drm_i915_gem_object *obj);
>
> +bool i915_gem_object_migratable(struct drm_i915_gem_object *obj);
> +
> +bool i915_gem_object_validates_to_lmem(struct drm_i915_gem_object *obj);
> +
> #ifdef CONFIG_MMU_NOTIFIER
> static inline bool
> i915_gem_object_is_userptr(struct drm_i915_gem_object *obj)
> --
> 2.30.2
>
> _______________________________________________
> 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