drivers/gpu/drm/i915/gt/intel_gtt.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/gt/intel_gtt.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/intel_gtt.c
Extension
.c
Size
21284 bytes
Lines
738
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!i915_gem_object_get_rcu(obj)) {
			/*
			 * Object is dying, but has not yet cleared its
			 * vma list.
			 * Unbind the dying vma to ensure our list
			 * is completely drained. We leave the destruction to
			 * the object destructor to avoid the vma
			 * disappearing under it.
			 */
			atomic_and(~I915_VMA_PIN_MASK, &vma->flags);
			WARN_ON(__i915_vma_unbind(vma));

			/* Remove from the unbound list */
			list_del_init(&vma->vm_link);

			/*
			 * Delay the vm and vm mutex freeing until the
			 * object is done with destruction.
			 */
			i915_vm_resv_get(vma->vm);
			vma->vm_ddestroy = true;
		} else {
			i915_vma_destroy_locked(vma);
			i915_gem_object_put(obj);
		}
	}
}

static void __i915_vm_close(struct i915_address_space *vm)
{
	mutex_lock(&vm->mutex);

	clear_vm_list(&vm->bound_list);
	clear_vm_list(&vm->unbound_list);

	/* Check for must-fix unanticipated side-effects */
	GEM_BUG_ON(!list_empty(&vm->bound_list));
	GEM_BUG_ON(!list_empty(&vm->unbound_list));

	mutex_unlock(&vm->mutex);
}

/* lock the vm into the current ww, if we lock one, we lock all */
int i915_vm_lock_objects(struct i915_address_space *vm,
			 struct i915_gem_ww_ctx *ww)
{
	if (vm->scratch[0]->base.resv == &vm->_resv) {
		return i915_gem_object_lock(vm->scratch[0], ww);
	} else {
		struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);

		/* We borrowed the scratch page from ggtt, take the top level object */
		return i915_gem_object_lock(ppgtt->pd->pt.base, ww);
	}
}

void i915_address_space_fini(struct i915_address_space *vm)
{
	drm_mm_takedown(&vm->mm);
}

/**
 * i915_vm_resv_release - Final struct i915_address_space destructor
 * @kref: Pointer to the &i915_address_space.resv_ref member.
 *
 * This function is called when the last lock sharer no longer shares the
 * &i915_address_space._resv lock, and also if we raced when
 * destroying a vma by the vma destruction
 */
void i915_vm_resv_release(struct kref *kref)
{
	struct i915_address_space *vm =
		container_of(kref, typeof(*vm), resv_ref);

	dma_resv_fini(&vm->_resv);
	mutex_destroy(&vm->mutex);

	kfree(vm);
}

static void __i915_vm_release(struct work_struct *work)
{
	struct i915_address_space *vm =
		container_of(work, struct i915_address_space, release_work);

	__i915_vm_close(vm);

	/* Synchronize async unbinds. */
	i915_vma_resource_bind_dep_sync_all(vm);

Annotation

Implementation Notes