Commit 8b1f7f92 authored by Thomas Hellström's avatar Thomas Hellström
Browse files

drm/i915/ttm: Drop region reference counting



There is an interesting refcounting loop:
struct intel_memory_region has a struct ttm_resource_manager,
ttm_resource_manager->move may hold a reference to i915_request,
i915_request may hold a reference to intel_context,
intel_context may hold a reference to drm_i915_gem_object,
drm_i915_gem_object may hold a reference to intel_memory_region.

Break this loop by dropping region reference counting.

In addition, Have regions with a manager moving fence make sure
that all region objects are released before freeing the region.

v6:
- Fix a code comment.

Signed-off-by: default avatarThomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211122214554.371864-4-thomas.hellstrom@linux.intel.com
parent 05d1c761
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@
void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj,
					struct intel_memory_region *mem)
{
	obj->mm.region = intel_memory_region_get(mem);
	obj->mm.region = mem;

	mutex_lock(&mem->objects.lock);
	list_add(&obj->mm.region_link, &mem->objects.list);
@@ -25,8 +25,6 @@ void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj)
	mutex_lock(&mem->objects.lock);
	list_del(&obj->mm.region_link);
	mutex_unlock(&mem->objects.lock);

	intel_memory_region_put(mem);
}

struct drm_i915_gem_object *
+2 −1
Original line number Diff line number Diff line
@@ -664,9 +664,10 @@ static int init_shmem(struct intel_memory_region *mem)
	return 0; /* Don't error, we can simply fallback to the kernel mnt */
}

static void release_shmem(struct intel_memory_region *mem)
static int release_shmem(struct intel_memory_region *mem)
{
	i915_gemfs_fini(mem->i915);
	return 0;
}

static const struct intel_memory_region_ops shmem_region_ops = {
+4 −2
Original line number Diff line number Diff line
@@ -720,9 +720,10 @@ static int init_stolen_smem(struct intel_memory_region *mem)
	return i915_gem_init_stolen(mem);
}

static void release_stolen_smem(struct intel_memory_region *mem)
static int release_stolen_smem(struct intel_memory_region *mem)
{
	i915_gem_cleanup_stolen(mem->i915);
	return 0;
}

static const struct intel_memory_region_ops i915_region_stolen_smem_ops = {
@@ -759,10 +760,11 @@ static int init_stolen_lmem(struct intel_memory_region *mem)
	return err;
}

static void release_stolen_lmem(struct intel_memory_region *mem)
static int release_stolen_lmem(struct intel_memory_region *mem)
{
	io_mapping_fini(&mem->iomap);
	i915_gem_cleanup_stolen(mem->i915);
	return 0;
}

static const struct intel_memory_region_ops i915_region_stolen_lmem_ops = {
+2 −1
Original line number Diff line number Diff line
@@ -997,7 +997,7 @@ int __i915_gem_ttm_object_init(struct intel_memory_region *mem,
	i915_gem_object_init(obj, &i915_gem_ttm_obj_ops, &lock_class, flags);

	/* Don't put on a region list until we're either locked or fully initialized. */
	obj->mm.region = intel_memory_region_get(mem);
	obj->mm.region = mem;
	INIT_LIST_HEAD(&obj->mm.region_link);

	INIT_RADIX_TREE(&obj->ttm.get_io_page.radix, GFP_KERNEL | __GFP_NOWARN);
@@ -1044,6 +1044,7 @@ int __i915_gem_ttm_object_init(struct intel_memory_region *mem,

static const struct intel_memory_region_ops ttm_system_region_ops = {
	.init_object = __i915_gem_ttm_object_init,
	.release = intel_region_ttm_fini,
};

struct intel_memory_region *
+1 −1
Original line number Diff line number Diff line
@@ -568,7 +568,7 @@ static int igt_mock_memory_region_huge_pages(void *arg)
out_put:
	i915_gem_object_put(obj);
out_region:
	intel_memory_region_put(mem);
	intel_memory_region_destroy(mem);
	return err;
}

Loading