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

drm/i915: Preallocate the drm_mm_node prior to manipulating the GTT drm_mm manager

As we may reap neighbouring objects in order to free up pages for
allocations, we need to be careful not to allocate in the middle of the
drm_mm manager. To accomplish this, we can simply allocate the
drm_mm_node up front and then use the combined search & insert
drm_mm routines, reducing our code footprint in the process.

Fixes (partially) i-g-t/gem_tiled_swapping
Reported-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarJani Nikula <jani.nikula@intel.com>
[danvet: Again fixup atomic bikeshed.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent b8103450
...@@ -2890,7 +2890,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, ...@@ -2890,7 +2890,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
{ {
struct drm_device *dev = obj->base.dev; struct drm_device *dev = obj->base.dev;
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_mm_node *free_space; struct drm_mm_node *node;
u32 size, fence_size, fence_alignment, unfenced_alignment; u32 size, fence_size, fence_alignment, unfenced_alignment;
bool mappable, fenceable; bool mappable, fenceable;
int ret; int ret;
...@@ -2936,66 +2936,54 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, ...@@ -2936,66 +2936,54 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
i915_gem_object_pin_pages(obj); i915_gem_object_pin_pages(obj);
node = kzalloc(sizeof(*node), GFP_KERNEL);
if (node == NULL) {
i915_gem_object_unpin_pages(obj);
return -ENOMEM;
}
search_free: search_free:
if (map_and_fenceable) if (map_and_fenceable)
free_space = drm_mm_search_free_in_range_color(&dev_priv->mm.gtt_space, ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, node,
size, alignment, obj->cache_level, size, alignment, obj->cache_level,
0, dev_priv->mm.gtt_mappable_end, 0, dev_priv->mm.gtt_mappable_end);
false);
else else
free_space = drm_mm_search_free_color(&dev_priv->mm.gtt_space, ret = drm_mm_insert_node_generic(&dev_priv->mm.gtt_space, node,
size, alignment, obj->cache_level, size, alignment, obj->cache_level);
false); if (ret) {
if (free_space != NULL) {
if (map_and_fenceable)
free_space =
drm_mm_get_block_range_generic(free_space,
size, alignment, obj->cache_level,
0, dev_priv->mm.gtt_mappable_end,
false);
else
free_space =
drm_mm_get_block_generic(free_space,
size, alignment, obj->cache_level,
false);
}
if (free_space == NULL) {
ret = i915_gem_evict_something(dev, size, alignment, ret = i915_gem_evict_something(dev, size, alignment,
obj->cache_level, obj->cache_level,
map_and_fenceable, map_and_fenceable,
nonblocking); nonblocking);
if (ret) { if (ret == 0)
i915_gem_object_unpin_pages(obj); goto search_free;
return ret;
}
goto search_free; i915_gem_object_unpin_pages(obj);
kfree(node);
return ret;
} }
if (WARN_ON(!i915_gem_valid_gtt_space(dev, if (WARN_ON(!i915_gem_valid_gtt_space(dev, node, obj->cache_level))) {
free_space,
obj->cache_level))) {
i915_gem_object_unpin_pages(obj); i915_gem_object_unpin_pages(obj);
drm_mm_put_block(free_space); drm_mm_put_block(node);
return -EINVAL; return -EINVAL;
} }
ret = i915_gem_gtt_prepare_object(obj); ret = i915_gem_gtt_prepare_object(obj);
if (ret) { if (ret) {
i915_gem_object_unpin_pages(obj); i915_gem_object_unpin_pages(obj);
drm_mm_put_block(free_space); drm_mm_put_block(node);
return ret; return ret;
} }
list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list); list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list);
list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
obj->gtt_space = free_space; obj->gtt_space = node;
obj->gtt_offset = free_space->start; obj->gtt_offset = node->start;
fenceable = fenceable =
free_space->size == fence_size && node->size == fence_size &&
(free_space->start & (fence_alignment - 1)) == 0; (node->start & (fence_alignment - 1)) == 0;
mappable = mappable =
obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end;
......
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