diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2009-09-20 14:25:47 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2009-09-22 20:05:26 -0400 |
commit | ab5ee57650165dc342a20d1213d48d585f2a72bd (patch) | |
tree | 7fd6e26d6a0a317df77234b8d5612f8b954070de /drivers/gpu | |
parent | 1c5d22f76dc721f3acb7a3dadc657a221e487fb7 (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.c | 39 |
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); |
51 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); | 51 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); |
52 | static int i915_gem_evict_something(struct drm_device *dev, int min_size); | 52 | static int i915_gem_evict_something(struct drm_device *dev, int min_size); |
53 | static int i915_gem_evict_from_list(struct drm_device *dev, | 53 | static int i915_gem_evict_from_inactive_list(struct drm_device *dev); |
54 | struct list_head *head); | ||
55 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | 54 | static 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. */ |
4159 | static int | 4157 | static int |
4160 | i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head) | 4158 | i915_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); |