drivers/gpu/drm/msm/msm_gem_shrinker.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/msm/msm_gem_shrinker.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/msm/msm_gem_shrinker.c
Extension
.c
Size
7065 bytes
Lines
306
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 (!dma_resv_trylock(resv)) {
			locked = false;
			goto out_unlock;
		}

		/*
		 * Hold a ref to prevent the vm_bo from being freed
		 * and removed from the obj's gpuva list, as that would
		 * would result in missing the unlock below
		 */
		drm_gpuvm_bo_get(vm_bo);

		last_locked = vm_bo;
	}

	fn(obj);

out_unlock:
	if (last_locked) {
		drm_gem_for_each_gpuvm_bo (vm_bo, obj) {
			struct dma_resv *resv = drm_gpuvm_resv(vm_bo->vm);

			if (resv == obj->resv)
				continue;

			dma_resv_unlock(resv);

			/* Drop the ref taken while locking: */
			drm_gpuvm_bo_put(vm_bo);

			if (last_locked == vm_bo)
				break;
		}
	}

	return locked;
}

static bool
purge(struct drm_gem_object *obj, struct ww_acquire_ctx *unused)
{
	if (!is_purgeable(to_msm_bo(obj)))
		return false;

	if (msm_gem_active(obj))
		return false;

	return with_vm_locks(msm_gem_purge, obj);
}

static bool
evict(struct drm_gem_object *obj, struct ww_acquire_ctx *unused)
{
	if (is_unevictable(to_msm_bo(obj)))
		return false;

	if (msm_gem_active(obj))
		return false;

	return with_vm_locks(msm_gem_evict, obj);
}

static bool
wait_for_idle(struct drm_gem_object *obj)
{
	enum dma_resv_usage usage = DMA_RESV_USAGE_BOOKKEEP;
	return dma_resv_wait_timeout(obj->resv, usage, false, 10) > 0;
}

static bool
active_purge(struct drm_gem_object *obj, struct ww_acquire_ctx *ticket)
{
	if (!wait_for_idle(obj))
		return false;

	return purge(obj, ticket);
}

static bool
active_evict(struct drm_gem_object *obj, struct ww_acquire_ctx *ticket)
{
	if (!wait_for_idle(obj))
		return false;

	return evict(obj, ticket);
}

static unsigned long
msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
{

Annotation

Implementation Notes