mutex_is_locked_by() checks the owner of the lock against current. This is done by accessing a private member of struct mutex which works on mainline but does not on RT. I did not figure out, why this "lock-owner-check" and the "lock stealing flag" is required. If the lock can not be acquire the lock (because it would deadlock) then it can return -1. The lock stealing makes actually no sense to me. If shrinker_no_lock_stealing is true then the same functions (i915_gem_purge(), i915_gem_shrink_all()) are called from i915_gem_object_create_mmap_offset() as from i915_gem_inactive_shrink(). I haven't found a path in which i915_gem_inactive_shrink() is invoked from i915_gem_object_create_mmap_offset() that means there is no way shrinker_no_lock_stealing is true _and_ the lock is owned by the current process. Since I don't see why the i915 needs this hack while all other user do not I recommend to remove this hack and return -1 in case of a dead lock. Here is the patch. Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de> --- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/i915_gem.c | 32 +++----------------------------- 2 files changed, 3 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 01769e2..47f28ee 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -724,7 +724,6 @@ struct i915_gem_mm { struct i915_hw_ppgtt *aliasing_ppgtt; struct shrinker inactive_shrinker; - bool shrinker_no_lock_stealing; /** * List of objects currently involved in rendering. diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0e207e6..7949517 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1500,8 +1500,6 @@ static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj) if (obj->base.map_list.map) return 0; - dev_priv->mm.shrinker_no_lock_stealing = true; - ret = drm_gem_create_mmap_offset(&obj->base); if (ret != -ENOSPC) goto out; @@ -1521,8 +1519,6 @@ static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj) i915_gem_shrink_all(dev_priv); ret = drm_gem_create_mmap_offset(&obj->base); out: - dev_priv->mm.shrinker_no_lock_stealing = false; - return ret; } @@ -4368,19 +4364,6 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file) spin_unlock(&file_priv->mm.lock); } -static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task) -{ - if (!mutex_is_locked(mutex)) - return false; - -#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES) - return mutex->owner == task; -#else - /* Since UP may be pre-empted, we cannot assume that we own the lock */ - return false; -#endif -} - static int i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) { @@ -4391,18 +4374,10 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) struct drm_device *dev = dev_priv->dev; struct drm_i915_gem_object *obj; int nr_to_scan = sc->nr_to_scan; - bool unlock = true; int cnt; - if (!mutex_trylock(&dev->struct_mutex)) { - if (!mutex_is_locked_by(&dev->struct_mutex, current)) - return 0; - - if (dev_priv->mm.shrinker_no_lock_stealing) - return 0; - - unlock = false; - } + if (!mutex_trylock(&dev->struct_mutex)) + return -1; if (nr_to_scan) { nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan); @@ -4421,7 +4396,6 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) if (obj->pin_count == 0 && obj->pages_pin_count == 0) cnt += obj->base.size >> PAGE_SHIFT; - if (unlock) - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&dev->struct_mutex); return cnt; } -- 1.7.6.5