Commit 0ff37575 authored by Thomas Hellström's avatar Thomas Hellström Committed by Matthew Auld
Browse files

drm/i915: Update object placement flags to be mutable



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.

Signed-off-by: default avatarThomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Signed-off-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210624084240.270219-2-thomas.hellstrom@linux.intel.com
parent 4bc2d574
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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
+22 −0
Original line number Diff line number Diff line
@@ -71,6 +71,28 @@ bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
		      mr->type == INTEL_MEMORY_STOLEN_LOCAL);
}

/**
 * __i915_gem_object_is_lmem - Whether the object is resident in
 * lmem while in the fence signaling critical path.
 * @obj: The object to check.
 *
 * This function is intended to be called from within the fence signaling
 * path where the fence keeps the object from being migrated. For example
 * during gpu reset or similar.
 *
 * Return: Whether the object is resident in lmem.
 */
bool __i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
{
	struct intel_memory_region *mr = READ_ONCE(obj->mm.region);

#ifdef CONFIG_LOCKDEP
	GEM_WARN_ON(dma_resv_test_signaled(obj->base.resv, true));
#endif
	return mr && (mr->type == INTEL_MEMORY_LOCAL ||
		      mr->type == INTEL_MEMORY_STOLEN_LOCAL);
}

struct drm_i915_gem_object *
i915_gem_object_create_lmem(struct drm_i915_private *i915,
			    resource_size_t size,
+2 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,

bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);

bool __i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);

struct drm_i915_gem_object *
i915_gem_object_create_lmem(struct drm_i915_private *i915,
			    resource_size_t size,
+7 −5
Original line number Diff line number Diff line
@@ -684,7 +684,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);
@@ -708,7 +708,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;
}
@@ -932,10 +937,7 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
		return PTR_ERR(anon);
	}

	vma->vm_flags |= VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;

	if (i915_gem_object_has_iomem(obj))
		vma->vm_flags |= VM_IO;
	vma->vm_flags |= VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_IO;

	/*
	 * We keep the ref on mmo->obj, not vm_file, but we require
+38 −0
Original line number Diff line number Diff line
@@ -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);
Loading