From patchwork Thu Aug 9 14:44:54 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 1301041 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id A5E28DFF7B for ; Thu, 9 Aug 2012 14:28:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 89A66A0E66 for ; Thu, 9 Aug 2012 07:28:17 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-we0-f177.google.com (mail-we0-f177.google.com [74.125.82.177]) by gabe.freedesktop.org (Postfix) with ESMTP id 666539E936 for ; Thu, 9 Aug 2012 07:28:04 -0700 (PDT) Received: by weyr3 with SMTP id r3so354319wey.36 for ; Thu, 09 Aug 2012 07:28:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=gY6kOmKzH0wi+Cbmxddc9IkIEcAsYGrL8Lf8gE7juYM=; b=HpfgZ/k6fBk6WoR1oozaOE//gYMyqp1KYTpUEpPVLYihQ9tQpLYe+TfulJDCqWOZ/C YLeLcUvqY+9EgfA+7XrttrRgQEimgDQ4xP+O1E1KMCna00QuCtfQFb7jw92GrpbxTfl3 zJBRkzWwgIdHpdlX+TAuFF4ktrtvr1zAkoQS4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=gY6kOmKzH0wi+Cbmxddc9IkIEcAsYGrL8Lf8gE7juYM=; b=V69HsgFKtGSSZ645QILAVVtdSSVlwPeIyzBRQjE1ceG8UHsCxFg+UBdAE7FotxcTcq xrPf70+uTsB8+i2jR7Wrpz8CYsS0W2E3KHw9OVSLGXzkP6pZXCGb9ULglXGGCGb7XSON RYuXjPH5XrNQLInic1AfyzPxb1BWUH0Z0JnpSWul0g1bYQg4topSL2LkfSFU/DQoejUh aEo5i0TETvP8hQznAGCnnpjMMIKWIyV3OHt+x3dli3ITAxkoRjnvuWIQ5iFranaGU7zJ aAxfxwW+md4DtbOkKscMd3wZHSGqDvdH5zPpua6GKGpgB0upfE/b3OmqM5c7F6Bj6rYg zRzw== Received: by 10.180.82.39 with SMTP id f7mr3445151wiy.2.1344522483630; Thu, 09 Aug 2012 07:28:03 -0700 (PDT) Received: from hummel.ffwll.local (178-83-130-250.dynamic.hispeed.ch. [178.83.130.250]) by mx.google.com with ESMTPS id eu4sm1966466wib.2.2012.08.09.07.28.02 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 09 Aug 2012 07:28:02 -0700 (PDT) From: Daniel Vetter To: Intel Graphics Development Date: Thu, 9 Aug 2012 16:44:54 +0200 Message-Id: <1344523494-32702-1-git-send-email-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1344461740-1231-2-git-send-email-daniel.vetter@ffwll.ch> References: <1344461740-1231-2-git-send-email-daniel.vetter@ffwll.ch> X-Gm-Message-State: ALoCoQmbykg6p7dQ4wBrWimbVQMMuWvxjQ2mWIb4qJ3chM8OKinRMsEzZY84aksHUc8iD9b6xBs0 Cc: Daniel Vetter Subject: [Intel-gfx] [PATCH] drm/i915: properly guard ilk ips state X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org The update_gfx_val function called from mark_busy wasn't taking the mchdev_lock, as it should have. Also sprinkle a few spinlock asserts over the code to document things better. Things are still rather confusing, especially since a few variables in dev_priv are used by both the gen6+ rps code and the ilk ips code. But protected by totally different locks. Follow-on patches will clean that up. v2: Don't add a deadlock ... hence split up update_gfx_val into a wrapper that grabs the lock and an internal __ variant for callsites within intel_pm.c that already have taken the lock. v3: Mark the internal helper as static, noticed by Ben Widawsky. v4: Damien Lespiau had questions about the safety of the ips setup sequence, explain in a comment why it works. Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 52 +++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 5050bb8..ec3fe92 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2710,6 +2710,21 @@ static const struct cparams { { 0, 800, 231, 23784 }, }; +/** + * Lock protecting IPS related data structures + * - i915_mch_dev + * - dev_priv->max_delay + * - dev_priv->min_delay + * - dev_priv->fmax + * - dev_priv->gpu_busy + * - dev_priv->gfx_power + */ +static DEFINE_SPINLOCK(mchdev_lock); + +/* Global for IPS driver to get at the current i915 device. Protected by + * mchdev_lock. */ +static struct drm_i915_private *i915_mch_dev; + unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) { u64 total_count, diff, ret; @@ -2717,6 +2732,8 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) unsigned long now = jiffies_to_msecs(jiffies), diff1; int i; + assert_spin_locked(&mchdev_lock); + diff1 = now - dev_priv->last_time1; /* Prevent division-by-zero if we are asking too fast. @@ -2918,15 +2935,14 @@ static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) return v_table[pxvid].vd; } -void i915_update_gfx_val(struct drm_i915_private *dev_priv) +static void __i915_update_gfx_val(struct drm_i915_private *dev_priv) { struct timespec now, diff1; u64 diff; unsigned long diffms; u32 count; - if (dev_priv->info->gen != 5) - return; + assert_spin_locked(&mchdev_lock); getrawmonotonic(&now); diff1 = timespec_sub(now, dev_priv->last_time2); @@ -2954,11 +2970,25 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv) dev_priv->gfx_power = diff; } +void i915_update_gfx_val(struct drm_i915_private *dev_priv) +{ + if (dev_priv->info->gen != 5) + return; + + spin_lock(&mchdev_lock); + + __i915_update_gfx_val(dev_priv); + + spin_unlock(&mchdev_lock); +} + unsigned long i915_gfx_val(struct drm_i915_private *dev_priv) { unsigned long t, corr, state1, corr2, state2; u32 pxvid, ext_v; + assert_spin_locked(&mchdev_lock); + pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->cur_delay * 4)); pxvid = (pxvid >> 24) & 0x7f; ext_v = pvid_to_extvid(dev_priv, pxvid); @@ -2984,23 +3014,11 @@ unsigned long i915_gfx_val(struct drm_i915_private *dev_priv) state2 = (corr2 * state1) / 10000; state2 /= 100; /* convert to mW */ - i915_update_gfx_val(dev_priv); + __i915_update_gfx_val(dev_priv); return dev_priv->gfx_power + state2; } -/* Global for IPS driver to get at the current i915 device */ -static struct drm_i915_private *i915_mch_dev; -/* - * Lock protecting IPS related data structures - * - i915_mch_dev - * - dev_priv->max_delay - * - dev_priv->min_delay - * - dev_priv->fmax - * - dev_priv->gpu_busy - */ -static DEFINE_SPINLOCK(mchdev_lock); - /** * i915_read_mch_val - return value for IPS use * @@ -3163,6 +3181,8 @@ ips_ping_for_i915_load(void) void intel_gpu_ips_init(struct drm_i915_private *dev_priv) { + /* We only register the i915 ips part with intel-ips once everything is + * set up, to avoid intel-ips sneaking in and reading bogus values. */ spin_lock(&mchdev_lock); i915_mch_dev = dev_priv; dev_priv->mchdev_lock = &mchdev_lock;