Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 463704d0 authored by Alex Dai's avatar Alex Dai Committed by Daniel Vetter
Browse files

drm/i915/guc: Add GuC ADS - scheduler policies



GuC supports different scheduling policies for its four internal
queues. Currently these have been set to the same default values
as KMD_NORMAL queue.

Particularly POLICY_MAX_NUM_WI is set to 15 to match GuC internal
maximum submit queue numbers to avoid an out-of-space problem.
This value indicates max number of work items allowed to be queued
for one DPC process. A smaller value will let GuC schedule more
frequently while a larger number may increase chances to optimize
cmds (such as collapse cmds from same lrc) with risks that keeps
CS idle.

v1: tidy up code

Signed-off-by: default avatarAlex Dai <yu.dai@intel.com>
Reviewed-by: default avatarDave Gordon <david.s.gordon@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1450468812-4882-4-git-send-email-yu.dai@intel.com


Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 68371a95
Loading
Loading
Loading
Loading
+31 −1
Original line number Diff line number Diff line
@@ -839,17 +839,40 @@ static void guc_create_log(struct intel_guc *guc)
	guc->log_flags = (offset << GUC_LOG_BUF_ADDR_SHIFT) | flags;
}

static void init_guc_policies(struct guc_policies *policies)
{
	struct guc_policy *policy;
	u32 p, i;

	policies->dpc_promote_time = 500000;
	policies->max_num_work_items = POLICY_MAX_NUM_WI;

	for (p = 0; p < GUC_CTX_PRIORITY_NUM; p++) {
		for (i = 0; i < I915_NUM_RINGS; i++) {
			policy = &policies->policy[p][i];

			policy->execution_quantum = 1000000;
			policy->preemption_time = 500000;
			policy->fault_time = 250000;
			policy->policy_flags = 0;
		}
	}

	policies->is_valid = 1;
}

static void guc_create_ads(struct intel_guc *guc)
{
	struct drm_i915_private *dev_priv = guc_to_i915(guc);
	struct drm_i915_gem_object *obj;
	struct guc_ads *ads;
	struct guc_policies *policies;
	struct intel_engine_cs *ring;
	struct page *page;
	u32 size, i;

	/* The ads obj includes the struct itself and buffers passed to GuC */
	size = sizeof(struct guc_ads);
	size = sizeof(struct guc_ads) + sizeof(struct guc_policies);

	obj = guc->ads_obj;
	if (!obj) {
@@ -876,6 +899,13 @@ static void guc_create_ads(struct intel_guc *guc)
	for_each_ring(ring, dev_priv, i)
		ads->eng_state_size[i] = intel_lr_context_size(ring);

	/* GuC scheduling policies */
	policies = (void *)ads + sizeof(struct guc_ads);
	init_guc_policies(policies);

	ads->scheduler_policies = i915_gem_obj_ggtt_offset(obj) +
			sizeof(struct guc_ads);

	kunmap(page);
}

+45 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#define GUC_CTX_PRIORITY_HIGH		1
#define GUC_CTX_PRIORITY_KMD_NORMAL	2
#define GUC_CTX_PRIORITY_NORMAL		3
#define GUC_CTX_PRIORITY_NUM		4

#define GUC_MAX_GPU_CONTEXTS		1024
#define	GUC_INVALID_CTX_ID		GUC_MAX_GPU_CONTEXTS
@@ -316,6 +317,50 @@ struct guc_context_desc {
#define GUC_POWER_D2		3
#define GUC_POWER_D3		4

/* Scheduling policy settings */

/* Reset engine upon preempt failure */
#define POLICY_RESET_ENGINE		(1<<0)
/* Preempt to idle on quantum expiry */
#define POLICY_PREEMPT_TO_IDLE		(1<<1)

#define POLICY_MAX_NUM_WI		15

struct guc_policy {
	/* Time for one workload to execute. (in micro seconds) */
	u32 execution_quantum;
	u32 reserved1;

	/* Time to wait for a preemption request to completed before issuing a
	 * reset. (in micro seconds). */
	u32 preemption_time;

	/* How much time to allow to run after the first fault is observed.
	 * Then preempt afterwards. (in micro seconds) */
	u32 fault_time;

	u32 policy_flags;
	u32 reserved[2];
} __packed;

struct guc_policies {
	struct guc_policy policy[GUC_CTX_PRIORITY_NUM][I915_NUM_RINGS];

	/* In micro seconds. How much time to allow before DPC processing is
	 * called back via interrupt (to prevent DPC queue drain starving).
	 * Typically 1000s of micro seconds (example only, not granularity). */
	u32 dpc_promote_time;

	/* Must be set to take these new values. */
	u32 is_valid;

	/* Max number of WIs to process per call. A large value may keep CS
	 * idle. */
	u32 max_num_work_items;

	u32 reserved[19];
} __packed;

/* GuC Additional Data Struct */

struct guc_ads {