aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h11
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c23
2 files changed, 30 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index aaf934d96f21..b99b6a841d95 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -493,6 +493,15 @@ typedef struct drm_i915_private {
493 struct list_head flushing_list; 493 struct list_head flushing_list;
494 494
495 /** 495 /**
496 * List of objects currently pending a GPU write flush.
497 *
498 * All elements on this list will belong to either the
499 * active_list or flushing_list, last_rendering_seqno can
500 * be used to differentiate between the two elements.
501 */
502 struct list_head gpu_write_list;
503
504 /**
496 * LRU list of objects which are not in the ringbuffer and 505 * LRU list of objects which are not in the ringbuffer and
497 * are ready to unbind, but are still in the GTT. 506 * are ready to unbind, but are still in the GTT.
498 * 507 *
@@ -592,6 +601,8 @@ struct drm_i915_gem_object {
592 601
593 /** This object's place on the active/flushing/inactive lists */ 602 /** This object's place on the active/flushing/inactive lists */
594 struct list_head list; 603 struct list_head list;
604 /** This object's place on GPU write list */
605 struct list_head gpu_write_list;
595 606
596 /** This object's place on the fenced object LRU */ 607 /** This object's place on the fenced object LRU */
597 struct list_head fence_list; 608 struct list_head fence_list;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b4c8c0230689..11daa618385f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1552,6 +1552,8 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
1552 else 1552 else
1553 list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); 1553 list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
1554 1554
1555 BUG_ON(!list_empty(&obj_priv->gpu_write_list));
1556
1555 obj_priv->last_rendering_seqno = 0; 1557 obj_priv->last_rendering_seqno = 0;
1556 if (obj_priv->active) { 1558 if (obj_priv->active) {
1557 obj_priv->active = 0; 1559 obj_priv->active = 0;
@@ -1622,7 +1624,8 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
1622 struct drm_i915_gem_object *obj_priv, *next; 1624 struct drm_i915_gem_object *obj_priv, *next;
1623 1625
1624 list_for_each_entry_safe(obj_priv, next, 1626 list_for_each_entry_safe(obj_priv, next,
1625 &dev_priv->mm.flushing_list, list) { 1627 &dev_priv->mm.gpu_write_list,
1628 gpu_write_list) {
1626 struct drm_gem_object *obj = obj_priv->obj; 1629 struct drm_gem_object *obj = obj_priv->obj;
1627 1630
1628 if ((obj->write_domain & flush_domains) == 1631 if ((obj->write_domain & flush_domains) ==
@@ -1630,6 +1633,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
1630 uint32_t old_write_domain = obj->write_domain; 1633 uint32_t old_write_domain = obj->write_domain;
1631 1634
1632 obj->write_domain = 0; 1635 obj->write_domain = 0;
1636 list_del_init(&obj_priv->gpu_write_list);
1633 i915_gem_object_move_to_active(obj, seqno); 1637 i915_gem_object_move_to_active(obj, seqno);
1634 1638
1635 trace_i915_gem_object_change_domain(obj, 1639 trace_i915_gem_object_change_domain(obj,
@@ -2084,8 +2088,8 @@ static int
2084i915_gem_evict_everything(struct drm_device *dev) 2088i915_gem_evict_everything(struct drm_device *dev)
2085{ 2089{
2086 drm_i915_private_t *dev_priv = dev->dev_private; 2090 drm_i915_private_t *dev_priv = dev->dev_private;
2087 uint32_t seqno;
2088 int ret; 2091 int ret;
2092 uint32_t seqno;
2089 bool lists_empty; 2093 bool lists_empty;
2090 2094
2091 spin_lock(&dev_priv->mm.active_list_lock); 2095 spin_lock(&dev_priv->mm.active_list_lock);
@@ -2107,6 +2111,8 @@ i915_gem_evict_everything(struct drm_device *dev)
2107 if (ret) 2111 if (ret)
2108 return ret; 2112 return ret;
2109 2113
2114 BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
2115
2110 ret = i915_gem_evict_from_inactive_list(dev); 2116 ret = i915_gem_evict_from_inactive_list(dev);
2111 if (ret) 2117 if (ret)
2112 return ret; 2118 return ret;
@@ -2701,7 +2707,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
2701 old_write_domain = obj->write_domain; 2707 old_write_domain = obj->write_domain;
2702 i915_gem_flush(dev, 0, obj->write_domain); 2708 i915_gem_flush(dev, 0, obj->write_domain);
2703 seqno = i915_add_request(dev, NULL, obj->write_domain); 2709 seqno = i915_add_request(dev, NULL, obj->write_domain);
2704 obj->write_domain = 0; 2710 BUG_ON(obj->write_domain);
2705 i915_gem_object_move_to_active(obj, seqno); 2711 i915_gem_object_move_to_active(obj, seqno);
2706 2712
2707 trace_i915_gem_object_change_domain(obj, 2713 trace_i915_gem_object_change_domain(obj,
@@ -3850,16 +3856,23 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
3850 i915_gem_flush(dev, 3856 i915_gem_flush(dev,
3851 dev->invalidate_domains, 3857 dev->invalidate_domains,
3852 dev->flush_domains); 3858 dev->flush_domains);
3853 if (dev->flush_domains) 3859 if (dev->flush_domains & I915_GEM_GPU_DOMAINS)
3854 (void)i915_add_request(dev, file_priv, 3860 (void)i915_add_request(dev, file_priv,
3855 dev->flush_domains); 3861 dev->flush_domains);
3856 } 3862 }
3857 3863
3858 for (i = 0; i < args->buffer_count; i++) { 3864 for (i = 0; i < args->buffer_count; i++) {
3859 struct drm_gem_object *obj = object_list[i]; 3865 struct drm_gem_object *obj = object_list[i];
3866 struct drm_i915_gem_object *obj_priv = obj->driver_private;
3860 uint32_t old_write_domain = obj->write_domain; 3867 uint32_t old_write_domain = obj->write_domain;
3861 3868
3862 obj->write_domain = obj->pending_write_domain; 3869 obj->write_domain = obj->pending_write_domain;
3870 if (obj->write_domain)
3871 list_move_tail(&obj_priv->gpu_write_list,
3872 &dev_priv->mm.gpu_write_list);
3873 else
3874 list_del_init(&obj_priv->gpu_write_list);
3875
3863 trace_i915_gem_object_change_domain(obj, 3876 trace_i915_gem_object_change_domain(obj,
3864 obj->read_domains, 3877 obj->read_domains,
3865 old_write_domain); 3878 old_write_domain);
@@ -4370,6 +4383,7 @@ int i915_gem_init_object(struct drm_gem_object *obj)
4370 obj_priv->obj = obj; 4383 obj_priv->obj = obj;
4371 obj_priv->fence_reg = I915_FENCE_REG_NONE; 4384 obj_priv->fence_reg = I915_FENCE_REG_NONE;
4372 INIT_LIST_HEAD(&obj_priv->list); 4385 INIT_LIST_HEAD(&obj_priv->list);
4386 INIT_LIST_HEAD(&obj_priv->gpu_write_list);
4373 INIT_LIST_HEAD(&obj_priv->fence_list); 4387 INIT_LIST_HEAD(&obj_priv->fence_list);
4374 obj_priv->madv = I915_MADV_WILLNEED; 4388 obj_priv->madv = I915_MADV_WILLNEED;
4375 4389
@@ -4821,6 +4835,7 @@ i915_gem_load(struct drm_device *dev)
4821 spin_lock_init(&dev_priv->mm.active_list_lock); 4835 spin_lock_init(&dev_priv->mm.active_list_lock);
4822 INIT_LIST_HEAD(&dev_priv->mm.active_list); 4836 INIT_LIST_HEAD(&dev_priv->mm.active_list);
4823 INIT_LIST_HEAD(&dev_priv->mm.flushing_list); 4837 INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
4838 INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list);
4824 INIT_LIST_HEAD(&dev_priv->mm.inactive_list); 4839 INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
4825 INIT_LIST_HEAD(&dev_priv->mm.request_list); 4840 INIT_LIST_HEAD(&dev_priv->mm.request_list);
4826 INIT_LIST_HEAD(&dev_priv->mm.fence_list); 4841 INIT_LIST_HEAD(&dev_priv->mm.fence_list);