[PATCH v7] drm/i915: Allocate intel_engine_cs structure only for the enabled engines

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Tue Aug 9 13:17:46 UTC 2016


On 05/08/16 13:40, akash.goel at intel.com wrote:
> From: Akash Goel <akash.goel at intel.com>
>
> With the possibility of addition of many more number of rings in future,
> the drm_i915_private structure could bloat as an array, of type
> intel_engine_cs, is embedded inside it.
> 	struct intel_engine_cs engine[I915_NUM_ENGINES];
> Though this is still fine as generally there is only a single instance of
> drm_i915_private structure used, but not all of the possible rings would be
> enabled or active on most of the platforms. Some memory can be saved by
> allocating intel_engine_cs structure only for the enabled/active engines.
> Currently the engine/ring ID is kept static and dev_priv->engine[] is simply
> indexed using the enums defined in intel_engine_id.
> To save memory and continue using the static engine/ring IDs, 'engine' is
> defined as an array of pointers.
> 	struct intel_engine_cs *engine[I915_NUM_ENGINES];
> dev_priv->engine[engine_ID] will be NULL for disabled engine instances.
>
> v2:
> - Remove the engine iterator field added in drm_i915_private structure,
>    instead pass a local iterator variable to the for_each_engine**
>    macros. (Chris)
> - Do away with intel_engine_initialized() and instead directly use the
>    NULL pointer check on engine pointer. (Chris)
>
> v3:
> - Remove for_each_engine_id() macro, as the updated macro for_each_engine()
>    can be used in place of it. (Chris)
> - Protect the access to Render engine Fault register with a NULL check, as
>    engine specific init is done later in Driver load sequence.
>
> v4:
> - Use !!dev_priv->engine[VCS] style for the engine check in getparam. (Chris)
> - Kill the superfluous init_engine_lists().
>
> v5:
> - Cleanup the intel_engines_init() & intel_engines_setup(), with respect to
>    allocation of intel_engine_cs structure. (Chris)
>
> v6:
> - Rebase.
>
> v7:
> - Optimize the for_each_engine_masked() macro. (Chris)
> - Change the type of 'iter' local variable to enum intel_engine_id. (Chris)
> - Rebase.
>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Signed-off-by: Akash Goel <akash.goel at intel.com>
> ---
>   drivers/gpu/drm/i915/i915_cmd_parser.c     |  3 +-
>   drivers/gpu/drm/i915/i915_debugfs.c        | 55 ++++++++++++++++++------------
>   drivers/gpu/drm/i915/i915_drv.c            |  8 ++---
>   drivers/gpu/drm/i915/i915_drv.h            | 33 +++++++-----------
>   drivers/gpu/drm/i915/i915_gem.c            | 25 ++++++--------
>   drivers/gpu/drm/i915/i915_gem_context.c    | 15 ++++----
>   drivers/gpu/drm/i915/i915_gem_evict.c      |  3 +-
>   drivers/gpu/drm/i915/i915_gem_execbuffer.c |  6 ++--
>   drivers/gpu/drm/i915/i915_gem_gtt.c        | 14 +++++---
>   drivers/gpu/drm/i915/i915_gem_request.c    |  8 +++--
>   drivers/gpu/drm/i915/i915_gpu_error.c      | 24 ++++++-------
>   drivers/gpu/drm/i915/i915_guc_submission.c | 13 ++++---
>   drivers/gpu/drm/i915/i915_irq.c            | 46 +++++++++++++------------
>   drivers/gpu/drm/i915/intel_breadcrumbs.c   |  6 ++--
>   drivers/gpu/drm/i915/intel_display.c       |  8 ++---
>   drivers/gpu/drm/i915/intel_engine_cs.c     | 22 ++++++++----
>   drivers/gpu/drm/i915/intel_guc_loader.c    |  6 ++--
>   drivers/gpu/drm/i915/intel_lrc.c           | 10 ++++--
>   drivers/gpu/drm/i915/intel_overlay.c       |  2 +-
>   drivers/gpu/drm/i915/intel_pm.c            | 17 +++++----
>   drivers/gpu/drm/i915/intel_ringbuffer.c    | 10 +++---
>   drivers/gpu/drm/i915/intel_ringbuffer.h    |  6 ----
>   drivers/gpu/drm/i915/intel_uncore.c        |  8 +++--
>   23 files changed, 196 insertions(+), 152 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c
> index 1db829c..713b4ce 100644
> --- a/drivers/gpu/drm/i915/i915_cmd_parser.c
> +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
> @@ -1295,10 +1295,11 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine,
>   int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	bool active = false;
>
>   	/* If the command parser is not enabled, report 0 - unsupported */
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		if (intel_engine_needs_cmd_parser(engine)) {
>   			active = true;
>   			break;
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 0620a84..6863525 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -154,7 +154,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
>   		   obj->base.size / 1024,
>   		   obj->base.read_domains,
>   		   obj->base.write_domain);
> -	for_each_engine_id(engine, dev_priv, id)
> +	for_each_engine(engine, dev_priv, id)
>   		seq_printf(m, "%x ",
>   			   i915_gem_active_get_seqno(&obj->last_read[id],
>   						     &obj->base.dev->struct_mutex));
> @@ -395,11 +395,12 @@ static void print_batch_pool_stats(struct seq_file *m,
>   	struct drm_i915_gem_object *obj;
>   	struct file_stats stats;
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	int j;
>
>   	memset(&stats, 0, sizeof(stats));
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) {
>   			list_for_each_entry(obj,
>   					    &engine->batch_pool.cache_list[j],
> @@ -692,6 +693,7 @@ static int i915_gem_batch_pool_info(struct seq_file *m, void *data)
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct drm_i915_gem_object *obj;
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	int total = 0;
>   	int ret, j;
>
> @@ -699,7 +701,7 @@ static int i915_gem_batch_pool_info(struct seq_file *m, void *data)
>   	if (ret)
>   		return ret;
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) {
>   			int count;
>
> @@ -736,6 +738,7 @@ static int i915_gem_request_info(struct seq_file *m, void *data)
>   	struct drm_device *dev = node->minor->dev;
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	struct drm_i915_gem_request *req;
>   	int ret, any;
>
> @@ -744,7 +747,7 @@ static int i915_gem_request_info(struct seq_file *m, void *data)
>   		return ret;
>
>   	any = 0;
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		int count;
>
>   		count = 0;
> @@ -806,6 +809,7 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data)
>   	struct drm_device *dev = node->minor->dev;
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	int ret;
>
>   	ret = mutex_lock_interruptible(&dev->struct_mutex);
> @@ -813,7 +817,7 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data)
>   		return ret;
>   	intel_runtime_pm_get(dev_priv);
>
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		i915_ring_seqno_info(m, engine);
>
>   	intel_runtime_pm_put(dev_priv);
> @@ -829,6 +833,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
>   	struct drm_device *dev = node->minor->dev;
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	int ret, i, pipe;
>
>   	ret = mutex_lock_interruptible(&dev->struct_mutex);
> @@ -1000,7 +1005,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
>   		seq_printf(m, "Graphics Interrupt mask:		%08x\n",
>   			   I915_READ(GTIMR));
>   	}
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		if (INTEL_INFO(dev)->gen >= 6) {
>   			seq_printf(m,
>   				   "Graphics Interrupt mask (%s):	%08x\n",
> @@ -1051,7 +1056,7 @@ static int i915_hws_info(struct seq_file *m, void *data)
>   	const u32 *hws;
>   	int i;
>
> -	engine = &dev_priv->engine[(uintptr_t)node->info_ent->data];
> +	engine = dev_priv->engine[(uintptr_t)node->info_ent->data];
>   	hws = engine->status_page.page_addr;
>   	if (hws == NULL)
>   		return 0;
> @@ -1412,7 +1417,7 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
>
>   	intel_runtime_pm_get(dev_priv);
>
> -	for_each_engine_id(engine, dev_priv, id) {
> +	for_each_engine(engine, dev_priv, id) {
>   		acthd[id] = intel_engine_get_active_head(engine);
>   		seqno[id] = intel_engine_get_seqno(engine);
>   	}
> @@ -1428,7 +1433,7 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
>   	} else
>   		seq_printf(m, "Hangcheck inactive\n");
>
> -	for_each_engine_id(engine, dev_priv, id) {
> +	for_each_engine(engine, dev_priv, id) {
>   		seq_printf(m, "%s:\n", engine->name);
>   		seq_printf(m, "\tseqno = %x [current %x, last %x]\n",
>   			   engine->hangcheck.seqno,
> @@ -2043,6 +2048,7 @@ static int i915_context_status(struct seq_file *m, void *unused)
>   	struct drm_device *dev = node->minor->dev;
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	struct i915_gem_context *ctx;
>   	int ret;
>
> @@ -2071,7 +2077,7 @@ static int i915_context_status(struct seq_file *m, void *unused)
>   		seq_putc(m, ctx->remap_slice ? 'R' : 'r');
>   		seq_putc(m, '\n');
>
> -		for_each_engine(engine, dev_priv) {
> +		for_each_engine(engine, dev_priv, iter) {
>   			struct intel_context *ce = &ctx->engine[engine->id];
>
>   			seq_printf(m, "%s: ", engine->name);
> @@ -2140,6 +2146,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused)
>   	struct drm_device *dev = node->minor->dev;
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	struct i915_gem_context *ctx;
>   	int ret;
>
> @@ -2153,7 +2160,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused)
>   		return ret;
>
>   	list_for_each_entry(ctx, &dev_priv->context_list, link)
> -		for_each_engine(engine, dev_priv)
> +		for_each_engine(engine, dev_priv, iter)
>   			i915_dump_lrc_obj(m, ctx, engine);
>
>   	mutex_unlock(&dev->struct_mutex);
> @@ -2167,6 +2174,7 @@ static int i915_execlists(struct seq_file *m, void *data)
>   	struct drm_device *dev = node->minor->dev;
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	u32 status_pointer;
>   	u8 read_pointer;
>   	u8 write_pointer;
> @@ -2186,7 +2194,7 @@ static int i915_execlists(struct seq_file *m, void *data)
>
>   	intel_runtime_pm_get(dev_priv);
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		struct drm_i915_gem_request *head_req = NULL;
>   		int count = 0;
>
> @@ -2343,13 +2351,14 @@ static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev)
>   {
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
>   	int i;
>
>   	if (!ppgtt)
>   		return;
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		seq_printf(m, "%s\n", engine->name);
>   		for (i = 0; i < 4; i++) {
>   			u64 pdp = I915_READ(GEN8_RING_PDP_UDW(engine, i));
> @@ -2364,11 +2373,12 @@ static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
>   {
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
>   	if (IS_GEN6(dev_priv))
>   		seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE));
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		seq_printf(m, "%s\n", engine->name);
>   		if (IS_GEN7(dev_priv))
>   			seq_printf(m, "GFX_MODE: 0x%08x\n",
> @@ -2436,9 +2446,10 @@ out_unlock:
>   static int count_irq_waiters(struct drm_i915_private *i915)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	int count = 0;
>
> -	for_each_engine(engine, i915)
> +	for_each_engine(engine, i915, iter)
>   		count += intel_engine_has_waiter(engine);
>
>   	return count;
> @@ -2547,6 +2558,7 @@ static void i915_guc_client_info(struct seq_file *m,
>   				 struct i915_guc_client *client)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	uint64_t tot = 0;
>
>   	seq_printf(m, "\tPriority %d, GuC ctx index: %u, PD offset 0x%x\n",
> @@ -2561,7 +2573,7 @@ static void i915_guc_client_info(struct seq_file *m,
>   	seq_printf(m, "\tFailed doorbell: %u\n", client->b_fail);
>   	seq_printf(m, "\tLast submission result: %d\n", client->retcode);
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		seq_printf(m, "\tSubmissions: %llu %s\n",
>   				client->submissions[engine->id],
>   				engine->name);
> @@ -2578,6 +2590,7 @@ static int i915_guc_info(struct seq_file *m, void *data)
>   	struct intel_guc guc;
>   	struct i915_guc_client client = {};
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	u64 total = 0;
>
>   	if (!HAS_GUC_SCHED(dev_priv))
> @@ -2604,7 +2617,7 @@ static int i915_guc_info(struct seq_file *m, void *data)
>   	seq_printf(m, "GuC last action error code: %d\n", guc.action_err);
>
>   	seq_printf(m, "\nGuC submissions:\n");
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x\n",
>   			engine->name, guc.submissions[engine->id],
>   			guc.last_seqno[engine->id]);
> @@ -3249,7 +3262,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused)
>   		page = i915_gem_object_get_page(dev_priv->semaphore_obj, 0);
>
>   		seqno = (uint64_t *)kmap_atomic(page);
> -		for_each_engine_id(engine, dev_priv, id) {
> +		for_each_engine(engine, dev_priv, id) {
>   			uint64_t offset;
>
>   			seq_printf(m, "%s\n", engine->name);
> @@ -3274,7 +3287,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused)
>   		kunmap_atomic(seqno);
>   	} else {
>   		seq_puts(m, "  Last signal:");
> -		for_each_engine(engine, dev_priv)
> +		for_each_engine(engine, dev_priv, id)
>   			for (j = 0; j < num_rings; j++)
>   				seq_printf(m, "0x%08x\n",
>   					   I915_READ(engine->semaphore.mbox.signal[j]));
> @@ -3282,7 +3295,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused)
>   	}
>
>   	seq_puts(m, "\nSync seqno:\n");
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, id) {
>   		for (j = 0; j < num_rings; j++)
>   			seq_printf(m, "  0x%08x ",
>   				   engine->semaphore.sync_seqno[j]);
> @@ -3340,7 +3353,7 @@ static int i915_wa_registers(struct seq_file *m, void *unused)
>   	intel_runtime_pm_get(dev_priv);
>
>   	seq_printf(m, "Workarounds applied: %d\n", workarounds->count);
> -	for_each_engine_id(engine, dev_priv, id)
> +	for_each_engine(engine, dev_priv, id)
>   		seq_printf(m, "HW whitelist count for %s: %d\n",
>   			   engine->name, workarounds->hw_whitelist_count[id]);
>   	for (i = 0; i < workarounds->count; ++i) {
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 8cfc264..7f5739d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -264,16 +264,16 @@ static int i915_getparam(struct drm_device *dev, void *data,
>   		value = 1;
>   		break;
>   	case I915_PARAM_HAS_BSD:
> -		value = intel_engine_initialized(&dev_priv->engine[VCS]);
> +		value = !!dev_priv->engine[VCS];
>   		break;
>   	case I915_PARAM_HAS_BLT:
> -		value = intel_engine_initialized(&dev_priv->engine[BCS]);
> +		value = !!dev_priv->engine[BCS];
>   		break;
>   	case I915_PARAM_HAS_VEBOX:
> -		value = intel_engine_initialized(&dev_priv->engine[VECS]);
> +		value = !!dev_priv->engine[VECS];
>   		break;
>   	case I915_PARAM_HAS_BSD2:
> -		value = intel_engine_initialized(&dev_priv->engine[VCS2]);
> +		value = !!dev_priv->engine[VCS2];
>   		break;
>   	case I915_PARAM_HAS_RELAXED_FENCING:
>   		value = 1;
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index feec00f..1dd62b8 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1753,7 +1753,7 @@ struct drm_i915_private {
>
>   	struct pci_dev *bridge_dev;
>   	struct i915_gem_context *kernel_context;
> -	struct intel_engine_cs engine[I915_NUM_ENGINES];
> +	struct intel_engine_cs *engine[I915_NUM_ENGINES];

It is a little bit of a pity since iterator removal was a nice code 
shrink IIRC. Nevermind..

What I wanted to say is, would it be feasible to have, in addition to 
the above:

	unsigned int num_engines;
	struct intel_engine_cs **engine_list;

dev_priv->engine[] would be a direct map of intel_engine_id to engine 
for lookups, while the iterators would use dynamically sized (no holes) 
dev_priv->engine_list.

On the other hand there probably isn't a lot of for_each_engines on fast 
paths so it may not be that interesting optimisation.

Regards,

Tvrtko

>   	struct drm_i915_gem_object *semaphore_obj;
>   	u32 next_seqno;
>
> @@ -2060,27 +2060,20 @@ static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc)
>   }
>
>   /* Simple iterator over all initialised engines */
> -#define for_each_engine(engine__, dev_priv__) \
> -	for ((engine__) = &(dev_priv__)->engine[0]; \
> -	     (engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \
> -	     (engine__)++) \
> -		for_each_if (intel_engine_initialized(engine__))
> -
> -/* Iterator with engine_id */
> -#define for_each_engine_id(engine__, dev_priv__, id__) \
> -	for ((engine__) = &(dev_priv__)->engine[0], (id__) = 0; \
> -	     (engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \
> -	     (engine__)++) \
> -		for_each_if (((id__) = (engine__)->id, \
> -			      intel_engine_initialized(engine__)))
> +#define for_each_engine(engine__, dev_priv__, iter__) \
> +	for ((iter__) = 0; \
> +	     ((iter__) < I915_NUM_ENGINES) && \
> +	     ((engine__) = (dev_priv__)->engine[(iter__)], true); \
> +	     (iter__)++) \
> +		for_each_if ((engine__))
>
>   /* Iterator over subset of engines selected by mask */
> -#define for_each_engine_masked(engine__, dev_priv__, mask__) \
> -	for ((engine__) = &(dev_priv__)->engine[0]; \
> -	     (engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \
> -	     (engine__)++) \
> -		for_each_if (((mask__) & intel_engine_flag(engine__)) && \
> -			     intel_engine_initialized(engine__))
> +#define for_each_engine_masked(engine__, dev_priv__, mask__, iter__) \
> +	for ((iter__) = 0; \
> +	     (iter__) < I915_NUM_ENGINES; \
> +	     (iter__)++) \
> +		for_each_if (((mask__) & BIT((iter__))) && \
> +			     ((engine__) = (dev_priv__)->engine[(iter__)]))
>
>   enum hdmi_force_audio {
>   	HDMI_AUDIO_OFF_DVI = -2,	/* no aux data for HDMI-DVI converter */
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index f4f8eaa..0279254 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2476,16 +2476,17 @@ void i915_gem_reset(struct drm_device *dev)
>   {
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
>   	/*
>   	 * Before we free the objects from the requests, we need to inspect
>   	 * them for finding the guilty party. As the requests only borrow
>   	 * their reference to the objects, the inspection must be done first.
>   	 */
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		i915_gem_reset_engine_status(engine);
>
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		i915_gem_reset_engine_cleanup(engine);
>   	mod_delayed_work(dev_priv->wq, &dev_priv->gt.idle_work, 0);
>
> @@ -2526,6 +2527,7 @@ i915_gem_idle_work_handler(struct work_struct *work)
>   		container_of(work, typeof(*dev_priv), gt.idle_work.work);
>   	struct drm_device *dev = &dev_priv->drm;
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	unsigned int stuck_engines;
>   	bool rearm_hangcheck;
>
> @@ -2549,7 +2551,7 @@ i915_gem_idle_work_handler(struct work_struct *work)
>   	if (dev_priv->gt.active_engines)
>   		goto out_unlock;
>
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		i915_gem_batch_pool_fini(&engine->batch_pool);
>
>   	GEM_BUG_ON(!dev_priv->gt.awake);
> @@ -2863,9 +2865,10 @@ int i915_gem_wait_for_idle(struct drm_i915_private *dev_priv,
>   			   bool interruptible)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	int ret;
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		if (engine->last_context == NULL)
>   			continue;
>
> @@ -4228,6 +4231,7 @@ i915_gem_init_hw(struct drm_device *dev)
>   {
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	int ret;
>
>   	/* Double layer security blanket, see i915_gem_init() */
> @@ -4271,7 +4275,7 @@ i915_gem_init_hw(struct drm_device *dev)
>   	}
>
>   	/* Need to do basic initialisation of all rings first: */
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		ret = engine->init_hw(engine);
>   		if (ret)
>   			goto out;
> @@ -4368,17 +4372,12 @@ i915_gem_cleanup_engines(struct drm_device *dev)
>   {
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		dev_priv->gt.cleanup_engine(engine);
>   }
>
> -static void
> -init_engine_lists(struct intel_engine_cs *engine)
> -{
> -	INIT_LIST_HEAD(&engine->request_list);
> -}
> -
>   void
>   i915_gem_load_init_fences(struct drm_i915_private *dev_priv)
>   {
> @@ -4431,8 +4430,6 @@ i915_gem_load_init(struct drm_device *dev)
>   	INIT_LIST_HEAD(&dev_priv->mm.unbound_list);
>   	INIT_LIST_HEAD(&dev_priv->mm.bound_list);
>   	INIT_LIST_HEAD(&dev_priv->mm.fence_list);
> -	for (i = 0; i < I915_NUM_ENGINES; i++)
> -		init_engine_lists(&dev_priv->engine[i]);
>   	for (i = 0; i < I915_MAX_NUM_FENCES; i++)
>   		INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
>   	INIT_DELAYED_WORK(&dev_priv->gt.retire_work,
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index bb72af5..c7e5d9b 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -475,10 +475,11 @@ int i915_gem_context_init(struct drm_device *dev)
>   void i915_gem_context_lost(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
>   	lockdep_assert_held(&dev_priv->drm.struct_mutex);
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		if (engine->last_context) {
>   			i915_gem_context_unpin(engine->last_context, engine);
>   			engine->last_context = NULL;
> @@ -493,13 +494,13 @@ void i915_gem_context_lost(struct drm_i915_private *dev_priv)
>   			if (!i915_gem_context_is_default(ctx))
>   				continue;
>
> -			for_each_engine(engine, dev_priv)
> +			for_each_engine(engine, dev_priv, iter)
>   				ctx->engine[engine->id].initialised = false;
>
>   			ctx->remap_slice = ALL_L3_SLICES(dev_priv);
>   		}
>
> -		for_each_engine(engine, dev_priv) {
> +		for_each_engine(engine, dev_priv, iter) {
>   			struct intel_context *kce =
>   				&dev_priv->kernel_context->engine[engine->id];
>
> @@ -564,6 +565,7 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags)
>   	struct drm_i915_private *dev_priv = req->i915;
>   	struct intel_ring *ring = req->ring;
>   	struct intel_engine_cs *engine = req->engine;
> +	enum intel_engine_id iter;
>   	u32 flags = hw_flags | MI_MM_SPACE_GTT;
>   	const int num_rings =
>   		/* Use an extended w/a on ivb+ if signalling from other rings */
> @@ -606,7 +608,7 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags)
>
>   			intel_ring_emit(ring,
>   					MI_LOAD_REGISTER_IMM(num_rings));
> -			for_each_engine(signaller, dev_priv) {
> +			for_each_engine(signaller, dev_priv, iter) {
>   				if (signaller == engine)
>   					continue;
>
> @@ -636,7 +638,7 @@ mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags)
>
>   			intel_ring_emit(ring,
>   					MI_LOAD_REGISTER_IMM(num_rings));
> -			for_each_engine(signaller, dev_priv) {
> +			for_each_engine(signaller, dev_priv, iter) {
>   				if (signaller == engine)
>   					continue;
>
> @@ -939,8 +941,9 @@ int i915_switch_context(struct drm_i915_gem_request *req)
>   int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		struct drm_i915_gem_request *req;
>   		int ret;
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
> index f76c06e..975324f 100644
> --- a/drivers/gpu/drm/i915/i915_gem_evict.c
> +++ b/drivers/gpu/drm/i915/i915_gem_evict.c
> @@ -37,8 +37,9 @@ static bool
>   gpu_is_idle(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		if (intel_engine_is_active(engine))
>   			return false;
>   	}
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index c494b79..f0e3a11 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -1494,12 +1494,12 @@ eb_select_engine(struct drm_i915_private *dev_priv,
>   			return NULL;
>   		}
>
> -		engine = &dev_priv->engine[_VCS(bsd_idx)];
> +		engine = dev_priv->engine[_VCS(bsd_idx)];
>   	} else {
> -		engine = &dev_priv->engine[user_ring_map[user_ring_id]];
> +		engine = dev_priv->engine[user_ring_map[user_ring_id]];
>   	}
>
> -	if (!intel_engine_initialized(engine)) {
> +	if (!engine) {
>   		DRM_DEBUG("execbuf with invalid ring: %u\n", user_ring_id);
>   		return NULL;
>   	}
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 8b4f2f3..79c0c8a 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -1734,8 +1734,9 @@ static void gen8_ppgtt_enable(struct drm_device *dev)
>   {
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		u32 four_level = USES_FULL_48BIT_PPGTT(dev) ? GEN8_GFX_PPGTT_48B : 0;
>   		I915_WRITE(RING_MODE_GEN7(engine),
>   			   _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE | four_level));
> @@ -1746,6 +1747,7 @@ static void gen7_ppgtt_enable(struct drm_device *dev)
>   {
>   	struct drm_i915_private *dev_priv = to_i915(dev);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	uint32_t ecochk, ecobits;
>
>   	ecobits = I915_READ(GAC_ECO_BITS);
> @@ -1760,7 +1762,7 @@ static void gen7_ppgtt_enable(struct drm_device *dev)
>   	}
>   	I915_WRITE(GAM_ECOCHK, ecochk);
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		/* GFX_MODE is per-ring on gen7+ */
>   		I915_WRITE(RING_MODE_GEN7(engine),
>   			   _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
> @@ -2244,11 +2246,12 @@ static bool needs_idle_maps(struct drm_i915_private *dev_priv)
>   void i915_check_and_clear_faults(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
>   	if (INTEL_INFO(dev_priv)->gen < 6)
>   		return;
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		u32 fault_reg;
>   		fault_reg = I915_READ(RING_FAULT_REG(engine));
>   		if (fault_reg & RING_FAULT_VALID) {
> @@ -2265,7 +2268,10 @@ void i915_check_and_clear_faults(struct drm_i915_private *dev_priv)
>   				   fault_reg & ~RING_FAULT_VALID);
>   		}
>   	}
> -	POSTING_READ(RING_FAULT_REG(&dev_priv->engine[RCS]));
> +
> +	/* Engine specific init may not have been done till this point. */
> +	if (dev_priv->engine[RCS])
> +		POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS]));
>   }
>
>   static void i915_ggtt_flush(struct drm_i915_private *dev_priv)
> diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
> index b317a67..435a8e3 100644
> --- a/drivers/gpu/drm/i915/i915_gem_request.c
> +++ b/drivers/gpu/drm/i915/i915_gem_request.c
> @@ -259,10 +259,11 @@ static int i915_gem_check_wedge(unsigned int reset_counter, bool interruptible)
>   static int i915_gem_init_seqno(struct drm_i915_private *dev_priv, u32 seqno)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	int ret;
>
>   	/* Carefully retire all requests without writing to the rings */
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		ret = intel_engine_idle(engine, true);
>   		if (ret)
>   			return ret;
> @@ -277,7 +278,7 @@ static int i915_gem_init_seqno(struct drm_i915_private *dev_priv, u32 seqno)
>   	}
>
>   	/* Finally reset hw state */
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		intel_engine_init_seqno(engine, seqno);
>
>   	return 0;
> @@ -746,6 +747,7 @@ static void engine_retire_requests(struct intel_engine_cs *engine)
>   void i915_gem_retire_requests(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
>   	lockdep_assert_held(&dev_priv->drm.struct_mutex);
>
> @@ -754,7 +756,7 @@ void i915_gem_retire_requests(struct drm_i915_private *dev_priv)
>
>   	GEM_BUG_ON(!dev_priv->gt.awake);
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		engine_retire_requests(engine);
>   		if (!intel_engine_is_active(engine))
>   			dev_priv->gt.active_engines &= ~intel_engine_flag(engine);
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> index eecb870..9e61c1f 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -431,7 +431,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
>
>   		obj = ee->batchbuffer;
>   		if (obj) {
> -			err_puts(m, dev_priv->engine[i].name);
> +			err_puts(m, dev_priv->engine[i]->name);
>   			if (ee->pid != -1)
>   				err_printf(m, " (submitted by %s [%d])",
>   					   ee->comm,
> @@ -445,14 +445,14 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
>   		obj = ee->wa_batchbuffer;
>   		if (obj) {
>   			err_printf(m, "%s (w/a) --- gtt_offset = 0x%08x\n",
> -				   dev_priv->engine[i].name,
> +				   dev_priv->engine[i]->name,
>   				   lower_32_bits(obj->gtt_offset));
>   			print_error_obj(m, obj);
>   		}
>
>   		if (ee->num_requests) {
>   			err_printf(m, "%s --- %d requests\n",
> -				   dev_priv->engine[i].name,
> +				   dev_priv->engine[i]->name,
>   				   ee->num_requests);
>   			for (j = 0; j < ee->num_requests; j++) {
>   				err_printf(m, "  seqno 0x%08x, emitted %ld, tail 0x%08x\n",
> @@ -464,7 +464,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
>
>   		if (ee->num_waiters) {
>   			err_printf(m, "%s --- %d waiters\n",
> -				   dev_priv->engine[i].name,
> +				   dev_priv->engine[i]->name,
>   				   ee->num_waiters);
>   			for (j = 0; j < ee->num_waiters; j++) {
>   				err_printf(m, " seqno 0x%08x for %s [%d]\n",
> @@ -476,7 +476,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
>
>   		if ((obj = ee->ringbuffer)) {
>   			err_printf(m, "%s --- ringbuffer = 0x%08x\n",
> -				   dev_priv->engine[i].name,
> +				   dev_priv->engine[i]->name,
>   				   lower_32_bits(obj->gtt_offset));
>   			print_error_obj(m, obj);
>   		}
> @@ -490,7 +490,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
>   				hws_page = &obj->pages[LRC_PPHWSP_PN][0];
>   			}
>   			err_printf(m, "%s --- HW Status = 0x%08llx\n",
> -				   dev_priv->engine[i].name, hws_offset);
> +				   dev_priv->engine[i]->name, hws_offset);
>   			offset = 0;
>   			for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
>   				err_printf(m, "[%04x] %08x %08x %08x %08x\n",
> @@ -507,12 +507,12 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
>   		if (obj) {
>   			u64 wa_ctx_offset = obj->gtt_offset;
>   			u32 *wa_ctx_page = &obj->pages[0][0];
> -			struct intel_engine_cs *engine = &dev_priv->engine[RCS];
> +			struct intel_engine_cs *engine = dev_priv->engine[RCS];
>   			u32 wa_ctx_size = (engine->wa_ctx.indirect_ctx.size +
>   					   engine->wa_ctx.per_ctx.size);
>
>   			err_printf(m, "%s --- WA ctx batch buffer = 0x%08llx\n",
> -				   dev_priv->engine[i].name, wa_ctx_offset);
> +				   dev_priv->engine[i]->name, wa_ctx_offset);
>   			offset = 0;
>   			for (elt = 0; elt < wa_ctx_size; elt += 4) {
>   				err_printf(m, "[%04x] %08x %08x %08x %08x\n",
> @@ -527,7 +527,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
>
>   		if ((obj = ee->ctx)) {
>   			err_printf(m, "%s --- HW Context = 0x%08x\n",
> -				   dev_priv->engine[i].name,
> +				   dev_priv->engine[i]->name,
>   				   lower_32_bits(obj->gtt_offset));
>   			print_error_obj(m, obj);
>   		}
> @@ -887,7 +887,7 @@ static void gen8_record_semaphore_state(struct drm_i915_error_state *error,
>   	if (!error->semaphore_obj)
>   		return;
>
> -	for_each_engine_id(to, dev_priv, id) {
> +	for_each_engine(to, dev_priv, id) {
>   		int idx;
>   		u16 signal_offset;
>   		u32 *tmp;
> @@ -1099,13 +1099,13 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv,
>   	}
>
>   	for (i = 0; i < I915_NUM_ENGINES; i++) {
> -		struct intel_engine_cs *engine = &dev_priv->engine[i];
> +		struct intel_engine_cs *engine = dev_priv->engine[i];
>   		struct drm_i915_error_engine *ee = &error->engine[i];
>
>   		ee->pid = -1;
>   		ee->engine_id = -1;
>
> -		if (!intel_engine_initialized(engine))
> +		if (!engine)
>   			continue;
>
>   		ee->engine_id = i;
> diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
> index 03a5cef..5ef8864 100644
> --- a/drivers/gpu/drm/i915/i915_guc_submission.c
> +++ b/drivers/gpu/drm/i915/i915_guc_submission.c
> @@ -328,6 +328,7 @@ static void guc_init_ctx_desc(struct intel_guc *guc,
>   	struct drm_i915_gem_object *client_obj = client->client_obj;
>   	struct drm_i915_private *dev_priv = guc_to_i915(guc);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	struct i915_gem_context *ctx = client->owner;
>   	struct guc_context_desc desc;
>   	struct sg_table *sg;
> @@ -340,7 +341,7 @@ static void guc_init_ctx_desc(struct intel_guc *guc,
>   	desc.priority = client->priority;
>   	desc.db_id = client->doorbell_id;
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		struct intel_context *ce = &ctx->engine[engine->id];
>   		struct guc_execlist_context *lrc = &desc.lrc[engine->guc_id];
>   		struct drm_i915_gem_object *obj;
> @@ -894,6 +895,7 @@ static void guc_create_ads(struct intel_guc *guc)
>   	struct guc_policies *policies;
>   	struct guc_mmio_reg_state *reg_state;
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	struct page *page;
>   	u32 size;
>
> @@ -921,10 +923,10 @@ static void guc_create_ads(struct intel_guc *guc)
>   	 * so its address won't change after we've told the GuC where
>   	 * to find it.
>   	 */
> -	engine = &dev_priv->engine[RCS];
> +	engine = dev_priv->engine[RCS];
>   	ads->golden_context_lrca = engine->status_page.gfx_addr;
>
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		ads->eng_state_size[engine->guc_id] = intel_lr_context_size(engine);
>
>   	/* GuC scheduling policies */
> @@ -937,7 +939,7 @@ static void guc_create_ads(struct intel_guc *guc)
>   	/* MMIO reg state */
>   	reg_state = (void *)policies + sizeof(struct guc_policies);
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		reg_state->mmio_white_list[engine->guc_id].mmio_start =
>   			engine->mmio_base + GUC_MMIO_WHITE_LIST_START;
>
> @@ -991,6 +993,7 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv)
>   	struct intel_guc *guc = &dev_priv->guc;
>   	struct i915_guc_client *client;
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
>   	/* client for execbuf submission */
>   	client = guc_client_alloc(dev_priv,
> @@ -1006,7 +1009,7 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv)
>   	guc_init_doorbell_hw(guc);
>
>   	/* Take over from manual control of ELSP (execlists) */
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		engine->submit_request = i915_guc_submit;
>
>   	return 0;
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 006a855..2b2c57b 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -1060,8 +1060,9 @@ static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
>   static bool any_waiters(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		if (intel_engine_has_waiter(engine))
>   			return true;
>
> @@ -1259,20 +1260,20 @@ static void ilk_gt_irq_handler(struct drm_i915_private *dev_priv,
>   			       u32 gt_iir)
>   {
>   	if (gt_iir & GT_RENDER_USER_INTERRUPT)
> -		notify_ring(&dev_priv->engine[RCS]);
> +		notify_ring(dev_priv->engine[RCS]);
>   	if (gt_iir & ILK_BSD_USER_INTERRUPT)
> -		notify_ring(&dev_priv->engine[VCS]);
> +		notify_ring(dev_priv->engine[VCS]);
>   }
>
>   static void snb_gt_irq_handler(struct drm_i915_private *dev_priv,
>   			       u32 gt_iir)
>   {
>   	if (gt_iir & GT_RENDER_USER_INTERRUPT)
> -		notify_ring(&dev_priv->engine[RCS]);
> +		notify_ring(dev_priv->engine[RCS]);
>   	if (gt_iir & GT_BSD_USER_INTERRUPT)
> -		notify_ring(&dev_priv->engine[VCS]);
> +		notify_ring(dev_priv->engine[VCS]);
>   	if (gt_iir & GT_BLT_USER_INTERRUPT)
> -		notify_ring(&dev_priv->engine[BCS]);
> +		notify_ring(dev_priv->engine[BCS]);
>
>   	if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT |
>   		      GT_BSD_CS_ERROR_INTERRUPT |
> @@ -1342,21 +1343,21 @@ static void gen8_gt_irq_handler(struct drm_i915_private *dev_priv,
>   				u32 gt_iir[4])
>   {
>   	if (gt_iir[0]) {
> -		gen8_cs_irq_handler(&dev_priv->engine[RCS],
> +		gen8_cs_irq_handler(dev_priv->engine[RCS],
>   				    gt_iir[0], GEN8_RCS_IRQ_SHIFT);
> -		gen8_cs_irq_handler(&dev_priv->engine[BCS],
> +		gen8_cs_irq_handler(dev_priv->engine[BCS],
>   				    gt_iir[0], GEN8_BCS_IRQ_SHIFT);
>   	}
>
>   	if (gt_iir[1]) {
> -		gen8_cs_irq_handler(&dev_priv->engine[VCS],
> +		gen8_cs_irq_handler(dev_priv->engine[VCS],
>   				    gt_iir[1], GEN8_VCS1_IRQ_SHIFT);
> -		gen8_cs_irq_handler(&dev_priv->engine[VCS2],
> +		gen8_cs_irq_handler(dev_priv->engine[VCS2],
>   				    gt_iir[1], GEN8_VCS2_IRQ_SHIFT);
>   	}
>
>   	if (gt_iir[3])
> -		gen8_cs_irq_handler(&dev_priv->engine[VECS],
> +		gen8_cs_irq_handler(dev_priv->engine[VECS],
>   				    gt_iir[3], GEN8_VECS_IRQ_SHIFT);
>
>   	if (gt_iir[2] & dev_priv->pm_rps_events)
> @@ -1600,7 +1601,7 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
>
>   	if (HAS_VEBOX(dev_priv)) {
>   		if (pm_iir & PM_VEBOX_USER_INTERRUPT)
> -			notify_ring(&dev_priv->engine[VECS]);
> +			notify_ring(dev_priv->engine[VECS]);
>
>   		if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT)
>   			DRM_DEBUG("Command parser error, pm_iir 0x%08x\n", pm_iir);
> @@ -2822,9 +2823,10 @@ semaphore_wait_to_signaller_ring(struct intel_engine_cs *engine, u32 ipehr,
>   {
>   	struct drm_i915_private *dev_priv = engine->i915;
>   	struct intel_engine_cs *signaller;
> +	enum intel_engine_id iter;
>
>   	if (INTEL_GEN(dev_priv) >= 8) {
> -		for_each_engine(signaller, dev_priv) {
> +		for_each_engine(signaller, dev_priv, iter) {
>   			if (engine == signaller)
>   				continue;
>
> @@ -2834,7 +2836,7 @@ semaphore_wait_to_signaller_ring(struct intel_engine_cs *engine, u32 ipehr,
>   	} else {
>   		u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK;
>
> -		for_each_engine(signaller, dev_priv) {
> +		for_each_engine(signaller, dev_priv, iter) {
>   			if(engine == signaller)
>   				continue;
>
> @@ -2952,8 +2954,9 @@ static int semaphore_passed(struct intel_engine_cs *engine)
>   static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		engine->hangcheck.deadlock = 0;
>   }
>
> @@ -3080,6 +3083,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work)
>   		container_of(work, typeof(*dev_priv),
>   			     gpu_error.hangcheck_work.work);
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	unsigned int hung = 0, stuck = 0;
>   	int busy_count = 0;
>   #define BUSY 1
> @@ -3099,7 +3103,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work)
>   	 */
>   	intel_uncore_arm_unclaimed_mmio_detection(dev_priv);
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		bool busy = intel_engine_has_waiter(engine);
>   		u64 acthd;
>   		u32 seqno;
> @@ -3206,7 +3210,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work)
>   			hung &= ~stuck;
>   		len = scnprintf(msg, sizeof(msg),
>   				"%s on ", stuck == hung ? "No progress" : "Hang");
> -		for_each_engine_masked(engine, dev_priv, hung)
> +		for_each_engine_masked(engine, dev_priv, hung, iter)
>   			len += scnprintf(msg + len, sizeof(msg) - len,
>   					 "%s, ", engine->name);
>   		msg[len-2] = '\0';
> @@ -3997,7 +4001,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
>   		new_iir = I915_READ16(IIR); /* Flush posted writes */
>
>   		if (iir & I915_USER_INTERRUPT)
> -			notify_ring(&dev_priv->engine[RCS]);
> +			notify_ring(dev_priv->engine[RCS]);
>
>   		for_each_pipe(dev_priv, pipe) {
>   			int plane = pipe;
> @@ -4194,7 +4198,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
>   		new_iir = I915_READ(IIR); /* Flush posted writes */
>
>   		if (iir & I915_USER_INTERRUPT)
> -			notify_ring(&dev_priv->engine[RCS]);
> +			notify_ring(dev_priv->engine[RCS]);
>
>   		for_each_pipe(dev_priv, pipe) {
>   			int plane = pipe;
> @@ -4426,9 +4430,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
>   		new_iir = I915_READ(IIR); /* Flush posted writes */
>
>   		if (iir & I915_USER_INTERRUPT)
> -			notify_ring(&dev_priv->engine[RCS]);
> +			notify_ring(dev_priv->engine[RCS]);
>   		if (iir & I915_BSD_USER_INTERRUPT)
> -			notify_ring(&dev_priv->engine[VCS]);
> +			notify_ring(dev_priv->engine[VCS]);
>
>   		for_each_pipe(dev_priv, pipe) {
>   			if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
> diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
> index 9086744..fc18d2d1 100644
> --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
> +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
> @@ -566,6 +566,7 @@ void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)
>   unsigned int intel_kick_waiters(struct drm_i915_private *i915)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	unsigned int mask = 0;
>
>   	/* To avoid the task_struct disappearing beneath us as we wake up
> @@ -574,7 +575,7 @@ unsigned int intel_kick_waiters(struct drm_i915_private *i915)
>   	 * rcu_read_lock().
>   	 */
>   	rcu_read_lock();
> -	for_each_engine(engine, i915)
> +	for_each_engine(engine, i915, iter)
>   		if (unlikely(intel_engine_wakeup(engine)))
>   			mask |= intel_engine_flag(engine);
>   	rcu_read_unlock();
> @@ -585,9 +586,10 @@ unsigned int intel_kick_waiters(struct drm_i915_private *i915)
>   unsigned int intel_kick_signalers(struct drm_i915_private *i915)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	unsigned int mask = 0;
>
> -	for_each_engine(engine, i915) {
> +	for_each_engine(engine, i915, iter) {
>   		if (unlikely(READ_ONCE(engine->breadcrumbs.first_signal))) {
>   			wake_up_process(engine->breadcrumbs.signaler);
>   			mask |= intel_engine_flag(engine);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 9cbf543..392fff3 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11667,20 +11667,20 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
>   		work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(pipe)) + 1;
>
>   	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
> -		engine = &dev_priv->engine[BCS];
> +		engine = dev_priv->engine[BCS];
>   		if (i915_gem_object_get_tiling(obj) !=
>   		    i915_gem_object_get_tiling(intel_fb_obj(work->old_fb)))
>   			/* vlv: DISPLAY_FLIP fails to change tiling */
>   			engine = NULL;
>   	} else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
> -		engine = &dev_priv->engine[BCS];
> +		engine = dev_priv->engine[BCS];
>   	} else if (INTEL_INFO(dev)->gen >= 7) {
>   		engine = i915_gem_active_get_engine(&obj->last_write,
>   						    &obj->base.dev->struct_mutex);
>   		if (engine == NULL || engine->id != RCS)
> -			engine = &dev_priv->engine[BCS];
> +			engine = dev_priv->engine[BCS];
>   	} else {
> -		engine = &dev_priv->engine[RCS];
> +		engine = dev_priv->engine[RCS];
>   	}
>
>   	mmio_flip = use_mmio_flip(engine, obj);
> diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
> index e9b301a..9900fdd 100644
> --- a/drivers/gpu/drm/i915/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
> @@ -82,12 +82,17 @@ static const struct engine_info {
>   	},
>   };
>
> -static struct intel_engine_cs *
> +static int
>   intel_engine_setup(struct drm_i915_private *dev_priv,
>   		   enum intel_engine_id id)
>   {
>   	const struct engine_info *info = &intel_engines[id];
> -	struct intel_engine_cs *engine = &dev_priv->engine[id];
> +	struct intel_engine_cs *engine;
> +
> +	GEM_BUG_ON(dev_priv->engine[id]);
> +	engine = kzalloc(sizeof(*engine), GFP_KERNEL);
> +	if (!engine)
> +		return -ENOMEM;
>
>   	engine->id = id;
>   	engine->i915 = dev_priv;
> @@ -97,7 +102,8 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
>   	engine->mmio_base = info->mmio_base;
>   	engine->irq_shift = info->irq_shift;
>
> -	return engine;
> +	dev_priv->engine[id] = engine;
> +	return 0;
>   }
>
>   /**
> @@ -130,7 +136,11 @@ int intel_engines_init(struct drm_device *dev)
>   		if (!init)
>   			continue;
>
> -		ret = init(intel_engine_setup(dev_priv, i));
> +		ret = intel_engine_setup(dev_priv, i);
> +		if (ret)
> +			goto cleanup;
> +
> +		ret = init(dev_priv->engine[i]);
>   		if (ret)
>   			goto cleanup;
>
> @@ -153,9 +163,9 @@ int intel_engines_init(struct drm_device *dev)
>   cleanup:
>   	for (i = 0; i < I915_NUM_ENGINES; i++) {
>   		if (i915.enable_execlists)
> -			intel_logical_ring_cleanup(&dev_priv->engine[i]);
> +			intel_logical_ring_cleanup(dev_priv->engine[i]);
>   		else
> -			intel_engine_cleanup(&dev_priv->engine[i]);
> +			intel_engine_cleanup(dev_priv->engine[i]);
>   	}
>
>   	return ret;
> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
> index 3763e30..1054a5d2 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -88,12 +88,13 @@ const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status)
>   static void direct_interrupts_to_host(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	int irqs;
>
>   	/* tell all command streamers NOT to forward interrupts or vblank to GuC */
>   	irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_NEVER);
>   	irqs |= _MASKED_BIT_DISABLE(GFX_INTERRUPT_STEERING);
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		I915_WRITE(RING_MODE_GEN7(engine), irqs);
>
>   	/* route all GT interrupts to the host */
> @@ -105,12 +106,13 @@ static void direct_interrupts_to_host(struct drm_i915_private *dev_priv)
>   static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	int irqs;
>   	u32 tmp;
>
>   	/* tell all command streamers to forward interrupts (but not vblank) to GuC */
>   	irqs = _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING);
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		I915_WRITE(RING_MODE_GEN7(engine), irqs);
>
>   	/* route USER_INTERRUPT to Host, all others are sent to GuC. */
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 309c5d9..6fc794d 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -1679,7 +1679,7 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine)
>   {
>   	struct drm_i915_private *dev_priv;
>
> -	if (!intel_engine_initialized(engine))
> +	if (!engine)
>   		return;
>
>   	/*
> @@ -1712,13 +1712,16 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine)
>
>   	lrc_destroy_wa_ctx_obj(engine);
>   	engine->i915 = NULL;
> +	dev_priv->engine[engine->id] = NULL;
> +	kfree(engine);
>   }
>
>   void intel_execlists_enable_submission(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		engine->submit_request = execlists_submit_request;
>   }
>
> @@ -2179,8 +2182,9 @@ void intel_lr_context_reset(struct drm_i915_private *dev_priv,
>   			    struct i915_gem_context *ctx)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
> -	for_each_engine(engine, dev_priv) {
> +	for_each_engine(engine, dev_priv, iter) {
>   		struct intel_context *ce = &ctx->engine[engine->id];
>   		struct drm_i915_gem_object *ctx_obj = ce->state;
>   		void *vaddr;
> diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
> index 90f3ab4..1254334 100644
> --- a/drivers/gpu/drm/i915/intel_overlay.c
> +++ b/drivers/gpu/drm/i915/intel_overlay.c
> @@ -233,7 +233,7 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
>   static struct drm_i915_gem_request *alloc_request(struct intel_overlay *overlay)
>   {
>   	struct drm_i915_private *dev_priv = overlay->i915;
> -	struct intel_engine_cs *engine = &dev_priv->engine[RCS];
> +	struct intel_engine_cs *engine = dev_priv->engine[RCS];
>
>   	return i915_gem_request_alloc(engine, dev_priv->kernel_context);
>   }
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index aef0b10..aaf020a 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5211,6 +5211,7 @@ static void gen9_enable_rps(struct drm_i915_private *dev_priv)
>   static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	uint32_t rc6_mask = 0;
>
>   	/* 1a: Software RC state - RC0 */
> @@ -5232,7 +5233,7 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
>   		I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
>   	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
>   	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
>
>   	if (HAS_GUC(dev_priv))
> @@ -5278,6 +5279,7 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
>   static void gen8_enable_rps(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	uint32_t rc6_mask = 0;
>
>   	/* 1a: Software RC state - RC0 */
> @@ -5294,7 +5296,7 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv)
>   	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
>   	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
>   	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
>   	I915_WRITE(GEN6_RC_SLEEP, 0);
>   	if (IS_BROADWELL(dev_priv))
> @@ -5354,6 +5356,7 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv)
>   static void gen6_enable_rps(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	u32 rc6vids, rc6_mask = 0;
>   	u32 gtfifodbg;
>   	int rc6_mode;
> @@ -5387,7 +5390,7 @@ static void gen6_enable_rps(struct drm_i915_private *dev_priv)
>   	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000);
>   	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25);
>
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
>
>   	I915_WRITE(GEN6_RC_SLEEP, 0);
> @@ -5839,6 +5842,7 @@ static void valleyview_cleanup_gt_powersave(struct drm_i915_private *dev_priv)
>   static void cherryview_enable_rps(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	u32 gtfifodbg, val, rc6_mode = 0, pcbr;
>
>   	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
> @@ -5865,7 +5869,7 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv)
>   	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
>   	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
>
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
>   	I915_WRITE(GEN6_RC_SLEEP, 0);
>
> @@ -5927,6 +5931,7 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv)
>   static void valleyview_enable_rps(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	u32 gtfifodbg, val, rc6_mode = 0;
>
>   	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
> @@ -5966,7 +5971,7 @@ static void valleyview_enable_rps(struct drm_i915_private *dev_priv)
>   	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000);
>   	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25);
>
> -	for_each_engine(engine, dev_priv)
> +	for_each_engine(engine, dev_priv, iter)
>   		I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
>
>   	I915_WRITE(GEN6_RC6_THRESHOLD, 0x557);
> @@ -6647,7 +6652,7 @@ static void __intel_autoenable_gt_powersave(struct work_struct *work)
>   	if (READ_ONCE(dev_priv->rps.enabled))
>   		goto out;
>
> -	rcs = &dev_priv->engine[RCS];
> +	rcs = dev_priv->engine[RCS];
>   	if (rcs->last_context)
>   		goto out;
>
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index e08a1e1..5cda41a 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -1322,7 +1322,7 @@ static int gen8_rcs_signal(struct drm_i915_gem_request *req)
>   	if (ret)
>   		return ret;
>
> -	for_each_engine_id(waiter, dev_priv, id) {
> +	for_each_engine(waiter, dev_priv, id) {
>   		u64 gtt_offset = req->engine->semaphore.signal_ggtt[id];
>   		if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
>   			continue;
> @@ -1359,7 +1359,7 @@ static int gen8_xcs_signal(struct drm_i915_gem_request *req)
>   	if (ret)
>   		return ret;
>
> -	for_each_engine_id(waiter, dev_priv, id) {
> +	for_each_engine(waiter, dev_priv, id) {
>   		u64 gtt_offset = req->engine->semaphore.signal_ggtt[id];
>   		if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
>   			continue;
> @@ -1394,7 +1394,7 @@ static int gen6_signal(struct drm_i915_gem_request *req)
>   	if (ret)
>   		return ret;
>
> -	for_each_engine_id(useless, dev_priv, id) {
> +	for_each_engine(useless, dev_priv, id) {
>   		i915_reg_t mbox_reg = req->engine->semaphore.mbox.signal[id];
>
>   		if (i915_mmio_reg_valid(mbox_reg)) {
> @@ -2197,7 +2197,7 @@ void intel_engine_cleanup(struct intel_engine_cs *engine)
>   {
>   	struct drm_i915_private *dev_priv;
>
> -	if (!intel_engine_initialized(engine))
> +	if (!engine)
>   		return;
>
>   	dev_priv = engine->i915;
> @@ -2225,6 +2225,8 @@ void intel_engine_cleanup(struct intel_engine_cs *engine)
>   	intel_ring_context_unpin(dev_priv->kernel_context, engine);
>
>   	engine->i915 = NULL;
> +	dev_priv->engine[engine->id] = NULL;
> +	kfree(engine);
>   }
>
>   int intel_ring_alloc_request_extras(struct drm_i915_gem_request *request)
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index 43e545e..8546d43 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -351,12 +351,6 @@ struct intel_engine_cs {
>   	u32 (*get_cmd_length_mask)(u32 cmd_header);
>   };
>
> -static inline bool
> -intel_engine_initialized(const struct intel_engine_cs *engine)
> -{
> -	return engine->i915 != NULL;
> -}
> -
>   static inline unsigned
>   intel_engine_flag(const struct intel_engine_cs *engine)
>   {
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 43f8339..efa20be 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -1584,6 +1584,7 @@ static int gen6_reset_engines(struct drm_i915_private *dev_priv,
>   			      unsigned engine_mask)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>   	const u32 hw_engine_mask[I915_NUM_ENGINES] = {
>   		[RCS] = GEN6_GRDOM_RENDER,
>   		[BCS] = GEN6_GRDOM_BLT,
> @@ -1598,7 +1599,7 @@ static int gen6_reset_engines(struct drm_i915_private *dev_priv,
>   		hw_mask = GEN6_GRDOM_FULL;
>   	} else {
>   		hw_mask = 0;
> -		for_each_engine_masked(engine, dev_priv, engine_mask)
> +		for_each_engine_masked(engine, dev_priv, engine_mask, iter)
>   			hw_mask |= hw_engine_mask[engine->id];
>   	}
>
> @@ -1714,15 +1715,16 @@ static int gen8_reset_engines(struct drm_i915_private *dev_priv,
>   			      unsigned engine_mask)
>   {
>   	struct intel_engine_cs *engine;
> +	enum intel_engine_id iter;
>
> -	for_each_engine_masked(engine, dev_priv, engine_mask)
> +	for_each_engine_masked(engine, dev_priv, engine_mask, iter)
>   		if (gen8_request_engine_reset(engine))
>   			goto not_ready;
>
>   	return gen6_reset_engines(dev_priv, engine_mask);
>
>   not_ready:
> -	for_each_engine_masked(engine, dev_priv, engine_mask)
> +	for_each_engine_masked(engine, dev_priv, engine_mask, iter)
>   		gen8_unrequest_engine_reset(engine);
>
>   	return -EIO;
>


More information about the Intel-gfx-trybot mailing list