Commit a6e0aa42 authored by Daniel Vetter's avatar Daniel Vetter Committed by Chris Wilson

drm/i915: range-restricted eviction support

Add a mappable parameter to i915_gem_evict_something to distinguish
the two cases (non-restricted vs. mappable gtt allocations). No
functional changes because the mappable limit is set to the end of
the gtt currently.
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent d935cc61
...@@ -535,6 +535,8 @@ typedef struct drm_i915_private { ...@@ -535,6 +535,8 @@ typedef struct drm_i915_private {
struct drm_mm vram; struct drm_mm vram;
/** Memory allocator for GTT */ /** Memory allocator for GTT */
struct drm_mm gtt_space; struct drm_mm gtt_space;
/** End of mappable part of GTT */
unsigned long gtt_mappable_end;
struct io_mapping *gtt_mapping; struct io_mapping *gtt_mapping;
int gtt_mtrr; int gtt_mtrr;
...@@ -1067,7 +1069,8 @@ void i915_gem_shrinker_init(void); ...@@ -1067,7 +1069,8 @@ void i915_gem_shrinker_init(void);
void i915_gem_shrinker_exit(void); void i915_gem_shrinker_exit(void);
/* i915_gem_evict.c */ /* i915_gem_evict.c */
int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment); int i915_gem_evict_something(struct drm_device *dev, int min_size,
unsigned alignment, bool mappable);
int i915_gem_evict_everything(struct drm_device *dev); int i915_gem_evict_everything(struct drm_device *dev);
int i915_gem_evict_inactive(struct drm_device *dev); int i915_gem_evict_inactive(struct drm_device *dev);
......
...@@ -187,6 +187,7 @@ int i915_gem_do_init(struct drm_device *dev, ...@@ -187,6 +187,7 @@ int i915_gem_do_init(struct drm_device *dev,
end - start); end - start);
dev_priv->mm.gtt_total = end - start; dev_priv->mm.gtt_total = end - start;
dev_priv->mm.gtt_mappable_end = end;
return 0; return 0;
} }
...@@ -413,7 +414,8 @@ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) ...@@ -413,7 +414,8 @@ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj)
struct drm_device *dev = obj->dev; struct drm_device *dev = obj->dev;
ret = i915_gem_evict_something(dev, obj->size, ret = i915_gem_evict_something(dev, obj->size,
i915_gem_get_gtt_alignment(obj)); i915_gem_get_gtt_alignment(obj),
false);
if (ret) if (ret)
return ret; return ret;
...@@ -2672,7 +2674,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) ...@@ -2672,7 +2674,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
/* If the gtt is empty and we're still having trouble /* If the gtt is empty and we're still having trouble
* fitting our object in, we're out of memory. * fitting our object in, we're out of memory.
*/ */
ret = i915_gem_evict_something(dev, obj->size, alignment); ret = i915_gem_evict_something(dev, obj->size, alignment, true);
if (ret) if (ret)
return ret; return ret;
...@@ -2687,7 +2689,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) ...@@ -2687,7 +2689,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
if (ret == -ENOMEM) { if (ret == -ENOMEM) {
/* first try to clear up some space from the GTT */ /* first try to clear up some space from the GTT */
ret = i915_gem_evict_something(dev, obj->size, ret = i915_gem_evict_something(dev, obj->size,
alignment); alignment, true);
if (ret) { if (ret) {
/* now try to shrink everyone else */ /* now try to shrink everyone else */
if (gfpmask) { if (gfpmask) {
...@@ -2717,7 +2719,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) ...@@ -2717,7 +2719,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
drm_mm_put_block(obj_priv->gtt_space); drm_mm_put_block(obj_priv->gtt_space);
obj_priv->gtt_space = NULL; obj_priv->gtt_space = NULL;
ret = i915_gem_evict_something(dev, obj->size, alignment); ret = i915_gem_evict_something(dev, obj->size, alignment, true);
if (ret) if (ret)
return ret; return ret;
......
...@@ -41,7 +41,8 @@ mark_free(struct drm_i915_gem_object *obj_priv, ...@@ -41,7 +41,8 @@ mark_free(struct drm_i915_gem_object *obj_priv,
} }
int int
i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment) i915_gem_evict_something(struct drm_device *dev, int min_size,
unsigned alignment, bool mappable)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
struct list_head eviction_list, unwind_list; struct list_head eviction_list, unwind_list;
...@@ -51,9 +52,17 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen ...@@ -51,9 +52,17 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen
i915_gem_retire_requests(dev); i915_gem_retire_requests(dev);
/* Re-check for free space after retiring requests */ /* Re-check for free space after retiring requests */
if (mappable) {
if (drm_mm_search_free_in_range(&dev_priv->mm.gtt_space,
min_size, alignment, 0,
dev_priv->mm.gtt_mappable_end,
0))
return 0;
} else {
if (drm_mm_search_free(&dev_priv->mm.gtt_space, if (drm_mm_search_free(&dev_priv->mm.gtt_space,
min_size, alignment, 0)) min_size, alignment, 0))
return 0; return 0;
}
/* /*
* The goal is to evict objects and amalgamate space in LRU order. * The goal is to evict objects and amalgamate space in LRU order.
...@@ -79,6 +88,11 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen ...@@ -79,6 +88,11 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen
*/ */
INIT_LIST_HEAD(&unwind_list); INIT_LIST_HEAD(&unwind_list);
if (mappable)
drm_mm_init_scan_with_range(&dev_priv->mm.gtt_space, min_size,
alignment, 0,
dev_priv->mm.gtt_mappable_end);
else
drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment);
/* First see if there is a large enough contiguous idle region... */ /* First see if there is a large enough contiguous idle region... */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment