mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-03 11:06:42 +07:00
drm/i915/execbuffer: Reorder relocations to match new object order
On the fault path, commit 6fe4f140
introduction a regression whereby it
changed the sequence of the objects but continued to use the original
ordering of relocation entries. The result was that incorrect GTT offsets
were being fed into the execbuffer causing lots of misrendering and
potential hangs.
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Tested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
c37d9a5de9
commit
dd6864a4ed
@ -636,6 +636,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
|
||||
{
|
||||
struct drm_i915_gem_relocation_entry *reloc;
|
||||
struct drm_i915_gem_object *obj;
|
||||
int *reloc_offset;
|
||||
int i, total, ret;
|
||||
|
||||
/* We may process another execbuffer during the unlock... */
|
||||
@ -653,8 +654,11 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
|
||||
for (i = 0; i < count; i++)
|
||||
total += exec[i].relocation_count;
|
||||
|
||||
reloc_offset = drm_malloc_ab(count, sizeof(*reloc_offset));
|
||||
reloc = drm_malloc_ab(total, sizeof(*reloc));
|
||||
if (reloc == NULL) {
|
||||
if (reloc == NULL || reloc_offset == NULL) {
|
||||
drm_free_large(reloc);
|
||||
drm_free_large(reloc_offset);
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -672,6 +676,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
|
||||
goto err;
|
||||
}
|
||||
|
||||
reloc_offset[i] = total;
|
||||
total += exec[i].relocation_count;
|
||||
}
|
||||
|
||||
@ -705,17 +710,14 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
total = 0;
|
||||
list_for_each_entry(obj, objects, exec_list) {
|
||||
int offset = obj->exec_entry - exec;
|
||||
obj->base.pending_read_domains = 0;
|
||||
obj->base.pending_write_domain = 0;
|
||||
ret = i915_gem_execbuffer_relocate_object_slow(obj, eb,
|
||||
reloc + total);
|
||||
reloc + reloc_offset[offset]);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
total += exec->relocation_count;
|
||||
exec++;
|
||||
}
|
||||
|
||||
/* Leave the user relocations as are, this is the painfully slow path,
|
||||
@ -726,6 +728,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
|
||||
|
||||
err:
|
||||
drm_free_large(reloc);
|
||||
drm_free_large(reloc_offset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user