From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from youngberry.canonical.com ([91.189.89.112]:46552 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755385AbbI3Jx7 (ORCPT ); Wed, 30 Sep 2015 05:53:59 -0400 From: Luis Henriques To: linux-kernel@vger.kernel.org, stable@vger.kernel.org, kernel-team@lists.ubuntu.com Cc: Chris Wilson , =?UTF-8?q?Micha=C5=82=20Winiarski?= , Daniel Vetter , Jani Nikula , Jani Nikula , Luis Henriques Subject: [PATCH 3.16.y-ckt 080/133] drm/i915: Limit the number of loops for reading a split 64bit register Date: Wed, 30 Sep 2015 10:50:28 +0100 Message-Id: <1443606681-7124-81-git-send-email-luis.henriques@canonical.com> In-Reply-To: <1443606681-7124-1-git-send-email-luis.henriques@canonical.com> References: <1443606681-7124-1-git-send-email-luis.henriques@canonical.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: stable-owner@vger.kernel.org List-ID: 3.16.7-ckt18 -stable review patch. If anyone has any objections, please let me know. ------------------ From: Chris Wilson commit acd29f7b22262d9e848393b9b6ae13eb42d22514 upstream. In I915_READ64_2x32 we attempt to read a 64bit register using 2 32bit reads. Due to the nature of the registers we try to read in this manner, they may increment between the two instruction (e.g. a timestamp counter). To keep the result accurate, we repeat the read if we detect an overflow (i.e. the upper value varies). However, some hardware is just plain flaky and may endless loop as the the upper 32bits are not stable. Just give up after a couple of tries and report whatever we read last. v2: Use the most recent values when erring out on an unstable register. Reported-by: russianneuromancer@ya.ru Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91906 Signed-off-by: Chris Wilson Cc: MichaƂ Winiarski Cc: Daniel Vetter Cc: Jani Nikula Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Signed-off-by: Luis Henriques --- drivers/gpu/drm/i915/i915_drv.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 67f72fa5a769..1378dadc618e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2682,13 +2682,13 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val); #define I915_READ64(reg) dev_priv->uncore.funcs.mmio_readq(dev_priv, (reg), true) #define I915_READ64_2x32(lower_reg, upper_reg) ({ \ - u32 upper, lower, tmp; \ - tmp = I915_READ(upper_reg); \ + u32 upper, lower, old_upper, loop = 0; \ + upper = I915_READ(upper_reg); \ do { \ - upper = tmp; \ + old_upper = upper; \ lower = I915_READ(lower_reg); \ - tmp = I915_READ(upper_reg); \ - } while (upper != tmp); \ + upper = I915_READ(upper_reg); \ + } while (upper != old_upper && loop++ < 2); \ (u64)upper << 32 | lower; }) #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg)