drivers/gpu/drm/xe/xe_guc_submit.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_guc_submit.c
Extension
.c
Size
98977 bytes
Lines
3418
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 exec_queue_policy {
	u32 count;
	struct guc_update_exec_queue_policy h2g;
};

static u32 __guc_exec_queue_policy_action_size(struct exec_queue_policy *policy)
{
	size_t bytes = sizeof(policy->h2g.header) +
		       (sizeof(policy->h2g.klv[0]) * policy->count);

	return bytes / sizeof(u32);
}

static void __guc_exec_queue_policy_start_klv(struct exec_queue_policy *policy,
					      u16 guc_id)
{
	policy->h2g.header.action =
		XE_GUC_ACTION_HOST2GUC_UPDATE_CONTEXT_POLICIES;
	policy->h2g.header.guc_id = guc_id;
	policy->count = 0;
}

#define MAKE_EXEC_QUEUE_POLICY_ADD(func, id) \
static void __guc_exec_queue_policy_add_##func(struct exec_queue_policy *policy, \
					   u32 data) \
{ \
	XE_WARN_ON(policy->count >= GUC_CONTEXT_POLICIES_KLV_NUM_IDS); \
\
	policy->h2g.klv[policy->count].kl = \
		FIELD_PREP(GUC_KLV_0_KEY, \
			   GUC_CONTEXT_POLICIES_KLV_ID_##id) | \
		FIELD_PREP(GUC_KLV_0_LEN, 1); \
	policy->h2g.klv[policy->count].value = data; \
	policy->count++; \
}

MAKE_EXEC_QUEUE_POLICY_ADD(execution_quantum, EXECUTION_QUANTUM)
MAKE_EXEC_QUEUE_POLICY_ADD(preemption_timeout, PREEMPTION_TIMEOUT)
MAKE_EXEC_QUEUE_POLICY_ADD(priority, SCHEDULING_PRIORITY)
MAKE_EXEC_QUEUE_POLICY_ADD(slpc_exec_queue_freq_req, SLPM_GT_FREQUENCY)
#undef MAKE_EXEC_QUEUE_POLICY_ADD

static const int xe_exec_queue_prio_to_guc[] = {
	[XE_EXEC_QUEUE_PRIORITY_LOW] = GUC_CLIENT_PRIORITY_NORMAL,
	[XE_EXEC_QUEUE_PRIORITY_NORMAL] = GUC_CLIENT_PRIORITY_KMD_NORMAL,
	[XE_EXEC_QUEUE_PRIORITY_HIGH] = GUC_CLIENT_PRIORITY_HIGH,
	[XE_EXEC_QUEUE_PRIORITY_KERNEL] = GUC_CLIENT_PRIORITY_KMD_HIGH,
};

static void init_policies(struct xe_guc *guc, struct xe_exec_queue *q)
{
	struct exec_queue_policy policy;
	enum xe_exec_queue_priority prio = q->sched_props.priority;
	u32 timeslice_us = q->sched_props.timeslice_us;
	u32 slpc_exec_queue_freq_req = 0;
	u32 preempt_timeout_us = q->sched_props.preempt_timeout_us;

	xe_gt_assert(guc_to_gt(guc), exec_queue_registered(q) &&
		     !xe_exec_queue_is_multi_queue_secondary(q));

	if (q->flags & EXEC_QUEUE_FLAG_LOW_LATENCY)
		slpc_exec_queue_freq_req |= SLPC_CTX_FREQ_REQ_IS_COMPUTE;

	__guc_exec_queue_policy_start_klv(&policy, q->guc->id);
	__guc_exec_queue_policy_add_priority(&policy, xe_exec_queue_prio_to_guc[prio]);
	__guc_exec_queue_policy_add_execution_quantum(&policy, timeslice_us);
	__guc_exec_queue_policy_add_preemption_timeout(&policy, preempt_timeout_us);
	__guc_exec_queue_policy_add_slpc_exec_queue_freq_req(&policy,
							     slpc_exec_queue_freq_req);

	xe_guc_ct_send(&guc->ct, (u32 *)&policy.h2g,
		       __guc_exec_queue_policy_action_size(&policy), 0, 0);
}

static void set_min_preemption_timeout(struct xe_guc *guc, struct xe_exec_queue *q)
{
	struct exec_queue_policy policy;

	xe_assert(guc_to_xe(guc), !xe_exec_queue_is_multi_queue_secondary(q));

	__guc_exec_queue_policy_start_klv(&policy, q->guc->id);
	__guc_exec_queue_policy_add_preemption_timeout(&policy, 1);

	xe_guc_ct_send(&guc->ct, (u32 *)&policy.h2g,
		       __guc_exec_queue_policy_action_size(&policy), 0, 0);
}

static bool vf_recovery(struct xe_guc *guc)
{
	return xe_gt_recovery_pending(guc_to_gt(guc));

Annotation

Implementation Notes