Commit 611cdf36 authored by Chris Wilson's avatar Chris Wilson Committed by Daniel Vetter

drm/i915: Disable EXEC_OBJECT_ASYNC when doing relocations

If we write a relocation into the buffer, we require our own implicit
synchronisation added after the start of the execbuf, outside of the
user's control. As we may end up clflushing, or doing the patch itself
on the GPU, asynchronously we need to look at the implicit serialisation
on obj->resv and hence need to disable EXEC_OBJECT_ASYNC for this
object.

If the user does trigger a stall for relocations, we make sure the stall
is complete enough so that the batch is not submitted before we complete
those relocations.

Fixes: 77ae9957 ("drm/i915: Enable userspace to opt-out of implicit fencing")
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
(cherry picked from commit 071750e5)
[danvet: Resolve conflicts, resolution reviewed by Tvrtko on irc.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 2c736762
...@@ -546,11 +546,12 @@ relocate_entry(struct drm_i915_gem_object *obj, ...@@ -546,11 +546,12 @@ relocate_entry(struct drm_i915_gem_object *obj,
} }
static int static int
i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, i915_gem_execbuffer_relocate_entry(struct i915_vma *vma,
struct eb_vmas *eb, struct eb_vmas *eb,
struct drm_i915_gem_relocation_entry *reloc, struct drm_i915_gem_relocation_entry *reloc,
struct reloc_cache *cache) struct reloc_cache *cache)
{ {
struct drm_i915_gem_object *obj = vma->obj;
struct drm_i915_private *dev_priv = to_i915(obj->base.dev); struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
struct drm_gem_object *target_obj; struct drm_gem_object *target_obj;
struct drm_i915_gem_object *target_i915_obj; struct drm_i915_gem_object *target_i915_obj;
...@@ -628,6 +629,16 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, ...@@ -628,6 +629,16 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
return -EINVAL; return -EINVAL;
} }
/*
* If we write into the object, we need to force the synchronisation
* barrier, either with an asynchronous clflush or if we executed the
* patching using the GPU (though that should be serialised by the
* timeline). To be completely sure, and since we are required to
* do relocations we are already stalling, disable the user's opt
* of our synchronisation.
*/
vma->exec_entry->flags &= ~EXEC_OBJECT_ASYNC;
ret = relocate_entry(obj, reloc, cache, target_offset); ret = relocate_entry(obj, reloc, cache, target_offset);
if (ret) if (ret)
return ret; return ret;
...@@ -678,7 +689,7 @@ i915_gem_execbuffer_relocate_vma(struct i915_vma *vma, ...@@ -678,7 +689,7 @@ i915_gem_execbuffer_relocate_vma(struct i915_vma *vma,
do { do {
u64 offset = r->presumed_offset; u64 offset = r->presumed_offset;
ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r, &cache); ret = i915_gem_execbuffer_relocate_entry(vma, eb, r, &cache);
if (ret) if (ret)
goto out; goto out;
...@@ -726,7 +737,7 @@ i915_gem_execbuffer_relocate_vma_slow(struct i915_vma *vma, ...@@ -726,7 +737,7 @@ i915_gem_execbuffer_relocate_vma_slow(struct i915_vma *vma,
reloc_cache_init(&cache, eb->i915); reloc_cache_init(&cache, eb->i915);
for (i = 0; i < entry->relocation_count; i++) { for (i = 0; i < entry->relocation_count; i++) {
ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, &relocs[i], &cache); ret = i915_gem_execbuffer_relocate_entry(vma, eb, &relocs[i], &cache);
if (ret) if (ret)
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment