From patchwork Wed Apr 6 09:33:12 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 8759951 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 8750F9F36E for ; Wed, 6 Apr 2016 09:33:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 88B5920149 for ; Wed, 6 Apr 2016 09:33:20 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 703CE20131 for ; Wed, 6 Apr 2016 09:33:19 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0F30A6E8BA; Wed, 6 Apr 2016 09:33:19 +0000 (UTC) X-Original-To: Intel-gfx@lists.freedesktop.org Delivered-To: Intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id 5699C6E8BA for ; Wed, 6 Apr 2016 09:33:18 +0000 (UTC) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 06 Apr 2016 02:33:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,447,1455004800"; d="scan'208";a="939374375" Received: from tursulin-linux.isw.intel.com ([10.102.226.196]) by fmsmga001.fm.intel.com with ESMTP; 06 Apr 2016 02:33:16 -0700 From: Tvrtko Ursulin To: Intel-gfx@lists.freedesktop.org Date: Wed, 6 Apr 2016 10:33:12 +0100 Message-Id: <1459935194-2318-1-git-send-email-tvrtko.ursulin@linux.intel.com> X-Mailer: git-send-email 1.9.1 Subject: [Intel-gfx] [PATCH resend-for-CI 1/3] drm/i915: Use consistent forcewake auto-release timeout across kernel configs X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-5.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Tvrtko Ursulin Because it is based on jiffies, current implementation releases the forcewake at any time between straight away and between 1ms and 10ms, depending on the kernel configuration (CONFIG_HZ). This is probably not what has been desired, since the dynamics of keeping parts of the GPU awake should not be correlated with this kernel configuration parameter. Change the auto-release mechanism to use hrtimers and set the timeout to 1ms with a 1ms of slack. This should make the GPU power consistent across kernel configs, and timer slack should enable some timer coalescing where multiple force-wake domains exist, or with unrelated timers. For GlBench/T-Rex this decreases the number of forcewake releases from ~480 to ~300 per second, and for a heavy combined OGL/OCL test from ~670 to ~360 (HZ=1000 kernel). Even though this reduction can be attributed to the average release period extending from 0-1ms to 1-2ms, as discussed above, it will make the forcewake timeout consistent for different CONFIG_HZ values. Real life measurements with the above workload has shown that, with this patch, both manage to auto-release the forcewake between 2-4 times per 10ms, even though the number of forcewake gets is dramatically different. T-Rex requests between 5-10 explicit gets and 5-10 implict gets in each 10ms period, while the OGL/OCL test requests 250 and 380 times in the same period. The two data points together suggest that the nature of the forwake accesses is bursty and that further changes and potential timeout extensions, or moving the start of timeout from the first to the last automatic forcewake grab, should be carefully measured for power and performance effects. v2: * Commit spelling. (Dave Gordon) * More discussion on numbers in the commit. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Reviewed-by: Dave Gordon Cc: Chris Wilson Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_uncore.c | 25 ++++++++++++++++--------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 313bc3576d87..8ee5f78d45bc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -666,7 +666,7 @@ struct intel_uncore { struct drm_i915_private *i915; enum forcewake_domain_id id; unsigned wake_count; - struct timer_list timer; + struct hrtimer timer; i915_reg_t reg_set; u32 val_set; u32 val_clear; diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index fbc1d215ca67..2e3e92469947 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -60,7 +60,11 @@ fw_domain_reset(const struct intel_uncore_forcewake_domain *d) static inline void fw_domain_arm_timer(struct intel_uncore_forcewake_domain *d) { - mod_timer_pinned(&d->timer, jiffies + 1); + d->wake_count++; + hrtimer_start_range_ns(&d->timer, + ktime_set(0, NSEC_PER_MSEC), + NSEC_PER_MSEC, + HRTIMER_MODE_REL); } static inline void @@ -224,9 +228,11 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) return ret; } -static void intel_uncore_fw_release_timer(unsigned long arg) +static enum hrtimer_restart +intel_uncore_fw_release_timer(struct hrtimer *timer) { - struct intel_uncore_forcewake_domain *domain = (void *)arg; + struct intel_uncore_forcewake_domain *domain = + container_of(timer, struct intel_uncore_forcewake_domain, timer); unsigned long irqflags; assert_rpm_device_not_suspended(domain->i915); @@ -240,6 +246,8 @@ static void intel_uncore_fw_release_timer(unsigned long arg) 1 << domain->id); spin_unlock_irqrestore(&domain->i915->uncore.lock, irqflags); + + return HRTIMER_NORESTART; } void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore) @@ -259,16 +267,16 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore) active_domains = 0; for_each_fw_domain(domain, dev_priv, id) { - if (del_timer_sync(&domain->timer) == 0) + if (hrtimer_cancel(&domain->timer) == 0) continue; - intel_uncore_fw_release_timer((unsigned long)domain); + intel_uncore_fw_release_timer(&domain->timer); } spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); for_each_fw_domain(domain, dev_priv, id) { - if (timer_pending(&domain->timer)) + if (hrtimer_active(&domain->timer)) active_domains |= (1 << id); } @@ -491,7 +499,6 @@ static void __intel_uncore_forcewake_put(struct drm_i915_private *dev_priv, if (--domain->wake_count) continue; - domain->wake_count++; fw_domain_arm_timer(domain); } } @@ -732,7 +739,6 @@ static inline void __force_wake_auto(struct drm_i915_private *dev_priv, continue; } - domain->wake_count++; fw_domain_arm_timer(domain); } @@ -1150,7 +1156,8 @@ static void fw_domain_init(struct drm_i915_private *dev_priv, d->i915 = dev_priv; d->id = domain_id; - setup_timer(&d->timer, intel_uncore_fw_release_timer, (unsigned long)d); + hrtimer_init(&d->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + d->timer.function = intel_uncore_fw_release_timer; dev_priv->uncore.fw_domains |= (1 << domain_id);