drivers/gpu/drm/drm_exec.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/drm_exec.c
Extension
.c
Size
8708 bytes
Lines
337
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

*	drm_exec_until_all_locked(&exec) {
 *		ret = drm_exec_prepare_obj(&exec, boA, 1);
 *		drm_exec_retry_on_contention(&exec);
 *		if (ret)
 *			goto error;
 *
 *		ret = drm_exec_prepare_obj(&exec, boB, 1);
 *		drm_exec_retry_on_contention(&exec);
 *		if (ret)
 *			goto error;
 *	}
 *
 *	drm_exec_for_each_locked_object(&exec, obj) {
 *		dma_resv_add_fence(obj->resv, fence, DMA_RESV_USAGE_READ);
 *		...
 *	}
 *	drm_exec_fini(&exec);
 *
 * See struct dma_exec for more details.
 */

/* Unlock all objects and drop references */
static void drm_exec_unlock_all(struct drm_exec *exec)
{
	struct drm_gem_object *obj;

	drm_exec_for_each_locked_object_reverse(exec, obj) {
		dma_resv_unlock(obj->resv);
		drm_gem_object_put(obj);
	}

	drm_gem_object_put(exec->prelocked);
	exec->prelocked = NULL;
}

/**
 * drm_exec_init - initialize a drm_exec object
 * @exec: the drm_exec object to initialize
 * @flags: controls locking behavior, see DRM_EXEC_* defines
 * @nr: the initial # of objects
 *
 * Initialize the object and make sure that we can track locked objects.
 *
 * If nr is non-zero then it is used as the initial objects table size.
 * In either case, the table will grow (be re-allocated) on demand.
 */
void drm_exec_init(struct drm_exec *exec, u32 flags, unsigned nr)
{
	if (!nr)
		nr = PAGE_SIZE / sizeof(void *);

	exec->flags = flags;
	exec->objects = kvmalloc_array(nr, sizeof(void *), GFP_KERNEL);

	/* If allocation here fails, just delay that till the first use */
	exec->max_objects = exec->objects ? nr : 0;
	exec->num_objects = 0;
	exec->contended = DRM_EXEC_DUMMY;
	exec->prelocked = NULL;
}
EXPORT_SYMBOL(drm_exec_init);

/**
 * drm_exec_fini - finalize a drm_exec object
 * @exec: the drm_exec object to finalize
 *
 * Unlock all locked objects, drop the references to objects and free all memory
 * used for tracking the state.
 */
void drm_exec_fini(struct drm_exec *exec)
{
	drm_exec_unlock_all(exec);
	kvfree(exec->objects);
	if (exec->contended != DRM_EXEC_DUMMY) {
		drm_gem_object_put(exec->contended);
		ww_acquire_fini(&exec->ticket);
	}
}
EXPORT_SYMBOL(drm_exec_fini);

/**
 * drm_exec_cleanup - cleanup when contention is detected
 * @exec: the drm_exec object to cleanup
 *
 * Cleanup the current state and return true if we should stay inside the retry
 * loop, false if there wasn't any contention detected and we can keep the
 * objects locked.
 */
bool drm_exec_cleanup(struct drm_exec *exec)
{

Annotation

Implementation Notes