drivers/gpu/drm/xe/xe_tlb_inval_job.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_tlb_inval_job.c
Extension
.c
Size
9648 bytes
Lines
320
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

struct xe_tlb_inval_job {
	/** @dep: base generic dependency Xe job */
	struct xe_dep_job dep;
	/** @tlb_inval: TLB invalidation client */
	struct xe_tlb_inval *tlb_inval;
	/** @q: exec queue issuing the invalidate */
	struct xe_exec_queue *q;
	/** @vm: VM which TLB invalidation is being issued for */
	struct xe_vm *vm;
	/** @prl: Embedded copy of page reclaim list */
	struct xe_page_reclaim_list prl;
	/** @refcount: ref count of this job */
	struct kref refcount;
	/**
	 * @fence: dma fence to indicate completion. 1 way relationship - job
	 * can safely reference fence, fence cannot safely reference job.
	 */
	struct dma_fence *fence;
	/** @start: Start address to invalidate */
	u64 start;
	/** @end: End address to invalidate */
	u64 end;
	/** @type: GT type */
	int type;
	/** @fence_armed: Fence has been armed */
	bool fence_armed;
};

static struct dma_fence *xe_tlb_inval_job_run(struct xe_dep_job *dep_job)
{
	struct xe_tlb_inval_job *job =
		container_of(dep_job, typeof(*job), dep);
	struct xe_tlb_inval_fence *ifence =
		container_of(job->fence, typeof(*ifence), base);
	struct drm_suballoc *prl_sa = NULL;

	if (xe_page_reclaim_list_valid(&job->prl)) {
		prl_sa = xe_page_reclaim_create_prl_bo(job->tlb_inval, &job->prl, ifence);
		if (IS_ERR(prl_sa))
			prl_sa = NULL; /* Indicate fall back PPC flush with NULL */
	}

	xe_tlb_inval_range(job->tlb_inval, ifence, job->start,
			   job->end, job->vm->usm.asid, prl_sa);

	return job->fence;
}

static void xe_tlb_inval_job_free(struct xe_dep_job *dep_job)
{
	struct xe_tlb_inval_job *job =
		container_of(dep_job, typeof(*job), dep);

	/* Pairs with get in xe_tlb_inval_job_push */
	xe_tlb_inval_job_put(job);
}

static const struct xe_dep_job_ops dep_job_ops = {
	.run_job = xe_tlb_inval_job_run,
	.free_job = xe_tlb_inval_job_free,
};

/**
 * xe_tlb_inval_job_create() - TLB invalidation job create
 * @q: exec queue issuing the invalidate
 * @tlb_inval: TLB invalidation client
 * @dep_scheduler: Dependency scheduler for job
 * @vm: VM which TLB invalidation is being issued for
 * @start: Start address to invalidate
 * @end: End address to invalidate
 * @type: GT type
 *
 * Create a TLB invalidation job and initialize internal fields. The caller is
 * responsible for releasing the creation reference.
 *
 * Return: TLB invalidation job object on success, ERR_PTR failure
 */
struct xe_tlb_inval_job *
xe_tlb_inval_job_create(struct xe_exec_queue *q, struct xe_tlb_inval *tlb_inval,
			struct xe_dep_scheduler *dep_scheduler,
			struct xe_vm *vm, u64 start, u64 end, int type)
{
	struct xe_tlb_inval_job *job;
	struct drm_sched_entity *entity =
		xe_dep_scheduler_entity(dep_scheduler);
	struct xe_tlb_inval_fence *ifence;
	int err;

	xe_assert(vm->xe, type == XE_EXEC_QUEUE_TLB_INVAL_MEDIA_GT ||
		  type == XE_EXEC_QUEUE_TLB_INVAL_PRIMARY_GT);

Annotation

Implementation Notes