aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 75e7b899e033..f150bfd2c851 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -35,6 +35,7 @@
35#include <linux/swap.h> 35#include <linux/swap.h>
36#include <linux/pci.h> 36#include <linux/pci.h>
37 37
38static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj);
38static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); 39static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
39static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); 40static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
40static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); 41static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
@@ -48,7 +49,8 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
48static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, 49static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
49 unsigned alignment); 50 unsigned alignment);
50static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); 51static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
51static int i915_gem_evict_something(struct drm_device *dev, int min_size); 52static int i915_gem_evict_something(struct drm_device *dev, int min_size,
53 unsigned alignment);
52static int i915_gem_evict_from_inactive_list(struct drm_device *dev); 54static int i915_gem_evict_from_inactive_list(struct drm_device *dev);
53static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, 55static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
54 struct drm_i915_gem_pwrite *args, 56 struct drm_i915_gem_pwrite *args,
@@ -313,7 +315,8 @@ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj)
313 if (ret == -ENOMEM) { 315 if (ret == -ENOMEM) {
314 struct drm_device *dev = obj->dev; 316 struct drm_device *dev = obj->dev;
315 317
316 ret = i915_gem_evict_something(dev, obj->size); 318 ret = i915_gem_evict_something(dev, obj->size,
319 i915_gem_get_gtt_alignment(obj));
317 if (ret) 320 if (ret)
318 return ret; 321 return ret;
319 322
@@ -2005,10 +2008,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
2005 return ret; 2008 return ret;
2006} 2009}
2007 2010
2008static struct drm_gem_object * 2011static int
2009i915_gem_find_inactive_object(struct drm_device *dev, int min_size) 2012i915_gem_scan_inactive_list_and_evict(struct drm_device *dev, int min_size,
2013 unsigned alignment, int *found)
2010{ 2014{
2011 drm_i915_private_t *dev_priv = dev->dev_private; 2015 drm_i915_private_t *dev_priv = dev->dev_private;
2016 struct drm_gem_object *obj;
2012 struct drm_i915_gem_object *obj_priv; 2017 struct drm_i915_gem_object *obj_priv;
2013 struct drm_gem_object *best = NULL; 2018 struct drm_gem_object *best = NULL;
2014 struct drm_gem_object *first = NULL; 2019 struct drm_gem_object *first = NULL;
@@ -2022,14 +2027,31 @@ i915_gem_find_inactive_object(struct drm_device *dev, int min_size)
2022 (!best || obj->size < best->size)) { 2027 (!best || obj->size < best->size)) {
2023 best = obj; 2028 best = obj;
2024 if (best->size == min_size) 2029 if (best->size == min_size)
2025 return best; 2030 break;
2026 } 2031 }
2027 if (!first) 2032 if (!first)
2028 first = obj; 2033 first = obj;
2029 } 2034 }
2030 } 2035 }
2031 2036
2032 return best ? best : first; 2037 obj = best ? best : first;
2038
2039 if (!obj) {
2040 *found = 0;
2041 return 0;
2042 }
2043
2044 *found = 1;
2045
2046#if WATCH_LRU
2047 DRM_INFO("%s: evicting %p\n", __func__, obj);
2048#endif
2049 obj_priv = to_intel_bo(obj);
2050 BUG_ON(obj_priv->pin_count != 0);
2051 BUG_ON(obj_priv->active);
2052
2053 /* Wait on the rendering and unbind the buffer. */
2054 return i915_gem_object_unbind(obj);
2033} 2055}
2034 2056
2035static int 2057static int
@@ -2115,11 +2137,11 @@ i915_gem_evict_everything(struct drm_device *dev)
2115} 2137}
2116 2138
2117static int 2139static int
2118i915_gem_evict_something(struct drm_device *dev, int min_size) 2140i915_gem_evict_something(struct drm_device *dev,
2141 int min_size, unsigned alignment)
2119{ 2142{
2120 drm_i915_private_t *dev_priv = dev->dev_private; 2143 drm_i915_private_t *dev_priv = dev->dev_private;
2121 struct drm_gem_object *obj; 2144 int ret, found;
2122 int ret;
2123 2145
2124 struct intel_ring_buffer *render_ring = &dev_priv->render_ring; 2146 struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
2125 struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring; 2147 struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring;
@@ -2129,20 +2151,11 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
2129 /* If there's an inactive buffer available now, grab it 2151 /* If there's an inactive buffer available now, grab it
2130 * and be done. 2152 * and be done.
2131 */ 2153 */
2132 obj = i915_gem_find_inactive_object(dev, min_size); 2154 ret = i915_gem_scan_inactive_list_and_evict(dev, min_size,
2133 if (obj) { 2155 alignment,
2134 struct drm_i915_gem_object *obj_priv; 2156 &found);
2135 2157 if (found)
2136#if WATCH_LRU 2158 return ret;
2137 DRM_INFO("%s: evicting %p\n", __func__, obj);
2138#endif
2139 obj_priv = to_intel_bo(obj);
2140 BUG_ON(obj_priv->pin_count != 0);
2141 BUG_ON(obj_priv->active);
2142
2143 /* Wait on the rendering and unbind the buffer. */
2144 return i915_gem_object_unbind(obj);
2145 }
2146 2159
2147 /* If we didn't get anything, but the ring is still processing 2160 /* If we didn't get anything, but the ring is still processing
2148 * things, wait for the next to finish and hopefully leave us 2161 * things, wait for the next to finish and hopefully leave us
@@ -2184,6 +2197,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
2184 * will get moved to inactive. 2197 * will get moved to inactive.
2185 */ 2198 */
2186 if (!list_empty(&dev_priv->mm.flushing_list)) { 2199 if (!list_empty(&dev_priv->mm.flushing_list)) {
2200 struct drm_gem_object *obj = NULL;
2187 struct drm_i915_gem_object *obj_priv; 2201 struct drm_i915_gem_object *obj_priv;
2188 2202
2189 /* Find an object that we can immediately reuse */ 2203 /* Find an object that we can immediately reuse */
@@ -2661,7 +2675,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2661#if WATCH_LRU 2675#if WATCH_LRU
2662 DRM_INFO("%s: GTT full, evicting something\n", __func__); 2676 DRM_INFO("%s: GTT full, evicting something\n", __func__);
2663#endif 2677#endif
2664 ret = i915_gem_evict_something(dev, obj->size); 2678 ret = i915_gem_evict_something(dev, obj->size, alignment);
2665 if (ret) 2679 if (ret)
2666 return ret; 2680 return ret;
2667 2681
@@ -2679,7 +2693,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2679 2693
2680 if (ret == -ENOMEM) { 2694 if (ret == -ENOMEM) {
2681 /* first try to clear up some space from the GTT */ 2695 /* first try to clear up some space from the GTT */
2682 ret = i915_gem_evict_something(dev, obj->size); 2696 ret = i915_gem_evict_something(dev, obj->size,
2697 alignment);
2683 if (ret) { 2698 if (ret) {
2684 /* now try to shrink everyone else */ 2699 /* now try to shrink everyone else */
2685 if (gfpmask) { 2700 if (gfpmask) {
@@ -2709,7 +2724,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2709 drm_mm_put_block(obj_priv->gtt_space); 2724 drm_mm_put_block(obj_priv->gtt_space);
2710 obj_priv->gtt_space = NULL; 2725 obj_priv->gtt_space = NULL;
2711 2726
2712 ret = i915_gem_evict_something(dev, obj->size); 2727 ret = i915_gem_evict_something(dev, obj->size, alignment);
2713 if (ret) 2728 if (ret)
2714 return ret; 2729 return ret;
2715 2730