diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_execbuffer.c')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 60 |
1 files changed, 32 insertions, 28 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 885d595e0e02..b7e787fb4649 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
| @@ -33,6 +33,9 @@ | |||
| 33 | #include "intel_drv.h" | 33 | #include "intel_drv.h" |
| 34 | #include <linux/dma_remapping.h> | 34 | #include <linux/dma_remapping.h> |
| 35 | 35 | ||
| 36 | #define __EXEC_OBJECT_HAS_PIN (1<<31) | ||
| 37 | #define __EXEC_OBJECT_HAS_FENCE (1<<30) | ||
| 38 | |||
| 36 | struct eb_vmas { | 39 | struct eb_vmas { |
| 37 | struct list_head vmas; | 40 | struct list_head vmas; |
| 38 | int and; | 41 | int and; |
| @@ -187,7 +190,28 @@ static struct i915_vma *eb_get_vma(struct eb_vmas *eb, unsigned long handle) | |||
| 187 | } | 190 | } |
| 188 | } | 191 | } |
| 189 | 192 | ||
| 190 | static void eb_destroy(struct eb_vmas *eb) { | 193 | static void |
| 194 | i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma) | ||
| 195 | { | ||
| 196 | struct drm_i915_gem_exec_object2 *entry; | ||
| 197 | struct drm_i915_gem_object *obj = vma->obj; | ||
| 198 | |||
| 199 | if (!drm_mm_node_allocated(&vma->node)) | ||
| 200 | return; | ||
| 201 | |||
| 202 | entry = vma->exec_entry; | ||
| 203 | |||
| 204 | if (entry->flags & __EXEC_OBJECT_HAS_FENCE) | ||
| 205 | i915_gem_object_unpin_fence(obj); | ||
| 206 | |||
| 207 | if (entry->flags & __EXEC_OBJECT_HAS_PIN) | ||
| 208 | i915_gem_object_unpin(obj); | ||
| 209 | |||
| 210 | entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN); | ||
| 211 | } | ||
| 212 | |||
| 213 | static void eb_destroy(struct eb_vmas *eb) | ||
| 214 | { | ||
| 191 | while (!list_empty(&eb->vmas)) { | 215 | while (!list_empty(&eb->vmas)) { |
| 192 | struct i915_vma *vma; | 216 | struct i915_vma *vma; |
| 193 | 217 | ||
| @@ -195,6 +219,7 @@ static void eb_destroy(struct eb_vmas *eb) { | |||
| 195 | struct i915_vma, | 219 | struct i915_vma, |
| 196 | exec_list); | 220 | exec_list); |
| 197 | list_del_init(&vma->exec_list); | 221 | list_del_init(&vma->exec_list); |
| 222 | i915_gem_execbuffer_unreserve_vma(vma); | ||
| 198 | drm_gem_object_unreference(&vma->obj->base); | 223 | drm_gem_object_unreference(&vma->obj->base); |
| 199 | } | 224 | } |
| 200 | kfree(eb); | 225 | kfree(eb); |
| @@ -478,9 +503,6 @@ i915_gem_execbuffer_relocate(struct eb_vmas *eb, | |||
| 478 | return ret; | 503 | return ret; |
| 479 | } | 504 | } |
| 480 | 505 | ||
| 481 | #define __EXEC_OBJECT_HAS_PIN (1<<31) | ||
| 482 | #define __EXEC_OBJECT_HAS_FENCE (1<<30) | ||
| 483 | |||
| 484 | static int | 506 | static int |
| 485 | need_reloc_mappable(struct i915_vma *vma) | 507 | need_reloc_mappable(struct i915_vma *vma) |
| 486 | { | 508 | { |
| @@ -552,26 +574,6 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, | |||
| 552 | return 0; | 574 | return 0; |
| 553 | } | 575 | } |
| 554 | 576 | ||
| 555 | static void | ||
| 556 | i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma) | ||
| 557 | { | ||
| 558 | struct drm_i915_gem_exec_object2 *entry; | ||
| 559 | struct drm_i915_gem_object *obj = vma->obj; | ||
| 560 | |||
| 561 | if (!drm_mm_node_allocated(&vma->node)) | ||
| 562 | return; | ||
| 563 | |||
| 564 | entry = vma->exec_entry; | ||
| 565 | |||
| 566 | if (entry->flags & __EXEC_OBJECT_HAS_FENCE) | ||
| 567 | i915_gem_object_unpin_fence(obj); | ||
| 568 | |||
| 569 | if (entry->flags & __EXEC_OBJECT_HAS_PIN) | ||
| 570 | i915_gem_object_unpin(obj); | ||
| 571 | |||
| 572 | entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN); | ||
| 573 | } | ||
| 574 | |||
| 575 | static int | 577 | static int |
| 576 | i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | 578 | i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, |
| 577 | struct list_head *vmas, | 579 | struct list_head *vmas, |
| @@ -670,13 +672,14 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | |||
| 670 | goto err; | 672 | goto err; |
| 671 | } | 673 | } |
| 672 | 674 | ||
| 673 | err: /* Decrement pin count for bound objects */ | 675 | err: |
| 674 | list_for_each_entry(vma, vmas, exec_list) | ||
| 675 | i915_gem_execbuffer_unreserve_vma(vma); | ||
| 676 | |||
| 677 | if (ret != -ENOSPC || retry++) | 676 | if (ret != -ENOSPC || retry++) |
| 678 | return ret; | 677 | return ret; |
| 679 | 678 | ||
| 679 | /* Decrement pin count for bound objects */ | ||
| 680 | list_for_each_entry(vma, vmas, exec_list) | ||
| 681 | i915_gem_execbuffer_unreserve_vma(vma); | ||
| 682 | |||
| 680 | ret = i915_gem_evict_vm(vm, true); | 683 | ret = i915_gem_evict_vm(vm, true); |
| 681 | if (ret) | 684 | if (ret) |
| 682 | return ret; | 685 | return ret; |
| @@ -708,6 +711,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
| 708 | while (!list_empty(&eb->vmas)) { | 711 | while (!list_empty(&eb->vmas)) { |
| 709 | vma = list_first_entry(&eb->vmas, struct i915_vma, exec_list); | 712 | vma = list_first_entry(&eb->vmas, struct i915_vma, exec_list); |
| 710 | list_del_init(&vma->exec_list); | 713 | list_del_init(&vma->exec_list); |
| 714 | i915_gem_execbuffer_unreserve_vma(vma); | ||
| 711 | drm_gem_object_unreference(&vma->obj->base); | 715 | drm_gem_object_unreference(&vma->obj->base); |
| 712 | } | 716 | } |
| 713 | 717 | ||
