diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_execbuffer.c')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 49 | 
1 files changed, 27 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index f627a8c47c58..22df17c8ca9b 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -489,7 +489,9 @@ eb_validate_vma(struct i915_execbuffer *eb,  }  static int -eb_add_vma(struct i915_execbuffer *eb, unsigned int i, struct i915_vma *vma) +eb_add_vma(struct i915_execbuffer *eb, +	   unsigned int i, unsigned batch_idx, +	   struct i915_vma *vma)  {  	struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];  	int err; @@ -522,6 +524,24 @@ eb_add_vma(struct i915_execbuffer *eb, unsigned int i, struct i915_vma *vma)  	eb->flags[i] = entry->flags;  	vma->exec_flags = &eb->flags[i]; +	/* +	 * SNA is doing fancy tricks with compressing batch buffers, which leads +	 * to negative relocation deltas. Usually that works out ok since the +	 * relocate address is still positive, except when the batch is placed +	 * very low in the GTT. Ensure this doesn't happen. +	 * +	 * Note that actual hangs have only been observed on gen7, but for +	 * paranoia do it everywhere. +	 */ +	if (i == batch_idx) { +		if (!(eb->flags[i] & EXEC_OBJECT_PINNED)) +			eb->flags[i] |= __EXEC_OBJECT_NEEDS_BIAS; +		if (eb->reloc_cache.has_fence) +			eb->flags[i] |= EXEC_OBJECT_NEEDS_FENCE; + +		eb->batch = vma; +	} +  	err = 0;  	if (eb_pin_vma(eb, entry, vma)) {  		if (entry->offset != vma->node.start) { @@ -716,7 +736,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)  {  	struct radix_tree_root *handles_vma = &eb->ctx->handles_vma;  	struct drm_i915_gem_object *obj; -	unsigned int i; +	unsigned int i, batch;  	int err;  	if (unlikely(i915_gem_context_is_closed(eb->ctx))) @@ -728,6 +748,8 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)  	INIT_LIST_HEAD(&eb->relocs);  	INIT_LIST_HEAD(&eb->unbound); +	batch = eb_batch_index(eb); +  	for (i = 0; i < eb->buffer_count; i++) {  		u32 handle = eb->exec[i].handle;  		struct i915_lut_handle *lut; @@ -770,33 +792,16 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)  		lut->handle = handle;  add_vma: -		err = eb_add_vma(eb, i, vma); +		err = eb_add_vma(eb, i, batch, vma);  		if (unlikely(err))  			goto err_vma;  		GEM_BUG_ON(vma != eb->vma[i]);  		GEM_BUG_ON(vma->exec_flags != &eb->flags[i]); +		GEM_BUG_ON(drm_mm_node_allocated(&vma->node) && +			   eb_vma_misplaced(&eb->exec[i], vma, eb->flags[i]));  	} -	/* take note of the batch buffer before we might reorder the lists */ -	i = eb_batch_index(eb); -	eb->batch = eb->vma[i]; -	GEM_BUG_ON(eb->batch->exec_flags != &eb->flags[i]); - -	/* -	 * SNA is doing fancy tricks with compressing batch buffers, which leads -	 * to negative relocation deltas. Usually that works out ok since the -	 * relocate address is still positive, except when the batch is placed -	 * very low in the GTT. Ensure this doesn't happen. -	 * -	 * Note that actual hangs have only been observed on gen7, but for -	 * paranoia do it everywhere. -	 */ -	if (!(eb->flags[i] & EXEC_OBJECT_PINNED)) -		eb->flags[i] |= __EXEC_OBJECT_NEEDS_BIAS; -	if (eb->reloc_cache.has_fence) -		eb->flags[i] |= EXEC_OBJECT_NEEDS_FENCE; -  	eb->args->flags |= __EXEC_VALIDATED;  	return eb_reserve(eb);  | 
