提交 05646543 编写于 作者: C Chris Wilson

drm/i915: Acquire uncore.lock over intel_uncore_wait_for_register()

We acquire the forcewake and use I915_READ_FW instead for the atomic
wait within intel_uncore_wait_for_register. However, this still leaves
us vulnerable to concurrent mmio access to the register, which can cause
system hangs on gen7. The protection is to acquire uncore.lock around
each register, so lets add it back.

v2: Wrap __intel_wait_for_register_fw() to re-use its atomic wait_for
loop and spare adding another for ourselves.
v3: Add might_sleep() annotation
Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170411101340.31994-3-chris@chris-wilson.co.ukReviewed-by: NTvrtko Ursulin <tvrtko.ursulin@intel.com>
上级 02b312d0
......@@ -1662,14 +1662,22 @@ int intel_wait_for_register(struct drm_i915_private *dev_priv,
u32 value,
unsigned int timeout_ms)
{
unsigned fw =
intel_uncore_forcewake_for_reg(dev_priv, reg, FW_REG_READ);
int ret;
intel_uncore_forcewake_get(dev_priv, fw);
ret = wait_for_us((I915_READ_FW(reg) & mask) == value, 2);
intel_uncore_forcewake_put(dev_priv, fw);
might_sleep();
spin_lock_irq(&dev_priv->uncore.lock);
intel_uncore_forcewake_get__locked(dev_priv, fw);
ret = __intel_wait_for_register_fw(dev_priv,
reg, mask, value,
2, 0, NULL);
intel_uncore_forcewake_put__locked(dev_priv, fw);
spin_unlock_irq(&dev_priv->uncore.lock);
if (ret)
ret = wait_for((I915_READ_NOTRACE(reg) & mask) == value,
timeout_ms);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册