@@ -2156,10 +2156,23 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
if (obj) {
struct drm_i915_gem_object *obj_priv;
+ obj_priv = obj->driver_private;
+
+ /* In the event that we have selected the most recently
+ * bound object to evict, then we are in the midst of
+ * thrashing the inactive list -- imagine a nearly full
+ * aperture and we are copying between large objects,
+ * only one of which can fit in at any one time. In
+ * this case it is better just to evict everything and
+ * start afresh -- or else suffer the page fault of
+ * doom.
+ */
+ if (obj_priv->list.next == &dev_priv->mm.inactive_list)
+ return i915_gem_evict_everything(dev);
+
#if WATCH_LRU
DRM_INFO("%s: evicting %p\n", __func__, obj);
#endif
- obj_priv = obj->driver_private;
BUG_ON(obj_priv->pin_count != 0);
BUG_ON(obj_priv->active);