Skip to content

Commit

Permalink
drm/i915: Fix unsafe vma iteration in i915_drop_caches
Browse files Browse the repository at this point in the history
When unbinding, there is a possibility that we drop the active reference
on the object, thereby freeing it. If that happens, we may destroy the
vm link as well as the object and vma. So iterate carefully.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Chris Wilson authored and Daniel Vetter committed Sep 4, 2014
1 parent 8fe8a3f commit 4ad72b7
Showing 1 changed file with 11 additions and 6 deletions.
17 changes: 11 additions & 6 deletions drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3812,8 +3812,6 @@ i915_drop_caches_set(void *data, u64 val)
struct drm_device *dev = data;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj, *next;
struct i915_address_space *vm;
struct i915_vma *vma, *x;
int ret;

DRM_DEBUG("Dropping caches: 0x%08llx\n", val);
Expand All @@ -3834,16 +3832,23 @@ i915_drop_caches_set(void *data, u64 val)
i915_gem_retire_requests(dev);

if (val & DROP_BOUND) {
list_for_each_entry(vm, &dev_priv->vm_list, global_link) {
list_for_each_entry_safe(vma, x, &vm->inactive_list,
mm_list) {
list_for_each_entry_safe(obj, next, &dev_priv->mm.bound_list,
global_list) {
struct i915_vma *vma, *v;

ret = 0;
drm_gem_object_reference(&obj->base);
list_for_each_entry_safe(vma, v, &obj->vma_list, vma_link) {
if (vma->pin_count)
continue;

ret = i915_vma_unbind(vma);
if (ret)
goto unlock;
break;
}
drm_gem_object_unreference(&obj->base);
if (ret)
goto unlock;
}
}

Expand Down

0 comments on commit 4ad72b7

Please sign in to comment.