|
@@ -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);
|
|
|
|