aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-09-20 14:25:47 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2009-09-22 20:05:26 -0400
commitab5ee57650165dc342a20d1213d48d585f2a72bd (patch)
tree7fd6e26d6a0a317df77234b8d5612f8b954070de /drivers/gpu
parent1c5d22f76dc721f3acb7a3dadc657a221e487fb7 (diff)
drm/i915: Clean up evict from list.
First the routine attempted to unlock a mutex it did not own along the error path. Secondly the routine should never be called on any list but the inactive one, since we attempt to unbind those objects, so fix the calling semantics. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c39
1 files changed, 14 insertions, 25 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 67e2cd5636ec..d49ac1c2e396 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -50,8 +50,7 @@ static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
50 unsigned alignment); 50 unsigned alignment);
51static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); 51static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
52static 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);
53static int i915_gem_evict_from_list(struct drm_device *dev, 53static int i915_gem_evict_from_inactive_list(struct drm_device *dev);
54 struct list_head *head);
55static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, 54static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
56 struct drm_i915_gem_pwrite *args, 55 struct drm_i915_gem_pwrite *args,
57 struct drm_file *file_priv); 56 struct drm_file *file_priv);
@@ -2095,7 +2094,7 @@ i915_gem_evict_everything(struct drm_device *dev)
2095 if (ret) 2094 if (ret)
2096 return ret; 2095 return ret;
2097 2096
2098 ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list); 2097 ret = i915_gem_evict_from_inactive_list(dev);
2099 if (ret) 2098 if (ret)
2100 return ret; 2099 return ret;
2101 2100
@@ -2195,8 +2194,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
2195 */ 2194 */
2196 if (!list_empty (&dev_priv->mm.inactive_list)) { 2195 if (!list_empty (&dev_priv->mm.inactive_list)) {
2197 DRM_INFO("GTT full, evicting inactive buffers\n"); 2196 DRM_INFO("GTT full, evicting inactive buffers\n");
2198 return i915_gem_evict_from_list(dev, 2197 return i915_gem_evict_from_inactive_list(dev);
2199 &dev_priv->mm.inactive_list);
2200 } else 2198 } else
2201 return i915_gem_evict_everything(dev); 2199 return i915_gem_evict_everything(dev);
2202 } 2200 }
@@ -4155,36 +4153,27 @@ void i915_gem_free_object(struct drm_gem_object *obj)
4155 kfree(obj->driver_private); 4153 kfree(obj->driver_private);
4156} 4154}
4157 4155
4158/** Unbinds all objects that are on the given buffer list. */ 4156/** Unbinds all inactive objects. */
4159static int 4157static int
4160i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head) 4158i915_gem_evict_from_inactive_list(struct drm_device *dev)
4161{ 4159{
4162 struct drm_gem_object *obj; 4160 drm_i915_private_t *dev_priv = dev->dev_private;
4163 struct drm_i915_gem_object *obj_priv;
4164 int ret;
4165 4161
4166 while (!list_empty(head)) { 4162 while (!list_empty(&dev_priv->mm.inactive_list)) {
4167 obj_priv = list_first_entry(head, 4163 struct drm_gem_object *obj;
4168 struct drm_i915_gem_object, 4164 int ret;
4169 list);
4170 obj = obj_priv->obj;
4171 4165
4172 if (obj_priv->pin_count != 0) { 4166 obj = list_first_entry(&dev_priv->mm.inactive_list,
4173 DRM_ERROR("Pinned object in unbind list\n"); 4167 struct drm_i915_gem_object,
4174 mutex_unlock(&dev->struct_mutex); 4168 list)->obj;
4175 return -EINVAL;
4176 }
4177 4169
4178 ret = i915_gem_object_unbind(obj); 4170 ret = i915_gem_object_unbind(obj);
4179 if (ret != 0) { 4171 if (ret != 0) {
4180 DRM_ERROR("Error unbinding object in LeaveVT: %d\n", 4172 DRM_ERROR("Error unbinding object: %d\n", ret);
4181 ret);
4182 mutex_unlock(&dev->struct_mutex);
4183 return ret; 4173 return ret;
4184 } 4174 }
4185 } 4175 }
4186 4176
4187
4188 return 0; 4177 return 0;
4189} 4178}
4190 4179
@@ -4301,7 +4290,7 @@ i915_gem_idle(struct drm_device *dev)
4301 4290
4302 4291
4303 /* Move all inactive buffers out of the GTT. */ 4292 /* Move all inactive buffers out of the GTT. */
4304 ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list); 4293 ret = i915_gem_evict_from_inactive_list(dev);
4305 WARN_ON(!list_empty(&dev_priv->mm.inactive_list)); 4294 WARN_ON(!list_empty(&dev_priv->mm.inactive_list));
4306 if (ret) { 4295 if (ret) {
4307 mutex_unlock(&dev->struct_mutex); 4296 mutex_unlock(&dev->struct_mutex);