[PATCH 07/10] drm/i915/evict: Ensure we completely cleanup on failure

From: Chris Wilson
Date: Fri Jun 17 2011 - 11:04:22 EST


BugLink: http://bugs.launchpad.net/bugs/599017

... and not leave the objects in a inconsistent state.

[seth.forshee@xxxxxxxxxxxxx: Also backported similar cleanups in success
path from commit e39a01501b228e1be2037d5bddccae2a820af902]
Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
Cc: stable@xxxxxxxxxx
(backported from commit 092de6f225638ec300936bfcbdc67805733cc78c upstream)

Signed-off-by: Seth Forshee <seth.forshee@xxxxxxxxxxxxx>
Signed-off-by: Stefan Bader <stefan.bader@xxxxxxxxxxxxx>
---
drivers/gpu/drm/i915/i915_gem_evict.c | 32 ++++++++++++++++++++------------
1 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 84ed1a7..9c1ec78 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -134,9 +134,15 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen
}

/* Nothing found, clean up and bail out! */
- list_for_each_entry(obj_priv, &unwind_list, evict_list) {
+ while (!list_empty(&unwind_list)) {
+ obj_priv = list_first_entry(&unwind_list,
+ struct drm_i915_gem_object,
+ evict_list);
+
ret = drm_mm_scan_remove_block(obj_priv->gtt_space);
BUG_ON(ret);
+
+ list_del_init(&obj_priv->evict_list);
}

/* We expect the caller to unpin, evict all and try again, or give up.
@@ -145,26 +151,28 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen
return -ENOSPC;

found:
+ /* drm_mm doesn't allow any other other operations while
+ * scanning, therefore store to be evicted objects on a
+ * temporary list. */
INIT_LIST_HEAD(&eviction_list);
list_for_each_entry_safe(obj_priv, tmp_obj_priv,
&unwind_list, evict_list) {
if (drm_mm_scan_remove_block(obj_priv->gtt_space)) {
- /* drm_mm doesn't allow any other other operations while
- * scanning, therefore store to be evicted objects on a
- * temporary list. */
list_move(&obj_priv->evict_list, &eviction_list);
+ continue;
}
+ list_del_init(&obj_priv->evict_list);
}

/* Unbinding will emit any required flushes */
- list_for_each_entry_safe(obj_priv, tmp_obj_priv,
- &eviction_list, evict_list) {
-#if WATCH_LRU
- DRM_INFO("%s: evicting %p\n", __func__, obj);
-#endif
- ret = i915_gem_object_unbind(obj_priv->obj);
- if (ret)
- return ret;
+ while (!list_empty(&eviction_list)) {
+ obj_priv = list_first_entry(&eviction_list,
+ struct drm_i915_gem_object,
+ evict_list);
+ if (ret == 0)
+ ret = i915_gem_object_unbind(obj_priv->obj);
+
+ list_del_init(&obj_priv->evict_list);
}

/* The just created free hole should be on the top of the free stack
--
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/