drivers/gpu/drm/xe/xe_hw_fence.c

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

File Facts

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

list_for_each_entry_safe(fence, next, &irq->pending, irq_link) {
			struct dma_fence *dma_fence = &fence->dma;

			trace_xe_hw_fence_try_signal(fence);
			if (dma_fence_is_signaled_locked(dma_fence)) {
				trace_xe_hw_fence_signal(fence);
				list_del_init(&fence->irq_link);
				dma_fence_put(dma_fence);
			}
		}
	}
	spin_unlock(&irq->lock);
	dma_fence_end_signalling(tmp);
}

void xe_hw_fence_irq_init(struct xe_hw_fence_irq *irq)
{
	spin_lock_init(&irq->lock);
	init_irq_work(&irq->work, hw_fence_irq_run_cb);
	INIT_LIST_HEAD(&irq->pending);
	irq->enabled = true;
}

void xe_hw_fence_irq_finish(struct xe_hw_fence_irq *irq)
{
	struct xe_hw_fence *fence, *next;
	unsigned long flags;
	bool tmp;

	if (XE_WARN_ON(!list_empty(&irq->pending))) {
		tmp = dma_fence_begin_signalling();
		spin_lock_irqsave(&irq->lock, flags);
		list_for_each_entry_safe(fence, next, &irq->pending, irq_link) {
			list_del_init(&fence->irq_link);
			XE_WARN_ON(dma_fence_check_and_signal_locked(&fence->dma));
			dma_fence_put(&fence->dma);
		}
		spin_unlock_irqrestore(&irq->lock, flags);
		dma_fence_end_signalling(tmp);
	}

	/* Safe release of the irq->lock used in dma_fence_init. */
	synchronize_rcu();
}

void xe_hw_fence_irq_run(struct xe_hw_fence_irq *irq)
{
	irq_work_queue(&irq->work);
}

void xe_hw_fence_ctx_init(struct xe_hw_fence_ctx *ctx, struct xe_gt *gt,
			  struct xe_hw_fence_irq *irq, const char *name)
{
	ctx->gt = gt;
	ctx->irq = irq;
	ctx->dma_fence_ctx = dma_fence_context_alloc(1);
	ctx->next_seqno = XE_FENCE_INITIAL_SEQNO;
	snprintf(ctx->name, sizeof(ctx->name), "%s", name);
}

void xe_hw_fence_ctx_finish(struct xe_hw_fence_ctx *ctx)
{
}

static struct xe_hw_fence *to_xe_hw_fence(struct dma_fence *fence);

static struct xe_hw_fence_irq *xe_hw_fence_irq(struct xe_hw_fence *fence)
{
	return container_of(fence->dma.extern_lock, struct xe_hw_fence_irq,
			    lock);
}

static const char *xe_hw_fence_get_driver_name(struct dma_fence *dma_fence)
{
	struct xe_hw_fence *fence = to_xe_hw_fence(dma_fence);

	return dev_name(fence->xe->drm.dev);
}

static const char *xe_hw_fence_get_timeline_name(struct dma_fence *dma_fence)
{
	struct xe_hw_fence *fence = to_xe_hw_fence(dma_fence);

	return fence->name;
}

static bool xe_hw_fence_signaled(struct dma_fence *dma_fence)
{
	struct xe_hw_fence *fence = to_xe_hw_fence(dma_fence);
	struct xe_device *xe = fence->xe;

Annotation

Implementation Notes