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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
Extension
.c
Size
27332 bytes
Lines
931
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 (gpu_uses_fence_registers(fence)) {
			/* implicit 'unfenced' GPU blits */
			ret = i915_vma_sync(vma);
			if (ret)
				return ret;
		}

		GEM_BUG_ON(vma->fence_size > i915_vma_size(vma));
		fence->start = i915_ggtt_offset(vma);
		fence->size = vma->fence_size;
		fence->stride = i915_gem_object_get_stride(vma->obj);
		fence->tiling = i915_gem_object_get_tiling(vma->obj);
	}
	WRITE_ONCE(fence->dirty, false);

	old = xchg(&fence->vma, NULL);
	if (old) {
		/* XXX Ideally we would move the waiting to outside the mutex */
		ret = i915_active_wait(&fence->active);
		if (ret) {
			fence->vma = old;
			return ret;
		}

		i915_vma_flush_writes(old);

		/*
		 * Ensure that all userspace CPU access is completed before
		 * stealing the fence.
		 */
		if (old != vma) {
			GEM_BUG_ON(old->fence != fence);
			i915_vma_revoke_mmap(old);
			old->fence = NULL;
		}

		list_move(&fence->link, &ggtt->fence_list);
	}

	/*
	 * We only need to update the register itself if the device is awake.
	 * If the device is currently powered down, we will defer the write
	 * to the runtime resume, see intel_ggtt_restore_fences().
	 *
	 * This only works for removing the fence register, on acquisition
	 * the caller must hold the rpm wakeref. The fence register must
	 * be cleared before we can use any other fences to ensure that
	 * the new fences do not overlap the elided clears, confusing HW.
	 */
	wakeref = intel_runtime_pm_get_if_in_use(uncore->rpm);
	if (!wakeref) {
		GEM_BUG_ON(vma);
		return 0;
	}

	WRITE_ONCE(fence->vma, vma);
	fence_write(fence);

	if (vma) {
		vma->fence = fence;
		list_move_tail(&fence->link, &ggtt->fence_list);
	}

	intel_runtime_pm_put(uncore->rpm, wakeref);
	return 0;
}

/**
 * i915_vma_revoke_fence - force-remove fence for a VMA
 * @vma: vma to map linearly (not through a fence reg)
 *
 * This function force-removes any fence from the given object, which is useful
 * if the kernel wants to do untiled GTT access.
 */
void i915_vma_revoke_fence(struct i915_vma *vma)
{
	struct i915_fence_reg *fence = vma->fence;
	intel_wakeref_t wakeref;

	lockdep_assert_held(&vma->vm->mutex);
	if (!fence)
		return;

	GEM_BUG_ON(fence->vma != vma);
	i915_active_wait(&fence->active);
	GEM_BUG_ON(!i915_active_is_idle(&fence->active));
	GEM_BUG_ON(atomic_read(&fence->pin_count));

	fence->tiling = 0;
	WRITE_ONCE(fence->vma, NULL);

Annotation

Implementation Notes