diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index e69834341ef0..6b34e98a1270 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -636,6 +636,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
636 | { | 636 | { |
637 | struct drm_i915_gem_relocation_entry *reloc; | 637 | struct drm_i915_gem_relocation_entry *reloc; |
638 | struct drm_i915_gem_object *obj; | 638 | struct drm_i915_gem_object *obj; |
639 | int *reloc_offset; | ||
639 | int i, total, ret; | 640 | int i, total, ret; |
640 | 641 | ||
641 | /* We may process another execbuffer during the unlock... */ | 642 | /* We may process another execbuffer during the unlock... */ |
@@ -653,8 +654,11 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
653 | for (i = 0; i < count; i++) | 654 | for (i = 0; i < count; i++) |
654 | total += exec[i].relocation_count; | 655 | total += exec[i].relocation_count; |
655 | 656 | ||
657 | reloc_offset = drm_malloc_ab(count, sizeof(*reloc_offset)); | ||
656 | reloc = drm_malloc_ab(total, sizeof(*reloc)); | 658 | reloc = drm_malloc_ab(total, sizeof(*reloc)); |
657 | if (reloc == NULL) { | 659 | if (reloc == NULL || reloc_offset == NULL) { |
660 | drm_free_large(reloc); | ||
661 | drm_free_large(reloc_offset); | ||
658 | mutex_lock(&dev->struct_mutex); | 662 | mutex_lock(&dev->struct_mutex); |
659 | return -ENOMEM; | 663 | return -ENOMEM; |
660 | } | 664 | } |
@@ -672,6 +676,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
672 | goto err; | 676 | goto err; |
673 | } | 677 | } |
674 | 678 | ||
679 | reloc_offset[i] = total; | ||
675 | total += exec[i].relocation_count; | 680 | total += exec[i].relocation_count; |
676 | } | 681 | } |
677 | 682 | ||
@@ -705,17 +710,14 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
705 | if (ret) | 710 | if (ret) |
706 | goto err; | 711 | goto err; |
707 | 712 | ||
708 | total = 0; | ||
709 | list_for_each_entry(obj, objects, exec_list) { | 713 | list_for_each_entry(obj, objects, exec_list) { |
714 | int offset = obj->exec_entry - exec; | ||
710 | obj->base.pending_read_domains = 0; | 715 | obj->base.pending_read_domains = 0; |
711 | obj->base.pending_write_domain = 0; | 716 | obj->base.pending_write_domain = 0; |
712 | ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, | 717 | ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, |
713 | reloc + total); | 718 | reloc + reloc_offset[offset]); |
714 | if (ret) | 719 | if (ret) |
715 | goto err; | 720 | goto err; |
716 | |||
717 | total += exec->relocation_count; | ||
718 | exec++; | ||
719 | } | 721 | } |
720 | 722 | ||
721 | /* Leave the user relocations as are, this is the painfully slow path, | 723 | /* 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, | |||
726 | 728 | ||
727 | err: | 729 | err: |
728 | drm_free_large(reloc); | 730 | drm_free_large(reloc); |
731 | drm_free_large(reloc_offset); | ||
729 | return ret; | 732 | return ret; |
730 | } | 733 | } |
731 | 734 | ||