From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>
Cc: intel-gfx@lists.freedesktop.org, Ben Widawsky <ben@bwidawsk.net>
Subject: Re: [PATCH] drm/i915: Convert the forcewake worker into a timer func
Date: Mon, 3 Mar 2014 16:46:20 +0200 [thread overview]
Message-ID: <20140303144620.GY3852@intel.com> (raw)
In-Reply-To: <1393613043-23213-1-git-send-email-chris@chris-wilson.co.uk>
On Fri, Feb 28, 2014 at 06:44:03PM +0000, Chris Wilson wrote:
> We don't want to suffer scheduling delay when turning off the GPU after
> waking it up to touch registers. Ideally, we only want to keep the GPU
> awake for the register access sequence, with a single forcewake dance on
> the first access and release immediately after the last. We set a timer
> on the first access so that we only dance once and on the next scheduler
> tick, we drop the forcewake again.
>
> This moves the cleanup routine from the common i915 workqueue to a timer
> func so that we don't anger powertop, and drop the forcewake again
> quicker.
>
> v2: Enable the deferred force_wake_put for regular register reads as
> well.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Ben Widawsky <ben@bwidawsk.net>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 2 +-
> drivers/gpu/drm/i915/intel_uncore.c | 34 +++++++++++++++-------------------
> 2 files changed, 16 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index b22765192018..8af8e0dd3943 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -508,7 +508,7 @@ struct intel_uncore {
> unsigned fw_rendercount;
> unsigned fw_mediacount;
>
> - struct delayed_work force_wake_work;
> + struct timer_list force_wake_timer;
> };
>
> #define DEV_INFO_FOR_EACH_FLAG(func, sep) \
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index c62841404c82..8ee171178bfe 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -289,10 +289,8 @@ void vlv_force_wake_put(struct drm_i915_private *dev_priv,
> spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> }
>
> -static void gen6_force_wake_work(struct work_struct *work)
> +static void gen6_force_wake_timer(struct drm_i915_private *dev_priv)
> {
> - struct drm_i915_private *dev_priv =
> - container_of(work, typeof(*dev_priv), uncore.force_wake_work.work);
> unsigned long irqflags;
>
> spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> @@ -405,9 +403,8 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
> spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> if (--dev_priv->uncore.forcewake_count == 0) {
> dev_priv->uncore.forcewake_count++;
> - mod_delayed_work(dev_priv->wq,
> - &dev_priv->uncore.force_wake_work,
> - 1);
> + mod_timer_pinned(&dev_priv->uncore.force_wake_timer,
> + jiffies + 1);
This could expire more or less immediately, but it should be fine. We'd
just end up doing two forcewake_get()s instead of one, which should
still be better than >2 if the theory of the timer holds.
> }
> spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>
> @@ -484,17 +481,15 @@ gen5_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> static u##x \
> gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> REG_READ_HEADER(x); \
> - if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
> - if (dev_priv->uncore.forcewake_count == 0) \
> - dev_priv->uncore.funcs.force_wake_get(dev_priv, \
> - FORCEWAKE_ALL); \
> - val = __raw_i915_read##x(dev_priv, reg); \
> - if (dev_priv->uncore.forcewake_count == 0) \
> - dev_priv->uncore.funcs.force_wake_put(dev_priv, \
> - FORCEWAKE_ALL); \
> - } else { \
> - val = __raw_i915_read##x(dev_priv, reg); \
> + if (dev_priv->uncore.forcewake_count == 0 && \
> + NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
> + dev_priv->uncore.funcs.force_wake_get(dev_priv, \
> + FORCEWAKE_ALL); \
> + dev_priv->uncore.forcewake_count++; \
> + mod_timer_pinned(&dev_priv->uncore.force_wake_timer, \
> + jiffies + 1); \
> } \
> + val = __raw_i915_read##x(dev_priv, reg); \
> REG_READ_FOOTER; \
> }
>
> @@ -681,8 +676,9 @@ void intel_uncore_init(struct drm_device *dev)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
>
> - INIT_DELAYED_WORK(&dev_priv->uncore.force_wake_work,
> - gen6_force_wake_work);
> + setup_timer(&dev_priv->uncore.force_wake_timer,
> + (void (*)(unsigned long))gen6_force_wake_timer,
I'd prefer to do the required casting in gen6_force_wake_timer(). Seems
a bit less error prone since we'd at least get type checking for the
function pointer.
> + (unsigned long)dev_priv);
>
> if (IS_VALLEYVIEW(dev)) {
> dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
> @@ -794,7 +790,7 @@ void intel_uncore_fini(struct drm_device *dev)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
>
> - flush_delayed_work(&dev_priv->uncore.force_wake_work);
> + del_timer_sync(&dev_priv->uncore.force_wake_timer);
This could leave force wake enabled.
>
> /* Paranoia: make sure we have disabled everything before we exit. */
> intel_uncore_sanitize(dev);
> --
> 1.9.0
--
Ville Syrjälä
Intel OTC
next prev parent reply other threads:[~2014-03-03 14:46 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-26 11:06 [PATCH] drm/i915: Delay the relase of the forcewake by a jiffie Chris Wilson
2013-08-26 11:49 ` Ville Syrjälä
2014-02-23 20:12 ` Ben Widawsky
2014-02-24 8:30 ` Chris Wilson
2014-02-24 20:31 ` Ben Widawsky
2014-02-28 9:02 ` [PATCH] drm/i915: Convert the forcewake worker into a timer func Chris Wilson
2014-02-28 9:16 ` Ville Syrjälä
2014-02-28 16:38 ` Chris Wilson
2014-02-28 18:44 ` Chris Wilson
2014-03-03 1:01 ` Ben Widawsky
2014-03-03 7:05 ` Chris Wilson
2014-03-03 14:46 ` Ville Syrjälä [this message]
2014-03-03 14:55 ` Chris Wilson
2014-03-05 12:00 ` Chris Wilson
2014-03-05 12:21 ` Ville Syrjälä
2014-03-05 12:50 ` Daniel Vetter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140303144620.GY3852@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=ben@bwidawsk.net \
--cc=chris@chris-wilson.co.uk \
--cc=intel-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.