fs_reclaim_acquire(GFP_KERNEL);
        if (val & DROP_BOUND)
-               i915_gem_shrink(dev_priv, LONG_MAX, I915_SHRINK_BOUND);
+               i915_gem_shrink(dev_priv, LONG_MAX, NULL, I915_SHRINK_BOUND);
 
        if (val & DROP_UNBOUND)
-               i915_gem_shrink(dev_priv, LONG_MAX, I915_SHRINK_UNBOUND);
+               i915_gem_shrink(dev_priv, LONG_MAX, NULL, I915_SHRINK_UNBOUND);
 
        if (val & DROP_SHRINK_ALL)
                i915_gem_shrink_all(dev_priv);
 
                                goto err_sg;
                        }
 
-                       i915_gem_shrink(dev_priv, 2 * page_count, *s++);
+                       i915_gem_shrink(dev_priv, 2 * page_count, NULL, *s++);
                        cond_resched();
 
                        /* We've tried hard to allocate the memory by reaping
         * the objects as well, see i915_gem_freeze()
         */
 
-       i915_gem_shrink(dev_priv, -1UL, I915_SHRINK_UNBOUND);
+       i915_gem_shrink(dev_priv, -1UL, NULL, I915_SHRINK_UNBOUND);
        i915_gem_drain_freed_objects(dev_priv);
 
        mutex_lock(&dev_priv->drm.struct_mutex);
 
  * i915_gem_shrink - Shrink buffer object caches
  * @dev_priv: i915 device
  * @target: amount of memory to make available, in pages
+ * @nr_scanned: optional output for number of pages scanned (incremental)
  * @flags: control flags for selecting cache types
  *
  * This function is the main interface to the shrinker. It will try to release
  */
 unsigned long
 i915_gem_shrink(struct drm_i915_private *dev_priv,
-               unsigned long target, unsigned flags)
+               unsigned long target,
+               unsigned long *nr_scanned,
+               unsigned flags)
 {
        const struct {
                struct list_head *list;
                { NULL, 0 },
        }, *phase;
        unsigned long count = 0;
+       unsigned long scanned = 0;
        bool unlock;
 
        if (!shrinker_lock(dev_priv, &unlock))
                                        count += obj->base.size >> PAGE_SHIFT;
                                }
                                mutex_unlock(&obj->mm.lock);
+                               scanned += obj->base.size >> PAGE_SHIFT;
                        }
                }
                list_splice_tail(&still_in_list, phase->list);
 
        shrinker_unlock(dev_priv, unlock);
 
+       if (nr_scanned)
+               *nr_scanned += scanned;
        return count;
 }
 
        unsigned long freed;
 
        intel_runtime_pm_get(dev_priv);
-       freed = i915_gem_shrink(dev_priv, -1UL,
+       freed = i915_gem_shrink(dev_priv, -1UL, NULL,
                                I915_SHRINK_BOUND |
                                I915_SHRINK_UNBOUND |
                                I915_SHRINK_ACTIVE);
        unsigned long freed;
        bool unlock;
 
+       sc->nr_scanned = 0;
+
        if (!shrinker_lock(dev_priv, &unlock))
                return SHRINK_STOP;
 
        freed = i915_gem_shrink(dev_priv,
                                sc->nr_to_scan,
+                               &sc->nr_scanned,
                                I915_SHRINK_BOUND |
                                I915_SHRINK_UNBOUND |
                                I915_SHRINK_PURGEABLE);
        if (freed < sc->nr_to_scan)
                freed += i915_gem_shrink(dev_priv,
-                                        sc->nr_to_scan - freed,
+                                        sc->nr_to_scan - sc->nr_scanned,
+                                        &sc->nr_scanned,
                                         I915_SHRINK_BOUND |
                                         I915_SHRINK_UNBOUND);
        if (freed < sc->nr_to_scan && current_is_kswapd()) {
                intel_runtime_pm_get(dev_priv);
                freed += i915_gem_shrink(dev_priv,
-                                        sc->nr_to_scan - freed,
+                                        sc->nr_to_scan - sc->nr_scanned,
+                                        &sc->nr_scanned,
                                         I915_SHRINK_ACTIVE |
                                         I915_SHRINK_BOUND |
                                         I915_SHRINK_UNBOUND);
 
        shrinker_unlock(dev_priv, unlock);
 
-       return freed;
+       return sc->nr_scanned ? freed : SHRINK_STOP;
 }
 
 static bool
                goto out;
 
        intel_runtime_pm_get(dev_priv);
-       freed_pages += i915_gem_shrink(dev_priv, -1UL,
+       freed_pages += i915_gem_shrink(dev_priv, -1UL, NULL,
                                       I915_SHRINK_BOUND |
                                       I915_SHRINK_UNBOUND |
                                       I915_SHRINK_ACTIVE |