diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 72 |
1 files changed, 30 insertions, 42 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6c403654e33a..36f1093e3c63 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -39,8 +39,7 @@ | |||
39 | #include <linux/dma-buf.h> | 39 | #include <linux/dma-buf.h> |
40 | 40 | ||
41 | static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); | 41 | static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); |
42 | static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj, | 42 | static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); |
43 | bool force); | ||
44 | static __must_check int | 43 | static __must_check int |
45 | i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, | 44 | i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, |
46 | bool readonly); | 45 | bool readonly); |
@@ -1516,7 +1515,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | |||
1516 | 1515 | ||
1517 | /* Pinned buffers may be scanout, so flush the cache */ | 1516 | /* Pinned buffers may be scanout, so flush the cache */ |
1518 | if (obj->pin_display) | 1517 | if (obj->pin_display) |
1519 | i915_gem_object_flush_cpu_write_domain(obj, true); | 1518 | i915_gem_object_flush_cpu_write_domain(obj); |
1520 | 1519 | ||
1521 | drm_gem_object_unreference(&obj->base); | 1520 | drm_gem_object_unreference(&obj->base); |
1522 | unlock: | 1521 | unlock: |
@@ -2414,7 +2413,7 @@ int __i915_add_request(struct intel_engine_cs *ring, | |||
2414 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | 2413 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
2415 | struct drm_i915_gem_request *request; | 2414 | struct drm_i915_gem_request *request; |
2416 | struct intel_ringbuffer *ringbuf; | 2415 | struct intel_ringbuffer *ringbuf; |
2417 | u32 request_ring_position, request_start; | 2416 | u32 request_start; |
2418 | int ret; | 2417 | int ret; |
2419 | 2418 | ||
2420 | request = ring->outstanding_lazy_request; | 2419 | request = ring->outstanding_lazy_request; |
@@ -2422,8 +2421,7 @@ int __i915_add_request(struct intel_engine_cs *ring, | |||
2422 | return -ENOMEM; | 2421 | return -ENOMEM; |
2423 | 2422 | ||
2424 | if (i915.enable_execlists) { | 2423 | if (i915.enable_execlists) { |
2425 | struct intel_context *ctx = request->ctx; | 2424 | ringbuf = request->ctx->engine[ring->id].ringbuf; |
2426 | ringbuf = ctx->engine[ring->id].ringbuf; | ||
2427 | } else | 2425 | } else |
2428 | ringbuf = ring->buffer; | 2426 | ringbuf = ring->buffer; |
2429 | 2427 | ||
@@ -2436,7 +2434,7 @@ int __i915_add_request(struct intel_engine_cs *ring, | |||
2436 | * what. | 2434 | * what. |
2437 | */ | 2435 | */ |
2438 | if (i915.enable_execlists) { | 2436 | if (i915.enable_execlists) { |
2439 | ret = logical_ring_flush_all_caches(ringbuf); | 2437 | ret = logical_ring_flush_all_caches(ringbuf, request->ctx); |
2440 | if (ret) | 2438 | if (ret) |
2441 | return ret; | 2439 | return ret; |
2442 | } else { | 2440 | } else { |
@@ -2450,10 +2448,10 @@ int __i915_add_request(struct intel_engine_cs *ring, | |||
2450 | * GPU processing the request, we never over-estimate the | 2448 | * GPU processing the request, we never over-estimate the |
2451 | * position of the head. | 2449 | * position of the head. |
2452 | */ | 2450 | */ |
2453 | request_ring_position = intel_ring_get_tail(ringbuf); | 2451 | request->postfix = intel_ring_get_tail(ringbuf); |
2454 | 2452 | ||
2455 | if (i915.enable_execlists) { | 2453 | if (i915.enable_execlists) { |
2456 | ret = ring->emit_request(ringbuf); | 2454 | ret = ring->emit_request(ringbuf, request); |
2457 | if (ret) | 2455 | if (ret) |
2458 | return ret; | 2456 | return ret; |
2459 | } else { | 2457 | } else { |
@@ -2463,7 +2461,7 @@ int __i915_add_request(struct intel_engine_cs *ring, | |||
2463 | } | 2461 | } |
2464 | 2462 | ||
2465 | request->head = request_start; | 2463 | request->head = request_start; |
2466 | request->tail = request_ring_position; | 2464 | request->tail = intel_ring_get_tail(ringbuf); |
2467 | 2465 | ||
2468 | /* Whilst this request exists, batch_obj will be on the | 2466 | /* Whilst this request exists, batch_obj will be on the |
2469 | * active_list, and so will hold the active reference. Only when this | 2467 | * active_list, and so will hold the active reference. Only when this |
@@ -2650,13 +2648,17 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, | |||
2650 | * pinned in place. | 2648 | * pinned in place. |
2651 | */ | 2649 | */ |
2652 | while (!list_empty(&ring->execlist_queue)) { | 2650 | while (!list_empty(&ring->execlist_queue)) { |
2653 | struct intel_ctx_submit_request *submit_req; | 2651 | struct drm_i915_gem_request *submit_req; |
2654 | 2652 | ||
2655 | submit_req = list_first_entry(&ring->execlist_queue, | 2653 | submit_req = list_first_entry(&ring->execlist_queue, |
2656 | struct intel_ctx_submit_request, | 2654 | struct drm_i915_gem_request, |
2657 | execlist_link); | 2655 | execlist_link); |
2658 | list_del(&submit_req->execlist_link); | 2656 | list_del(&submit_req->execlist_link); |
2659 | intel_runtime_pm_put(dev_priv); | 2657 | intel_runtime_pm_put(dev_priv); |
2658 | |||
2659 | if (submit_req->ctx != ring->default_context) | ||
2660 | intel_lr_context_unpin(ring, submit_req->ctx); | ||
2661 | |||
2660 | i915_gem_context_unreference(submit_req->ctx); | 2662 | i915_gem_context_unreference(submit_req->ctx); |
2661 | kfree(submit_req); | 2663 | kfree(submit_req); |
2662 | } | 2664 | } |
@@ -2783,7 +2785,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring) | |||
2783 | * of tail of the request to update the last known position | 2785 | * of tail of the request to update the last known position |
2784 | * of the GPU head. | 2786 | * of the GPU head. |
2785 | */ | 2787 | */ |
2786 | ringbuf->last_retired_head = request->tail; | 2788 | ringbuf->last_retired_head = request->postfix; |
2787 | 2789 | ||
2788 | i915_gem_free_request(request); | 2790 | i915_gem_free_request(request); |
2789 | } | 2791 | } |
@@ -3634,11 +3636,14 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj, | |||
3634 | * snooping behaviour occurs naturally as the result of our domain | 3636 | * snooping behaviour occurs naturally as the result of our domain |
3635 | * tracking. | 3637 | * tracking. |
3636 | */ | 3638 | */ |
3637 | if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) | 3639 | if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) { |
3640 | obj->cache_dirty = true; | ||
3638 | return false; | 3641 | return false; |
3642 | } | ||
3639 | 3643 | ||
3640 | trace_i915_gem_object_clflush(obj); | 3644 | trace_i915_gem_object_clflush(obj); |
3641 | drm_clflush_sg(obj->pages); | 3645 | drm_clflush_sg(obj->pages); |
3646 | obj->cache_dirty = false; | ||
3642 | 3647 | ||
3643 | return true; | 3648 | return true; |
3644 | } | 3649 | } |
@@ -3674,15 +3679,14 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) | |||
3674 | 3679 | ||
3675 | /** Flushes the CPU write domain for the object if it's dirty. */ | 3680 | /** Flushes the CPU write domain for the object if it's dirty. */ |
3676 | static void | 3681 | static void |
3677 | i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj, | 3682 | i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) |
3678 | bool force) | ||
3679 | { | 3683 | { |
3680 | uint32_t old_write_domain; | 3684 | uint32_t old_write_domain; |
3681 | 3685 | ||
3682 | if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) | 3686 | if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) |
3683 | return; | 3687 | return; |
3684 | 3688 | ||
3685 | if (i915_gem_clflush_object(obj, force)) | 3689 | if (i915_gem_clflush_object(obj, obj->pin_display)) |
3686 | i915_gem_chipset_flush(obj->base.dev); | 3690 | i915_gem_chipset_flush(obj->base.dev); |
3687 | 3691 | ||
3688 | old_write_domain = obj->base.write_domain; | 3692 | old_write_domain = obj->base.write_domain; |
@@ -3729,7 +3733,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) | |||
3729 | if (ret) | 3733 | if (ret) |
3730 | return ret; | 3734 | return ret; |
3731 | 3735 | ||
3732 | i915_gem_object_flush_cpu_write_domain(obj, false); | 3736 | i915_gem_object_flush_cpu_write_domain(obj); |
3733 | 3737 | ||
3734 | /* Serialise direct access to this object with the barriers for | 3738 | /* Serialise direct access to this object with the barriers for |
3735 | * coherent writes from the GPU, by effectively invalidating the | 3739 | * coherent writes from the GPU, by effectively invalidating the |
@@ -3821,27 +3825,11 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, | |||
3821 | vma->node.color = cache_level; | 3825 | vma->node.color = cache_level; |
3822 | obj->cache_level = cache_level; | 3826 | obj->cache_level = cache_level; |
3823 | 3827 | ||
3824 | if (cpu_write_needs_clflush(obj)) { | 3828 | if (obj->cache_dirty && |
3825 | u32 old_read_domains, old_write_domain; | 3829 | obj->base.write_domain != I915_GEM_DOMAIN_CPU && |
3826 | 3830 | cpu_write_needs_clflush(obj)) { | |
3827 | /* If we're coming from LLC cached, then we haven't | 3831 | if (i915_gem_clflush_object(obj, true)) |
3828 | * actually been tracking whether the data is in the | 3832 | i915_gem_chipset_flush(obj->base.dev); |
3829 | * CPU cache or not, since we only allow one bit set | ||
3830 | * in obj->write_domain and have been skipping the clflushes. | ||
3831 | * Just set it to the CPU cache for now. | ||
3832 | */ | ||
3833 | i915_gem_object_retire(obj); | ||
3834 | WARN_ON(obj->base.write_domain & ~I915_GEM_DOMAIN_CPU); | ||
3835 | |||
3836 | old_read_domains = obj->base.read_domains; | ||
3837 | old_write_domain = obj->base.write_domain; | ||
3838 | |||
3839 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; | ||
3840 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; | ||
3841 | |||
3842 | trace_i915_gem_object_change_domain(obj, | ||
3843 | old_read_domains, | ||
3844 | old_write_domain); | ||
3845 | } | 3833 | } |
3846 | 3834 | ||
3847 | return 0; | 3835 | return 0; |
@@ -3991,7 +3979,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, | |||
3991 | if (ret) | 3979 | if (ret) |
3992 | goto err_unpin_display; | 3980 | goto err_unpin_display; |
3993 | 3981 | ||
3994 | i915_gem_object_flush_cpu_write_domain(obj, true); | 3982 | i915_gem_object_flush_cpu_write_domain(obj); |
3995 | 3983 | ||
3996 | old_write_domain = obj->base.write_domain; | 3984 | old_write_domain = obj->base.write_domain; |
3997 | old_read_domains = obj->base.read_domains; | 3985 | old_read_domains = obj->base.read_domains; |
@@ -4620,7 +4608,7 @@ i915_gem_suspend(struct drm_device *dev) | |||
4620 | i915_gem_stop_ringbuffers(dev); | 4608 | i915_gem_stop_ringbuffers(dev); |
4621 | mutex_unlock(&dev->struct_mutex); | 4609 | mutex_unlock(&dev->struct_mutex); |
4622 | 4610 | ||
4623 | del_timer_sync(&dev_priv->gpu_error.hangcheck_timer); | 4611 | cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); |
4624 | cancel_delayed_work_sync(&dev_priv->mm.retire_work); | 4612 | cancel_delayed_work_sync(&dev_priv->mm.retire_work); |
4625 | flush_delayed_work(&dev_priv->mm.idle_work); | 4613 | flush_delayed_work(&dev_priv->mm.idle_work); |
4626 | 4614 | ||
@@ -5111,7 +5099,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task) | |||
5111 | if (!mutex_is_locked(mutex)) | 5099 | if (!mutex_is_locked(mutex)) |
5112 | return false; | 5100 | return false; |
5113 | 5101 | ||
5114 | #if defined(CONFIG_SMP) && !defined(CONFIG_DEBUG_MUTEXES) | 5102 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES) |
5115 | return mutex->owner == task; | 5103 | return mutex->owner == task; |
5116 | #else | 5104 | #else |
5117 | /* Since UP may be pre-empted, we cannot assume that we own the lock */ | 5105 | /* Since UP may be pre-empted, we cannot assume that we own the lock */ |