intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: Ben Widawsky <ben@bwidawsk.net>
To: Chris Wilson <chris@chris-wilson.co.uk>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH] drm/i915: read/write IOCTLs
Date: Fri, 1 Apr 2011 00:06:37 -0700	[thread overview]
Message-ID: <20110401070636.GA23731@snipes.kumite> (raw)
In-Reply-To: <b9dded$ih7ctg@orsmga002.jf.intel.com>

On Fri, Apr 01, 2011 at 07:36:56AM +0100, Chris Wilson wrote:
> Nice. The consensus is that this ioctl is required, just a few comments
> inline.

Nobody likes it, but it could pay off, especially if we end up with
weird non-mappable registers we wish to allow user space to read. I had
actually decided to add another field (something like a bus) to the
interface just in case.

> > +static inline int
> > +reg_in_rsvd_range(struct drm_device *dev, u32 reg)
> > +{
> > +	if (INTEL_INFO(dev)->gen < 6) {
> > +		if (REG_IN_RANGE(reg, 0x1000, 0x1fff) ||
> > +		    ((IS_BROADWATER(dev) || IS_CRESTLINE(dev)) ?
> > +			REG_IN_RANGE(reg, 0x4000, 0x4fff) : 0) ||
> > +		    REG_IN_RANGE(reg, 0x9000, 0x9fff) ||
> > +		    REG_IN_RANGE(reg, 0xb000, 0xffff) ||
> > +		    REG_IN_RANGE(reg, 0x14000, 0x2ffff) ||
> > +		    REG_IN_RANGE(reg, 0x40000, 0x5ffff))
> > +			return 1;
> > +
> > +		if (reg > 0x73fff)
> > +			return 1;
> > +	} else {
> > +		if (REG_IN_RANGE(reg, 0x1000, 0x1fff) ||
> > +		    REG_IN_RANGE(reg, 0x9000, 0x9fff) ||
> > +		    REG_IN_RANGE(reg, 0xb000, 0xffff) ||
> > +		    REG_IN_RANGE(reg, 0x15000, 0x21fff) ||
> > +		    REG_IN_RANGE(reg, 0x23000, 0x23fff) ||
> > +		    REG_IN_RANGE(reg, 0x25000, 0x2ffff) ||
> > +		    REG_IN_RANGE(reg, 0x40000, 0xfffff) ||
> > +		    REG_IN_RANGE(reg, 0x108000, 0x13ffff))
> > +			return 1;
> > +
> > +		if (reg > 0x17ffff)
> > +			return 1;
> > +	}
> 
> I think this would be more maintainable as a set of tables with the
> ranges. And a r/w flag could be stored in the table for the individual
> read/write blacklists.

That's fine with me. When I started it was much less complicated than by
the time I submitted the patch.

> > +	if (ret)
> > +		DRM_DEBUG_DRIVER("Couldn't acquire mutex, reading anyway\n");
> > +
> > +	args->value = (u32)i915_gt_read(dev_priv, args->offset);
> > +
> > +	mutex_unlock(&dev->struct_mutex);
> 
> Don't even think about unlocking an unlocked mutex. We either apply
> strict locking or we don't bother. I think we can assume that in the
> scenario where the mutex is blocked (from experience that is only from an
> OOPS within i915.ko) we can play with the registers to our hearts contents
> directly from userspace.

This was a bug in my patch... you mean?
ret = mutex_lock_interruptible();
if (ret)
	reg_read

if (!ret)
	mutex_unlock()

> > +static int
> > +i915_write_register_ioctl(struct drm_device *dev, void *data,
> > +			  struct drm_file *file_priv)
> > +{
> > +	struct drm_intel_read_reg *args = data;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	int ret;
> > +
> > +	if (!reg_write_allowed(dev, args->offset))
> > +		return -EINVAL;
> > +
> > +	ret = i915_mutex_lock_interruptible(dev);
> > +	if (ret)
> > +		DRM_DEBUG_DRIVER("Couldn't acquire mutex, writing anyway\n");
> > +
> > +	DRM_INFO("User space write %x %x\n", args->offset, (u32)args->value);
> > +	dev_priv->user_tainted = true;
> 
> Nice touch. Let's try add_taint(TAINT_USER) instead.

Cool! I didn't know about that interface. I'd like to be able to query
this at runtime as opposed to an OOPS... I'm too tired to look if it
supports that right now, but if it does, I'll switch.

> >  
> > +struct drm_intel_read_reg {
> > +	/* register offset to read */
> > +	__u32 offset;
> > +
> > +	/* register size, RFU */
> > +	__u8 size;
> > +
> > +	/* return value, high 4 bytes RFU */
> > +	__u64 value;
> > +};
> 
> Haha! I was going to ask for this to handle arbitrary register sizes.
> What I think is also necessary is to be able to read/write a block of
> registers in a single call - thinking of some of the more complex
> procedures we may want to try from userspace (the pcode messages for
> example) or for snapshotting a set of registers.

I brought this question up at our meeting on Thursday. The consensus to
was just have the 1 register at a time because the overhead of the
syscall was small enough to make it not matter. I think I prefer the
single read/write a little bit just because it keeps the kernel code
simpler, but I don't care enough to argue, and I most certainly don't
care enough to set up some kind of performance test for it. Anyone else
care enough to argue?

> 
> My dream would be a small domain specific language that would allow me to
> write a set of registers and poll for a result and then return that
> result. In the meantime I'd settle for passing an array of registers to be
> written and read in a single ioctl.
> 

GFX User mode driver? :)

> -- 
> Chris Wilson, Intel Open Source Technology Centre

Thanks for the feedback. I'll try to fix it up when I wake up.

Ben

  reply	other threads:[~2011-04-01  7:08 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-01  1:31 [PATCH] drm/i915: read/write IOCTLs Ben Widawsky
2011-04-01  1:39 ` [PATCH v2] " Ben Widawsky
2011-04-01 23:54   ` Read/Write IOCTL compromise Ben Widawsky
2011-04-06 21:38     ` No more read/write ioctls Ben Widawsky
2011-04-08 17:10       ` Eric Anholt
2011-04-08 17:29         ` Chris Wilson
2011-04-01 23:54   ` [PATCH v3 1/2] drm/i915: read/write ioctls for userspace Ben Widawsky
2011-04-04 17:14     ` Chris Wilson
2011-04-05  1:30       ` Read/Write ioctls Ben Widawsky
2011-04-05  1:30       ` [PATCH v4] drm/i915: read/write ioctls for userspace Ben Widawsky
2011-04-01 23:54   ` [PATCH v3 2/2] drm/i915: debugfs for register write taint Ben Widawsky
2011-04-01  6:36 ` [PATCH] drm/i915: read/write IOCTLs Chris Wilson
2011-04-01  7:06   ` Ben Widawsky [this message]
2011-04-01  7:32     ` Chris Wilson
2011-04-01 18:51       ` Eric Anholt
2011-04-02  6:46         ` Chris Wilson
2011-04-02 15:16           ` Ben Widawsky
2011-04-04  1:35           ` Ben Widawsky
2011-04-04  7:36             ` Chris Wilson

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=20110401070636.GA23731@snipes.kumite \
    --to=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).