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: 290271de34
("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>
This commit is contained in:
Родитель
28152a238b
Коммит
6cb0c6ad9e
|
@ -43,16 +43,21 @@ static bool shrinker_lock(struct drm_i915_private *dev_priv, bool *unlock)
|
|||
return true;
|
||||
|
||||
case MUTEX_TRYLOCK_FAILED:
|
||||
*unlock = false;
|
||||
preempt_disable();
|
||||
do {
|
||||
cpu_relax();
|
||||
if (mutex_trylock(&dev_priv->drm.struct_mutex)) {
|
||||
case MUTEX_TRYLOCK_SUCCESS:
|
||||
*unlock = true;
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
} while (!need_resched());
|
||||
preempt_enable();
|
||||
return *unlock;
|
||||
|
||||
return false;
|
||||
case MUTEX_TRYLOCK_SUCCESS:
|
||||
*unlock = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
BUG();
|
||||
|
|
Загрузка…
Ссылка в новой задаче