drm/i915/gem: Pin the L-shape quirked object as unshrinkable
authorChris Wilson <chris@chris-wilson.co.uk>
Mon, 17 May 2021 08:46:40 +0000 (09:46 +0100)
committerMatthew Auld <matthew.auld@intel.com>
Mon, 17 May 2021 13:12:52 +0000 (14:12 +0100)
When instantiating a tiled object on an L-shaped memory machine, we mark
the object as unshrinkable to prevent the shrinker from trying to swap
out the pages. We have to do this as we do not know the swizzling on the
individual pages, and so the data will be scrambled across swap out/in.

Not only do we need to move the object off the shrinker list, we need to
mark the object with shrink_pin so that the counter is consistent across
calls to madvise.

v2: in the madvise ioctl we need to check if the object is currently
shrinkable/purgeable, not if the object type supports shrinking

Fixes: 0175969e489a ("drm/i915/gem: Use shrinkable status for unknown swizzle quirks")
References: https://gitlab.freedesktop.org/drm/intel/-/issues/3293
References: https://gitlab.freedesktop.org/drm/intel/-/issues/3450
Reported-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Tested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: <stable@vger.kernel.org> # v5.12+
Link: https://patchwork.freedesktop.org/patch/msgid/20210517084640.18862-1-matthew.auld@intel.com
drivers/gpu/drm/i915/gem/i915_gem_pages.c
drivers/gpu/drm/i915/i915_gem.c

index aed8a37ccdc938ea4022b758d59c3a654f2e9bd9..7361971c177ddb6a7975342c184ca64f6355d91c 100644 (file)
@@ -63,6 +63,8 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
            i915->quirks & QUIRK_PIN_SWIZZLED_PAGES) {
                GEM_BUG_ON(i915_gem_object_has_tiling_quirk(obj));
                i915_gem_object_set_tiling_quirk(obj);
+               GEM_BUG_ON(!list_empty(&obj->mm.link));
+               atomic_inc(&obj->mm.shrink_pin);
                shrinkable = false;
        }
 
index d0018c5f88bd9e838091405df1d12341e36d9920..cffd7f4f87dc8ef848eeed330b2e7de2ba6d8c7b 100644 (file)
@@ -1009,12 +1009,11 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
                obj->mm.madv = args->madv;
 
        if (i915_gem_object_has_pages(obj)) {
-               struct list_head *list;
+               unsigned long flags;
 
-               if (i915_gem_object_is_shrinkable(obj)) {
-                       unsigned long flags;
-
-                       spin_lock_irqsave(&i915->mm.obj_lock, flags);
+               spin_lock_irqsave(&i915->mm.obj_lock, flags);
+               if (!list_empty(&obj->mm.link)) {
+                       struct list_head *list;
 
                        if (obj->mm.madv != I915_MADV_WILLNEED)
                                list = &i915->mm.purge_list;
@@ -1022,8 +1021,8 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
                                list = &i915->mm.shrink_list;
                        list_move_tail(&obj->mm.link, list);
 
-                       spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
                }
+               spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
        }
 
        /* if the object is no longer attached, discard its backing storage */