mirror of https://gitee.com/openkylin/linux.git
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: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
d935cc61d4
commit
a6e0aa4214
|
@ -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);
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
/* 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)
|
||||||
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)
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
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 (drm_mm_search_free(&dev_priv->mm.gtt_space,
|
if (mappable) {
|
||||||
min_size, alignment, 0))
|
if (drm_mm_search_free_in_range(&dev_priv->mm.gtt_space,
|
||||||
return 0;
|
min_size, alignment, 0,
|
||||||
|
dev_priv->mm.gtt_mappable_end,
|
||||||
|
0))
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
if (drm_mm_search_free(&dev_priv->mm.gtt_space,
|
||||||
|
min_size, alignment, 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,7 +88,12 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen
|
||||||
*/
|
*/
|
||||||
|
|
||||||
INIT_LIST_HEAD(&unwind_list);
|
INIT_LIST_HEAD(&unwind_list);
|
||||||
drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment);
|
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);
|
||||||
|
|
||||||
/* First see if there is a large enough contiguous idle region... */
|
/* First see if there is a large enough contiguous idle region... */
|
||||||
list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, mm_list) {
|
list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, mm_list) {
|
||||||
|
|
Loading…
Reference in New Issue