diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-08-04 06:41:35 -0400 |
---|---|---|
committer | Jani Nikula <jani.nikula@intel.com> | 2017-08-07 06:38:56 -0400 |
commit | cd82f37a9ddaaafb33d8bc3f44857edbad5d52bf (patch) | |
tree | fe4ac7530bfd8cde14873c3844aa29f04890e4f0 | |
parent | b5fa57ddc4a2492441a1391f07d5c8a282271249 (diff) |
drm/i915/shrinker: Wrap need_resched() inside preempt-disable
In order for us to successfully detect the end of a timeslice,
preemption must be disabled. Otherwise, inside the loop we may be
preempted many times without our noticing, and each time our timeslice
will be reset, invalidating need_resched()
Reported-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reported-by: Tomi Sarvela <tomi.p.sarvela@intel.com>
Fixes: 290271de34f6 ("drm/i915: Spin for struct_mutex inside shrinker")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: <drm-intel-fixes@lists.freedesktop.org> # v4.13-rc1+
Link: https://patchwork.freedesktop.org/patch/msgid/20170804104135.26805-1-chris@chris-wilson.co.uk
Tested-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
(cherry picked from commit 6cb0c6ad9e07f2c7971c4e8e0d9b7ceba151a925)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_shrinker.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 1032f98add11..77fb39808131 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c | |||
@@ -43,16 +43,21 @@ static bool shrinker_lock(struct drm_i915_private *dev_priv, bool *unlock) | |||
43 | return true; | 43 | return true; |
44 | 44 | ||
45 | case MUTEX_TRYLOCK_FAILED: | 45 | case MUTEX_TRYLOCK_FAILED: |
46 | *unlock = false; | ||
47 | preempt_disable(); | ||
46 | do { | 48 | do { |
47 | cpu_relax(); | 49 | cpu_relax(); |
48 | if (mutex_trylock(&dev_priv->drm.struct_mutex)) { | 50 | if (mutex_trylock(&dev_priv->drm.struct_mutex)) { |
49 | case MUTEX_TRYLOCK_SUCCESS: | ||
50 | *unlock = true; | 51 | *unlock = true; |
51 | return true; | 52 | break; |
52 | } | 53 | } |
53 | } while (!need_resched()); | 54 | } while (!need_resched()); |
55 | preempt_enable(); | ||
56 | return *unlock; | ||
54 | 57 | ||
55 | return false; | 58 | case MUTEX_TRYLOCK_SUCCESS: |
59 | *unlock = true; | ||
60 | return true; | ||
56 | } | 61 | } |
57 | 62 | ||
58 | BUG(); | 63 | BUG(); |