summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-11-24 12:23:44 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2010-11-25 15:04:53 +0000
commit6299f992c0491232f008028a1f40bc9d86c4c76c (patch)
tree7c8d2a23fa6a749ffe5a918bb06c4b78d63a0e26 /drivers/gpu/drm/i915/i915_gem.c
parent2021746e1d5ad1e3b51e24480c566acbb833c7c1 (diff)
drm/i915: Defer accounting until read from debugfs
Simply remove our accounting of objects inside the aperture, keeping only track of what is in the aperture and its current usage. This removes the over-complication of BUGs that were attempting to keep the accounting correct and also removes the overhead of the accounting on the hot-paths. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c128
1 files changed, 22 insertions, 106 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f6167c55a649..7507a86c3feb 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -83,80 +83,6 @@ static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv,
dev_priv->mm.object_memory -= size;
}
-static void i915_gem_info_add_gtt(struct drm_i915_private *dev_priv,
- struct drm_i915_gem_object *obj)
-{
- dev_priv->mm.gtt_count++;
- dev_priv->mm.gtt_memory += obj->gtt_space->size;
- if (obj->gtt_offset < dev_priv->mm.gtt_mappable_end) {
- dev_priv->mm.mappable_gtt_used +=
- min_t(size_t, obj->gtt_space->size,
- dev_priv->mm.gtt_mappable_end - obj->gtt_offset);
- }
- list_add_tail(&obj->gtt_list, &dev_priv->mm.gtt_list);
-}
-
-static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv,
- struct drm_i915_gem_object *obj)
-{
- dev_priv->mm.gtt_count--;
- dev_priv->mm.gtt_memory -= obj->gtt_space->size;
- if (obj->gtt_offset < dev_priv->mm.gtt_mappable_end) {
- dev_priv->mm.mappable_gtt_used -=
- min_t(size_t, obj->gtt_space->size,
- dev_priv->mm.gtt_mappable_end - obj->gtt_offset);
- }
- list_del_init(&obj->gtt_list);
-}
-
-/**
- * Update the mappable working set counters. Call _only_ when there is a change
- * in one of (pin|fault)_mappable and update *_mappable _before_ calling.
- * @mappable: new state the changed mappable flag (either pin_ or fault_).
- */
-static void
-i915_gem_info_update_mappable(struct drm_i915_private *dev_priv,
- struct drm_i915_gem_object *obj,
- bool mappable)
-{
- if (mappable) {
- if (obj->pin_mappable && obj->fault_mappable)
- /* Combined state was already mappable. */
- return;
- dev_priv->mm.gtt_mappable_count++;
- dev_priv->mm.gtt_mappable_memory += obj->gtt_space->size;
- } else {
- if (obj->pin_mappable || obj->fault_mappable)
- /* Combined state still mappable. */
- return;
- dev_priv->mm.gtt_mappable_count--;
- dev_priv->mm.gtt_mappable_memory -= obj->gtt_space->size;
- }
-}
-
-static void i915_gem_info_add_pin(struct drm_i915_private *dev_priv,
- struct drm_i915_gem_object *obj,
- bool mappable)
-{
- dev_priv->mm.pin_count++;
- dev_priv->mm.pin_memory += obj->gtt_space->size;
- if (mappable) {
- obj->pin_mappable = true;
- i915_gem_info_update_mappable(dev_priv, obj, true);
- }
-}
-
-static void i915_gem_info_remove_pin(struct drm_i915_private *dev_priv,
- struct drm_i915_gem_object *obj)
-{
- dev_priv->mm.pin_count--;
- dev_priv->mm.pin_memory -= obj->gtt_space->size;
- if (obj->pin_mappable) {
- obj->pin_mappable = false;
- i915_gem_info_update_mappable(dev_priv, obj, false);
- }
-}
-
int
i915_gem_check_is_wedged(struct drm_device *dev)
{
@@ -253,19 +179,24 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_get_aperture *args = data;
+ struct drm_i915_gem_object *obj;
+ size_t pinned;
if (!(dev->driver->driver_features & DRIVER_GEM))
return -ENODEV;
+ pinned = 0;
mutex_lock(&dev->struct_mutex);
- args->aper_size = dev_priv->mm.gtt_total;
- args->aper_available_size = args->aper_size - dev_priv->mm.pin_memory;
+ list_for_each_entry(obj, &dev_priv->mm.pinned_list, mm_list)
+ pinned += obj->gtt_space->size;
mutex_unlock(&dev->struct_mutex);
+ args->aper_size = dev_priv->mm.gtt_total;
+ args->aper_available_size = args->aper_size -pinned;
+
return 0;
}
-
/**
* Creates a new mm object and returns a handle to it.
*/
@@ -1267,14 +1198,12 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
/* Now bind it into the GTT if needed */
mutex_lock(&dev->struct_mutex);
- BUG_ON(obj->pin_count && !obj->pin_mappable);
if (!obj->map_and_fenceable) {
ret = i915_gem_object_unbind(obj);
if (ret)
goto unlock;
}
-
if (!obj->gtt_space) {
ret = i915_gem_object_bind_to_gtt(obj, 0, true);
if (ret)
@@ -1285,11 +1214,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
if (ret)
goto unlock;
- if (!obj->fault_mappable) {
- obj->fault_mappable = true;
- i915_gem_info_update_mappable(dev_priv, obj, true);
- }
-
/* Need a new fence register? */
if (obj->tiling_mode != I915_TILING_NONE) {
ret = i915_gem_object_get_fence_reg(obj, true);
@@ -1300,6 +1224,8 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
if (i915_gem_object_is_inactive(obj))
list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
+ obj->fault_mappable = true;
+
pfn = ((dev->agp->base + obj->gtt_offset) >> PAGE_SHIFT) +
page_offset;
@@ -1406,18 +1332,14 @@ out_free_list:
void
i915_gem_release_mmap(struct drm_i915_gem_object *obj)
{
- struct drm_device *dev = obj->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
+ if (!obj->fault_mappable)
+ return;
- if (unlikely(obj->base.map_list.map && dev->dev_mapping))
- unmap_mapping_range(dev->dev_mapping,
- (loff_t)obj->base.map_list.hash.key<<PAGE_SHIFT,
- obj->base.size, 1);
+ unmap_mapping_range(obj->base.dev->dev_mapping,
+ (loff_t)obj->base.map_list.hash.key<<PAGE_SHIFT,
+ obj->base.size, 1);
- if (obj->fault_mappable) {
- obj->fault_mappable = false;
- i915_gem_info_update_mappable(dev_priv, obj, false);
- }
+ obj->fault_mappable = false;
}
static void
@@ -2221,8 +2143,6 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
int
i915_gem_object_unbind(struct drm_i915_gem_object *obj)
{
- struct drm_device *dev = obj->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
int ret = 0;
if (obj->gtt_space == NULL)
@@ -2259,10 +2179,9 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
i915_gem_clear_fence_reg(obj);
i915_gem_gtt_unbind_object(obj);
-
i915_gem_object_put_pages_gtt(obj);
- i915_gem_info_remove_gtt(dev_priv, obj);
+ list_del_init(&obj->gtt_list);
list_del_init(&obj->mm_list);
/* Avoid an unnecessary call to unbind on rebind. */
obj->map_and_fenceable = true;
@@ -2833,11 +2752,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
goto search_free;
}
- obj->gtt_offset = obj->gtt_space->start;
-
- /* keep track of bounds object by adding it to the inactive list */
+ list_add_tail(&obj->gtt_list, &dev_priv->mm.gtt_list);
list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
- i915_gem_info_add_gtt(dev_priv, obj);
/* Assert that the object is not currently in any GPU domain. As it
* wasn't in the GTT, there shouldn't be any way it could have been in
@@ -2846,7 +2762,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS);
BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS);
- trace_i915_gem_object_bind(obj, obj->gtt_offset, map_and_fenceable);
+ obj->gtt_offset = obj->gtt_space->start;
fenceable =
obj->gtt_space->size == fence_size &&
@@ -2857,6 +2773,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
obj->map_and_fenceable = mappable && fenceable;
+ trace_i915_gem_object_bind(obj, obj->gtt_offset, map_and_fenceable);
return 0;
}
@@ -4372,12 +4289,11 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
}
if (obj->pin_count++ == 0) {
- i915_gem_info_add_pin(dev_priv, obj, map_and_fenceable);
if (!obj->active)
list_move_tail(&obj->mm_list,
&dev_priv->mm.pinned_list);
}
- BUG_ON(!obj->pin_mappable && map_and_fenceable);
+ obj->pin_mappable |= map_and_fenceable;
WARN_ON(i915_verify_lists(dev));
return 0;
@@ -4397,7 +4313,7 @@ i915_gem_object_unpin(struct drm_i915_gem_object *obj)
if (!obj->active)
list_move_tail(&obj->mm_list,
&dev_priv->mm.inactive_list);
- i915_gem_info_remove_pin(dev_priv, obj);
+ obj->pin_mappable = false;
}
WARN_ON(i915_verify_lists(dev));
}