From: "Nicolas Kalkhof" <nkalkhof@web.de>
To: intel-gfx <intel-gfx@lists.freedesktop.org>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Subject: Re: [PATCH] drm/i915: protect force_wake_(get|put) with the gt_lock
Date: Sun, 6 Nov 2011 18:42:00 +0100 (CET) [thread overview]
Message-ID: <286366260.978244.1320601320728.JavaMail.fmail@mwmweb016> (raw)
Hi Daniel,
is there a specific git branch availble where I can test your patch? I'm also experiencing random forcewake hangs and would like to see if your patch helps.
Thanks
Nic
-----Ursprüngliche Nachricht-----
Von: "Daniel Vetter" <daniel.vetter@ffwll.ch>
Gesendet: Nov 6, 2011 1:35:22 PM
An: intel-gfx <intel-gfx@lists.freedesktop.org>
Betreff: [Intel-gfx] [PATCH] drm/i915: protect force_wake_(get|put) with the gt_lock
>The problem this patch solves is that the forcewake accounting
>necessary for register reads is protected by dev->struct_mutex. But the
>hangcheck and error_capture code need to access registers without
>grabbing this mutex because we hold it while waiting for the gpu.
>So a new lock is required. Because currently the error_state capture
>is called from the error irq handler and the hangcheck code runs from
>a timer, it needs to be an irqsafe spinlock (note that the registers
>used by the irq handler (neglecting the error handling part) only uses
>registers that don't need the forcewake dance).
>
>We could tune this down to a normal spinlock when we rework the
>error_state capture and hangcheck code to run from a workqueue. But
>we don't have any read in a fastpath that needs forcewake, so I've
>decided to not care much about overhead.
>
>This prevents tests/gem_hangcheck_forcewake from i-g-t from killing my
>snb on recent kernels - something must have slightly changed the
>timings. On previous kernels it only trigger a WARN about the broken
>locking.
>
>v2: Drop the previous patch for the register writes.
>
>v3: Improve the commit message per Chris Wilson's suggestions.
>
>Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>---
> drivers/gpu/drm/i915/i915_debugfs.c | 8 ++++++--
> drivers/gpu/drm/i915/i915_dma.c | 1 +
> drivers/gpu/drm/i915/i915_drv.c | 19 +++++++++++++------
> drivers/gpu/drm/i915/i915_drv.h | 10 +++++++---
> 4 files changed, 27 insertions(+), 11 deletions(-)
>
>diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
>index 5ba63ad..51b21eb 100644
>--- a/drivers/gpu/drm/i915/i915_debugfs.c
>+++ b/drivers/gpu/drm/i915/i915_debugfs.c
>@@ -1320,9 +1320,13 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
> struct drm_info_node *node = (struct drm_info_node *) m->private;
> struct drm_device *dev = node->minor->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
>+ unsigned forcewake_count;
>
>- seq_printf(m, "forcewake count = %d\n",
>- atomic_read(&dev_priv->forcewake_count));
>+ spin_lock_irq(&dev_priv->gt_lock);
>+ forcewake_count = dev_priv->forcewake_count;
>+ spin_unlock_irq(&dev_priv->gt_lock);
>+
>+ seq_printf(m, "forcewake count = %d\n", forcewake_count);
>
> return 0;
> }
>diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
>index 2eac955..ab3a3fd 100644
>--- a/drivers/gpu/drm/i915/i915_dma.c
>+++ b/drivers/gpu/drm/i915/i915_dma.c
>@@ -2031,6 +2031,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
> if (!IS_I945G(dev) && !IS_I945GM(dev))
> pci_enable_msi(dev->pdev);
>
>+ spin_lock_init(&dev_priv->gt_lock);
> spin_lock_init(&dev_priv->irq_lock);
> spin_lock_init(&dev_priv->error_lock);
> spin_lock_init(&dev_priv->rps_lock);
>diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
>index 548e04b..bab4e08 100644
>--- a/drivers/gpu/drm/i915/i915_drv.c
>+++ b/drivers/gpu/drm/i915/i915_drv.c
>@@ -351,11 +351,12 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
> */
> void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
> {
>- WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
>+ unsigned long irqflags;
>
>- /* Forcewake is atomic in case we get in here without the lock */
>- if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
>+ spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
>+ if (dev_priv->forcewake_count++ == 0)
> __gen6_gt_force_wake_get(dev_priv);
>+ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
> }
>
> static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
>@@ -369,10 +370,13 @@ static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
> */
> void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
> {
>- WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
>+ unsigned long irqflags;
>
>- if (atomic_dec_and_test(&dev_priv->forcewake_count))
>+ spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
>+
>+ if (--dev_priv->forcewake_count == 0)
> __gen6_gt_force_wake_put(dev_priv);
>+ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
> }
>
> void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
>@@ -603,6 +607,7 @@ int i915_reset(struct drm_device *dev, u8 flags)
> * need to
> */
> bool need_display = true;
>+ unsigned long irqflags;
> int ret;
>
> if (!i915_try_reset)
>@@ -621,8 +626,10 @@ int i915_reset(struct drm_device *dev, u8 flags)
> case 6:
> ret = gen6_do_reset(dev, flags);
> /* If reset with a user forcewake, try to restore */
>- if (atomic_read(&dev_priv->forcewake_count))
>+ spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
>+ if (dev_priv->forcewake_count)
> __gen6_gt_force_wake_get(dev_priv);
>+ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
> break;
> case 5:
> ret = ironlake_do_reset(dev, flags);
>diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>index bd98fb3..25036f5 100644
>--- a/drivers/gpu/drm/i915/i915_drv.h
>+++ b/drivers/gpu/drm/i915/i915_drv.h
>@@ -276,7 +276,13 @@ typedef struct drm_i915_private {
> int relative_constants_mode;
>
> void __iomem *regs;
>- u32 gt_fifo_count;
>+ /** gt_fifo_count and the subsequent register write are synchronized
>+ * with dev->struct_mutex. */
>+ unsigned gt_fifo_count;
>+ /** forcewake_count is protected by gt_lock */
>+ unsigned forcewake_count;
>+ /** gt_lock is also taken in irq contexts. */
>+ struct spinlock gt_lock;
>
> struct intel_gmbus {
> struct i2c_adapter adapter;
>@@ -725,8 +731,6 @@ typedef struct drm_i915_private {
>
> struct drm_property *broadcast_rgb_property;
> struct drm_property *force_audio_property;
>-
>- atomic_t forcewake_count;
> } drm_i915_private_t;
>
> enum i915_cache_level {
>--
>1.7.6.4
>
>_______________________________________________
>Intel-gfx mailing list
>Intel-gfx@lists.freedesktop.org
>http://lists.freedesktop.org/mailman/listinfo/intel-gfx
___________________________________________________________
SMS schreiben mit WEB.DE FreeMail - einfach, schnell und
kostenguenstig. Jetzt gleich testen! http://f.web.de/?mc=021192
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
next reply other threads:[~2011-11-06 17:42 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-06 17:42 Nicolas Kalkhof [this message]
2011-11-06 17:46 ` [PATCH] drm/i915: protect force_wake_(get|put) with the gt_lock Daniel Vetter
-- strict thread matches above, loose matches on Subject: below --
2011-11-09 16:22 Nicolas Kalkhof
2011-11-09 16:28 ` Daniel Vetter
2011-11-07 18:14 Nicolas Kalkhof
2011-11-07 18:36 ` Daniel Vetter
2011-11-07 17:31 Nicolas Kalkhof
2011-11-07 16:39 Nicolas Kalkhof
2011-11-07 16:56 ` Daniel Vetter
2011-11-07 13:52 Nicolas Kalkhof
2011-11-07 16:05 ` Daniel Vetter
2011-11-06 10:46 [PATCH 1/2] drm/i915: properly lock gt_fifo_count Daniel Vetter
2011-11-06 11:31 ` [PATCH] drm/i915: protect force_wake_(get|put) with the gt_lock Daniel Vetter
2011-11-06 11:57 ` Chris Wilson
2011-11-06 12:35 ` Daniel Vetter
2011-11-06 21:01 ` Chris Wilson
2011-11-06 22:06 ` 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=286366260.978244.1320601320728.JavaMail.fmail@mwmweb016 \
--to=nkalkhof@web.de \
--cc=daniel.vetter@ffwll.ch \
--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.