All of lore.kernel.org
 help / color / mirror / Atom feed
* enabling forcewake from userspace
@ 2011-03-26  2:07 Ben Widawsky
  2011-03-26  2:07 ` [PATCH] drm/i915: have a forcewake "refcount" Ben Widawsky
  2011-03-26  2:23 ` enabling forcewake from userspace Ben Widawsky
  0 siblings, 2 replies; 8+ messages in thread
From: Ben Widawsky @ 2011-03-26  2:07 UTC (permalink / raw)
  To: intel-gfx


Chris, do you already have something like this queued up?

I don't have a SNB with which to test this patch right now. I'd like to
know if anyone has any major issues with this, because I intend to use
this to enable userspace to properly read and write registers on SNB.

Also if you see any glaring issues before I get to testing it, might as
well point them out now :p

Ben

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] drm/i915: have a forcewake "refcount"
  2011-03-26  2:07 enabling forcewake from userspace Ben Widawsky
@ 2011-03-26  2:07 ` Ben Widawsky
  2011-03-26  2:23 ` enabling forcewake from userspace Ben Widawsky
  1 sibling, 0 replies; 8+ messages in thread
From: Ben Widawsky @ 2011-03-26  2:07 UTC (permalink / raw)
  To: intel-gfx

On Gen6, forcewake must be used to ensure certain HW bits are powered to
process commands (such as register writes). Forcewake should be
persistent according to the spec, so it is unnecessary to set it more
than once.

Further this "refcount" allows a userspace interaction with this part of
the HW (for say, reading and writing registers).

Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_debugfs.c |   11 +++++++++++
 drivers/gpu/drm/i915/i915_dma.c     |    3 +++
 drivers/gpu/drm/i915/i915_drv.c     |   24 ++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.h     |    4 ++++
 4 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 87c8e29..91ff99c 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1186,6 +1186,16 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
 	return 0;
 }
 
+static int i915_forcewake_count_info(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	seq_printf(m, "forcewake_count: %d\n",
+		   dev_priv->gen6_gt_forcewake_count);
+	return 0;
+}
+
 static int
 i915_wedged_open(struct inode *inode,
 		 struct file *filp)
@@ -1324,6 +1334,7 @@ static struct drm_info_list i915_debugfs_list[] = {
 	{"i915_sr_status", i915_sr_status, 0},
 	{"i915_opregion", i915_opregion, 0},
 	{"i915_gem_framebuffer", i915_gem_framebuffer_info, 0},
+	{"i915_forcewake_count", i915_forcewake_count_info, 0},
 };
 #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
 
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 7273037..35e0eaf 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -2026,6 +2026,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 	spin_lock_init(&dev_priv->irq_lock);
 	spin_lock_init(&dev_priv->error_lock);
 
+	if (IS_GEN6(dev))
+		spin_lock_init(&dev_priv->gen6_gt_forcewake_lock);
+
 	if (IS_MOBILE(dev) || !IS_GEN2(dev))
 		dev_priv->num_pipe = 2;
 	else
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index c34a8dd..d8da39f 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -266,6 +266,17 @@ void intel_detect_pch (struct drm_device *dev)
 void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
 {
 	int count;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->gen6_gt_forcewake_lock, flags);
+	if (++dev_priv->gen6_gt_forcewake_count > 1) {
+		count = 0;
+		while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
+			udelay(10);
+		spin_unlock_irqrestore(&dev_priv->gen6_gt_forcewake_lock, flags);
+		return;
+	}
+	WARN_ON(dev_priv->gen6_gt_forcewake_count != 1);
 
 	count = 0;
 	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
@@ -277,12 +288,25 @@ void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
 	count = 0;
 	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0)
 		udelay(10);
+
+	spin_unlock_irqrestore(&dev_priv->gen6_gt_forcewake_lock, flags);
 }
 
 void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->gen6_gt_forcewake_lock, flags);
+	if (--dev_priv->gen6_gt_forcewake_count > 0) {
+		spin_unlock_irqrestore(&dev_priv->gen6_gt_forcewake_lock, flags);
+		return;
+	}
+	WARN_ON(dev_priv->gen6_gt_forcewake_count != 0);
+
 	I915_WRITE_NOTRACE(FORCEWAKE, 0);
 	POSTING_READ(FORCEWAKE);
+
+	spin_unlock_irqrestore(&dev_priv->gen6_gt_forcewake_lock, flags);
 }
 
 void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5004724..f37bacd 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -703,6 +703,10 @@ typedef struct drm_i915_private {
 	struct intel_fbdev *fbdev;
 
 	struct drm_property *broadcast_rgb_property;
+
+	/* gen6 forcewake state */
+	spinlock_t gen6_gt_forcewake_lock;
+	int gen6_gt_forcewake_count;
 } drm_i915_private_t;
 
 struct drm_i915_gem_object {
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: enabling forcewake from userspace
  2011-03-26  2:07 enabling forcewake from userspace Ben Widawsky
  2011-03-26  2:07 ` [PATCH] drm/i915: have a forcewake "refcount" Ben Widawsky
@ 2011-03-26  2:23 ` Ben Widawsky
  2011-03-26  7:11   ` Chris Wilson
  1 sibling, 1 reply; 8+ messages in thread
From: Ben Widawsky @ 2011-03-26  2:23 UTC (permalink / raw)
  To: intel-gfx

On Fri, Mar 25, 2011 at 07:07:48PM -0700, Ben Widawsky wrote:
> 
> Chris, do you already have something like this queued up?
> 
> I don't have a SNB with which to test this patch right now. I'd like to
> know if anyone has any major issues with this, because I intend to use
> this to enable userspace to properly read and write registers on SNB.

So right after hitting 'y' I realized how much I detest this. It leaves
buggy usespace the opportunity to allow the GPU to never sleep. However,
I'd really like to find a solution to allow intel_reg_read and
intel_reg_write to work properly on GEN6.

Chris' idea from IRC of using LOAD/STORE_REGISTER will not work unless
we use a secure batch buffer.

The only other option floating around is IOCTLs to read/write the
registers, which previously seemed like a bad idea, but is now looking
like the only option.

Ben

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: enabling forcewake from userspace
  2011-03-26  2:23 ` enabling forcewake from userspace Ben Widawsky
@ 2011-03-26  7:11   ` Chris Wilson
  2011-03-26 15:46     ` Ben Widawsky
  0 siblings, 1 reply; 8+ messages in thread
From: Chris Wilson @ 2011-03-26  7:11 UTC (permalink / raw)
  To: Ben Widawsky, intel-gfx

On Fri, 25 Mar 2011 19:23:58 -0700, Ben Widawsky <ben@bwidawsk.net> wrote:
> The only other option floating around is IOCTLs to read/write the
> registers, which previously seemed like a bad idea, but is now looking
> like the only option.

The lazy option is to cross your fingers and do the forced-wake from
userspace debug tools. I'm not exactly wild about the idea, but it does
cut down on the number of blessed interfaces for touching hardware.

The other option is to continue to extend the debugfs to print out groups
of registers of interest. Maybe this would be a good addition to the
i915_*_ringbuffer_info?

An ioctl does seem to be a better longterm solution. But maybe we can
ignore the problem for a few more years? ;-)
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: enabling forcewake from userspace
  2011-03-26  7:11   ` Chris Wilson
@ 2011-03-26 15:46     ` Ben Widawsky
  2011-03-26 17:18       ` Chris Wilson
  0 siblings, 1 reply; 8+ messages in thread
From: Ben Widawsky @ 2011-03-26 15:46 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Sat, Mar 26, 2011 at 07:11:55AM +0000, Chris Wilson wrote:
> On Fri, 25 Mar 2011 19:23:58 -0700, Ben Widawsky <ben@bwidawsk.net> wrote:
> > The only other option floating around is IOCTLs to read/write the
> > registers, which previously seemed like a bad idea, but is now looking
> > like the only option.
> 
> The lazy option is to cross your fingers and do the forced-wake from
> userspace debug tools. I'm not exactly wild about the idea, but it does
> cut down on the number of blessed interfaces for touching hardware.
> 
> The other option is to continue to extend the debugfs to print out groups
> of registers of interest. Maybe this would be a good addition to the
> i915_*_ringbuffer_info?
This still leaves the reg write problem unsolved. But I think this is
better.

> 
> An ioctl does seem to be a better longterm solution. But maybe we can
> ignore the problem for a few more years? ;-)
I think I won't bother trying to upstream my solution. But I'm also
thinking we should make intel_reg_read/write print a warning/error if
it's running on GEN6? What do you think?


By the way, I do think the patch is beneficial just for kernel usage.
Right now it doesn't matter, but as more users of the interface pop up,
particularly in any time sensitive code... wouldn't it be awful if the
GPU could powerdown while we're servicing an interrupt?

(The patch probably doesn't need the poll when forceawake_ack is already
set, that was a copy/paste mistake.)

> -Chris

Ben

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: enabling forcewake from userspace
  2011-03-26 15:46     ` Ben Widawsky
@ 2011-03-26 17:18       ` Chris Wilson
  2011-03-26 19:27         ` Ben Widawsky
  0 siblings, 1 reply; 8+ messages in thread
From: Chris Wilson @ 2011-03-26 17:18 UTC (permalink / raw)
  To: Ben Widawsky; +Cc: intel-gfx

On Sat, 26 Mar 2011 08:46:25 -0700, Ben Widawsky <ben@bwidawsk.net> wrote:
> I think I won't bother trying to upstream my solution. But I'm also
> thinking we should make intel_reg_read/write print a warning/error if
> it's running on GEN6? What do you think?

Adding a code comment or an
if (IS_GEN6 && reg < 0x40000 && FORCE_WAKE == 0) printf("Muppet!\n");
is about as far as I would go. Certainly don't remind us on every
invocation.

> By the way, I do think the patch is beneficial just for kernel usage.
> Right now it doesn't matter, but as more users of the interface pop up,
> particularly in any time sensitive code... wouldn't it be awful if the
> GPU could powerdown while we're servicing an interrupt?

The GPU is definitely allowed to be powered down whilst the CPU is
servicing an interrupt. ;-) I take your point though that the current
method is not interrupt safe. However, we should not be doing such work
from an interrupt handler - if need be all the actual work is kicked off
from a workqueue.

Something we need to keep an eye on, but not a problem today. *touch wood*
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: enabling forcewake from userspace
  2011-03-26 17:18       ` Chris Wilson
@ 2011-03-26 19:27         ` Ben Widawsky
  2011-03-26 20:20           ` Chris Wilson
  0 siblings, 1 reply; 8+ messages in thread
From: Ben Widawsky @ 2011-03-26 19:27 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Sat, Mar 26, 2011 at 05:18:57PM +0000, Chris Wilson wrote:
> 
> The GPU is definitely allowed to be powered down whilst the CPU is
> servicing an interrupt. ;-) I take your point though that the current
> method is not interrupt safe. However, we should not be doing such work
> from an interrupt handler - if need be all the actual work is kicked off
> from a workqueue.
> 
> Something we need to keep an eye on, but not a problem today. *touch wood*

Efficiency aside, workqueue suffers from the same hazard. Unless the
assumption is struct_mutex (or something similar) is protecting all
register access which are in the power wells that can get disabled. My
quick inspection of the code shows this is probably true, but in this
case I'd suggest a WARN_ON or something in force_wake_get(), because
this would be a really hard bug to track down.

By the way, I think we currently have potential problem with
kick_ring().  Although given when this occurs it is probably a DON'T
CARE.

> -Chris
> 
Ben

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: enabling forcewake from userspace
  2011-03-26 19:27         ` Ben Widawsky
@ 2011-03-26 20:20           ` Chris Wilson
  0 siblings, 0 replies; 8+ messages in thread
From: Chris Wilson @ 2011-03-26 20:20 UTC (permalink / raw)
  To: Ben Widawsky; +Cc: intel-gfx

On Sat, 26 Mar 2011 12:27:17 -0700, Ben Widawsky <ben@bwidawsk.net> wrote:
> On Sat, Mar 26, 2011 at 05:18:57PM +0000, Chris Wilson wrote:
> > 
> > The GPU is definitely allowed to be powered down whilst the CPU is
> > servicing an interrupt. ;-) I take your point though that the current
> > method is not interrupt safe. However, we should not be doing such work
> > from an interrupt handler - if need be all the actual work is kicked off
> > from a workqueue.
> > 
> > Something we need to keep an eye on, but not a problem today. *touch wood*
> 
> Efficiency aside, workqueue suffers from the same hazard. Unless the
> assumption is struct_mutex (or something similar) is protecting all
> register access which are in the power wells that can get disabled.

Yes, currently we use struct mutex to serialise pretty much everything,
__gen6_gt_force_wake_* included.

> My
> quick inspection of the code shows this is probably true, but in this
> case I'd suggest a WARN_ON or something in force_wake_get(), because
> this would be a really hard bug to track down.

Similarly, a WARN_ON in i915_reg_write() if reg < 0x40000 && !force-wake.
 
> By the way, I think we currently have potential problem with
> kick_ring().  Although given when this occurs it is probably a DON'T
> CARE.

True. A task for a truly rainy day. And whilst you're there move the error
capture to a workqueue as well.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-03-26 20:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-26  2:07 enabling forcewake from userspace Ben Widawsky
2011-03-26  2:07 ` [PATCH] drm/i915: have a forcewake "refcount" Ben Widawsky
2011-03-26  2:23 ` enabling forcewake from userspace Ben Widawsky
2011-03-26  7:11   ` Chris Wilson
2011-03-26 15:46     ` Ben Widawsky
2011-03-26 17:18       ` Chris Wilson
2011-03-26 19:27         ` Ben Widawsky
2011-03-26 20:20           ` Chris Wilson

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.