Commit d3cb30f8 authored by Thomas Hellström's avatar Thomas Hellström
Browse files

drm/i915/ttm: Fix illegal addition to shrinker list



There's a small window of opportunity during which the adjust_lru()
function can be called with a GEM refcount of zero from the TTM
eviction code. This results in a kernel BUG().

Ensure that we don't attempt to modify the GEM shrinker lists unless
we have a GEM refcount.

Fixes: ebd4a8ec ("drm/i915/ttm: move shrinker management into adjust_lru")
Signed-off-by: default avatarThomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211110085527.1033475-1-thomas.hellstrom@linux.intel.com
parent 498f02b6
Loading
Loading
Loading
Loading
+21 −10
Original line number Original line Diff line number Diff line
@@ -771,7 +771,16 @@ void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj)
	 *
	 *
	 * TODO: consider maybe also bumping the shrinker list here when we have
	 * TODO: consider maybe also bumping the shrinker list here when we have
	 * already unpinned it, which should give us something more like an LRU.
	 * already unpinned it, which should give us something more like an LRU.
	 *
	 * TODO: There is a small window of opportunity for this function to
	 * get called from eviction after we've dropped the last GEM refcount,
	 * but before the TTM deleted flag is set on the object. Avoid
	 * adjusting the shrinker list in such cases, since the object is
	 * not available to the shrinker anyway due to its zero refcount.
	 * To fix this properly we should move to a TTM shrinker LRU list for
	 * these objects.
	 */
	 */
	if (kref_get_unless_zero(&obj->base.refcount)) {
		if (shrinkable != obj->mm.ttm_shrinkable) {
		if (shrinkable != obj->mm.ttm_shrinkable) {
			if (shrinkable) {
			if (shrinkable) {
				if (obj->mm.madv == I915_MADV_WILLNEED)
				if (obj->mm.madv == I915_MADV_WILLNEED)
@@ -784,6 +793,8 @@ void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj)


			obj->mm.ttm_shrinkable = shrinkable;
			obj->mm.ttm_shrinkable = shrinkable;
		}
		}
		i915_gem_object_put(obj);
	}


	/*
	/*
	 * Put on the correct LRU list depending on the MADV status
	 * Put on the correct LRU list depending on the MADV status