[Intel-gfx] [PATCH 1/2] drm/i915: Objects on the unbound list may still have an active reference

Chris Wilson chris at chris-wilson.co.uk
Tue Sep 9 08:02:42 CEST 2014


Due to the lazy retirement semantics, even though we have unbound an
object, it may still hold onto an active reference. So in te debug code,
play safe.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 2cbc85f3b237..d6c29dc6aacc 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3826,7 +3826,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;
 	int ret;
 
 	DRM_DEBUG("Dropping caches: 0x%08llx\n", val);
@@ -3847,10 +3846,18 @@ i915_drop_caches_set(void *data, u64 val)
 		i915_gem_retire_requests(dev);
 
 	if (val & DROP_BOUND) {
-		list_for_each_entry_safe(obj, next, &dev_priv->mm.bound_list,
-					 global_list) {
+		struct list_head still_in_list;
+
+		INIT_LIST_HEAD(&still_in_list);
+		while (!list_empty(&dev_priv->mm.bound_list)) {
+			struct drm_i915_gem_object *obj;
 			struct i915_vma *vma, *v;
 
+			obj = list_first_entry(&dev_priv->mm.bound_list,
+					       typeof(*obj), global_list);
+
+			list_move_tail(&obj->global_list, &still_in_list);
+
 			ret = 0;
 			drm_gem_object_reference(&obj->base);
 			list_for_each_entry_safe(vma, v, &obj->vma_list, vma_link) {
@@ -3865,16 +3872,30 @@ i915_drop_caches_set(void *data, u64 val)
 			if (ret)
 				goto unlock;
 		}
+
+		list_splice(&still_in_list, &dev_priv->mm.bound_list);
 	}
 
 	if (val & DROP_UNBOUND) {
-		list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list,
-					 global_list)
+		struct list_head still_in_list;
+
+		INIT_LIST_HEAD(&still_in_list);
+		while (!list_empty(&dev_priv->mm.unbound_list)) {
+			struct drm_i915_gem_object *obj;
+
+			obj = list_first_entry(&dev_priv->mm.unbound_list,
+					       typeof(*obj), global_list);
+
+			list_move_tail(&obj->global_list, &still_in_list);
+
 			if (obj->pages_pin_count == 0) {
 				ret = i915_gem_object_put_pages(obj);
 				if (ret)
 					goto unlock;
 			}
+		}
+
+		list_splice(&still_in_list, &dev_priv->mm.unbound_list);
 	}
 
 unlock:
-- 
2.1.0




More information about the Intel-gfx mailing list