drivers/gpu/drm/xe/xe_sched_job.c

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

File Facts

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

if (IS_ERR(fence)) {
			err = PTR_ERR(fence);
			goto err_sched_job;
		}
		job->ptrs[i].lrc_fence = fence;

		if (i + 1 == q->width)
			continue;

		chain = dma_fence_chain_alloc();
		if (!chain) {
			err = -ENOMEM;
			goto err_sched_job;
		}
		job->ptrs[i].chain_fence = chain;
	}

	width = q->width;
	if (is_migration)
		width = 2;

	for (i = 0; i < width; ++i)
		job->ptrs[i].batch_addr = batch_addr[i];

	atomic_inc(&q->job_cnt);
	xe_pm_runtime_get_noresume(job_to_xe(job));
	trace_xe_sched_job_create(job);
	return job;

err_sched_job:
	xe_sched_job_free_fences(job);
	drm_sched_job_cleanup(&job->drm);
err_free:
	xe_exec_queue_put(q);
	job_free(job);
	return ERR_PTR(err);
}

/**
 * xe_sched_job_destroy - Destroy Xe schedule job
 * @ref: reference to Xe schedule job
 *
 * Called when ref == 0, drop a reference to job's xe_engine + fence, cleanup
 * base DRM schedule job, and free memory for Xe schedule job.
 */
void xe_sched_job_destroy(struct kref *ref)
{
	struct xe_sched_job *job =
		container_of(ref, struct xe_sched_job, refcount);
	struct xe_device *xe = job_to_xe(job);
	struct xe_exec_queue *q = job->q;

	xe_sched_job_free_fences(job);
	dma_fence_put(job->fence);
	drm_sched_job_cleanup(&job->drm);
	job_free(job);
	atomic_dec(&q->job_cnt);
	xe_exec_queue_put(q);
	xe_pm_runtime_put(xe);
}

/* Set the error status under the fence to avoid racing with signaling */
static bool xe_fence_set_error(struct dma_fence *fence, int error)
{
	unsigned long irq_flags;
	bool signaled;

	dma_fence_lock_irqsave(fence, irq_flags);
	signaled = test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags);
	if (!signaled)
		dma_fence_set_error(fence, error);
	dma_fence_unlock_irqrestore(fence, irq_flags);

	return signaled;
}

void xe_sched_job_set_error(struct xe_sched_job *job, int error)
{
	if (xe_fence_set_error(job->fence, error))
		return;

	if (dma_fence_is_chain(job->fence)) {
		struct dma_fence *iter;

		dma_fence_chain_for_each(iter, job->fence)
			xe_fence_set_error(dma_fence_chain_contained(iter),
					   error);
	}

	trace_xe_sched_job_set_error(job);

Annotation

Implementation Notes