Re: [Intel-gfx] [PATCH 2/2] drm/i915: Enable DPLL VGA mode before P1/P2 divider write

2015-10-08 Thread Chris Wilson
On Thu, Oct 08, 2015 at 10:19:14AM +0200, Daniel Vetter wrote:
> On Wed, Oct 07, 2015 at 10:08:25PM +0300, ville.syrj...@linux.intel.com wrote:
> > From: Ville Syrjälä 
> > 
> > Apparently writing the DPLL register P1/P2 divider fields won't trigger
> > an actual change in the DPLL output unless VGA mode is enabled for
> > prior to the register write that changes the P1/P2 dividers. The write
> > with the new P1/P2 divider can itself disable VGA mode again without
> > problems.
> > 
> > I tested the behaviour on my 946GZ, and when manually frobbing the
> > register with the display on, the behaviour is very clear. However I
> > can't explain why this machine actually works. The P1/P2 divider
> > changes caused by normal modesets do seem to make it through to the
> > hardware somehow since I get a stable picture on the monitor with
> > any resolution. Maybe it's the "three times for luck" stuff that
> > somehow masks the problem, or something.
> > 
> > But apparently there are machines (eg. Nick Bowler's G45) where that
> > isn't the case and we fail to get the correct clock from the DPLL.
> > 
> > Things used to work because we enabled VGA mode for disabled DPLLs,
> > so when re-enabling the DPLL VGA mode was enabled just prior to the
> > first register write, and hence the P1/P2 change went through without
> > a hitch. That got changed in
> > 
> > b8afb9113c51 drm/i915: Keep GMCH DPLL VGA mode always disabled
> > 
> > in the name of consistency. In order to keep the consistency part,
> > leave VGA mode disabled for disabled DPLLs, but turn it on just prior
> > to updating the P1/P2 dividers to make sure the hardware picks up
> > on the new values.
> > 
> > Cc: Nick Bowler 
> > Reported-by: Nick Bowler 
> > Tested-by: Nick Bowler 
> > Signed-off-by: Ville Syrjälä 
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 7 +++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c 
> > b/drivers/gpu/drm/i915/intel_display.c
> > index f4fdff9..ce51dbc 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -1743,6 +1743,13 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
> >I915_READ(DPLL(!crtc->pipe)) | DPLL_DVO_2X_MODE);
> > }
> >  
> > +   /*
> > +* Apparently we need to have VGA mode enabled prior to changing
> > +* the P1/P2 dividers. Otherwise the DPLL will keep using the old
> > +* dividers, even though the register value does change.
> > +*/
> > +   I915_WRITE(reg, 0);
> 
> Again POSTING_READ for ordering? Otherwise Reviewed-by: Daniel Vetter 
> 
> Not that there's a lot to review since Bspec is silent ...

One option is to start using mmiowb() for documenting the write ordering
(which is a no-op on x86 and so heaven forbid we get to use WC ever.)
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Pin the ifbdev for the info->system_base GGTT mmapping

2015-10-08 Thread Chris Wilson
On Wed, Oct 07, 2015 at 11:34:17AM -0700, Wayne Boyer wrote:
> From: Chris Wilson 
> 
> A long time ago (before 3.14) we relied on a permanent pinning of the
> ifbdev to lock the fb in place inside the GGTT. However, the
> introduction of stealing the BIOS framebuffer and reusing its address in
> the GGTT for the fbdev has muddied waters and we use an inherited fb.
> However, the inherited fb is only pinned whilst it is active and we no
> longer have an explicit pin for the info->system_base mmapping used by
> the fbdev. The result is that after some aperture pressure the fbdev may
> be evicted, but we continue to write the fbcon into the same GGTT
> address - overwriting anything else that may be put into that offset.
> The effect is most pronounced across suspend/resume as
> intel_fbdev_set_suspend() does a full clear over the whole scanout.
> 
> v2: rebased on latest nightly (Wayne)
> 
> Signed-off-by: Chris Wilson 
> Cc: "Goel, Akash" 
> Cc: Daniel Vetter 
> Cc: Jesse Barnes 
> Cc: sta...@vger.kernel.org
> Reviewed-by: Deepak S 
> Signed-off-by: Wayne Boyer 
> ---
>  drivers/gpu/drm/i915/intel_fbdev.c | 15 +++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_fbdev.c 
> b/drivers/gpu/drm/i915/intel_fbdev.c
> index 6532912..c6aa4f9 100644
> --- a/drivers/gpu/drm/i915/intel_fbdev.c
> +++ b/drivers/gpu/drm/i915/intel_fbdev.c
> @@ -215,6 +215,16 @@ static int intelfb_create(struct drm_fb_helper *helper,
>   obj = intel_fb->obj;
>   size = obj->base.size;
>  
> + /* The fb constructor will have already pinned us (or inherited a
> +  * GGTT region from the BIOS) suitable for a scanout, so
> +  * this should just be a no-op and increment the pin count for the
> +  * fbdev mmapping. It does have a useful side-effect of validating
> +  * the pin for fbdev's use via a GGTT mmapping.
> +  */
> + ret = i915_gem_object_ggtt_pin(obj, NULL, 0, PIN_MAPPABLE);

This should be i915_gem_obj_ggtt_pin(obj, 0, PIN_MAPPABLE);
At which point I just rage quit.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 6/9] drm/i915: driver based PASID handling

2015-10-08 Thread Daniel Vetter
On Wed, Oct 07, 2015 at 10:26:20AM -0700, Jesse Barnes wrote:
> On 10/07/2015 10:17 AM, David Woodhouse wrote:
> > On Wed, 2015-10-07 at 09:28 -0700, Jesse Barnes wrote:
> >> On 10/07/2015 09:14 AM, Daniel Vetter wrote:
> >>> On Wed, Oct 07, 2015 at 08:16:42AM -0700, Jesse Barnes wrote:
>  On 10/07/2015 06:00 AM, David Woodhouse wrote:
> > On Fri, 2015-09-04 at 09:59 -0700, Jesse Barnes wrote:
> >> +
> >> +   ret = handle_mm_fault(mm, vma, address,
> >> + desc.wr_req ? FAULT_FLAG_WRITE : 0);
> >> +   if (ret & VM_FAULT_ERROR) {
> >> +   gpu_mm_segv(tsk, address, SEGV_ACCERR); /* ? */
> >> +   goto out_unlock;
> >> +   }
> >> +
> >
> > Hm, do you need to force the SEGV there, in what ought to be generic
> > IOMMU code?
> >
> > Can you instead just let the fault handler return an appropriate
> > failure code to the IOMMU request queue and then deal with the
> > resulting error on the i915 device side?
> 
>  I'm not sure if we get enough info on the i915 side to handle it
>  reasonably, we'll have to test that out.
> >>>
> >>> We do know precisely which context blew up, but without the TDR work we
> >>> can't yet just kill the offender selective without affecting the other
> >>> active gpu contexts.
> >>
> >> How?  The notification from the IOMMU queue is asynchronous...
> > 
> > The page request, and the response, include 'private data' which an
> > endpoint can use to carry that kind of information.
> > 
> > In $7.5.1.1 of the VT-d specification it tells us:
> > 
> > "Private Data: The Private Data field can be used by 
> >  Root-Complex integrated endpoints to uniquely identify
> >  device-specific private information associated with an 
> >  individual page request.
> > 
> > "For Intel ® Processor Graphics device, the Private Data field 
> >  specifies the identity of the GPU advanced-context (see 
> >  Section 3.10) sending the page request."
> 
> Ah right so we could put our private context ID in there if the PASID
> doesn't end up being per-context.  That would work fine (though as
> Daniel said we still need fancier reset to handle things more
> gracefully).

I'd hope we can be even more lazy: If we complete the page request with a
failure then hopefully the gpu read/write transaction never completes in
the EU/ff-unit which means it'll be stuck forever and our hangcheck will
get around to clean up the mess. That should work with 0 code changes (but
needs a testcase ofc).

Later on we can get fancy and try to immediate preempt the ctx and kill it
if it faults. But there's a bit of infrastructure missing for that, and I
think it'd be better to not stall svm on that.

> >>> But besides that I really don't see a reason why we need to kill the
> >>> process if the gpu faults. After all if a thread sigfaults then signal
> >>> goes to that thread and not some random one (or the one thread that forked
> >>> the thread that blew up). And we do have interfaces to tell userspace that
> >>> something bad happened with the gpu work it submitted.
> > 
> > I certainly don't want the core IOMMU code killing things. I really
> > want to just complete the page request with an appropriate failure
> > code, and let the endpoint device deal with it from there.
> 
> I think that will work, but I want to test and make sure.  In the driver
> mode version I took advantage of the fact that I got an unambiguous page
> request failure from the IOMMU along with a unique PASID to send the
> signal.  Getting it on the GPU side means looking at some of our
> existing error state bits, which is something I've been avoiding...

gem_reset_stats does this for your already, including test coverage and
all. What might be missing is getting reset events from a pollable fd,
since the current needs explicit polling. It works that way since that's
all arb_robustness wants.

And with an fd we can always use the generic SIG_IO stuff for userspace
that wants a signal, but by default I don't think we should use signals at
all for gpu page faults: The current SIG_SEGV can't be used (since it's
clearly for thread-local faults only), same for SIG_BUS, SIG_IO is for fd
polling and there's nothing else available.

But even the pollable fd is probably best done in a follow-up series, if
we even have a need for it.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915/irq: Fix misspelled word register in kernel-doc

2015-10-08 Thread Javier Martinez Canillas
There is a typo in the function i915_handle_error()
kernel-doc and the word register is spelled wrongly.

Signed-off-by: Javier Martinez Canillas 
---

 drivers/gpu/drm/i915/i915_irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 0344a9181dac..38dadd23684d 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2571,7 +2571,7 @@ static void i915_report_and_clear_eir(struct drm_device 
*dev)
  * i915_handle_error - handle a gpu error
  * @dev: drm device
  *
- * Do some basic checking of regsiter state at error time and
+ * Do some basic checking of register state at error time and
  * dump it to the syslog.  Also call i915_capture_error_state() to make
  * sure we get a record and make it available in debugfs.  Fire a uevent
  * so userspace knows something bad happened (should trigger collection
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915/irq: Fix kernel-doc warnings

2015-10-08 Thread Javier Martinez Canillas
Add the dev parameter for the functions i915_enable_asle_pipestat() and
i915_reset_and_wakeup() to the kernel-doc to fix the following warnings:

.//drivers/gpu/drm/i915/i915_irq.c:586: warning: No description found for 
parameter 'dev'
.//drivers/gpu/drm/i915/i915_irq.c:2400: warning: No description found for 
parameter 'dev'

Signed-off-by: Javier Martinez Canillas 

---

 drivers/gpu/drm/i915/i915_irq.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 8ca772deabdb..0344a9181dac 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -581,6 +581,7 @@ i915_disable_pipestat(struct drm_i915_private *dev_priv, 
enum pipe pipe,
 
 /**
  * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion
+ * @dev: drm device
  */
 static void i915_enable_asle_pipestat(struct drm_device *dev)
 {
@@ -2392,6 +2393,7 @@ static void i915_error_wake_up(struct drm_i915_private 
*dev_priv,
 
 /**
  * i915_reset_and_wakeup - do process context error handling work
+ * @dev: drm device
  *
  * Fire an error uevent so userspace can see that a hang or error
  * was detected.
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/2] drm/i915: Restore lost DPLL register write on gen2-4

2015-10-08 Thread Daniel Vetter
On Wed, Oct 07, 2015 at 10:08:24PM +0300, ville.syrj...@linux.intel.com wrote:
> From: Ville Syrjälä 
> 
> We accidentally lost the initial DPLL register write in
> 1c4e02746147 drm/i915: Fix DVO 2x clock enable on 830M
> 
> The "three times for luck" hack probably saved us from a total
> disaster. But anyway, bring the initial write back so that the
> code actually makes some sense.
> 
> Cc: sta...@vger.kernel.org
> Cc: Nick Bowler 
Reported-and-tested-by: Nick Bowler 
References: 
http://lists.freedesktop.org/archives/intel-gfx/2015-October/077463.html

> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_display.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 147e700..f4fdff9 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -1743,6 +1743,8 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
>  I915_READ(DPLL(!crtc->pipe)) | DPLL_DVO_2X_MODE);

Don't we also need a POSTING_READ here to make sure the two-step 2x mode
sequence is still followed?

With that addressed Reviewed-by: Daniel Vetter 
>   }
>  
> + I915_WRITE(reg, dpll);
> +
>   /* Wait for the clocks to stabilize. */
>   POSTING_READ(reg);
>   udelay(150);
> -- 
> 2.4.9
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/2] drm/i915: Enable DPLL VGA mode before P1/P2 divider write

2015-10-08 Thread Daniel Vetter
On Wed, Oct 07, 2015 at 10:08:25PM +0300, ville.syrj...@linux.intel.com wrote:
> From: Ville Syrjälä 
> 
> Apparently writing the DPLL register P1/P2 divider fields won't trigger
> an actual change in the DPLL output unless VGA mode is enabled for
> prior to the register write that changes the P1/P2 dividers. The write
> with the new P1/P2 divider can itself disable VGA mode again without
> problems.
> 
> I tested the behaviour on my 946GZ, and when manually frobbing the
> register with the display on, the behaviour is very clear. However I
> can't explain why this machine actually works. The P1/P2 divider
> changes caused by normal modesets do seem to make it through to the
> hardware somehow since I get a stable picture on the monitor with
> any resolution. Maybe it's the "three times for luck" stuff that
> somehow masks the problem, or something.
> 
> But apparently there are machines (eg. Nick Bowler's G45) where that
> isn't the case and we fail to get the correct clock from the DPLL.
> 
> Things used to work because we enabled VGA mode for disabled DPLLs,
> so when re-enabling the DPLL VGA mode was enabled just prior to the
> first register write, and hence the P1/P2 change went through without
> a hitch. That got changed in
> 
> b8afb9113c51 drm/i915: Keep GMCH DPLL VGA mode always disabled
> 
> in the name of consistency. In order to keep the consistency part,
> leave VGA mode disabled for disabled DPLLs, but turn it on just prior
> to updating the P1/P2 dividers to make sure the hardware picks up
> on the new values.
> 
> Cc: Nick Bowler 
> Reported-by: Nick Bowler 
> Tested-by: Nick Bowler 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_display.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index f4fdff9..ce51dbc 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -1743,6 +1743,13 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
>  I915_READ(DPLL(!crtc->pipe)) | DPLL_DVO_2X_MODE);
>   }
>  
> + /*
> +  * Apparently we need to have VGA mode enabled prior to changing
> +  * the P1/P2 dividers. Otherwise the DPLL will keep using the old
> +  * dividers, even though the register value does change.
> +  */
> + I915_WRITE(reg, 0);

Again POSTING_READ for ordering? Otherwise Reviewed-by: Daniel Vetter 

Not that there's a lot to review since Bspec is silent ...
-Daniel
> +
>   I915_WRITE(reg, dpll);
>  
>   /* Wait for the clocks to stabilize. */
> -- 
> 2.4.9
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915/irq: Fix misspelled word register in kernel-doc

2015-10-08 Thread Daniel Vetter
On Thu, Oct 08, 2015 at 09:57:49AM +0200, Javier Martinez Canillas wrote:
> There is a typo in the function i915_handle_error()
> kernel-doc and the word register is spelled wrongly.
> 
> Signed-off-by: Javier Martinez Canillas 

Both kerneldoc patches applied, thanks.
-Daniel

> ---
> 
>  drivers/gpu/drm/i915/i915_irq.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 0344a9181dac..38dadd23684d 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -2571,7 +2571,7 @@ static void i915_report_and_clear_eir(struct drm_device 
> *dev)
>   * i915_handle_error - handle a gpu error
>   * @dev: drm device
>   *
> - * Do some basic checking of regsiter state at error time and
> + * Do some basic checking of register state at error time and
>   * dump it to the syslog.  Also call i915_capture_error_state() to make
>   * sure we get a record and make it available in debugfs.  Fire a uevent
>   * so userspace knows something bad happened (should trigger collection
> -- 
> 2.4.3
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/2] drm/i915: Restore lost DPLL register write on gen2-4

2015-10-08 Thread Ville Syrjälä
On Thu, Oct 08, 2015 at 10:17:30AM +0200, Daniel Vetter wrote:
> On Wed, Oct 07, 2015 at 10:08:24PM +0300, ville.syrj...@linux.intel.com wrote:
> > From: Ville Syrjälä 
> > 
> > We accidentally lost the initial DPLL register write in
> > 1c4e02746147 drm/i915: Fix DVO 2x clock enable on 830M
> > 
> > The "three times for luck" hack probably saved us from a total
> > disaster. But anyway, bring the initial write back so that the
> > code actually makes some sense.
> > 
> > Cc: sta...@vger.kernel.org
> > Cc: Nick Bowler 
> Reported-and-tested-by: Nick Bowler 
> References: 
> http://lists.freedesktop.org/archives/intel-gfx/2015-October/077463.html
> 
> > Signed-off-by: Ville Syrjälä 
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c 
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 147e700..f4fdff9 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -1743,6 +1743,8 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
> >I915_READ(DPLL(!crtc->pipe)) | DPLL_DVO_2X_MODE);
> 
> Don't we also need a POSTING_READ here to make sure the two-step 2x mode
> sequence is still followed?

We don't do write combining on registers, and there are no shadow
register type of things to consider in this case either.

> 
> With that addressed Reviewed-by: Daniel Vetter 
> > }
> >  
> > +   I915_WRITE(reg, dpll);
> > +
> > /* Wait for the clocks to stabilize. */
> > POSTING_READ(reg);
> > udelay(150);
> > -- 
> > 2.4.9
> > 
> > ___
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Ville Syrjälä
Intel OTC
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/6] drm/i915: Implement L3 partitioning set-up from the workaround list.

2015-10-08 Thread Chris Wilson
On Wed, Oct 07, 2015 at 04:30:35PM +0300, Francisco Jerez wrote:
> Chris Wilson  writes:
> 
> > On Wed, Oct 07, 2015 at 02:44:00PM +0300, Francisco Jerez wrote:
> >> This programs the L3 configuration based on the sizes given for each
> >> partition as arguments.  The relevant register writes are added to the
> >> workaround list so that they are re-applied to each context while it's
> >> initialized, preventing state leaks from other userspace processes
> >> which may have modified the L3 partitioning from its boot-up state,
> >> since all relevant registers are part of the software and hardware
> >> command checker whitelists.
> >> 
> >> Some userspace clients (DDX and current versions of Mesa not patched
> >> with my L3 partitioning series [1]) assume that the L3 configuration,
> >> in particular the URB size, comes up in certain state when a context
> >> is created, but nothing in the kernel guarantees this assumption, the
> >> registers that control the partitioning of the L3 cache were being
> >> left untouched.
> >> 
> >> Note that the VLV_L3SQCREG1_SQGHPCI_DEFAULT macro defined here has the
> >> same value as the previously defined VLV_B0_WA_L3SQCREG1_VALUE, but
> >> the latter will be removed in a future commit.
> >> 
> >> [1] 
> >> http://lists.freedesktop.org/archives/mesa-dev/2015-September/093550.html
> >
> > Merge this with 1 + 5 (or was it 4?)- not only does it introduce a
> > temporary unused function, but we have to jump between patches to see
> > whether the function is safe (especially given those BUGs), and you add
> > all w/a in the same patch so bisection is not improved.
> >
> What do you want me to merge it with?  This *is* PATCH 1, and PATCH 5 is
> largely unrelated.  I wouldn't have any objection to squashing PATCH 4
> into this commit though.

1+4. That just highlights the issue of having two very tightly coupled
patches arbitrary split - the split here doesn't even improve bisection.
 
> > Looking at the function itself, I am not convinced that it actually adds
> > anything over calling setting up the WA from the vfuncs - at least the
> > bdw/gen7 split is redundant (we split at the vfunc then call one
> > function where we replit again, but with nasty constraints on the
> > interface of the function for different gen, it's not a function for the
> > faint of heart).
> >
> The constraints are just the hardware's constraints on the L3
> partitioning.  The function is meant to implement the details of
> programming the L3 configuration, which is different for different gens
> even though the overall structure of the L3 partitioning is the same.
> Of course the constraints set by specific hardware on the partition
> sizes cannot be abstracted out.
> 
> I guess that splitting this out into two functions (one for gen7 and
> another for gen8) wouldn't hurt much, but open-coding the function in
> all its uses (5) would involve duplicating quite some code.

Having slept on it, and I think a gen7/gen8 split is best.

My issue with the current combined function is that the interface is
different based on generation, which says to me that it is multiple
functions. It scores very low on the hard-to-misuse ranking

http://ozlabs.org/~rusty/index.cgi/tech/2008-03-30.html

And instead of the multiline multiple ternary operators, just have
an if-else-chain for hsw/vlv/ivb (for setting the cmd value).
 
> Assuming I split the function into gen7 and gen8 variants, would you
> like them to implement a common consistent interface (i.e. the same
> prototype that my init_l3_partitioning_workarounds() implements), or
> would you like the variant for each gen to implement an ad-hoc interface
> according to the partition configs actually needed on each gen?  I
> suspect the former would be cleaner.

No, the BUGs tell me that the registers do not have a consistent
interface.
 
> >> +static int init_l3_partitioning_workarounds(struct intel_engine_cs *ring,
> >> +  unsigned int n_urb,
> >> +  unsigned int n_ro,
> >> +  unsigned int n_dc,
> >> +  unsigned int n_all)
> >> +{
> >> +  struct drm_device *dev = ring->dev;
> >> +  struct drm_i915_private *dev_priv = dev->dev_private;
> >> +
> >> +  if (INTEL_INFO(dev)->gen >= 8) {
> >
> > Why use dev here? You already have dev_priv, so why chase the pointer
> > again?
> 
> Sorry?  Does INTEL_INFO() take a drm_device or a drm_i915_private
> pointer as argument?  The two types don't seem to be related by an
> inheritance relationship or anything similar AFAICT, and most other uses
> in this file seem to pass a drm_device as argument even where a
> drm_i915_private is available.

drm_i915_private is our primary internal pointer. We can shave over 8KiB
of object code by removing the pointer dance we have from still passing
around drm_device and jumping to drm_i915_private. New code is supposed
to be 

[Intel-gfx] [PATCH v4] drm/i915: Determine the stolen memory base address on gen2

2015-10-08 Thread ville . syrjala
From: Ville Syrjälä 

There isn't an explicit stolen memory base register on gen2.
Some old comment in the i915 code suggests we should get it via
max_low_pfn_mapped, but that's clearly a bad idea on my MGM.

The e820 map in said machine looks like this:
[0.00] BIOS-e820: [mem 0x-0x0009f7ff] usable
[0.00] BIOS-e820: [mem 0x0009f800-0x0009] reserved
[0.00] BIOS-e820: [mem 0x000ce000-0x000c] reserved
[0.00] BIOS-e820: [mem 0x000dc000-0x000f] reserved
[0.00] BIOS-e820: [mem 0x0010-0x1f6e] usable
[0.00] BIOS-e820: [mem 0x1f6f-0x1f6f7fff] ACPI data
[0.00] BIOS-e820: [mem 0x1f6f8000-0x1f6f] ACPI NVS
[0.00] BIOS-e820: [mem 0x1f70-0x1fff] reserved
[0.00] BIOS-e820: [mem 0xfec1-0xfec1] reserved
[0.00] BIOS-e820: [mem 0xffb0-0xffbf] reserved
[0.00] BIOS-e820: [mem 0xfff0-0x] reserved

That makes max_low_pfn_mapped = 1f6f, so assuming our stolen memory
would start there would place it on top of some ACPI memory regions.
So not a good idea as already stated.

The 9MB region after the ACPI regions at 0x1f70 however looks
promising given that the macine reports the stolen memory size to be
8MB. Looking at the PGTBL_CTL register, the GTT entries are at offset
0x1fee0, and given that the GTT entries occupy 128KB, it looks like
the stolen memory could start at 0x1f70 and the GTT entries would
occupy the last 128KB of the stolen memory.

After some more digging through chipset documentation, I've determined
the BIOS first allocates space for something called TSEG (something to
do with SMM) from the top of memory, and then it allocates the graphics
stolen memory below that. Accordind to the chipset documentation TSEG
has a fixed size of 1MB on 855. So that explains the top 1MB in the
e820 region. And it also confirms that the GTT entries are in fact at
the end of the the stolen memory region.

Derive the stolen memory base address on gen2 the same as the BIOS does
(TOM-TSEG_SIZE-stolen_size). There are a few differences between the
registers on various gen2 chipsets, so a few different codepaths are
required.

865G is again bit more special since it seems to support enough memory
to hit 4GB address space issues. This means the PCI allocations will
also affect the location of the stolen memory. Fortunately there
appears to be the TOUD register which may give us the correct answer
directly. But the chipset docs are a bit unclear, so I'm not 100%
sure that the graphics stolen memory is always the last thing the
BIOS steals. Someone would need to verify it on a real system.

I tested this on the my 830 and 855 machines, and so far everything
looks peachy.

v2: Rewrite to use the TOM-TSEG_SIZE-stolen_size and TOUD methods
v3: Fix TSEG size for 830
v4: Add missing 'else' (Chris)

Tested-by: Chris Wilson 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/i915_gem_stolen.c | 92 ++
 1 file changed, 81 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 69eebc6..cdacf3f 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -30,6 +30,9 @@
 #include 
 #include "i915_drv.h"
 
+#define KB(x) ((x) * 1024)
+#define MB(x) (KB(x) * 1024)
+
 /*
  * The BIOS typically reserves some of the system's memory for the exclusive
  * use of the integrated graphics. This memory is no longer available for
@@ -91,24 +94,91 @@ static unsigned long i915_stolen_to_physical(struct 
drm_device *dev)
/* Almost universally we can find the Graphics Base of Stolen Memory
 * at offset 0x5c in the igfx configuration space. On a few (desktop)
 * machines this is also mirrored in the bridge device at different
-* locations, or in the MCHBAR. On gen2, the layout is again slightly
-* different with the Graphics Segment immediately following Top of
-* Memory (or Top of Usable DRAM). Note it appears that TOUD is only
-* reported by 865g, so we just use the top of memory as determined
-* by the e820 probe.
+* locations, or in the MCHBAR.
+*
+* On 865 we just check the TOUD register.
+*
+* On 830/845/85x the stolen memory base isn't available in any
+* register. We need to calculate it as TOM-TSEG_SIZE-stolen_size.
 *
-* XXX However gen2 requires an unavailable symbol.
 */
base = 0;
if (INTEL_INFO(dev)->gen >= 3) {
/* Read Graphics Base of Stolen Memory directly */
pci_read_config_dword(dev->pdev, 

[Intel-gfx] [PATCH 3/6] drm/i915: Propagating correct error codes to the userspace

2015-10-08 Thread ankitprasad . r . sharma
From: Ankitprasad Sharma 

Propagating correct error codes to userspace by using ERR_PTR and
PTR_ERR macros for stolen memory based object allocation. We generally
return -ENOMEM to the user whenever there is a failure in object
allocation. This patch helps user to identify the correct reason for the
failure and not just -ENOMEM each time.

v2: Moved the patch up in the series, added error propagation for
i915_gem_alloc_object too (Chris)

Signed-off-by: Ankitprasad Sharma 
---
 drivers/gpu/drm/i915/i915_gem.c  | 15 +-
 drivers/gpu/drm/i915/i915_gem_batch_pool.c   |  4 +--
 drivers/gpu/drm/i915/i915_gem_context.c  |  4 +--
 drivers/gpu/drm/i915/i915_gem_render_state.c |  4 +--
 drivers/gpu/drm/i915/i915_gem_stolen.c   | 43 
 drivers/gpu/drm/i915/i915_guc_submission.c   |  4 +--
 drivers/gpu/drm/i915/intel_display.c |  2 +-
 drivers/gpu/drm/i915/intel_fbdev.c   |  6 ++--
 drivers/gpu/drm/i915/intel_lrc.c |  8 +++---
 drivers/gpu/drm/i915/intel_overlay.c |  4 +--
 drivers/gpu/drm/i915/intel_pm.c  |  2 +-
 drivers/gpu/drm/i915/intel_ringbuffer.c  | 20 ++---
 12 files changed, 61 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d3f4321..54f7df1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -393,9 +393,9 @@ i915_gem_create(struct drm_file *file,
if (flags & I915_CREATE_PLACEMENT_STOLEN) {
mutex_lock(>struct_mutex);
obj = i915_gem_object_create_stolen(dev, size);
-   if (!obj) {
+   if (IS_ERR(obj)) {
mutex_unlock(>struct_mutex);
-   return -ENOMEM;
+   return PTR_ERR(obj);
}
 
/* Always clear fresh buffers before handing to userspace */
@@ -411,8 +411,8 @@ i915_gem_create(struct drm_file *file,
obj = i915_gem_alloc_object(dev, size);
}
 
-   if (obj == NULL)
-   return -ENOMEM;
+   if (IS_ERR(obj))
+   return PTR_ERR(obj);
 
ret = drm_gem_handle_create(file, >base, );
/* drop reference from allocate - handle holds it now */
@@ -4273,14 +4273,15 @@ struct drm_i915_gem_object 
*i915_gem_alloc_object(struct drm_device *dev,
struct drm_i915_gem_object *obj;
struct address_space *mapping;
gfp_t mask;
+   int ret = 0;
 
obj = i915_gem_object_alloc(dev);
if (obj == NULL)
-   return NULL;
+   return ERR_PTR(-ENOMEM);
 
-   if (drm_gem_object_init(dev, >base, size) != 0) {
+   if ((ret = drm_gem_object_init(dev, >base, size)) != 0) {
i915_gem_object_free(obj);
-   return NULL;
+   return ERR_PTR(ret);
}
 
mask = GFP_HIGHUSER | __GFP_RECLAIMABLE;
diff --git a/drivers/gpu/drm/i915/i915_gem_batch_pool.c 
b/drivers/gpu/drm/i915/i915_gem_batch_pool.c
index 7bf2f3f..d79caa2 100644
--- a/drivers/gpu/drm/i915/i915_gem_batch_pool.c
+++ b/drivers/gpu/drm/i915/i915_gem_batch_pool.c
@@ -135,8 +135,8 @@ i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool,
int ret;
 
obj = i915_gem_alloc_object(pool->dev, size);
-   if (obj == NULL)
-   return ERR_PTR(-ENOMEM);
+   if (IS_ERR(obj))
+   return obj;
 
ret = i915_gem_object_get_pages(obj);
if (ret)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 74aa0c9..603600c 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -157,8 +157,8 @@ i915_gem_alloc_context_obj(struct drm_device *dev, size_t 
size)
int ret;
 
obj = i915_gem_alloc_object(dev, size);
-   if (obj == NULL)
-   return ERR_PTR(-ENOMEM);
+   if (IS_ERR(obj))
+   return obj;
 
/*
 * Try to make the context utilize L3 as well as LLC.
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c 
b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 5026a62..50d010e 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -58,8 +58,8 @@ static int render_state_init(struct render_state *so, struct 
drm_device *dev)
return -EINVAL;
 
so->obj = i915_gem_alloc_object(dev, 4096);
-   if (so->obj == NULL)
-   return -ENOMEM;
+   if (IS_ERR(so->obj))
+   return PTR_ERR(so->obj);
 
ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0);
if (ret)
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 5ec2190..d3e6813 100644
--- 

[Intel-gfx] [PATCH 2/6] drm/i915: Support for creating Stolen memory backed objects

2015-10-08 Thread ankitprasad . r . sharma
From: Ankitprasad Sharma 

Extend the drm_i915_gem_create structure to add support for
creating Stolen memory backed objects. Added a new flag through
which user can specify the preference to allocate the object from
stolen memory, which if set, an attempt will be made to allocate
the object from stolen memory subject to the availability of
free space in the stolen region.

v2: Rebased to the latest drm-intel-nightly (Ankit)

v3: Changed versioning of GEM_CREATE param, added new comments (Tvrtko)

v4: Changed size from 32b to 64b to prevent userspace overflow (Tvrtko)
Corrected function arguments ordering (Chris)

Testcase: igt/gem_stolen

Signed-off-by: Ankitprasad Sharma 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_dma.c|  3 +++
 drivers/gpu/drm/i915/i915_drv.h|  2 +-
 drivers/gpu/drm/i915/i915_gem.c| 30 +++---
 drivers/gpu/drm/i915/i915_gem_stolen.c |  4 ++--
 include/uapi/drm/i915_drm.h| 16 
 5 files changed, 49 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 817b05c..0a25f23 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -170,6 +170,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_RESOURCE_STREAMER:
value = HAS_RESOURCE_STREAMER(dev);
break;
+   case I915_PARAM_CREATE_VERSION:
+   value = 2;
+   break;
default:
DRM_DEBUG("Unknown parameter %d\n", param->param);
return -EINVAL;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f962425..bca1572 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3191,7 +3191,7 @@ void i915_gem_stolen_remove_node(struct drm_i915_private 
*dev_priv,
 int i915_gem_init_stolen(struct drm_device *dev);
 void i915_gem_cleanup_stolen(struct drm_device *dev);
 struct drm_i915_gem_object *
-i915_gem_object_create_stolen(struct drm_device *dev, u32 size);
+i915_gem_object_create_stolen(struct drm_device *dev, u64 size);
 struct drm_i915_gem_object *
 i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
   u32 stolen_offset,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e6b3bc7..d3f4321 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -375,6 +375,7 @@ static int
 i915_gem_create(struct drm_file *file,
struct drm_device *dev,
uint64_t size,
+   uint32_t flags,
uint32_t *handle_p)
 {
struct drm_i915_gem_object *obj;
@@ -385,8 +386,31 @@ i915_gem_create(struct drm_file *file,
if (size == 0)
return -EINVAL;
 
+   if (flags & __I915_CREATE_UNKNOWN_FLAGS)
+   return -EINVAL;
+
/* Allocate the new object */
-   obj = i915_gem_alloc_object(dev, size);
+   if (flags & I915_CREATE_PLACEMENT_STOLEN) {
+   mutex_lock(>struct_mutex);
+   obj = i915_gem_object_create_stolen(dev, size);
+   if (!obj) {
+   mutex_unlock(>struct_mutex);
+   return -ENOMEM;
+   }
+
+   /* Always clear fresh buffers before handing to userspace */
+   ret = i915_gem_clear_object(obj);
+   if (ret) {
+   drm_gem_object_unreference(>base);
+   mutex_unlock(>struct_mutex);
+   return ret;
+   }
+
+   mutex_unlock(>struct_mutex);
+   } else {
+   obj = i915_gem_alloc_object(dev, size);
+   }
+
if (obj == NULL)
return -ENOMEM;
 
@@ -409,7 +433,7 @@ i915_gem_dumb_create(struct drm_file *file,
args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64);
args->size = args->pitch * args->height;
return i915_gem_create(file, dev,
-  args->size, >handle);
+  args->size, 0, >handle);
 }
 
 /**
@@ -422,7 +446,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
struct drm_i915_gem_create *args = data;
 
return i915_gem_create(file, dev,
-  args->size, >handle);
+  args->size, args->flags, >handle);
 }
 
 static inline int
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 1520779..5ec2190 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -497,7 +497,7 @@ cleanup:
 }
 
 struct drm_i915_gem_object *
-i915_gem_object_create_stolen(struct drm_device *dev, u32 size)

[Intel-gfx] [PATCH 5/6] drm/i915: Support for pread/pwrite from/to non shmem backed objects

2015-10-08 Thread ankitprasad . r . sharma
From: Ankitprasad Sharma 

This patch adds support for extending the pread/pwrite functionality
for objects not backed by shmem. The access will be made through
gtt interface.
This will cover prime objects as well as stolen memory backed objects
but for userptr objects it is still forbidden.

v2: Drop locks around slow_user_access, prefault the pages before
access (Chris)

v3: Rebased to the latest drm-intel-nightly (Ankit)

v4: Moved page base & offset calculations outside the copy loop,
corrected data types for size and offset variables, corrected if-else
braces format (Tvrtko/kerneldocs)

v5: Enabled pread/pwrite for all non-shmem backed objects including
without tiling restrictions (Ankit)

v6: Using pwrite_fast for non-shmem backed objects as well (Chris)

Testcase: igt/gem_stolen

Signed-off-by: Ankitprasad Sharma 
---
 drivers/gpu/drm/i915/i915_gem.c | 125 +---
 1 file changed, 104 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 91a2e97..2c94e22 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -614,6 +614,99 @@ shmem_pread_slow(struct page *page, int shmem_page_offset, 
int page_length,
return ret ? - EFAULT : 0;
 }
 
+static inline uint64_t
+slow_user_access(struct io_mapping *mapping,
+uint64_t page_base, int page_offset,
+char __user *user_data,
+int length, bool pwrite)
+{
+   void __iomem *vaddr_inatomic;
+   void *vaddr;
+   uint64_t unwritten;
+
+   vaddr_inatomic = io_mapping_map_wc(mapping, page_base);
+   /* We can use the cpu mem copy function because this is X86. */
+   vaddr = (void __force *)vaddr_inatomic + page_offset;
+   if (pwrite)
+   unwritten = __copy_from_user(vaddr, user_data, length);
+   else
+   unwritten = __copy_to_user(user_data, vaddr, length);
+
+   io_mapping_unmap(vaddr_inatomic);
+   return unwritten;
+}
+
+static int
+i915_gem_gtt_pread(struct drm_device *dev,
+  struct drm_i915_gem_object *obj, uint64_t size,
+  uint64_t data_offset, uint64_t data_ptr)
+{
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   char __user *user_data;
+   uint64_t remain;
+   uint64_t offset, page_base;
+   int page_offset, page_length, ret = 0;
+
+   ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_MAPPABLE);
+   if (ret)
+   goto out;
+
+   ret = i915_gem_object_set_to_gtt_domain(obj, false);
+   if (ret)
+   goto out_unpin;
+
+   ret = i915_gem_object_put_fence(obj);
+   if (ret)
+   goto out_unpin;
+
+   user_data = to_user_ptr(data_ptr);
+   remain = size;
+   offset = i915_gem_obj_ggtt_offset(obj) + data_offset;
+
+   mutex_unlock(>struct_mutex);
+   if (likely(!i915.prefault_disable))
+   ret = fault_in_multipages_writeable(user_data, remain);
+
+   /*
+* page_offset = offset within page
+* page_base = page offset within aperture
+*/
+   page_offset = offset_in_page(offset);
+   page_base = offset & PAGE_MASK;
+
+   while (remain > 0) {
+   /* page_length = bytes to copy for this page */
+   page_length = remain;
+   if ((page_offset + remain) > PAGE_SIZE)
+   page_length = PAGE_SIZE - page_offset;
+
+   /* This is a slow read/write as it tries to read from
+* and write to user memory which may result into page
+* faults
+*/
+   ret = slow_user_access(dev_priv->gtt.mappable, page_base,
+  page_offset, user_data,
+  page_length, false);
+
+   if (ret) {
+   ret = -EFAULT;
+   break;
+   }
+
+   remain -= page_length;
+   user_data += page_length;
+   page_base += page_length;
+   page_offset = 0;
+   }
+
+   mutex_lock(>struct_mutex);
+
+out_unpin:
+   i915_gem_object_ggtt_unpin(obj);
+out:
+   return ret;
+}
+
 static int
 i915_gem_shmem_pread(struct drm_device *dev,
 struct drm_i915_gem_object *obj,
@@ -737,17 +830,14 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
goto out;
}
 
-   /* prime objects have no backing filp to GEM pread/pwrite
-* pages from.
-*/
-   if (!obj->base.filp) {
-   ret = -EINVAL;
-   goto out;
-   }
-
trace_i915_gem_object_pread(obj, args->offset, args->size);
 
-   ret = i915_gem_shmem_pread(dev, obj, args, file);
+   /* pread for non shmem backed objects */
+   if (!obj->base.filp && obj->tiling_mode 

[Intel-gfx] [PATCH 1/6] drm/i915: Clearing buffer objects via CPU/GTT

2015-10-08 Thread ankitprasad . r . sharma
From: Ankitprasad Sharma 

This patch adds support for clearing buffer objects via CPU/GTT. This
is particularly useful for clearing out the non shmem backed objects.
Currently intend to use this only for buffers allocated from stolen
region.

v2: Added kernel doc for i915_gem_clear_object(), corrected/removed
variable assignments (Tvrtko)

Testcase: igt/gem_stolen

Signed-off-by: Ankitprasad Sharma 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_drv.h |  1 +
 drivers/gpu/drm/i915/i915_gem.c | 39 +++
 2 files changed, 40 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2b5d587..f962425 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2848,6 +2848,7 @@ int i915_gem_obj_prepare_shmem_read(struct 
drm_i915_gem_object *obj,
int *needs_clflush);
 
 int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj);
+int i915_gem_clear_object(struct drm_i915_gem_object *obj);
 
 static inline int __sg_page_count(struct scatterlist *sg)
 {
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index bf5ef7a..e6b3bc7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5143,3 +5143,42 @@ fail:
drm_gem_object_unreference(>base);
return ERR_PTR(ret);
 }
+
+/**
+ * i915_gem_clear_object() - Clear buffer object via CPU/GTT
+ * @obj: Buffer object to be cleared
+ *
+ * Return: 0 - success, non-zero - failure
+ */
+int i915_gem_clear_object(struct drm_i915_gem_object *obj)
+{
+   int ret;
+   char __iomem *base;
+   size_t size = obj->base.size;
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+
+   WARN_ON(!mutex_is_locked(>base.dev->struct_mutex));
+   ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_MAPPABLE);
+   if (ret)
+   return ret;
+
+   ret = i915_gem_object_put_fence(obj);
+   if (ret)
+   goto unpin;
+
+   /* Get the CPU virtual address of the buffer */
+   base = ioremap_wc(dev_priv->gtt.mappable_base +
+   i915_gem_obj_ggtt_offset(obj), size);
+   if (base == NULL) {
+   DRM_ERROR("Mapping of gem object to CPU failed!\n");
+   ret = -ENOSPC;
+   goto unpin;
+   }
+
+   memset_io(base, 0, size);
+
+   iounmap(base);
+unpin:
+   i915_gem_object_ggtt_unpin(obj);
+   return ret;
+}
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 4/6] drm/i915: Add support for stealing purgable stolen pages

2015-10-08 Thread ankitprasad . r . sharma
From: Chris Wilson 

If we run out of stolen memory when trying to allocate an object, see if
we can reap enough purgeable objects to free up enough contiguous free
space for the allocation. This is in principle very much like evicting
objects to free up enough contiguous space in the vma when binding
a new object - and you will be forgiven for thinking that the code looks
very similar.

At the moment, we do not allow userspace to allocate objects in stolen,
so there is neither the memory pressure to trigger stolen eviction nor
any purgeable objects inside the stolen arena. However, this will change
in the near future, and so better management and defragmentation of
stolen memory will become a real issue.

v2: Remember to remove the drm_mm_node.

v3: Rebased to the latest drm-intel-nightly (Ankit)

v4: corrected if-else braces format (Tvrtko/kerneldoc)

v5: Rebased to the latest drm-intel-nightly (Ankit)
Added a seperate list to maintain purgable objects from stolen memory
region (Chris/Daniel)

v6: Compiler optimization (merging 2 single loops into one for() loop),
corrected code for object eviction, retire_requests before starting
object eviction (Chris)

v7: Added kernel doc for i915_gem_object_create_stolen()

Testcase: igt/gem_stolen

Signed-off-by: Chris Wilson 
Signed-off-by: Ankitprasad Sharma 
---
 drivers/gpu/drm/i915/i915_debugfs.c|   4 +-
 drivers/gpu/drm/i915/i915_drv.h|  17 +++-
 drivers/gpu/drm/i915/i915_gem.c|  16 
 drivers/gpu/drm/i915/i915_gem_stolen.c | 169 +
 drivers/gpu/drm/i915/intel_pm.c|   4 +-
 5 files changed, 186 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 8797717..13762c1 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -174,7 +174,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object 
*obj)
seq_puts(m, ")");
}
if (obj->stolen)
-   seq_printf(m, " (stolen: %08llx)", obj->stolen->start);
+   seq_printf(m, " (stolen: %08llx)", obj->stolen->base.start);
if (obj->pin_display || obj->fault_mappable) {
char s[3], *t = s;
if (obj->pin_display)
@@ -253,7 +253,7 @@ static int obj_rank_by_stolen(void *priv,
struct drm_i915_gem_object *b =
container_of(B, struct drm_i915_gem_object, obj_exec_link);
 
-   return a->stolen->start - b->stolen->start;
+   return a->stolen->base.start - b->stolen->base.start;
 }
 
 static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bca1572..5612df3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -850,6 +850,12 @@ struct i915_ctx_hang_stats {
bool banned;
 };
 
+struct i915_stolen_node {
+   struct drm_mm_node base;
+   struct list_head mm_link;
+   struct drm_i915_gem_object *obj;
+};
+
 /* This must match up with the value previously used for execbuf2.rsvd1. */
 #define DEFAULT_CONTEXT_HANDLE 0
 
@@ -1279,6 +1285,13 @@ struct i915_gem_mm {
 */
struct list_head unbound_list;
 
+   /**
+* List of stolen objects that have been marked as purgeable and
+* thus available for reaping if we need more space for a new
+* allocation. Ordered by time of marking purgeable.
+*/
+   struct list_head stolen_list;
+
/** Usable portion of the GTT for GEM */
unsigned long stolen_base; /* limited to low memory (32-bit) */
 
@@ -2047,7 +2060,7 @@ struct drm_i915_gem_object {
struct list_head vma_list;
 
/** Stolen memory for this object, instead of being backed by shmem. */
-   struct drm_mm_node *stolen;
+   struct i915_stolen_node *stolen;
struct list_head global_list;
 
struct list_head ring_list[I915_NUM_RINGS];
@@ -2055,6 +2068,7 @@ struct drm_i915_gem_object {
struct list_head obj_exec_link;
 
struct list_head batch_pool_link;
+   struct list_head tmp_link;
 
/**
 * This is set if the object is on the active lists (has pending
@@ -2171,6 +2185,7 @@ struct drm_i915_gem_object {
};
 };
 #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base)
+#define I915_BO_IS_ACTIVE(__obj) (__obj->active)
 
 void i915_gem_track_fb(struct drm_i915_gem_object *old,
   struct drm_i915_gem_object *new,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 54f7df1..91a2e97 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4233,6 +4233,20 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void 
*data,
if (obj->madv == I915_MADV_DONTNEED && obj->pages == NULL)
i915_gem_object_truncate(obj);
 
+ 

[Intel-gfx] [PATCH 6/6] drm/i915: Migrate stolen objects before hibernation

2015-10-08 Thread ankitprasad . r . sharma
From: Chris Wilson 

Ville reminded us that stolen memory is not preserved across
hibernation, and a result of this was that context objects now being
allocated from stolen were being corrupted on S4 and promptly hanging
the GPU on resume.

We want to utilise stolen for as much as possible (nothing else will use
that wasted memory otherwise), so we need a strategy for handling
general objects allocated from stolen and hibernation. A simple solution
is to do a CPU copy through the GTT of the stolen object into a fresh
shmemfs backing store and thenceforth treat it as a normal objects. This
can be refined in future to either use a GPU copy to avoid the slow
uncached reads (though it's hibernation!) and recreate stolen objects
upon resume/first-use. For now, a simple approach should suffice for
testing the object migration.

v2:
Swap PTE for pinned bindings over to the shmemfs. This adds a
complicated dance, but is required as many stolen objects are likely to
be pinned for use by the hardware. Swapping the PTEs should not result
in externally visible behaviour, as each PTE update should be atomic and
the two pages identical. (danvet)

safe-by-default, or the principle of least surprise. We need a new flag
to mark objects that we can wilfully discard and recreate across
hibernation. (danvet)

Just use the global_list rather than invent a new stolen_list. This is
the slowpath hibernate and so adding a new list and the associated
complexity isn't worth it.

v3: Rebased on drm-intel-nightly (Ankit)

Signed-off-by: Chris Wilson 
Signed-off-by: Ankitprasad Sharma 
---
 drivers/gpu/drm/i915/i915_drv.c |  17 ++-
 drivers/gpu/drm/i915/i915_drv.h |   7 +
 drivers/gpu/drm/i915/i915_gem.c | 230 ++--
 drivers/gpu/drm/i915/intel_display.c|   3 +
 drivers/gpu/drm/i915/intel_fbdev.c  |   6 +
 drivers/gpu/drm/i915/intel_pm.c |   2 +
 drivers/gpu/drm/i915/intel_ringbuffer.c |   6 +
 7 files changed, 259 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index e6d7a69..7663fb4 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -968,6 +968,21 @@ static int i915_pm_suspend(struct device *dev)
return i915_drm_suspend(drm_dev);
 }
 
+static int i915_pm_freeze(struct device *dev)
+{
+   int ret;
+
+   ret = i915_gem_freeze(pci_get_drvdata(to_pci_dev(dev)));
+   if (ret)
+   return ret;
+
+   ret = i915_pm_suspend(dev);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
 static int i915_pm_suspend_late(struct device *dev)
 {
struct drm_device *drm_dev = dev_to_i915(dev)->dev;
@@ -1621,7 +1636,7 @@ static const struct dev_pm_ops i915_pm_ops = {
 * @restore, @restore_early : called after rebooting and restoring the
 *hibernation image [PMSG_RESTORE]
 */
-   .freeze = i915_pm_suspend,
+   .freeze = i915_pm_freeze,
.freeze_late = i915_pm_suspend_late,
.thaw_early = i915_pm_resume_early,
.thaw = i915_pm_resume,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5612df3..1efa3b6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2094,6 +2094,12 @@ struct drm_i915_gem_object {
 * Advice: are the backing pages purgeable?
 */
unsigned int madv:2;
+   /**
+* Whereas madv is for userspace, there are certain situations
+* where we want I915_MADV_DONTNEED behaviour on internal objects
+* without conflating the userspace setting.
+*/
+   unsigned int internal_volatile:1;
 
/**
 * Current tiling mode for the object.
@@ -2981,6 +2987,7 @@ int i915_gem_l3_remap(struct drm_i915_gem_request *req, 
int slice);
 void i915_gem_init_swizzling(struct drm_device *dev);
 void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
 int __must_check i915_gpu_idle(struct drm_device *dev);
+int __must_check i915_gem_freeze(struct drm_device *dev);
 int __must_check i915_gem_suspend(struct drm_device *dev);
 void __i915_add_request(struct drm_i915_gem_request *req,
struct drm_i915_gem_object *batch_obj,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 2c94e22..843f3d1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4365,12 +4365,27 @@ static const struct drm_i915_gem_object_ops 
i915_gem_object_ops = {
.put_pages = i915_gem_object_put_pages_gtt,
 };
 
+static struct address_space *
+i915_gem_set_inode_gfp(struct drm_device *dev, struct file *file)
+{
+   struct address_space *mapping = file_inode(file)->i_mapping;
+   gfp_t mask;
+
+   mask = GFP_HIGHUSER | __GFP_RECLAIMABLE;
+   if (IS_CRESTLINE(dev) || 

[Intel-gfx] [PULL] topic/drm-misc

2015-10-08 Thread Daniel Vetter
Hi Dave,

Another round of drm-misc. Unfortunately the DRM_UNLOCKED removal for
DRIVER_MODESET isn't complete yet for lack of review on 1-2 patches.
Otherwise just various stuff all over.

Cheers, Daniel


The following changes since commit 2d4df13c0f9ef56452b1d9a9016cb3946e17bfe5:

  Merge tag 'topic/drm-misc-2015-09-25' of 
git://anongit.freedesktop.org/drm-intel into drm-next (2015-09-30 08:35:45 
+1000)

are available in the git repository at:

  git://anongit.freedesktop.org/drm-intel tags/topic/drm-misc-2015-10-08

for you to fetch changes up to b44f84081b8db1b5830cbd30280ba1109cc1a084:

  drm: Stop using drm_vblank_count() as the hw frame counter (2015-10-07 
16:13:52 +0200)


Daniel Vetter (8):
  drm/doc: Update docs about device instance setup
  drm: Remove __OS_HAS_AGP
  drm: Define a drm_invalid_op ioctl implementation
  drm/drm_ioctl.c: kerneldoc
  drm/vmwgfx: Stop checking for DRM_UNLOCKED
  drm: Remove dummy agp ioctl wrappers
  drm/i915: Remove setparam ioctl
  drm: Hack around CONFIG_AGP=m build failures

Joonas Lahtinen (2):
  drm: Add DRM_ROTATE_MASK and DRM_REFLECT_MASK
  drm: Use DRM_ROTATE_MASK and DRM_REFLECT_MASK

Lukas Wunner (1):
  vga_switcheroo: Add missing locking

Rasmus Villemoes (1):
  vgaarb: use kzalloc in vga_arbiter_add_pci_device()

Thierry Reding (1):
  drm/irq: Use unsigned int pipe in public API

Ville Syrjälä (2):
  drm: Don't zero vblank timestamps from the irq handler
  drm: Stop using drm_vblank_count() as the hw frame counter

 Documentation/DocBook/drm.tmpl  | 100 +---
 drivers/gpu/drm/Makefile|   5 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu.h |   8 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c |   9 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c |  36 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h|   9 +--
 drivers/gpu/drm/armada/armada_drv.c |  10 +--
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c|   8 +-
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c |   2 +-
 drivers/gpu/drm/drm_agpsupport.c|   4 -
 drivers/gpu/drm/drm_bufs.c  |   6 +-
 drivers/gpu/drm/drm_crtc.c  |   3 +-
 drivers/gpu/drm/drm_drv.c   |  55 -
 drivers/gpu/drm/drm_ioc32.c |   6 +-
 drivers/gpu/drm/drm_ioctl.c |  83 ++--
 drivers/gpu/drm/drm_irq.c   |  26 +-
 drivers/gpu/drm/drm_memory.c|   6 +-
 drivers/gpu/drm/drm_pci.c   |  11 +++
 drivers/gpu/drm/drm_platform.c  |   3 +
 drivers/gpu/drm/drm_rect.c  |   4 +-
 drivers/gpu/drm/drm_vm.c|   8 +-
 drivers/gpu/drm/exynos/exynos_drm_crtc.c|   4 +-
 drivers/gpu/drm/exynos/exynos_drm_crtc.h|   4 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c |   2 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c   |   7 +-
 drivers/gpu/drm/gma500/psb_drv.h|   6 +-
 drivers/gpu/drm/gma500/psb_irq.c|   8 +-
 drivers/gpu/drm/gma500/psb_irq.h|   6 +-
 drivers/gpu/drm/i915/i915_debugfs.c |   1 -
 drivers/gpu/drm/i915/i915_dma.c |  33 +---
 drivers/gpu/drm/i915/i915_drv.h |   1 -
 drivers/gpu/drm/i915/i915_gem_fence.c   |   2 +-
 drivers/gpu/drm/i915/i915_irq.c |  34 
 drivers/gpu/drm/imx/imx-drm-core.c  |  10 +--
 drivers/gpu/drm/mga/mga_dma.c   |   4 +-
 drivers/gpu/drm/mga/mga_drv.h   |   6 +-
 drivers/gpu/drm/mga/mga_irq.c   |  20 ++---
 drivers/gpu/drm/msm/msm_drv.c   |  14 ++--
 drivers/gpu/drm/nouveau/nouveau_bo.c|   8 +-
 drivers/gpu/drm/nouveau/nouveau_display.c   |  23 +++---
 drivers/gpu/drm/nouveau/nouveau_display.h   |  12 +--
 drivers/gpu/drm/nouveau/nouveau_drm.c   |   2 +-
 drivers/gpu/drm/omapdrm/omap_drv.c  |   2 +-
 drivers/gpu/drm/omapdrm/omap_drv.h  |   4 +-
 drivers/gpu/drm/omapdrm/omap_fb.c   |   4 +-
 drivers/gpu/drm/omapdrm/omap_irq.c  |  16 ++--
 drivers/gpu/drm/omapdrm/omap_plane.c|   2 +-
 drivers/gpu/drm/qxl/qxl_drv.c   |   7 +-
 drivers/gpu/drm/r128/r128_cce.c |  12 +--
 drivers/gpu/drm/r128/r128_drv.h |   6 +-
 drivers/gpu/drm/r128/r128_irq.c |  16 ++--
 drivers/gpu/drm/radeon/r600_cp.c|  14 ++--
 drivers/gpu/drm/radeon/radeon_agp.c |   8 +-
 drivers/gpu/drm/radeon/radeon_cp.c  |  16 ++--
 drivers/gpu/drm/radeon/radeon_display.c |  25 +++---
 drivers/gpu/drm/radeon/radeon_drv.c |  13 ++-
 

[Intel-gfx] [PATCH 2/3] drm/edid: Round to closest when computing the CEA/HDMI alternate clock

2015-10-08 Thread ville . syrjala
From: Ville Syrjälä 

Rounding to the closest kHz seems like the better option that round
down or up when computing the alternate clock for CEA/HDMI modes.
It'll give us a slightly more accurate clock in some cases.

Not sure why I went for the down+up approach originally. Perhaps
I was thinking we can go back and forth betwen the two frequencies
without introducing errors, but round to closest still maintains
that property.

Cc: Adam Jackson 
Cc: Clint Taylor 
Cc: Libin Yang 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_edid.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 977915c..d5d2c03 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2538,9 +2538,9 @@ cea_mode_alternate_clock(const struct drm_display_mode 
*cea_mode)
 * and the 60Hz variant otherwise.
 */
if (cea_mode->vdisplay == 240 || cea_mode->vdisplay == 480)
-   clock = clock * 1001 / 1000;
+   clock = DIV_ROUND_CLOSEST(clock * 1001, 1000);
else
-   clock = DIV_ROUND_UP(clock * 1000, 1001);
+   clock = DIV_ROUND_CLOSEST(clock * 1000, 1001);
 
return clock;
 }
-- 
2.4.9

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/3] drm/edid: Fix up clock for CEA/HDMI modes specified via detailed timings

2015-10-08 Thread ville . syrjala
From: Ville Syrjälä 

EDID detailed timings have a resolution of 10kHz for the pixel clock, so
they can't represent certain CEA/HDMI modes accurately. If we see a mode
coming in via detailed timings which otherwise matches one of the
CEA/HDMI modes except the clock is just a bit off, let's assume that the
intention was for that mode to be one of the CEA/HDMI modes and go ahead
and fix up the clock to match the CEA/HDMI spec exactly (well, as close
as we can get with the 1 kHz resolution we use).

This should help code that's looking for an exact clock match (eg. i915
audio N/CTS setup).

Cc: Adam Jackson 
Cc: Clint Taylor 
Cc: Libin Yang 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_edid.c | 48 ++
 1 file changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index d895556..977915c 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2418,6 +2418,8 @@ add_cvt_modes(struct drm_connector *connector, struct 
edid *edid)
return closure.modes;
 }
 
+static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode);
+
 static void
 do_detailed_mode(struct detailed_timing *timing, void *c)
 {
@@ -2434,6 +2436,13 @@ do_detailed_mode(struct detailed_timing *timing, void *c)
if (closure->preferred)
newmode->type |= DRM_MODE_TYPE_PREFERRED;
 
+   /*
+* Detailed modes are limited to 10kHz pixel clock resolution,
+* so fix up anything that looks like CEA/HDMI mode, but the 
clock
+* is just slightly off.
+*/
+   fixup_detailed_cea_mode_clock(newmode);
+
drm_mode_probed_add(closure->connector, newmode);
closure->modes++;
closure->preferred = 0;
@@ -3103,6 +3112,45 @@ add_cea_modes(struct drm_connector *connector, struct 
edid *edid)
return modes;
 }
 
+static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode)
+{
+   const struct drm_display_mode *cea_mode;
+   int clock1, clock2, clock;
+   u8 mode_idx;
+   const char *type;
+
+   mode_idx = drm_match_cea_mode(mode) - 1;
+   if (mode_idx < ARRAY_SIZE(edid_cea_modes)) {
+   type = "CEA";
+   cea_mode = _cea_modes[mode_idx];
+   clock1 = cea_mode->clock;
+   clock2 = cea_mode_alternate_clock(cea_mode);
+   } else {
+   mode_idx = drm_match_hdmi_mode(mode) - 1;
+   if (mode_idx < ARRAY_SIZE(edid_4k_modes)) {
+   type = "HDMI";
+   cea_mode = _4k_modes[mode_idx];
+   clock1 = cea_mode->clock;
+   clock2 = hdmi_mode_alternate_clock(cea_mode);
+   } else {
+   return;
+   }
+   }
+
+   /* pick whichever is closest */
+   if (abs(mode->clock - clock1) < abs(mode->clock - clock2))
+   clock = clock1;
+   else
+   clock = clock2;
+
+   if (mode->clock == clock)
+   return;
+
+   DRM_DEBUG("detailed mode matches %s VIC %d, adjusting clock %d -> %d\n",
+ type, mode_idx + 1, mode->clock, clock);
+   mode->clock = clock;
+}
+
 static void
 parse_hdmi_vsdb(struct drm_connector *connector, const u8 *db)
 {
-- 
2.4.9

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 3/3] drm/i915: Use round to closest when computing the CEA 1.001 pixel clocks

2015-10-08 Thread ville . syrjala
From: Ville Syrjälä 

drm_edid.c now computes the alternate CEA clocks using
DIV_ROUND_CLOSEST(), so follow suit in the N/CTS setup to make sure we
pick the right setting for the mode.

Unfortunately we can't actually use DIV_ROUND_CLOSEST() here due to the
({}) construct used, so just stick in raw numbers instead.

Cc: Clint Taylor 
Cc: Libin Yang 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_audio.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_audio.c 
b/drivers/gpu/drm/i915/intel_audio.c
index 56c2f54..4dccd9b 100644
--- a/drivers/gpu/drm/i915/intel_audio.c
+++ b/drivers/gpu/drm/i915/intel_audio.c
@@ -61,21 +61,21 @@ static const struct {
int clock;
u32 config;
 } hdmi_audio_clock[] = {
-   { DIV_ROUND_UP(25200 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 },
+   { 25175, AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 },
{ 25200, AUD_CONFIG_PIXEL_CLOCK_HDMI_25200 }, /* default per bspec */
{ 27000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27000 },
-   { 27000 * 1001 / 1000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 },
+   { 27027, AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 },
{ 54000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54000 },
-   { 54000 * 1001 / 1000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 },
-   { DIV_ROUND_UP(74250 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 },
+   { 54054, AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 },
+   { 74176, AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 },
{ 74250, AUD_CONFIG_PIXEL_CLOCK_HDMI_74250 },
-   { DIV_ROUND_UP(148500 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 
},
+   { 148352, AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 },
{ 148500, AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 },
 };
 
 /* HDMI N/CTS table */
 #define TMDS_297M 297000
-#define TMDS_296M DIV_ROUND_UP(297000 * 1000, 1001)
+#define TMDS_296M 296703
 static const struct {
int sample_rate;
int clock;
-- 
2.4.9

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: 4K audio N value incorrect at 29.97 and 23.98 refresh rate

2015-10-08 Thread Ville Syrjälä
On Wed, Oct 07, 2015 at 02:38:29PM -0700, clinton.a.tay...@intel.com wrote:
> From: Clint Taylor 
> 
> The TMDS_296M define was computing as 296704 but the mode->clock is
> 296700 as defined by EDID. Adjusted define to allow correct detection
> of the need to program the correct N value for 29.97 and 23.98 refresh
> rate.
> 
> Signed-off-by: Clint Taylor 
> ---
>  drivers/gpu/drm/i915/intel_audio.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_audio.c 
> b/drivers/gpu/drm/i915/intel_audio.c
> index 56c2f54..419c979 100644
> --- a/drivers/gpu/drm/i915/intel_audio.c
> +++ b/drivers/gpu/drm/i915/intel_audio.c
> @@ -75,7 +75,7 @@ static const struct {
>  
>  /* HDMI N/CTS table */
>  #define TMDS_297M 297000
> -#define TMDS_296M DIV_ROUND_UP(297000 * 1000, 1001)
> +#define TMDS_296M 296700

Hmm. I think we might want to fix up the mode instead. Let me post a few
patches, and let's see what people think...

>  static const struct {
>   int sample_rate;
>   int clock;
> -- 
> 1.7.9.5
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] igt/kms_addfb_basic: New subtest to check for fb modifier and tiling mode mismatch

2015-10-08 Thread Tvrtko Ursulin

On 07/10/15 22:07, Vivek Kasireddy wrote:


Hi Tvrtko,

On Wed, 7 Oct 2015 15:07:30 +0100
Tvrtko Ursulin  wrote:



Hi,

On 07/10/15 03:35, Vivek Kasireddy wrote:

This new subtest will validate a Y-tiled object's tiling mode
against its associated fb modifier.

Cc: Tvrtko Ursulin 
Signed-off-by: Vivek Kasireddy 
---
   tests/kms_addfb_basic.c | 9 +
   1 file changed, 9 insertions(+)

diff --git a/tests/kms_addfb_basic.c b/tests/kms_addfb_basic.c
index d466e4d..7ca1add 100644
--- a/tests/kms_addfb_basic.c
+++ b/tests/kms_addfb_basic.c
@@ -373,6 +373,15 @@ static void addfb25_ytile(int fd, int gen)
f.handles[0] = gem_bo;
}

+   igt_subtest("addfb25-Y-tiled-X-modifier-mismatch") {
+   igt_require(gen >= 9);
+   igt_require_fb_modifiers(fd);
+   gem_set_tiling(fd, gem_bo, I915_TILING_Y, 1024*4);
+
+   f.modifier[0] = LOCAL_I915_FORMAT_MOD_X_TILED;
+   igt_assert(drmIoctl(fd,
LOCAL_DRM_IOCTL_MODE_ADDFB2, ) < 0 && errno == EINVAL);
+   }
+
igt_subtest("addfb25-Y-tiled") {
igt_require_fb_modifiers(fd);



Wasn't the original WARN triggered by Y tiled object and Y fb
modifier?


Creating a new fb using a Y-tiled object and Y/X fb modifier will not
trigger the original WARN. It'll be triggered only if the fb is going
to be pinned -- and flipped. I am not sure how to get that WARN to be
triggered with the existing suite of igt tests.


Ah yes, you would need to attempt display it, not even necessarily flip 
it. I am sure there are tests which do that. :) I know from recent 
activity kms_rotation_crc for example creates a Y tiled FB and displays 
it. So maybe borrow some code to start with from there.


Regards,

Tvrtko
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v8 0/6] Support for creating/using Stolen memory backed objects

2015-10-08 Thread ankitprasad . r . sharma
From: Ankitprasad Sharma 

This patch series adds support for creating/using Stolen memory backed
objects.

Despite being a unified memory architecture (UMA) some bits of memory
are more equal than others. In particular we have the thorny issue of
stolen memory, memory stolen from the system by the BIOS and reserved
for igfx use. Stolen memory is required for some functions of the GPU
and display engine, but in general it goes wasted. Whilst we cannot
return it back to the system, we need to find some other method for
utilising it. As we do not support direct access to the physical address
in the stolen region, it behaves like a different class of memory,
closer in kin to local GPU memory. This strongly suggests that we need a
placement model like TTM if we are to fully utilize these discrete
chunks of differing memory.

To add support for creating Stolen memory backed objects, we extend the
drm_i915_gem_create structure, by adding a new flag through which user
can specify the preference to allocate the object from stolen memory,
which if set, an attempt will be made to allocate the object from stolen
memory subject to the availability of free space in the stolen region.

This patch series adds support for clearing buffer objects via CPU/GTT.
This is particularly useful for clearing out the memory from stolen
region, but can also be used for other shmem allocated objects. Currently
being used for buffers allocated in the stolen region. Also adding support
for stealing purgable stolen pages, if we run out of stolen memory when
trying to allocate an object.

v2: Added support for read/write from/to objects not backed by
shmem using the pread/pwrite interface.
Also extended the current get_aperture ioctl to retrieve the
total and available size of the stolen region

v3: Removed the extended get_aperture ioctl patch 5 (to be submitted as
part of other patch series), addressed comments by Chris about pread/pwrite
for non shmem backed objects

v4: Rebased to the latest drm-intel-nightly

v5: Addressed comments, replaced patch 1/4 "Clearing buffers via blitter
engine" by "Clearing buffers via CPU/GTT"

v6: Rebased to the latest drm-intel-nightly, Addressed comments, updated
stolen memory purging logic by maintaining a list for purgable stolen
memory objects, enabled pread/pwrite for all non-shmem backed objects
without tiling restrictions

v7: Addressed comments, compiler optimization, new patch added for correct
error code propagation to the userspace

v8: Added a new patch to the series to Migrate stolen objects before
hibernation, as stolen memory is not preserved across hibernation. Added
correct error propagation for shmem as well non-shmem backed object allocation

This can be verified using IGT tests: igt/gem_stolen, igt/gem_create

Ankitprasad Sharma (4):
  drm/i915: Clearing buffer objects via CPU/GTT
  drm/i915: Support for creating Stolen memory backed objects
  drm/i915: Propagating correct error codes to the userspace
  drm/i915: Support for pread/pwrite from/to non shmem backed objects

Chris Wilson (2):
  drm/i915: Add support for stealing purgable stolen pages
  drm/i915: Migrate stolen objects before hibernation

 drivers/gpu/drm/i915/i915_debugfs.c  |   4 +-
 drivers/gpu/drm/i915/i915_dma.c  |   3 +
 drivers/gpu/drm/i915/i915_drv.c  |  17 +-
 drivers/gpu/drm/i915/i915_drv.h  |  27 +-
 drivers/gpu/drm/i915/i915_gem.c  | 451 ---
 drivers/gpu/drm/i915/i915_gem_batch_pool.c   |   4 +-
 drivers/gpu/drm/i915/i915_gem_context.c  |   4 +-
 drivers/gpu/drm/i915/i915_gem_render_state.c |   4 +-
 drivers/gpu/drm/i915/i915_gem_stolen.c   | 210 ++---
 drivers/gpu/drm/i915/i915_guc_submission.c   |   4 +-
 drivers/gpu/drm/i915/intel_display.c |   5 +-
 drivers/gpu/drm/i915/intel_fbdev.c   |  12 +-
 drivers/gpu/drm/i915/intel_lrc.c |   8 +-
 drivers/gpu/drm/i915/intel_overlay.c |   4 +-
 drivers/gpu/drm/i915/intel_pm.c  |   8 +-
 drivers/gpu/drm/i915/intel_ringbuffer.c  |  26 +-
 include/uapi/drm/i915_drm.h  |  16 +
 17 files changed, 694 insertions(+), 113 deletions(-)

-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/2] drm/i915/skl: Allow universal planes to position

2015-10-08 Thread Tvrtko Ursulin


On 07/10/15 15:19, Daniel Vetter wrote:

On Tue, Oct 06, 2015 at 07:28:10PM +0300, Ville Syrjälä wrote:

On Tue, Oct 06, 2015 at 08:16:19AM -0700, Matt Roper wrote:

On Tue, Oct 06, 2015 at 05:42:42PM +0300, Ville Syrjälä wrote:

On Tue, Oct 06, 2015 at 07:29:54AM -0700, Matt Roper wrote:

On Tue, Oct 06, 2015 at 02:32:47PM +0100, Tvrtko Ursulin wrote:


On 10/04/15 10:07, Sonika Jindal wrote:

Signed-off-by: Sonika Jindal 
Reviewed-by: Matt Roper 
---
  drivers/gpu/drm/i915/intel_display.c |7 ++-
  1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index ceb2e61..f0bbc22 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12150,16 +12150,21 @@ intel_check_primary_plane(struct drm_plane *plane,
struct drm_rect *dest = >dst;
struct drm_rect *src = >src;
const struct drm_rect *clip = >clip;
+   bool can_position = false;
int ret;

crtc = crtc ? crtc : plane->crtc;
intel_crtc = to_intel_crtc(crtc);

+   if (INTEL_INFO(dev)->gen >= 9)
+   can_position = true;
+
ret = drm_plane_helper_check_update(plane, crtc, fb,
src, dest, clip,
DRM_PLANE_HELPER_NO_SCALING,
DRM_PLANE_HELPER_NO_SCALING,
-   false, true, >visible);
+   can_position, true,
+   >visible);
if (ret)
return ret;




I have discovered today that, while this allows SetCrtc and SetPlane
ioctls to work with frame buffers which do not cover the plane, page
flips are not that lucky and fail roughly with:

[drm:drm_crtc_check_viewport] Invalid fb size 1080x1080 for CRTC
viewport 1920x1080+0+0.


Maybe I'm misunderstanding your explanation, but a framebuffer is always
required to fill/cover the plane scanning out of it.  What this patch is
supposed to be allowing is for the primary plane to not cover the entire
CRTC (since that's something that only became possible for Intel
hardware on the gen9+ platforms).  I.e., the primary plane is now
allowed to positioned and resized to cover a subset of the CRTC area,
just like "sprite" planes have always been able to.

If you've got a 1080x1080 framebuffer, then it's legal to have a
1080x1080 primary plane while running in 1920x1080 mode on SKL/BXT.
However it is not legal to size the primary plane as 1920x1080 and use
this same 1080x1080 framebuffer with any of our interfaces (setplane,
setcrtc, pageflip, or atomic).

Are you using ioctls/libdrm directly or are you using igt_kms helpers?
IIRC, the IGT helpers will try to be extra helpful and automatically
size the plane to match the framebuffer (unless you override that
behavior), so that might be what's causing the confusion here.


The problem is clear as day in drm_mode_page_flip_ioctl():
ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, >mode, fb);
if (ret)
goto out;

The fix should be easy; just extract the current src coordinates from
the plane state and check those against the new fb size. And then hope
that the plane state is really up to date.


Yep, that's the conclusion we came to once Tvrtko explained what he was
seeing on IRC.  I'm not sure whether non-atomic drivers have enough
state setup by the default helpers to work properly.  Worst case we'll
just assume that a non-atomic driver won't support primary plane
windowing (since none have in the past) and fall back to looking at the
mode for legacy non-atomic drivers.



And I'm sure rotated cases will go boom in some other ways. Probably
we should just switch over to using the full plane update for mmio
flips to fix it.


Yeah; the core looks at a drm_plane->invert_dimensions field that's only
set by omap.  That should probably be updated to look at the state's
rotation on atomic-capable drivers.


We can just look at the src coordinates. Those always match the fb
orientation.


Can we just not bother with legacy pageflips on rotated planes? setplane
works and once you rotate it kinda gets nasty anyway.


I don't know - thought it is simple enough to make it work so why not? 
Just " [PATCH] drm/i915: Consider plane rotation when calculating stride 
in skl_do_mmio_flip" I posted, plus Matt's "[PATCH] drm: Check fb 
against plane size rather than CRTC mode for pageflip​" to allow smaller 
than mode planes.



The problem I see is that with legacy pageflip we also need to hack up
something that doesn't look at plane->state for legacy and all that for a
grand total of about 2 drivers, both getting converted to atomic.


I'll leave the legacy/atomic/etc considerations to the experts. :)

Regards,

Tvrtko



___

Re: [Intel-gfx] [PATCH] drm/i915: 4K audio N value incorrect at 29.97 and 23.98 refresh rate

2015-10-08 Thread Jani Nikula
On Thu, 08 Oct 2015, clinton.a.tay...@intel.com wrote:
> From: Clint Taylor 
>
> The TMDS_296M define was computing as 296704 but the mode->clock is
> 296700 as defined by EDID. Adjusted define to allow correct detection
> of the need to program the correct N value for 29.97 and 23.98 refresh
> rate.




>
> Signed-off-by: Clint Taylor 
> ---
>  drivers/gpu/drm/i915/intel_audio.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_audio.c 
> b/drivers/gpu/drm/i915/intel_audio.c
> index 56c2f54..419c979 100644
> --- a/drivers/gpu/drm/i915/intel_audio.c
> +++ b/drivers/gpu/drm/i915/intel_audio.c
> @@ -75,7 +75,7 @@ static const struct {
>  
>  /* HDMI N/CTS table */
>  #define TMDS_297M 297000
> -#define TMDS_296M DIV_ROUND_UP(297000 * 1000, 1001)
> +#define TMDS_296M 296700
>  static const struct {
>   int sample_rate;
>   int clock;
> -- 
> 1.7.9.5
>
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/4] drm/i915: Unify execlist and legacy request life-cycles

2015-10-08 Thread Chris Wilson
On Tue, Oct 06, 2015 at 03:52:01PM +0100, Nick Hoath wrote:
> There is a desire to simplify the i915 driver by reducing the number of
> different code paths introduced by the LRC / execlists support.  As the
> execlists request is now part of the gem request it is possible and
> desirable to unify the request life-cycles for execlist and legacy
> requests.
> 
> Added a context complete flag to a request which gets set during the
> context switch interrupt.

Wrong approach. Legacy uses the request itself as the indicator for when
the context is complete, if you were to take the same approach for LRC
we would not need to add yet more execlist specific state.

Lines of code is reduced by keeping the GEM semantics the same and just
having execlists hold an indepedent ref on the request for its async
submission approach.
 
> Added a function i915_gem_request_retireable().  A request is considered
> retireable if its seqno passed (i.e. the request has completed) and either
> it was never submitted to the ELSP or its context completed.  This ensures
> that context save is carried out before the last request for a context is
> considered retireable.  retire_requests_ring() now uses
> i915_gem_request_retireable() rather than request_complete() when deciding
> which requests to retire. Requests that were not waiting for a context
> switch interrupt (either as a result of being merged into a following
> request or by being a legacy request) will be considered retireable as
> soon as their seqno has passed.
> 
> Removed the extra request reference held for the execlist request.
> 
> Removed intel_execlists_retire_requests() and all references to
> intel_engine_cs.execlist_retired_req_list.
> 
> Moved context unpinning into retire_requests_ring() for now.  Further work
> is pending for the context pinning - this patch should allow us to use the
> active list to track context and ring buffer objects later.
> 
> Changed gen8_cs_irq_handler() so that notify_ring() is called when
> contexts complete as well as when a user interrupt occurs so that
> notification happens when a request is complete and context save has
> finished.
> 
> v2: Rebase over the read-read optimisation changes
> 
> v3: Reworked IRQ handler after removing IRQ handler cleanup patch
> 
> v4: Fixed various pin leaks
> 
> Issue: VIZ-4277
> Signed-off-by: Thomas Daniel 
> Signed-off-by: Nick Hoath 
> ---
>  drivers/gpu/drm/i915/i915_drv.h |  6 +++
>  drivers/gpu/drm/i915/i915_gem.c | 67 +--
>  drivers/gpu/drm/i915/i915_irq.c | 81 
> +
>  drivers/gpu/drm/i915/intel_lrc.c| 43 +++--
>  drivers/gpu/drm/i915/intel_lrc.h|  2 +-
>  drivers/gpu/drm/i915/intel_ringbuffer.h |  1 -
>  6 files changed, 118 insertions(+), 82 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index fbf0ae9..3d217f9 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2262,6 +2262,12 @@ struct drm_i915_gem_request {
>   /** Execlists no. of times this request has been sent to the ELSP */
>   int elsp_submitted;
>  
> + /**
> +  * Execlists: whether this requests's context has completed after
> +  * submission to the ELSP
> +  */
> + bool ctx_complete;
> +
>  };
>  
>  int i915_gem_request_alloc(struct intel_engine_cs *ring,
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 52642af..fc82171 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -1386,6 +1386,24 @@ __i915_gem_request_retire__upto(struct 
> drm_i915_gem_request *req)
>  typeof(*tmp), list);
>  
>   i915_gem_request_retire(tmp);
> +
> + if (i915.enable_execlists) {
> + struct intel_context *ctx = tmp->ctx;
> + struct drm_i915_private *dev_priv =
> + engine->dev->dev_private;
> + unsigned long flags;
> + struct drm_i915_gem_object *ctx_obj =
> + ctx->engine[engine->id].state;
> +
> + spin_lock_irqsave(>execlist_lock, flags);
> +
> + if (ctx_obj && (ctx != engine->default_context))
> + intel_lr_context_unpin(tmp);
> +
> + intel_runtime_pm_put(dev_priv);
> + spin_unlock_irqrestore(>execlist_lock, flags);
> + }

Why here? Surely you intended this to be called by
i915_gem_request_retire(). The runtime pm interaction is wrong, that is
handled by GPU busyness tracking. But by doing this at this juncture you
now increase the frequency at which we have to recreate the iomapping,
most noticeable on bsw+ and take more spinlocks unnecessarily.

Also since you no longer do 

Re: [Intel-gfx] [PATCH 3/6] drm/i915: Propagating correct error codes to the userspace

2015-10-08 Thread Tvrtko Ursulin


Hi,

On 08/10/15 07:24, ankitprasad.r.sha...@intel.com wrote:

From: Ankitprasad Sharma 

Propagating correct error codes to userspace by using ERR_PTR and
PTR_ERR macros for stolen memory based object allocation. We generally
return -ENOMEM to the user whenever there is a failure in object
allocation. This patch helps user to identify the correct reason for the
failure and not just -ENOMEM each time.

v2: Moved the patch up in the series, added error propagation for
i915_gem_alloc_object too (Chris)

Signed-off-by: Ankitprasad Sharma 
---
  drivers/gpu/drm/i915/i915_gem.c  | 15 +-
  drivers/gpu/drm/i915/i915_gem_batch_pool.c   |  4 +--
  drivers/gpu/drm/i915/i915_gem_context.c  |  4 +--
  drivers/gpu/drm/i915/i915_gem_render_state.c |  4 +--
  drivers/gpu/drm/i915/i915_gem_stolen.c   | 43 
  drivers/gpu/drm/i915/i915_guc_submission.c   |  4 +--
  drivers/gpu/drm/i915/intel_display.c |  2 +-
  drivers/gpu/drm/i915/intel_fbdev.c   |  6 ++--
  drivers/gpu/drm/i915/intel_lrc.c |  8 +++---
  drivers/gpu/drm/i915/intel_overlay.c |  4 +--
  drivers/gpu/drm/i915/intel_pm.c  |  2 +-
  drivers/gpu/drm/i915/intel_ringbuffer.c  | 20 ++---
  12 files changed, 61 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d3f4321..54f7df1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -393,9 +393,9 @@ i915_gem_create(struct drm_file *file,
if (flags & I915_CREATE_PLACEMENT_STOLEN) {
mutex_lock(>struct_mutex);
obj = i915_gem_object_create_stolen(dev, size);
-   if (!obj) {
+   if (IS_ERR(obj)) {
mutex_unlock(>struct_mutex);
-   return -ENOMEM;
+   return PTR_ERR(obj);
}

/* Always clear fresh buffers before handing to userspace */
@@ -411,8 +411,8 @@ i915_gem_create(struct drm_file *file,
obj = i915_gem_alloc_object(dev, size);
}

-   if (obj == NULL)
-   return -ENOMEM;
+   if (IS_ERR(obj))
+   return PTR_ERR(obj);

>

ret = drm_gem_handle_create(file, >base, );
/* drop reference from allocate - handle holds it now */
@@ -4273,14 +4273,15 @@ struct drm_i915_gem_object 
*i915_gem_alloc_object(struct drm_device *dev,
struct drm_i915_gem_object *obj;
struct address_space *mapping;
gfp_t mask;
+   int ret = 0;

obj = i915_gem_object_alloc(dev);
if (obj == NULL)
-   return NULL;
+   return ERR_PTR(-ENOMEM);

-   if (drm_gem_object_init(dev, >base, size) != 0) {
+   if ((ret = drm_gem_object_init(dev, >base, size)) != 0) {
i915_gem_object_free(obj);
-   return NULL;
+   return ERR_PTR(ret);
}

mask = GFP_HIGHUSER | __GFP_RECLAIMABLE;
diff --git a/drivers/gpu/drm/i915/i915_gem_batch_pool.c 
b/drivers/gpu/drm/i915/i915_gem_batch_pool.c
index 7bf2f3f..d79caa2 100644
--- a/drivers/gpu/drm/i915/i915_gem_batch_pool.c
+++ b/drivers/gpu/drm/i915/i915_gem_batch_pool.c
@@ -135,8 +135,8 @@ i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool,
int ret;

obj = i915_gem_alloc_object(pool->dev, size);
-   if (obj == NULL)
-   return ERR_PTR(-ENOMEM);
+   if (IS_ERR(obj))
+   return obj;

ret = i915_gem_object_get_pages(obj);
if (ret)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 74aa0c9..603600c 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -157,8 +157,8 @@ i915_gem_alloc_context_obj(struct drm_device *dev, size_t 
size)
int ret;

obj = i915_gem_alloc_object(dev, size);
-   if (obj == NULL)
-   return ERR_PTR(-ENOMEM);
+   if (IS_ERR(obj))
+   return obj;

/*
 * Try to make the context utilize L3 as well as LLC.
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c 
b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 5026a62..50d010e 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -58,8 +58,8 @@ static int render_state_init(struct render_state *so, struct 
drm_device *dev)
return -EINVAL;

so->obj = i915_gem_alloc_object(dev, 4096);
-   if (so->obj == NULL)
-   return -ENOMEM;
+   if (IS_ERR(so->obj))
+   return PTR_ERR(so->obj);

ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0);
if (ret)
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 

Re: [Intel-gfx] [PATCH 4/6] drm/i915: Add support for stealing purgable stolen pages

2015-10-08 Thread Tvrtko Ursulin


Hi,

On 08/10/15 07:24, ankitprasad.r.sha...@intel.com wrote:

From: Chris Wilson 

If we run out of stolen memory when trying to allocate an object, see if
we can reap enough purgeable objects to free up enough contiguous free
space for the allocation. This is in principle very much like evicting
objects to free up enough contiguous space in the vma when binding
a new object - and you will be forgiven for thinking that the code looks
very similar.

At the moment, we do not allow userspace to allocate objects in stolen,
so there is neither the memory pressure to trigger stolen eviction nor
any purgeable objects inside the stolen arena. However, this will change
in the near future, and so better management and defragmentation of
stolen memory will become a real issue.

v2: Remember to remove the drm_mm_node.

v3: Rebased to the latest drm-intel-nightly (Ankit)

v4: corrected if-else braces format (Tvrtko/kerneldoc)

v5: Rebased to the latest drm-intel-nightly (Ankit)
Added a seperate list to maintain purgable objects from stolen memory
region (Chris/Daniel)

v6: Compiler optimization (merging 2 single loops into one for() loop),
corrected code for object eviction, retire_requests before starting
object eviction (Chris)

v7: Added kernel doc for i915_gem_object_create_stolen()

Testcase: igt/gem_stolen

Signed-off-by: Chris Wilson 
Signed-off-by: Ankitprasad Sharma 
---
  drivers/gpu/drm/i915/i915_debugfs.c|   4 +-
  drivers/gpu/drm/i915/i915_drv.h|  17 +++-
  drivers/gpu/drm/i915/i915_gem.c|  16 
  drivers/gpu/drm/i915/i915_gem_stolen.c | 169 +
  drivers/gpu/drm/i915/intel_pm.c|   4 +-
  5 files changed, 186 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 8797717..13762c1 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -174,7 +174,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object 
*obj)
seq_puts(m, ")");
}
if (obj->stolen)
-   seq_printf(m, " (stolen: %08llx)", obj->stolen->start);
+   seq_printf(m, " (stolen: %08llx)", obj->stolen->base.start);
if (obj->pin_display || obj->fault_mappable) {
char s[3], *t = s;
if (obj->pin_display)
@@ -253,7 +253,7 @@ static int obj_rank_by_stolen(void *priv,
struct drm_i915_gem_object *b =
container_of(B, struct drm_i915_gem_object, obj_exec_link);

-   return a->stolen->start - b->stolen->start;
+   return a->stolen->base.start - b->stolen->base.start;
  }

  static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bca1572..5612df3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -850,6 +850,12 @@ struct i915_ctx_hang_stats {
bool banned;
  };

+struct i915_stolen_node {
+   struct drm_mm_node base;
+   struct list_head mm_link;
+   struct drm_i915_gem_object *obj;
+};
+
  /* This must match up with the value previously used for execbuf2.rsvd1. */
  #define DEFAULT_CONTEXT_HANDLE 0

@@ -1279,6 +1285,13 @@ struct i915_gem_mm {
 */
struct list_head unbound_list;

+   /**
+* List of stolen objects that have been marked as purgeable and
+* thus available for reaping if we need more space for a new
+* allocation. Ordered by time of marking purgeable.
+*/
+   struct list_head stolen_list;
+
/** Usable portion of the GTT for GEM */
unsigned long stolen_base; /* limited to low memory (32-bit) */

@@ -2047,7 +2060,7 @@ struct drm_i915_gem_object {
struct list_head vma_list;

/** Stolen memory for this object, instead of being backed by shmem. */
-   struct drm_mm_node *stolen;
+   struct i915_stolen_node *stolen;
struct list_head global_list;

struct list_head ring_list[I915_NUM_RINGS];
@@ -2055,6 +2068,7 @@ struct drm_i915_gem_object {
struct list_head obj_exec_link;

struct list_head batch_pool_link;
+   struct list_head tmp_link;

/**
 * This is set if the object is on the active lists (has pending
@@ -2171,6 +2185,7 @@ struct drm_i915_gem_object {
};
  };
  #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base)
+#define I915_BO_IS_ACTIVE(__obj) (__obj->active)

  void i915_gem_track_fb(struct drm_i915_gem_object *old,
   struct drm_i915_gem_object *new,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 54f7df1..91a2e97 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4233,6 +4233,20 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void 
*data,
if (obj->madv == I915_MADV_DONTNEED && 

Re: [Intel-gfx] [v2] drm/i915/skl: Init cdclk in the driver rather than relying on pre-os

2015-10-08 Thread Kumar, Shobhit

On 10/08/2015 04:59 PM, Imre Deak wrote:

On to, 2015-10-08 at 09:58 +0530, Shobhit Kumar wrote:

Reuse what is programmed by pre-os, but in case there is no pre-os
initialization, init the cdclk with the max value by default untill
dynamic cdclk support comes.

v2: Check if BIOS programmed correctly rather than always calling init
 - Do validation of programmed cdctl and what it is expected
 - Only do slk_init_cdclk if validation failed else reuse BIOS
   programmed value

Cc: Imre Deak 
Cc: Ville Syrjälä 
Signed-off-by: Shobhit Kumar 
---
  drivers/gpu/drm/i915/intel_ddi.c | 18 -
  drivers/gpu/drm/i915/intel_display.c | 39 +++-
  2 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 2d3cc82..3ec5618 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2946,11 +2946,19 @@ void intel_ddi_pll_init(struct drm_device *dev)
int cdclk_freq;

cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
-   dev_priv->skl_boot_cdclk = cdclk_freq;
-   if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
-   DRM_ERROR("LCPLL1 is disabled\n");
-   else
-   intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
+
+   /* Invalid CDCLK from BIOS ? */
+   if (cdclk_freq < 0) {
+   /* program to maximum cdclk till we have dynamic cdclk 
support */
+   dev_priv->skl_boot_cdclk = 675000;
+   skl_init_cdclk(dev_priv);


This would still try to reprogram CDCLK if BIOS enabled an output with
an incorrect CDCLK decimal part. Isn't this the exact scenario you're
seeing? As said before reprogramming CDCLK in that case would require
disabling the outputs first.


I went with the hypothesis that if VBIOS/GOP was loaded it would have to 
correct the cdclock, with wrong decimal value display cannot be enabled. 
For example AUX will fail on SKL. So for correct display output enabled 
cdclock has to be correctly programmed. If it is wrong display was not 
enabled at all.


The scenario which I am seeing is VBIOS/GOP is not loaded at all, and 
the pre-os is not leaving cdclock in correct state.




We would also need to call skl_init_cdclk if the BIOS hasn't enabled the
PLL for some reason. But I guess that could be a separate change.


+   } else {
+   dev_priv->skl_boot_cdclk = cdclk_freq;
+   if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
+   DRM_ERROR("LCPLL1 is disabled\n");
+   else
+   intel_display_power_get(dev_priv, 
POWER_DOMAIN_PLLS);
+   }
} else if (IS_BROXTON(dev)) {
broxton_init_cdclk(dev);
broxton_ddi_phy_init(dev);
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index bbeb6d3..f734410 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6634,12 +6634,15 @@ static int skylake_get_display_clock_speed(struct 
drm_device *dev)
uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
uint32_t cdctl = I915_READ(CDCLK_CTL);
uint32_t linkrate;
+   int freq;

if (!(lcpll1 & LCPLL_PLL_ENABLE))
return 24000; /* 24MHz is the cd freq with NSSC ref */

-   if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540)
-   return 54;
+   if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540) {
+   freq = 54;
+   goto verify;
+   }

linkrate = (I915_READ(DPLL_CTRL1) &
DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1;
@@ -6649,30 +6652,46 @@ static int skylake_get_display_clock_speed(struct 
drm_device *dev)
/* vco 8640 */
switch (cdctl & CDCLK_FREQ_SEL_MASK) {
case CDCLK_FREQ_450_432:
-   return 432000;
+   freq = 432000;
+   break;
case CDCLK_FREQ_337_308:
-   return 308570;
+   freq = 308570;
+   break;
case CDCLK_FREQ_675_617:
-   return 617140;
+   freq = 617140;
+   break;
default:
WARN(1, "Unknown cd freq selection\n");
+   return -EINVAL;
}
} else {
/* vco 8100 */
switch (cdctl & CDCLK_FREQ_SEL_MASK) {
case CDCLK_FREQ_450_432:
-   return 45;
+   freq = 45;
+   break;
 

Re: [Intel-gfx] [PATCH 2/5] drm/i915: Notify user about outdated dmc firmware

2015-10-08 Thread Mika Kuoppala
Animesh Manna  writes:

> On 9/21/2015 2:00 PM, Mika Kuoppala wrote:
>> Jani Nikula  writes:
>>
>>> On Fri, 18 Sep 2015, Mika Kuoppala  wrote:
 If csr/dmc firmware is known to be outdated, notify
 user.
>>> What would break if we requested a firmware version that works? Or we've
>>> made it so that we only request the major version because there's not
>>> supposed to be changes like this between minor versions...?
>>>
>> I guess the question is more of a what should we do
>> if there is only outdated (known bad) firmware available.
>>
>> Refuse to load and limb onwards, or return with error code
>> on driver init.
>>
>> Latter would force firmware and version to be mandatory and the
>> version to be tightly coupled to kernel driver version.
>
> A softlink is used to use recommended firmware for dmc and the same 
> information is published through 01.org for the firmware user.
> Imo, we should not have this kind of hack in code which will change over time 
> and this is responsibility of repo-owner to link correct recommended firmware 
> for new kernel update.
>

On machines that had 1.19 symlinked, in filesystem, execlist submission
sometimes broke due to interrupt delivery problem. To reach a conclusion
that it was csr firmware, before 1.21 was out, took quite amount of work.

I bet there are still machines with 1.19 only, and we get to 
wade through error states trying to connect the dots.

The dmc/csr firmware is part of our driver functionality. Apparently
it is very tightly coupled to our driver functionality as it can
break things outside of its own domain.

And currently it is loosely coupled black box with our driver,
through symlink, accepting any version that happens to be in customers 
filesystem.

So we recommend latest in website and end up in a situation
that user gets what happens to be in filesystem. Even a known
broken version? And we will keep debugging these problems caused by
broken version? I don't want any more dimensions in our triaging
space, the distributio/firmware version dimension.

Symlink also means that bisectability is very close to worthless on these
kind of bugs. Both in our machines and also on customers. We have
loosely coupled, black box entity, affecting our driver depending
on customers filesystem. Symlink threw that valuable tool out, and
we gained what?

So we are left with triaging. Which is true detective work as there are
no traces of firmware versions nor loading success/fails on
logs/error states.

From where I look at, the version blacklist is not a hack. It is a cure.

-Mika

> -Animesh
>
>> -Mika
>>
>>> BR,
>>> Jani.
>>>
>>>
>>>
 Signed-off-by: Mika Kuoppala 
 ---
   drivers/gpu/drm/i915/intel_csr.c | 9 +
   1 file changed, 9 insertions(+)

 diff --git a/drivers/gpu/drm/i915/intel_csr.c 
 b/drivers/gpu/drm/i915/intel_csr.c
 index 58edc3f..73807c3 100644
 --- a/drivers/gpu/drm/i915/intel_csr.c
 +++ b/drivers/gpu/drm/i915/intel_csr.c
 @@ -45,6 +45,9 @@
   
   MODULE_FIRMWARE(I915_CSR_SKL);
   
 +#define RECOMMENDED_FW_MAJOR  1
 +#define RECOMMENDED_FW_MINOR  21
 +
   /*
   * SKL CSR registers for DC5 and DC6
   */
 @@ -387,6 +390,12 @@ static void finish_csr_load(const struct firmware 
 *fw, void *context)
   
DRM_DEBUG_KMS("Finished loading %s v%u.%u\n", dev_priv->csr.fw_path,
  csr->dmc_ver_major, csr->dmc_ver_minor);
 +
 +  if (csr->dmc_ver_major < RECOMMENDED_FW_MAJOR ||
 +  csr->dmc_ver_minor < RECOMMENDED_FW_MINOR)
 +  DRM_INFO("Outdated dmc firmware found, please upgrade to %u.%u 
 or newer\n",
 +   RECOMMENDED_FW_MAJOR, RECOMMENDED_FW_MINOR);
 +
   out:
if (fw_loaded)
intel_runtime_pm_put(dev_priv);
 -- 
 2.1.4

 ___
 Intel-gfx mailing list
 Intel-gfx@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>> -- 
>>> Jani Nikula, Intel Open Source Technology Center
>> ___
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Convert WARNs during userptr revoke to SIGBUS

2015-10-08 Thread Tvrtko Ursulin


On 28/09/15 15:14, Daniel Vetter wrote:

On Mon, Sep 28, 2015 at 02:52:30PM +0100, Chris Wilson wrote:

On Mon, Sep 28, 2015 at 03:42:22PM +0200, Daniel Vetter wrote:

On Wed, Sep 23, 2015 at 09:07:24PM +0100, Chris Wilson wrote:

If the client revokes the virtual address it asked to be mapped into GPU
space via userptr (by using anything along the lines of mmap, mprotect,
madvise, munmap, ftruncate etc) the mmu notifier sends a range
invalidate command to userptr. Upon receiving the invalidation signal
for the revoked range, we try to release the struct pages we pinned into
the GTT. However, this can fail if any of the GPU's VMA are pinned for
use by the hardware (i.e. despite the user's intention we cannot
relinquish the client's address range and keep uptodate with whatever is
placed in there). Currently we emit a few WARN so that we would notice
if this every occurred in the wild; it has. Sadly this means we need to
replace those WARNs with the proper SIGBUS to the offending clients
instead.

Signed-off-by: Chris Wilson 
Cc: Tvrtko Ursulin 
Cc: Michał Winiarski 
---
  drivers/gpu/drm/i915/i915_gem_userptr.c | 41 +
  1 file changed, 37 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c 
b/drivers/gpu/drm/i915/i915_gem_userptr.c
index f75d9011..efb404b9fe69 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -81,11 +81,44 @@ static void __cancel_userptr__worker(struct work_struct 
*work)
was_interruptible = dev_priv->mm.interruptible;
dev_priv->mm.interruptible = false;

-   list_for_each_entry_safe(vma, tmp, >vma_list, obj_link) {
-   int ret = i915_vma_unbind(vma);
-   WARN_ON(ret && ret != -EIO);
+   list_for_each_entry_safe(vma, tmp, >vma_list, obj_link)
+   i915_vma_unbind(vma);
+   if (i915_gem_object_put_pages(obj)) {
+   struct task_struct *p;
+
+   DRM_ERROR("Unable to revoke ownership by userptr of"
+ " invalidated address range, sending SIGBUS"
+ " to attached clients.\n");
+
+   rcu_read_lock();
+   for_each_process(p) {
+   siginfo_t info;
+
+   /* This doesn't capture everyone who has
+* the pages pinned behind a VMA as we
+* do not have that tracking information
+* available, it does however kill the
+* original process (and siblings) who
+* created the userptr and presumably tried
+* to reuse the address space despite having
+* pinned it (possibly indirectly) to the hw.
+* Arguably, we don't even want to kill the
+* other processes as they are not at fault,
+* likely to be a display server, and hopefully
+* will release the pages in due course once
+* the client is dead.
+*/
+   if (p->mm != obj->userptr.mm->mm)
+   continue;
+
+   info.si_signo = SIGBUS;
+   info.si_errno = 0;
+   info.si_code = BUS_ADRERR;
+   info.si_addr = (void __user *)obj->userptr.ptr;
+   force_sig_info(SIGBUS, , p);
+   }
+   rcu_read_unlock();


Why do we need to send a SIGBUS? It won't tear down the offending gem bo,
any new users will hopefully get it, and abusing SIGBUS without the thread
actually doing a memory access is a bit surprising. DRM_DEBUG seems to be
the most we can do here I think - I think userspace being able to do this
is just a fundamental property of userptr.


It is not the bo that is at fault but the *client's* *address* *space*
that is being changed. It is equivalent to mmap on a truncated file i.e.
if the client tries to use its mmapping after it has truncated the file
it is scolded via SIGBUS.


But existing SIGBUS is thread-bound and comes with the fault address
attached. This is just the gpu being a bit unhappy, so the SIGBUS comes
out of complete nowhere to smack the userspace thread. Any kind of SIGBUS
catcher userspace has for other reasons might be supremely surprised by
this and do stupid things. Hence I don't think throwing SIGBUS here is
correct behaviour. And there doesn't seem to be anything else suitable

Re: [Intel-gfx] [PATCH 2/2] drm/i915: Drop i915_gem_obj_is_pinned() from set-cache-level

2015-10-08 Thread Chris Wilson
On Thu, Oct 08, 2015 at 10:32:39AM +0100, Tvrtko Ursulin wrote:
> 
> On 07/10/15 17:19, Chris Wilson wrote:
> >On Wed, Oct 07, 2015 at 04:57:25PM +0100, Tvrtko Ursulin wrote:
> >>
> >>Hi,
> >>
> >>On 06/10/15 11:39, Chris Wilson wrote:
> >>>Since the remove of the pin-ioctl, we only care about not changing the
> >>>cache level on buffers pinned to the hardware as indicated by
> >>>obj->pin_display. So we can safely replace i915_gem_object_is_pinned()
> 
> [snip]
> 
> >>>diff --git a/drivers/gpu/drm/i915/i915_gem.c 
> >>>b/drivers/gpu/drm/i915/i915_gem.c
> >>>index d4a3bdf0c5b6..2b8ed7a2faab 100644
> >>>--- a/drivers/gpu/drm/i915/i915_gem.c
> >>>+++ b/drivers/gpu/drm/i915/i915_gem.c
> >>>@@ -3629,31 +3629,34 @@ int i915_gem_object_set_cache_level(struct 
> >>>drm_i915_gem_object *obj,
> >>>  {
> >>>   struct drm_device *dev = obj->base.dev;
> >>>   struct i915_vma *vma, *next;
> >>>+  bool bound = false;
> >>>   int ret = 0;
> >>>
> >>>   if (obj->cache_level == cache_level)
> >>>   goto out;
> >>>
> >>>-  if (i915_gem_obj_is_pinned(obj)) {
> >>>-  DRM_DEBUG("can not change the cache level of pinned objects\n");
> >>>-  return -EBUSY;
> >>>-  }
> >>>-
> >>>   list_for_each_entry_safe(vma, next, >vma_list, vma_link) {
> >>>+  if (!drm_mm_node_allocated(>node))
> >>>+  continue;
> >>>+
> >>>+  if (vma->pin_count) {
> >>>+  DRM_DEBUG("can not change the cache level of pinned 
> >>>objects\n");
> >>>+  return -EBUSY;
> >>>+  }
> >>>+
> >>
> >>But this is the same as i915_gem_obj_is_pinned, where is the
> >>obj->pin_display change commit message talks about?
> >
> >Right here. The difference is that we are only iterating the vma list
> >once rather than 3x.
> 
> Thats true, but the commit says it is going to use obj->pin_display
> for something and then doesn't use it at all. Riddles in patches are
> not that hot. :)

I was trying to explain what the actual rules pertaining to the
rebinding the vma was. We can rebind anything that isn't pinned and the
only thing pinned here can be obj->pin_display.
 
> >>>   if (!i915_gem_valid_gtt_space(vma, cache_level)) {
> >>>   ret = i915_vma_unbind(vma);
> >>>   if (ret)
> >>>   return ret;
> >>>-  }
> >>>+  } else
> >>>+  bound = true;
> >>>   }
> >>>
> >>>-  if (i915_gem_obj_bound_any(obj)) {
> >>>+  if (bound) {
> >>>   ret = i915_gem_object_wait_rendering(obj, false);
> >>>   if (ret)
> >>>   return ret;
> >>>
> >>>-  i915_gem_object_finish_gtt(obj);
> >>>-
> >>>   /* Before SandyBridge, you could not use tiling or fence
> >>>* registers with snooped memory, so relinquish any fences
> >>>* currently pointing to our region in the aperture.
> >>>@@ -3664,13 +3667,18 @@ int i915_gem_object_set_cache_level(struct 
> >>>drm_i915_gem_object *obj,
> >>>   return ret;
> >>>   }
> >>>
> >>>-  list_for_each_entry(vma, >vma_list, vma_link)
> >>>-  if (drm_mm_node_allocated(>node)) {
> >>>-  ret = i915_vma_bind(vma, cache_level,
> >>>-  PIN_UPDATE);
> >>>-  if (ret)
> >>>-  return ret;
> >>>-  }
> >>>+  /* Access to snoopable pages through the GTT is incoherent. */
> >>>+  if (cache_level != I915_CACHE_NONE && !HAS_LLC(dev))
> >>>+  i915_gem_release_mmap(obj);
> >>
> >>Don't fully understand this one - but my question is this.
> >>Previously userspace would lose mappings on cache level changes any
> >>time, after this only on !LLC when turning on caching mode. So this
> >>means userspace needs to know about this change and modify it's
> >>behavior? Or what exactly would happen in practice?
> >
> >No. Userspace has no knowledge of the kernel handling the PTEs, its
> >mapping is persistent (i.e. the obj->mmap_offset inside the dev->mappping).
> >Otoh, we are improving the situation so even if userspace tries to avoid
> >set-cache-level nothing is lost.
> 
> Hm so if a VMA is re-bound in this process and it could have gotten
> a new GGTT address, why it is not necessary to always release mmaps
> and so to update CPU PTEs?

The VMA are not moved by this function, only the PTEs are rewritten. The
GTT ignores the bits we are changing on llc architectures. On !llc using
the GTT to access snoopable PTE is verboten and does cause machine hangs.
 
> Also what about Sandy Bridge? Commit message mentions it and the
> code doesn't?

Age of patch and lack of !llc snb+ at the time, and the state of my mind
when I think about llc.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org

Re: [Intel-gfx] [PATCH 5/5] drm/i915: Add dmc firmware debugfs status entry

2015-10-08 Thread Animesh Manna



On 9/18/2015 8:47 PM, Mika Kuoppala wrote:

Add debugfs entry for csr/dmc fw to inspect firmware
loading status and version.

Signed-off-by: Mika Kuoppala 
---
  drivers/gpu/drm/i915/i915_debugfs.c | 32 
  drivers/gpu/drm/i915/i915_reg.h |  5 +
  drivers/gpu/drm/i915/intel_csr.c|  3 ---
  3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 72ae347..4a798a6 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2509,6 +2509,37 @@ static int i915_guc_log_dump(struct seq_file *m, void 
*data)
return 0;
  }
  
+static int i915_dmc_load_status_info(struct seq_file *m, void *data)

+{
+   struct drm_info_node *node = m->private;
+   struct drm_i915_private *dev_priv = node->minor->dev->dev_private;
+   struct intel_csr *csr = _priv->csr;
+   uint32_t state;
+   const char * const state_str[] = { "uninitialized",
+  "loaded",
+  "failed",
+  "unknown" };
+
+   seq_puts(m, "DMC firmware status:\n");
+
+   mutex_lock(_priv->csr_lock);


DMC-redesign series is floated for review where csr_lock is removed completely, 
not sure do we need mutex lock here.


+
+   seq_printf(m, "\tpath: %s\n", csr->fw_path);
+   seq_printf(m, "\tfw_ver: %u.%u\n", csr->dmc_ver_major,
+  csr->dmc_ver_minor);
+   seq_printf(m, "\tsize: %u bytes\n", csr->dmc_fw_size * 4);
+   state = (uint32_t)csr->state <= 3 ? csr->state : 3;
+   seq_printf(m, "\tstate: %s\n", state_str[state]);
+
+   seq_printf(m, "\tprogram base: 0x%08x\n", I915_READ(CSR_PROGRAM_BASE));
+   seq_printf(m, "\tssp base: 0x%08x\n", I915_READ(CSR_SSP_BASE));
+   seq_printf(m, "\thtp: 0x%08x\n", I915_READ(CSR_HTP_SKL));


Better print dmc firmware loading related info if firmware is loaded 
successfully.
In failure case, only firmware not loaded msg with path I feel is sufficient.

-Animesh


+
+   mutex_unlock(_priv->csr_lock);
+
+   return 0;
+}
+
  static int i915_edp_psr_status(struct seq_file *m, void *data)
  {
struct drm_info_node *node = m->private;
@@ -5173,6 +5204,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_guc_info", i915_guc_info, 0},
{"i915_guc_load_status", i915_guc_load_status_info, 0},
{"i915_guc_log_dump", i915_guc_log_dump, 0},
+   {"i915_dmc_load_status", i915_dmc_load_status_info, 0},
{"i915_frequency_info", i915_frequency_info, 0},
{"i915_hangcheck_info", i915_hangcheck_info, 0},
{"i915_drpc_info", i915_drpc_info, 0},
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 67bf205..cd040ff 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7977,4 +7977,9 @@ enum skl_disp_power_wells {
  #define GEN9_VEBOX_MOCS_0 0xcb00  /* Video MOCS base register*/
  #define GEN9_BLT_MOCS_0   0xcc00  /* Blitter MOCS base register*/
  
+/* DMC/CSR firmware */

+#define CSR_PROGRAM_BASE   0x8
+#define CSR_SSP_BASE   0x8F074
+#define CSR_HTP_SKL0x8F004
+
  #endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c
index 73807c3..876c839 100644
--- a/drivers/gpu/drm/i915/intel_csr.c
+++ b/drivers/gpu/drm/i915/intel_csr.c
@@ -51,11 +51,8 @@ MODULE_FIRMWARE(I915_CSR_SKL);
  /*
  * SKL CSR registers for DC5 and DC6
  */
-#define CSR_PROGRAM_BASE   0x8
  #define CSR_SSP_BASE_ADDR_GEN90x2FC0
  #define CSR_HTP_ADDR_SKL  0x00500034
-#define CSR_SSP_BASE   0x8F074
-#define CSR_HTP_SKL0x8F004
  #define CSR_LAST_WRITE0x8F034
  #define CSR_LAST_WRITE_VALUE  0xc003b400
  /* MMIO address range for CSR program (0x8 - 0x82FFF) */


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 6/9] drm/i915: driver based PASID handling

2015-10-08 Thread Tomas Elf

On 07/10/2015 17:14, Daniel Vetter wrote:

On Wed, Oct 07, 2015 at 08:16:42AM -0700, Jesse Barnes wrote:

On 10/07/2015 06:00 AM, David Woodhouse wrote:

On Fri, 2015-09-04 at 09:59 -0700, Jesse Barnes wrote:

+
+   ret = handle_mm_fault(mm, vma, address,
+ desc.wr_req ? FAULT_FLAG_WRITE : 0);
+   if (ret & VM_FAULT_ERROR) {
+   gpu_mm_segv(tsk, address, SEGV_ACCERR); /* ? */
+   goto out_unlock;
+   }
+


Hm, do you need to force the SEGV there, in what ought to be generic
IOMMU code?

Can you instead just let the fault handler return an appropriate
failure code to the IOMMU request queue and then deal with the
resulting error on the i915 device side?


I'm not sure if we get enough info on the i915 side to handle it
reasonably, we'll have to test that out.


We do know precisely which context blew up, but without the TDR work we
can't yet just kill the offender selective without affecting the other
active gpu contexts.


Could someone clarify what this means from the TDR point of view, 
please? When you say "context blew up" I'm guessing that you mean that 
come context caused the fault handler to get involved somehow?


Does this imply that the offending context will hang and the driver will 
have to detect this hang? If so, then yes - if we have the per-engine 
hang recovery mode as part of the upcoming TDR work in place then we 
could handle it by stepping over the offending batch buffer and moving 
on with a minimum of side-effects on the rest of the driver/GPU.


Or does this imply that we have some new integration path to deal with? 
(something that I should be aware of when upstreaming TDR?)


Sorry if I missed something blatantly obvious in the patch ;).

Thanks,
Tomas



But besides that I really don't see a reason why we need to kill the
process if the gpu faults. After all if a thread sigfaults then signal
goes to that thread and not some random one (or the one thread that forked
the thread that blew up). And we do have interfaces to tell userspace that
something bad happened with the gpu work it submitted.

Chris made a similar patch for userptr and I didn't like that one either.
Worst case userspace has a special SEGV handler and then things really go
down badly when that handler gets triggered at an unexpected place.
-Daniel



That way, you should hopefully get to gracefully cope with reporting
errors for a specific *context*, rather than killing the whole process.


It would be best to get per-context error info, but killing the process
may be unavoidable (just as if a single thread clobbers memory in your
process).

Jesse
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx




___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 9/9] drm/i915: add bufferless execbuf ioctl

2015-10-08 Thread David Woodhouse
On Fri, 2015-09-04 at 09:59 -0700, Jesse Barnes wrote:
> We just need to pass in an address to execute and some flags, since we
> don't have to worry about buffer relocation or any of the other usual
> stuff.  Returns a fence to be used for synchronization.
> ---
>  drivers/gpu/drm/i915/i915_dma.c| 140 
> -
>  drivers/gpu/drm/i915/i915_drv.h|   7 ++
>  drivers/gpu/drm/i915/i915_gem_execbuffer.c |   2 +-
>  drivers/gpu/drm/i915/i915_svm.c|  10 ---
>  drivers/gpu/drm/i915/i915_sync.c   |   4 +-
>  include/uapi/drm/i915_drm.h|  24 +
>  6 files changed, 173 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index b868084..19b463a 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -50,7 +50,8 @@
>  #include 
>  #include 
>  #include 
> -
> +#include 
> +#include "../../../staging/android/sync.h"
>  
>  static int i915_getparam(struct drm_device *dev, void *data,
>  >>   >   >  struct drm_file *file_priv)
> @@ -1247,6 +1248,132 @@ i915_gem_reject_pin_ioctl(struct drm_device *dev, 
> void *data,
>  >> return -ENODEV;
>  }
>  
> +int intel_exec_mm_ioctl(struct drm_device *dev, void *data,
> +>>   >   > struct drm_file *file)
> +{
> + >   > struct drm_i915_private *dev_priv = dev->dev_private;
> +>> struct drm_i915_exec_mm *exec_mm = data;
> +>> struct intel_ringbuffer *ringbuf;
> +>> struct intel_engine_cs *ring;
> +>> struct intel_context *ctx;
> +>> struct drm_i915_gem_request *request;
> +>> struct fence *fence;
> +>> struct sync_fence *sfence;
> +>> u32 ctx_id = exec_mm->ctx_id;
> +>> int fd = get_unused_fd_flags(O_CLOEXEC);
> +>> int ret = 0;
> +
> +>> if (exec_mm->batch_ptr & 3) {
> +>>   > DRM_ERROR("misaligned batch ptr\n");
> +>>   > ret = -ENOEXEC;
> +>>   > goto out;
> +>> }
> +
> +>> if (!dev_priv->svm.svm_available) {
> +>>   > ret = -ENODEV;
> +>>   > goto out;
> +>> }
> +
> +>> ret = i915_mutex_lock_interruptible(dev);
> +>> if (ret) {
> +>>   > DRM_ERROR("mutex interrupted\n");
> +>>   > goto out;
> +>> }
> +
> +>> if (file == NULL) {
> +>>   > ret = -EINVAL;
> +>>   > goto out_unlock;
> +>> }
> +
> +>> ctx = i915_gem_validate_context(dev, file, _priv->ring[RCS],
> +>>   >   >   >   > ctx_id);
> +>> if (ctx == NULL) {
> +>>   > ret = -ENOENT;
> +>>   > DRM_ERROR("couldn't get context\n");
> +>>   > goto out_unlock;
> +>> }
> +
> +>> if (!ctx->is_svm) {
> +>>   > ret = -EINVAL;
> +>>   > DRM_ERROR("context is not SVM enabled\n");
> +>>   > goto out_unlock;
> +>> }
> +
> +>> i915_gem_context_reference(ctx);
> +
> +>> ringbuf = ctx->engine[RCS].ringbuf;
> +>> ring = ringbuf->ring;
> +>> if (!ring) {
> +>>   > DRM_ERROR("context has no last ring\n");
> +>>   > ret = -EIO;
> +>>   > goto out_unref;
> +>> }
> +
> +>> if (!ctx->rcs_initialized) {
> +>>   > DRM_DEBUG("ring not ready\n");
> +>>   > ret = -EIO;
> +>>   > goto out_unref;
> +>> }
> +
> +>> ret = i915_gem_request_alloc(ring, ctx, );
> +>> if (ret) {
> +>>   > DRM_ERROR("request alloc failed\n");
> +>>   > goto out_unref;
> +>> }
> +
> +>> ret = i915_gem_request_add_to_client(request, file);
> +>> if (ret) {
> +>>   > DRM_ERROR("failed to add request to client\n");
> +>>   > goto out_free_req;
> +>> }
> +
> +>> fence = i915_fence_create_ring(ring, ctx);
> +>> if (!fence) {
> +>>   > ret = -ENOMEM;
> +>>   > DRM_ERROR("fence creation failed\n");
> +>>   > goto out_free_req;
> +>> }
> +
> +>> sfence = sync_fence_create_dma("svm-execbuf", fence);
> +>> if (!sfence) {
> +>>   > ret = -ENOMEM;
> +>>   > DRM_ERROR("sfence creation failed\n");
> +>>   > goto out_free_req;
> +>> }
> +
> +>> exec_mm->fence = fd;
> +>> sync_fence_install(sfence, fd);
> +
> +>> ret = ring->emit_flush(request, 0, I915_GEM_GPU_DOMAINS);
> +>> if (ret) {
> +>>   > DRM_ERROR("ring flush failed: %d\n", ret);
> +>>   > goto out_free_req;
> +>> }
> +
> +>> ret = ring->emit_bb_start(request, exec_mm->batch_ptr, 0);
> +>> if (ret) {
> +>>   > DRM_ERROR("ring dispatch execbuf failed: %d\n", ret);
> +>>   > goto out_free_req;
> +>> }

FWIW naïvely adding a call to 

 __i915_add_request(request, NULL, true);

here in the hope that it would actually do something *useful* rather
than just reserving space in the ring and never using it, causing the
warning in intel_ring_reserved_space_reserve() that I observed next
time we do anything... didn't work. With various and 

Re: [Intel-gfx] [PATCH 3/6] drm/i915: Propagating correct error codes to the userspace

2015-10-08 Thread Chris Wilson
On Thu, Oct 08, 2015 at 11:54:26AM +0530, ankitprasad.r.sha...@intel.com wrote:
> From: Ankitprasad Sharma 
> 
> Propagating correct error codes to userspace by using ERR_PTR and
> PTR_ERR macros for stolen memory based object allocation. We generally
> return -ENOMEM to the user whenever there is a failure in object
> allocation. This patch helps user to identify the correct reason for the
> failure and not just -ENOMEM each time.
> 
> v2: Moved the patch up in the series, added error propagation for
> i915_gem_alloc_object too (Chris)
> 
> Signed-off-by: Ankitprasad Sharma 
> ---
>  drivers/gpu/drm/i915/i915_gem.c  | 15 +-
>  drivers/gpu/drm/i915/i915_gem_batch_pool.c   |  4 +--
>  drivers/gpu/drm/i915/i915_gem_context.c  |  4 +--
>  drivers/gpu/drm/i915/i915_gem_render_state.c |  4 +--
>  drivers/gpu/drm/i915/i915_gem_stolen.c   | 43 
> 
>  drivers/gpu/drm/i915/i915_guc_submission.c   |  4 +--
>  drivers/gpu/drm/i915/intel_display.c |  2 +-
>  drivers/gpu/drm/i915/intel_fbdev.c   |  6 ++--
>  drivers/gpu/drm/i915/intel_lrc.c |  8 +++---
>  drivers/gpu/drm/i915/intel_overlay.c |  4 +--
>  drivers/gpu/drm/i915/intel_pm.c  |  2 +-
>  drivers/gpu/drm/i915/intel_ringbuffer.c  | 20 ++---
>  12 files changed, 61 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index d3f4321..54f7df1 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -4273,14 +4273,15 @@ struct drm_i915_gem_object 
> *i915_gem_alloc_object(struct drm_device *dev,
>   struct drm_i915_gem_object *obj;
>   struct address_space *mapping;
>   gfp_t mask;
> + int ret = 0;

Pointless initialisation.

>  
>   obj = i915_gem_object_alloc(dev);
>   if (obj == NULL)
> - return NULL;
> + return ERR_PTR(-ENOMEM);
>  
> - if (drm_gem_object_init(dev, >base, size) != 0) {
> + if ((ret = drm_gem_object_init(dev, >base, size)) != 0) {
>   i915_gem_object_free(obj);
> - return NULL;
> + return ERR_PTR(ret);
>   }
>  
>   mask = GFP_HIGHUSER | __GFP_RECLAIMABLE;
> diff --git a/drivers/gpu/drm/i915/i915_gem_batch_pool.c 
> b/drivers/gpu/drm/i915/i915_gem_batch_pool.c
> index 7bf2f3f..d79caa2 100644
> --- a/drivers/gpu/drm/i915/i915_gem_batch_pool.c
> +++ b/drivers/gpu/drm/i915/i915_gem_batch_pool.c
> @@ -135,8 +135,8 @@ i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool,
>   int ret;
>  
>   obj = i915_gem_alloc_object(pool->dev, size);
> - if (obj == NULL)
> - return ERR_PTR(-ENOMEM);
> + if (IS_ERR(obj))
> + return obj;
>  
>   ret = i915_gem_object_get_pages(obj);
>   if (ret)
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
> b/drivers/gpu/drm/i915/i915_gem_context.c
> index 74aa0c9..603600c 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -157,8 +157,8 @@ i915_gem_alloc_context_obj(struct drm_device *dev, size_t 
> size)
>   int ret;
>  
>   obj = i915_gem_alloc_object(dev, size);
> - if (obj == NULL)
> - return ERR_PTR(-ENOMEM);
> + if (IS_ERR(obj))
> + return obj;
>  
>   /*
>* Try to make the context utilize L3 as well as LLC.
> diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c 
> b/drivers/gpu/drm/i915/i915_gem_render_state.c
> index 5026a62..50d010e 100644
> --- a/drivers/gpu/drm/i915/i915_gem_render_state.c
> +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
> @@ -58,8 +58,8 @@ static int render_state_init(struct render_state *so, 
> struct drm_device *dev)
>   return -EINVAL;
>  
>   so->obj = i915_gem_alloc_object(dev, 4096);
> - if (so->obj == NULL)
> - return -ENOMEM;
> + if (IS_ERR(so->obj))
> + return PTR_ERR(so->obj);
>  
>   ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0);
>   if (ret)
> diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
> b/drivers/gpu/drm/i915/i915_gem_stolen.c
> index 5ec2190..d3e6813 100644
> --- a/drivers/gpu/drm/i915/i915_gem_stolen.c
> +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
> @@ -406,6 +406,7 @@ i915_pages_create_for_stolen(struct drm_device *dev,
>   struct drm_i915_private *dev_priv = dev->dev_private;
>   struct sg_table *st;
>   struct scatterlist *sg;
> + int ret;
>  
>   DRM_DEBUG_DRIVER("offset=0x%x, size=%d\n", offset, size);
>   BUG_ON(offset > dev_priv->gtt.stolen_size - size);
> @@ -417,11 +418,12 @@ i915_pages_create_for_stolen(struct drm_device *dev,
>  
>   st = kmalloc(sizeof(*st), GFP_KERNEL);
>   if (st == NULL)
> - return NULL;
> + return ERR_PTR(-ENOMEM);
>  
> -   

Re: [Intel-gfx] [PATCH 6/6] drm/i915: Migrate stolen objects before hibernation

2015-10-08 Thread Chris Wilson
On Thu, Oct 08, 2015 at 11:54:29AM +0530, ankitprasad.r.sha...@intel.com wrote:
> + /* stolen objects are already pinned to prevent shrinkage */
> + memset(, 0, sizeof(node));
> + ret = drm_mm_insert_node_in_range_generic(>gtt.base.mm,
> +   ,
> +   4096, 0, I915_CACHE_NONE,
> +   0, i915->gtt.mappable_end,
> +   DRM_MM_SEARCH_DEFAULT,
> +   DRM_MM_CREATE_DEFAULT);
> + if (ret)
> + return ret;
> +
> + i915->gtt.base.insert_entries(>gtt.base, obj->pages,
> +   node.start, I915_CACHE_NONE, 0);

This was written using an insert_page() function you don't have. Either
grab that as well, or you need to pin the entire object into the GGTT,
i.e. i915_gem_obj_ggtt_pin(obj, 0, PIN_MAPPABLE); note that to do so
will also need to be very careful to handle the pinning of obj->pages
and the introduction of a new GGTT vma.

> +
> + for (i = 0; i < obj->base.size / PAGE_SIZE; i++) {
> + struct page *page;
> + void *__iomem src;
> + void *dst;
> +
> + page = shmem_read_mapping_page(mapping, i);
> + if (IS_ERR(page)) {
> + ret = PTR_ERR(page);
> + goto err_node;
> + }
> +
> + src = io_mapping_map_atomic_wc(i915->gtt.mappable, node.start + 
> PAGE_SIZE * i);
> + dst = kmap_atomic(page);
> + memcpy_fromio(dst, src, PAGE_SIZE);
> + kunmap_atomic(dst);
> + io_mapping_unmap_atomic(src);
> +
> + page_cache_release(page);
> + }
> +
> + wmb();
> + i915->gtt.base.clear_range(>gtt.base,
> +node.start, node.size,
> +true);
> + drm_mm_remove_node();
> +
> +swap_pages:
> + stolen_pages = obj->pages;
> + obj->pages = NULL;
> +
> + obj->base.filp = file;
> + obj->base.read_domains = I915_GEM_DOMAIN_CPU;
> + obj->base.write_domain = I915_GEM_DOMAIN_CPU;
> +
> + /* Recreate any pinned binding with pointers to the new storage */
> + if (!list_empty(>vma_list)) {
> + ret = i915_gem_object_get_pages_gtt(obj);
> + if (ret) {
> + obj->pages = stolen_pages;
> + goto err_file;
> + }
> +
> + ret = i915_gem_gtt_prepare_object(obj);
> + if (ret) {
> + i915_gem_object_put_pages_gtt(obj);
> + obj->pages = stolen_pages;
> + goto err_file;
> + }
> +
> + ret = i915_gem_object_set_to_gtt_domain(obj, true);
> + if (ret) {
> + i915_gem_gtt_finish_object(obj);
> + i915_gem_object_put_pages_gtt(obj);
> + obj->pages = stolen_pages;
> + goto err_file;
> + }
> +
> + obj->get_page.sg = obj->pages->sgl;
> + obj->get_page.last = 0;
> +
> + list_for_each_entry(vma, >vma_list, vma_link) {
> + if (!drm_mm_node_allocated(>node))
> + continue;
> +
> + WARN_ON(i915_vma_bind(vma,
> +   obj->cache_level,
> +   PIN_UPDATE));
> + }
> + } else
> + list_del(>global_list);
> +
> + /* drop the stolen pin and backing */
> + shmemfs_pages = obj->pages;
> + obj->pages = stolen_pages;
> +
> + i915_gem_object_unpin_pages(obj);
> + obj->ops->put_pages(obj);
> + if (obj->ops->release)
> + obj->ops->release(obj);
> +
> + obj->ops = _gem_object_ops;
> + obj->pages = shmemfs_pages;
> +
> + return 0;
> +
> +err_node:
> + wmb();
> + i915->gtt.base.clear_range(>gtt.base,
> +node.start, node.size,
> +true);
> + drm_mm_remove_node();
> +err_file:
> + fput(file);
> + obj->base.filp = NULL;
> + return ret;
> +}
> +
> +int
> +i915_gem_freeze(struct drm_device *dev)
> +{
> + /* Called before i915_gem_suspend() when hibernating */
> + struct drm_i915_private *i915 = to_i915(dev);
> + struct drm_i915_gem_object *obj, *tmp;
> + struct list_head *phase[] = {
> + >mm.unbound_list, >mm.bound_list, NULL
> + }, **p;
> +
> + /* Across hibernation, the stolen area is not preserved.
> +  * Anything inside stolen must copied back to normal
> +  * memory if we wish to preserve it.
> +  */
> + for (p = phase; *p; p++) {

Didn't we introduce a list of stolen objects in one of the other
patches?

> + struct list_head migrate;
> + int ret;
> +
> + 

Re: [Intel-gfx] [PATCH 4/6] drm/i915: Add support for stealing purgable stolen pages

2015-10-08 Thread Chris Wilson
On Thu, Oct 08, 2015 at 11:43:29AM +0100, Tvrtko Ursulin wrote:
> >-struct drm_i915_gem_object *
> >-i915_gem_object_create_stolen(struct drm_device *dev, u64 size)
> >+static bool
> >+mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind)
> >+{
> >+BUG_ON(obj->stolen == NULL);
> 
> I am fundamentally opposed to BUG_ONs which can be avoided. In this
> I see no value in hanging the machine while we could WARN_ON and
> return false.

Don't bother with the WARN_ON. Either take the BUG_ON or accept that to
get to this point the machine is dead anyway and a warning here doesn't
help identify the root cause (better off with list debugging and memory
debugging). I have personally been converting these asserts over to a
dev-only compiletime option as I still find the BUGs more useful than
WARNs in the GEM code.
 
> >+if (obj->madv != I915_MADV_DONTNEED)
> >+return false;
> >+
> >+if (obj->pin_display)
> >+return false;
> >+
> >+list_add(>tmp_link, unwind);
> >+return drm_mm_scan_add_block(>stolen->base);
> >+}

> >@@ -520,17 +609,59 @@ i915_gem_object_create_stolen(struct drm_device *dev, 
> >u64 size)
> > if (!stolen)
> > return ERR_PTR(-ENOMEM);
> >
> >-ret = i915_gem_stolen_insert_node(dev_priv, stolen, size, 4096);
> >+ret = i915_gem_stolen_insert_node(dev_priv, >base, size, 4096);
> >+if (ret == 0)
> >+goto out;
> >+
> >+/* No more stolen memory available, or too fragmented.
> >+ * Try evicting purgeable objects and search again.
> >+ */
> >+ret = stolen_evict(dev_priv, size);
> 
> I have raised this question of struct_mutex in the previous round.
> 
> Correct me if I am wrong, but I thought there was some effort made
> to make stolen object allocation run without struct mutex?

Correct. But note that we do GEM operations inside the eviction logic
and the struct_mutex is the only one we have for them.
 
> With this change it requires it again. At the moment callers seem to
> hold it anyway. But I think lockdep_assert_held is needed now at
> least to document the requirement, probably in top level
> i915_gem_object_create_stolen.

And a comment as to why, might as well also try and document the logic
behind such decisions.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/5] drm/i915: Store and print dmc firmware version

2015-10-08 Thread Animesh Manna



On 9/18/2015 8:47 PM, Mika Kuoppala wrote:

Parse csr/dmc firmware version and augment debug message
by printing it.

Cc: Animesh Manna 
Signed-off-by: Mika Kuoppala 
---
  drivers/gpu/drm/i915/i915_drv.h  | 2 ++
  drivers/gpu/drm/i915/intel_csr.c | 7 ++-
  2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3bf8a9b..17e8b25 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -755,6 +755,8 @@ struct intel_csr {
const char *fw_path;
uint32_t *dmc_payload;
uint32_t dmc_fw_size;
+   uint16_t dmc_ver_major;
+   uint16_t dmc_ver_minor;
uint32_t mmio_count;
uint32_t mmioaddr[8];
uint32_t mmiodata[8];
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c
index b69264d..58edc3f 100644
--- a/drivers/gpu/drm/i915/intel_csr.c
+++ b/drivers/gpu/drm/i915/intel_csr.c
@@ -377,11 +377,16 @@ static void finish_csr_load(const struct firmware *fw, 
void *context)
dmc_payload = csr->dmc_payload;
memcpy(dmc_payload, >data[readcount], nbytes);
  
+	csr->dmc_ver_major = dmc_header->header_ver;

+   csr->dmc_ver_minor = ((dmc_header->fw_version & 0x) >> 16) * 10
+   + (dmc_header->fw_version & 0x);
+


I am not able to locate the the way major and minor version is derived, is it 
present in bspec?

-Animesh


/* load csr program during system boot, as needed for DC states */
intel_csr_load_program(dev);
fw_loaded = true;
  
-	DRM_DEBUG_KMS("Finished loading %s\n", dev_priv->csr.fw_path);

+   DRM_DEBUG_KMS("Finished loading %s v%u.%u\n", dev_priv->csr.fw_path,
+ csr->dmc_ver_major, csr->dmc_ver_minor);
  out:
if (fw_loaded)
intel_runtime_pm_put(dev_priv);


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/5] drm/i915: Store and print dmc firmware version

2015-10-08 Thread Damien Lespiau
On Fri, Sep 18, 2015 at 06:17:05PM +0300, Mika Kuoppala wrote:
> Parse csr/dmc firmware version and augment debug message
> by printing it.
> 
> Cc: Animesh Manna 
> Signed-off-by: Mika Kuoppala 

FWIW I did something similar in the past, but that contribution was
denied. I also had the DC states entry counts, which sounds like
something super useful to have:

  http://lists.freedesktop.org/archives/intel-gfx/2015-June/thread.html

The DMC firmware version decoding was different in my patch and I'm sure
it worked then. Maye the header has changed :(

Feel free to use any part of that series with your authorship.

-- 
Damien
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 6/9] drm/i915: driver based PASID handling

2015-10-08 Thread Tomas Elf

On 07/10/2015 17:14, Daniel Vetter wrote:

On Wed, Oct 07, 2015 at 08:16:42AM -0700, Jesse Barnes wrote:

On 10/07/2015 06:00 AM, David Woodhouse wrote:

On Fri, 2015-09-04 at 09:59 -0700, Jesse Barnes wrote:

+
+   ret = handle_mm_fault(mm, vma, address,
+ desc.wr_req ? FAULT_FLAG_WRITE : 0);
+   if (ret & VM_FAULT_ERROR) {
+   gpu_mm_segv(tsk, address, SEGV_ACCERR); /* ? */
+   goto out_unlock;
+   }
+


Hm, do you need to force the SEGV there, in what ought to be generic
IOMMU code?

Can you instead just let the fault handler return an appropriate
failure code to the IOMMU request queue and then deal with the
resulting error on the i915 device side?


I'm not sure if we get enough info on the i915 side to handle it
reasonably, we'll have to test that out.


We do know precisely which context blew up, but without the TDR work we
can't yet just kill the offender selective without affecting the other
active gpu contexts.


Could someone clarify what this means from the TDR point of view, 
please? When you say "context blew up" I'm guessing that you mean that 
come context caused the fault handler to get involved somehow?


Does this imply that the offending context will hang and the driver will 
have to detect this hang? If so, then yes - if we have the per-engine 
hang recovery mode as part of the upcoming TDR work in place then we 
could handle it by stepping over the offending batch buffer and moving 
on with a minimum of side-effects on the rest of the driver/GPU.


Or does this imply that we have some new integration path to deal with? 
(something that I should be aware of when upstreaming TDR?)


Sorry if I missed something blatantly obvious in the patch ;).

Thanks,
Tomas



But besides that I really don't see a reason why we need to kill the
process if the gpu faults. After all if a thread sigfaults then signal
goes to that thread and not some random one (or the one thread that forked
the thread that blew up). And we do have interfaces to tell userspace that
something bad happened with the gpu work it submitted.

Chris made a similar patch for userptr and I didn't like that one either.
Worst case userspace has a special SEGV handler and then things really go
down badly when that handler gets triggered at an unexpected place.
-Daniel



That way, you should hopefully get to gracefully cope with reporting
errors for a specific *context*, rather than killing the whole process.


It would be best to get per-context error info, but killing the process
may be unavoidable (just as if a single thread clobbers memory in your
process).

Jesse
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx




___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [v2] drm/i915/skl: Init cdclk in the driver rather than relying on pre-os

2015-10-08 Thread Ville Syrjälä
On Thu, Oct 08, 2015 at 05:43:41PM +0530, Kumar, Shobhit wrote:
> On 10/08/2015 04:59 PM, Imre Deak wrote:
> > On to, 2015-10-08 at 09:58 +0530, Shobhit Kumar wrote:
> >> Reuse what is programmed by pre-os, but in case there is no pre-os
> >> initialization, init the cdclk with the max value by default untill
> >> dynamic cdclk support comes.
> >>
> >> v2: Check if BIOS programmed correctly rather than always calling init
> >>  - Do validation of programmed cdctl and what it is expected
> >>  - Only do slk_init_cdclk if validation failed else reuse BIOS
> >>programmed value
> >>
> >> Cc: Imre Deak 
> >> Cc: Ville Syrjälä 
> >> Signed-off-by: Shobhit Kumar 
> >> ---
> >>   drivers/gpu/drm/i915/intel_ddi.c | 18 -
> >>   drivers/gpu/drm/i915/intel_display.c | 39 
> >> +++-
> >>   2 files changed, 42 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
> >> b/drivers/gpu/drm/i915/intel_ddi.c
> >> index 2d3cc82..3ec5618 100644
> >> --- a/drivers/gpu/drm/i915/intel_ddi.c
> >> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> >> @@ -2946,11 +2946,19 @@ void intel_ddi_pll_init(struct drm_device *dev)
> >>int cdclk_freq;
> >>
> >>cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
> >> -  dev_priv->skl_boot_cdclk = cdclk_freq;
> >> -  if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
> >> -  DRM_ERROR("LCPLL1 is disabled\n");
> >> -  else
> >> -  intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
> >> +
> >> +  /* Invalid CDCLK from BIOS ? */
> >> +  if (cdclk_freq < 0) {
> >> +  /* program to maximum cdclk till we have dynamic cdclk 
> >> support */
> >> +  dev_priv->skl_boot_cdclk = 675000;
> >> +  skl_init_cdclk(dev_priv);
> >
> > This would still try to reprogram CDCLK if BIOS enabled an output with
> > an incorrect CDCLK decimal part. Isn't this the exact scenario you're
> > seeing? As said before reprogramming CDCLK in that case would require
> > disabling the outputs first.
> 
> I went with the hypothesis that if VBIOS/GOP was loaded it would have to 
> correct the cdclock, with wrong decimal value display cannot be enabled. 
> For example AUX will fail on SKL. So for correct display output enabled 
> cdclock has to be correctly programmed. If it is wrong display was not 
> enabled at all.
> 
> The scenario which I am seeing is VBIOS/GOP is not loaded at all, and 
> the pre-os is not leaving cdclock in correct state.

But it still enabled DPLL0? Why does it do that if it doesn't set up
cdclk?

> 
> >
> > We would also need to call skl_init_cdclk if the BIOS hasn't enabled the
> > PLL for some reason. But I guess that could be a separate change.
> >
> >> +  } else {
> >> +  dev_priv->skl_boot_cdclk = cdclk_freq;
> >> +  if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
> >> +  DRM_ERROR("LCPLL1 is disabled\n");
> >> +  else
> >> +  intel_display_power_get(dev_priv, 
> >> POWER_DOMAIN_PLLS);
> >> +  }
> >>} else if (IS_BROXTON(dev)) {
> >>broxton_init_cdclk(dev);
> >>broxton_ddi_phy_init(dev);
> >> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> >> b/drivers/gpu/drm/i915/intel_display.c
> >> index bbeb6d3..f734410 100644
> >> --- a/drivers/gpu/drm/i915/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/intel_display.c
> >> @@ -6634,12 +6634,15 @@ static int skylake_get_display_clock_speed(struct 
> >> drm_device *dev)
> >>uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
> >>uint32_t cdctl = I915_READ(CDCLK_CTL);
> >>uint32_t linkrate;
> >> +  int freq;
> >>
> >>if (!(lcpll1 & LCPLL_PLL_ENABLE))
> >>return 24000; /* 24MHz is the cd freq with NSSC ref */
> >>
> >> -  if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540)
> >> -  return 54;
> >> +  if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540) {
> >> +  freq = 54;
> >> +  goto verify;
> >> +  }
> >>
> >>linkrate = (I915_READ(DPLL_CTRL1) &
> >>DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1;
> >> @@ -6649,30 +6652,46 @@ static int skylake_get_display_clock_speed(struct 
> >> drm_device *dev)
> >>/* vco 8640 */
> >>switch (cdctl & CDCLK_FREQ_SEL_MASK) {
> >>case CDCLK_FREQ_450_432:
> >> -  return 432000;
> >> +  freq = 432000;
> >> +  break;
> >>case CDCLK_FREQ_337_308:
> >> -  return 308570;
> >> +  freq = 308570;
> >> +  break;
> >>case CDCLK_FREQ_675_617:
> >> -  return 617140;
> >> +  freq = 617140;
> >> +  break;
> >>

Re: [Intel-gfx] [PATCH 2/5] drm/i915: Notify user about outdated dmc firmware

2015-10-08 Thread Animesh Manna



On 9/21/2015 2:00 PM, Mika Kuoppala wrote:

Jani Nikula  writes:


On Fri, 18 Sep 2015, Mika Kuoppala  wrote:

If csr/dmc firmware is known to be outdated, notify
user.

What would break if we requested a firmware version that works? Or we've
made it so that we only request the major version because there's not
supposed to be changes like this between minor versions...?


I guess the question is more of a what should we do
if there is only outdated (known bad) firmware available.

Refuse to load and limb onwards, or return with error code
on driver init.

Latter would force firmware and version to be mandatory and the
version to be tightly coupled to kernel driver version.


A softlink is used to use recommended firmware for dmc and the same information 
is published through 01.org for the firmware user.
Imo, we should not have this kind of hack in code which will change over time 
and this is responsibility of repo-owner to link correct recommended firmware 
for new kernel update.

-Animesh


-Mika


BR,
Jani.




Signed-off-by: Mika Kuoppala 
---
  drivers/gpu/drm/i915/intel_csr.c | 9 +
  1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c
index 58edc3f..73807c3 100644
--- a/drivers/gpu/drm/i915/intel_csr.c
+++ b/drivers/gpu/drm/i915/intel_csr.c
@@ -45,6 +45,9 @@
  
  MODULE_FIRMWARE(I915_CSR_SKL);
  
+#define RECOMMENDED_FW_MAJOR		1

+#define RECOMMENDED_FW_MINOR   21
+
  /*
  * SKL CSR registers for DC5 and DC6
  */
@@ -387,6 +390,12 @@ static void finish_csr_load(const struct firmware *fw, 
void *context)
  
  	DRM_DEBUG_KMS("Finished loading %s v%u.%u\n", dev_priv->csr.fw_path,

  csr->dmc_ver_major, csr->dmc_ver_minor);
+
+   if (csr->dmc_ver_major < RECOMMENDED_FW_MAJOR ||
+   csr->dmc_ver_minor < RECOMMENDED_FW_MINOR)
+   DRM_INFO("Outdated dmc firmware found, please upgrade to %u.%u or 
newer\n",
+RECOMMENDED_FW_MAJOR, RECOMMENDED_FW_MINOR);
+
  out:
if (fw_loaded)
intel_runtime_pm_put(dev_priv);
--
2.1.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

--
Jani Nikula, Intel Open Source Technology Center

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [v2] drm/i915/skl: Init cdclk in the driver rather than relying on pre-os

2015-10-08 Thread Imre Deak
On to, 2015-10-08 at 09:58 +0530, Shobhit Kumar wrote:
> Reuse what is programmed by pre-os, but in case there is no pre-os
> initialization, init the cdclk with the max value by default untill
> dynamic cdclk support comes.
> 
> v2: Check if BIOS programmed correctly rather than always calling init
> - Do validation of programmed cdctl and what it is expected
> - Only do slk_init_cdclk if validation failed else reuse BIOS
>   programmed value
> 
> Cc: Imre Deak 
> Cc: Ville Syrjälä 
> Signed-off-by: Shobhit Kumar 
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 18 -
>  drivers/gpu/drm/i915/intel_display.c | 39 
> +++-
>  2 files changed, 42 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
> b/drivers/gpu/drm/i915/intel_ddi.c
> index 2d3cc82..3ec5618 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2946,11 +2946,19 @@ void intel_ddi_pll_init(struct drm_device *dev)
>   int cdclk_freq;
>  
>   cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
> - dev_priv->skl_boot_cdclk = cdclk_freq;
> - if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
> - DRM_ERROR("LCPLL1 is disabled\n");
> - else
> - intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
> +
> + /* Invalid CDCLK from BIOS ? */
> + if (cdclk_freq < 0) {
> + /* program to maximum cdclk till we have dynamic cdclk 
> support */
> + dev_priv->skl_boot_cdclk = 675000;
> + skl_init_cdclk(dev_priv);

This would still try to reprogram CDCLK if BIOS enabled an output with
an incorrect CDCLK decimal part. Isn't this the exact scenario you're
seeing? As said before reprogramming CDCLK in that case would require
disabling the outputs first.

We would also need to call skl_init_cdclk if the BIOS hasn't enabled the
PLL for some reason. But I guess that could be a separate change.

> + } else {
> + dev_priv->skl_boot_cdclk = cdclk_freq;
> + if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
> + DRM_ERROR("LCPLL1 is disabled\n");
> + else
> + intel_display_power_get(dev_priv, 
> POWER_DOMAIN_PLLS);
> + }
>   } else if (IS_BROXTON(dev)) {
>   broxton_init_cdclk(dev);
>   broxton_ddi_phy_init(dev);
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index bbeb6d3..f734410 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -6634,12 +6634,15 @@ static int skylake_get_display_clock_speed(struct 
> drm_device *dev)
>   uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
>   uint32_t cdctl = I915_READ(CDCLK_CTL);
>   uint32_t linkrate;
> + int freq;
>  
>   if (!(lcpll1 & LCPLL_PLL_ENABLE))
>   return 24000; /* 24MHz is the cd freq with NSSC ref */
>  
> - if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540)
> - return 54;
> + if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540) {
> + freq = 54;
> + goto verify;
> + }
>  
>   linkrate = (I915_READ(DPLL_CTRL1) &
>   DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1;
> @@ -6649,30 +6652,46 @@ static int skylake_get_display_clock_speed(struct 
> drm_device *dev)
>   /* vco 8640 */
>   switch (cdctl & CDCLK_FREQ_SEL_MASK) {
>   case CDCLK_FREQ_450_432:
> - return 432000;
> + freq = 432000;
> + break;
>   case CDCLK_FREQ_337_308:
> - return 308570;
> + freq = 308570;
> + break;
>   case CDCLK_FREQ_675_617:
> - return 617140;
> + freq = 617140;
> + break;
>   default:
>   WARN(1, "Unknown cd freq selection\n");
> + return -EINVAL;
>   }
>   } else {
>   /* vco 8100 */
>   switch (cdctl & CDCLK_FREQ_SEL_MASK) {
>   case CDCLK_FREQ_450_432:
> - return 45;
> + freq = 45;
> + break;
>   case CDCLK_FREQ_337_308:
> - return 337500;
> + freq = 337500;
> + break;
>   case CDCLK_FREQ_675_617:
> - return 675000;
> + freq = 675000;
> + break;
>   default:
>   WARN(1, "Unknown cd freq selection\n");
> +  

Re: [Intel-gfx] [PATCH] drm/i915: 4K audio N value incorrect at 29.97 and 23.98 refresh rate

2015-10-08 Thread Jani Nikula
On Thu, 08 Oct 2015, Ville Syrjälä  wrote:
> On Wed, Oct 07, 2015 at 02:38:29PM -0700, clinton.a.tay...@intel.com wrote:
>> From: Clint Taylor 
>> 
>> The TMDS_296M define was computing as 296704 but the mode->clock is
>> 296700 as defined by EDID. Adjusted define to allow correct detection
>> of the need to program the correct N value for 29.97 and 23.98 refresh
>> rate.
>> 
>> Signed-off-by: Clint Taylor 
>> ---
>>  drivers/gpu/drm/i915/intel_audio.c |2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_audio.c 
>> b/drivers/gpu/drm/i915/intel_audio.c
>> index 56c2f54..419c979 100644
>> --- a/drivers/gpu/drm/i915/intel_audio.c
>> +++ b/drivers/gpu/drm/i915/intel_audio.c
>> @@ -75,7 +75,7 @@ static const struct {
>>  
>>  /* HDMI N/CTS table */
>>  #define TMDS_297M 297000
>> -#define TMDS_296M DIV_ROUND_UP(297000 * 1000, 1001)
>> +#define TMDS_296M 296700
>
> Hmm. I think we might want to fix up the mode instead. Let me post a few
> patches, and let's see what people think...

We might actually want to queue this up for v4.3 as the immediate fix,
as I feel it's doubtful your other patches will make it to v4.3.

If Someone(tm) provided their r-b that is.

BR,
Jani.


>
>>  static const struct {
>>  int sample_rate;
>>  int clock;
>> -- 
>> 1.7.9.5
>> 
>> ___
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> -- 
> Ville Syrjälä
> Intel OTC
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases

2015-10-08 Thread Ville Syrjälä
On Mon, Oct 05, 2015 at 04:43:14PM +0530, Sonika Jindal wrote:
> For all the encoders, call the hot_plug if it is registered.
> This is required for connected boot and resume cases to generate
> fake hpd resulting in reading of edid.
> Removing the initial sdvo hot_plug call too so that it will be called
> just once from this loop.
> 
> Signed-off-by: Sonika Jindal 
> ---
>  drivers/gpu/drm/i915/intel_hotplug.c |   11 +++
>  drivers/gpu/drm/i915/intel_sdvo.c|1 -
>  2 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c 
> b/drivers/gpu/drm/i915/intel_hotplug.c
> index 53c0173..eac4757 100644
> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> @@ -458,6 +458,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>  {
>   struct drm_device *dev = dev_priv->dev;
>   struct drm_mode_config *mode_config = >mode_config;
> + struct intel_encoder *encoder;
>   struct drm_connector *connector;
>   int i;
>  
> @@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>   if (dev_priv->display.hpd_irq_setup)
>   dev_priv->display.hpd_irq_setup(dev);
>   spin_unlock_irq(_priv->irq_lock);
> +
> + /*
> +  * Connected boot / resume scenarios can't generate new hot plug.
> +  * So, probe it manually.
> +  */
> + list_for_each_entry(encoder, >mode_config.encoder_list,
> + base.head) {
> + if (encoder->hot_plug)
> + encoder->hot_plug(encoder);
> + }


This breaks the world on CHV

[ 3187.575198] [drm:intel_hdmi_hot_plug] Live status not up!
[ 3187.585154] =
[ 3187.595010] [ INFO: possible recursive locking detected ]
[ 3187.604685] 4.3.0-rc4-bsw+ #2488 Tainted: G U  W  
[ 3187.614366] -
[ 3187.623892] Xorg/32212 is trying to acquire lock:
[ 3187.632635]  (_domains->lock){+.+...}, at: [] 
intel_display_power_get+0x38/0xcb [i915]
[ 3187.647492] 
[ 3187.647492] but task is already holding lock:
[ 3187.661054]  (_domains->lock){+.+...}, at: [] 
intel_display_power_get+0x38/0xcb [i915]
[ 3187.675960] 
[ 3187.675960] other info that might help us debug this:
[ 3187.690459]  Possible unsafe locking scenario:
[ 3187.690459] 
[ 3187.704224]CPU0
[ 3187.710485]
[ 3187.716711]   lock(_domains->lock);
[ 3187.724718]   lock(_domains->lock);
[ 3187.732663] 
[ 3187.732663]  *** DEADLOCK ***
[ 3187.732663] 
[ 3187.749460]  May be due to missing lock nesting notation
[ 3187.749460] 
[ 3187.763833] 5 locks held by Xorg/32212:
[ 3187.771523]  #0:  (drm_global_mutex){+.+.+.}, at: [] 
drm_release+0x3b/0x49b [drm]
[ 3187.785216]  #1:  (>mode_config.mutex){+.+.+.}, at: 
[] drm_modeset_lock_all+0x54/0xcd [drm]
[ 3187.800437]  #2:  (crtc_ww_class_acquire){+.+.+.}, at: [] 
drm_modeset_lock_all+0x5e/0xcd [drm]
[ 3187.815488]  #3:  (crtc_ww_class_mutex){+.+.+.}, at: [] 
drm_modeset_lock+0x75/0xfc [drm]
[ 3187.830094]  #4:  (_domains->lock){+.+...}, at: [] 
intel_display_power_get+0x38/0xcb [i915]
[ 3187.845534] 
[ 3187.845534] stack backtrace:
[ 3187.857685] CPU: 2 PID: 32212 Comm: Xorg Tainted: G U  W   
4.3.0-rc4-bsw+ #2488
[ 3187.870331] Hardware name: Intel Corporation CHERRYVIEW C0 PLATFORM/Braswell 
CRB, BIOS BRAS.X64.B085.R00.1509110553 09/11/2015
[ 3187.886827]   880175eff8e0 8128d59e 
823f5ee0
[ 3187.898904]  880175eff958 810a7a08  
880179d1c5d0
[ 3187.910954]  0004 0006 45422a91588a4c3e 
0005
[ 3187.923011] Call Trace:
[ 3187.929451]  [] dump_stack+0x4e/0x79
[ 3187.938912]  [] __lock_acquire+0x7ab/0x12af
[ 3187.949027]  [] lock_acquire+0x10e/0x1a9
[ 3187.958859]  [] ? intel_display_power_get+0x38/0xcb [i915]
[ 3187.970476]  [] ? intel_display_power_get+0x38/0xcb [i915]
[ 3187.982011]  [] mutex_lock_nested+0x71/0x346
[ 3187.992167]  [] ? intel_display_power_get+0x38/0xcb [i915]
[ 3188.003655]  [] ? _raw_spin_unlock_irqrestore+0x4b/0x60
[ 3188.014829]  [] ? __pm_runtime_resume+0x71/0x7e
[ 3188.025269]  [] intel_display_power_get+0x38/0xcb [i915]
[ 3188.036544]  [] ? intel_display_power_get+0x38/0xcb [i915]
[ 3188.047968]  [] intel_hdmi_set_edid+0x3f/0xd6 [i915]
[ 3188.058766]  [] intel_hdmi_hot_plug+0xbf/0xfb [i915]
[ 3188.069484]  [] intel_hpd_init+0xfa/0x10b [i915]
[ 3188.079753]  [] vlv_display_power_well_init+0xdb/0xe8 
[i915]
[ 3188.091224]  [] chv_pipe_power_well_enable+0x62/0x67 [i915]
[ 3188.102594]  [] intel_display_power_get+0xa0/0xcb [i915]
[ 3188.113657]  [] modeset_get_crtc_power_domains+0x11d/0x13c 
[i915]
[ 3188.125589]  [] intel_atomic_commit+0x228/0xf1b [i915]
[ 3188.136522]  [] ? drm_atomic_check_only+0x37b/0x4da [drm]
[ 3188.147676]  [] drm_atomic_commit+0x4d/0x52 [drm]
[ 3188.158023]  [] restore_fbdev_mode+0x11e/0x286 

[Intel-gfx] [PATCH] drm,i915: Introduce drm_malloc_gfp()

2015-10-08 Thread Chris Wilson
I have instances where I want to use drm_malloc_ab() but with a custom
gfp mask. And with those, where I want a temporary allocation, I want to
try a high-order kmalloc() before using a vmalloc().

So refactor my usage into drm_malloc_gfp().

Signed-off-by: Chris Wilson 
Cc: dri-de...@lists.freedesktop.org
Cc: Ville Syrjälä 
---
 drivers/gpu/drm/i915/i915_gem.c|  4 +---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  8 +++-
 drivers/gpu/drm/i915/i915_gem_gtt.c|  5 +++--
 drivers/gpu/drm/i915/i915_gem_userptr.c| 15 ---
 include/drm/drm_mem_util.h | 19 +++
 5 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index fe672d4a4d73..c81127518083 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2346,9 +2346,7 @@ void *i915_gem_object_pin_vmap(struct drm_i915_gem_object 
*obj)
int n;
 
n = obj->base.size >> PAGE_SHIFT;
-   pages = kmalloc(n*sizeof(*pages), GFP_TEMPORARY | __GFP_NOWARN);
-   if (pages == NULL)
-   pages = drm_malloc_ab(n, sizeof(*pages));
+   pages = drm_malloc_gfp(n, sizeof(*pages), GFP_TEMPORARY);
if (pages != NULL) {
n = 0;
for_each_sg_page(obj->pages->sgl, _iter, 
obj->pages->nents, 0)
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index c35c9dc526e7..91fb7417efc0 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1730,11 +1730,9 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
return -EINVAL;
}
 
-   exec2_list = kmalloc(sizeof(*exec2_list)*args->buffer_count,
-GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
-   if (exec2_list == NULL)
-   exec2_list = drm_malloc_ab(sizeof(*exec2_list),
-  args->buffer_count);
+   exec2_list = drm_malloc_gfp(sizeof(*exec2_list),
+   args->buffer_count,
+   GFP_TEMPORARY);
if (exec2_list == NULL) {
DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
  args->buffer_count);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 6e8c86d829d2..7820e8983136 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3221,8 +3221,9 @@ intel_rotate_fb_obj_pages(struct i915_ggtt_view 
*ggtt_view,
int ret = -ENOMEM;
 
/* Allocate a temporary list of source pages for random access. */
-   page_addr_list = drm_malloc_ab(obj->base.size / PAGE_SIZE,
-  sizeof(dma_addr_t));
+   page_addr_list = drm_malloc_gfp(obj->base.size / PAGE_SIZE,
+   sizeof(dma_addr_t),
+   GFP_TEMPORARY);
if (!page_addr_list)
return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c 
b/drivers/gpu/drm/i915/i915_gem_userptr.c
index afd4c2c4cc04..885605c38e7c 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -575,10 +575,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct 
*_work)
ret = -ENOMEM;
pinned = 0;
 
-   pvec = kmalloc(npages*sizeof(struct page *),
-  GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
-   if (pvec == NULL)
-   pvec = drm_malloc_ab(npages, sizeof(struct page *));
+   pvec = drm_malloc_gfp(npages, sizeof(struct page *), GFP_TEMPORARY);
if (pvec != NULL) {
struct mm_struct *mm = obj->userptr.mm->mm;
 
@@ -715,14 +712,10 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object 
*obj)
pvec = NULL;
pinned = 0;
if (obj->userptr.mm->mm == current->mm) {
-   pvec = kmalloc(num_pages*sizeof(struct page *),
-  GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
+   pvec = drm_malloc_gfp(num_pages, sizeof(struct page *), 
GFP_TEMPORARY);
if (pvec == NULL) {
-   pvec = drm_malloc_ab(num_pages, sizeof(struct page *));
-   if (pvec == NULL) {
-   __i915_gem_userptr_set_active(obj, false);
-   return -ENOMEM;
-   }
+   __i915_gem_userptr_set_active(obj, false);
+   return -ENOMEM;
}
 
pinned = __get_user_pages_fast(obj->userptr.ptr, num_pages,
diff --git a/include/drm/drm_mem_util.h 

Re: [Intel-gfx] [PATCH RESEND 1/3] drm/i915: use error path

2015-10-08 Thread Daniel Vetter
On Thu, Oct 08, 2015 at 07:27:59PM +0530, Sudip Mukherjee wrote:
> Use goto to handle the error path to avoid duplicating the same code. In
> the error path intel_dig_port is the last one to be released as it was
> the first one to be allocated and ideally the error path should be the
> reverse of the execution path.
> 
> Cc: Daniel Vetter 
> Cc: Jani Nikula 
> Signed-off-by: Sudip Mukherjee 

Queued for -next, thanks for the patch.
-Daniel

> ---
> 
> Sent on 27/07/2015
> 
>  drivers/gpu/drm/i915/intel_dp.c | 23 ++-
>  1 file changed, 14 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 8d34ca7..18bcfbe 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -6168,10 +6168,8 @@ intel_dp_init(struct drm_device *dev, int output_reg, 
> enum port port)
>   return;
>  
>   intel_connector = intel_connector_alloc();
> - if (!intel_connector) {
> - kfree(intel_dig_port);
> - return;
> - }
> + if (!intel_connector)
> + goto err_connector_alloc;
>  
>   intel_encoder = _dig_port->base;
>   encoder = _encoder->base;
> @@ -6219,11 +6217,18 @@ intel_dp_init(struct drm_device *dev, int output_reg, 
> enum port port)
>   intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
>   dev_priv->hotplug.irq_port[port] = intel_dig_port;
>  
> - if (!intel_dp_init_connector(intel_dig_port, intel_connector)) {
> - drm_encoder_cleanup(encoder);
> - kfree(intel_dig_port);
> - kfree(intel_connector);
> - }
> + if (!intel_dp_init_connector(intel_dig_port, intel_connector))
> + goto err_init_connector;
> +
> + return;
> +
> +err_init_connector:
> + drm_encoder_cleanup(encoder);
> + kfree(intel_connector);
> +err_connector_alloc:
> + kfree(intel_dig_port);
> +
> + return;
>  }
>  
>  void intel_dp_mst_suspend(struct drm_device *dev)
> -- 
> 1.9.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH RESEND 2/3] drm/i915: check for return value

2015-10-08 Thread Daniel Vetter
On Thu, Oct 08, 2015 at 07:28:00PM +0530, Sudip Mukherjee wrote:
> We were not checking the return value of drm_encoder_init() which can
> fail. And if it fails then we will be working with an uninitialized
> encoder.
> 
> Cc: Daniel Vetter 
> Cc: Jani Nikula 
> Signed-off-by: Sudip Mukherjee 

Queued for -next, thanks for the patch.
-Daniel

> ---
> 
> Sent on 27/07/2015
> 
>  drivers/gpu/drm/i915/intel_dp.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 18bcfbe..2a8b47e 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -6174,8 +6174,9 @@ intel_dp_init(struct drm_device *dev, int output_reg, 
> enum port port)
>   intel_encoder = _dig_port->base;
>   encoder = _encoder->base;
>  
> - drm_encoder_init(dev, _encoder->base, _dp_enc_funcs,
> -  DRM_MODE_ENCODER_TMDS);
> + if (drm_encoder_init(dev, _encoder->base, _dp_enc_funcs,
> +  DRM_MODE_ENCODER_TMDS))
> + goto err_encoder_init;
>  
>   intel_encoder->compute_config = intel_dp_compute_config;
>   intel_encoder->disable = intel_disable_dp;
> @@ -6224,6 +6225,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, 
> enum port port)
>  
>  err_init_connector:
>   drm_encoder_cleanup(encoder);
> +err_encoder_init:
>   kfree(intel_connector);
>  err_connector_alloc:
>   kfree(intel_dig_port);
> -- 
> 1.9.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm,i915: Introduce drm_malloc_gfp()

2015-10-08 Thread Ville Syrjälä
On Thu, Oct 08, 2015 at 02:39:24PM +0100, Chris Wilson wrote:
> I have instances where I want to use drm_malloc_ab() but with a custom
> gfp mask. And with those, where I want a temporary allocation, I want to
> try a high-order kmalloc() before using a vmalloc().
> 
> So refactor my usage into drm_malloc_gfp().
> 
> Signed-off-by: Chris Wilson 
> Cc: dri-de...@lists.freedesktop.org
> Cc: Ville Syrjälä 

lgtm
Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/i915/i915_gem.c|  4 +---
>  drivers/gpu/drm/i915/i915_gem_execbuffer.c |  8 +++-
>  drivers/gpu/drm/i915/i915_gem_gtt.c|  5 +++--
>  drivers/gpu/drm/i915/i915_gem_userptr.c| 15 ---
>  include/drm/drm_mem_util.h | 19 +++
>  5 files changed, 30 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index fe672d4a4d73..c81127518083 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2346,9 +2346,7 @@ void *i915_gem_object_pin_vmap(struct 
> drm_i915_gem_object *obj)
>   int n;
>  
>   n = obj->base.size >> PAGE_SHIFT;
> - pages = kmalloc(n*sizeof(*pages), GFP_TEMPORARY | __GFP_NOWARN);
> - if (pages == NULL)
> - pages = drm_malloc_ab(n, sizeof(*pages));
> + pages = drm_malloc_gfp(n, sizeof(*pages), GFP_TEMPORARY);
>   if (pages != NULL) {
>   n = 0;
>   for_each_sg_page(obj->pages->sgl, _iter, 
> obj->pages->nents, 0)
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
> b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index c35c9dc526e7..91fb7417efc0 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -1730,11 +1730,9 @@ i915_gem_execbuffer2(struct drm_device *dev, void 
> *data,
>   return -EINVAL;
>   }
>  
> - exec2_list = kmalloc(sizeof(*exec2_list)*args->buffer_count,
> -  GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
> - if (exec2_list == NULL)
> - exec2_list = drm_malloc_ab(sizeof(*exec2_list),
> -args->buffer_count);
> + exec2_list = drm_malloc_gfp(sizeof(*exec2_list),
> + args->buffer_count,
> + GFP_TEMPORARY);
>   if (exec2_list == NULL) {
>   DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
> args->buffer_count);
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 6e8c86d829d2..7820e8983136 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3221,8 +3221,9 @@ intel_rotate_fb_obj_pages(struct i915_ggtt_view 
> *ggtt_view,
>   int ret = -ENOMEM;
>  
>   /* Allocate a temporary list of source pages for random access. */
> - page_addr_list = drm_malloc_ab(obj->base.size / PAGE_SIZE,
> -sizeof(dma_addr_t));
> + page_addr_list = drm_malloc_gfp(obj->base.size / PAGE_SIZE,
> + sizeof(dma_addr_t),
> + GFP_TEMPORARY);
>   if (!page_addr_list)
>   return ERR_PTR(ret);
>  
> diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c 
> b/drivers/gpu/drm/i915/i915_gem_userptr.c
> index afd4c2c4cc04..885605c38e7c 100644
> --- a/drivers/gpu/drm/i915/i915_gem_userptr.c
> +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
> @@ -575,10 +575,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct 
> *_work)
>   ret = -ENOMEM;
>   pinned = 0;
>  
> - pvec = kmalloc(npages*sizeof(struct page *),
> -GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
> - if (pvec == NULL)
> - pvec = drm_malloc_ab(npages, sizeof(struct page *));
> + pvec = drm_malloc_gfp(npages, sizeof(struct page *), GFP_TEMPORARY);
>   if (pvec != NULL) {
>   struct mm_struct *mm = obj->userptr.mm->mm;
>  
> @@ -715,14 +712,10 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object 
> *obj)
>   pvec = NULL;
>   pinned = 0;
>   if (obj->userptr.mm->mm == current->mm) {
> - pvec = kmalloc(num_pages*sizeof(struct page *),
> -GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
> + pvec = drm_malloc_gfp(num_pages, sizeof(struct page *), 
> GFP_TEMPORARY);
>   if (pvec == NULL) {
> - pvec = drm_malloc_ab(num_pages, sizeof(struct page *));
> - if (pvec == NULL) {
> - __i915_gem_userptr_set_active(obj, false);
> - return -ENOMEM;
> - }
> + 

Re: [Intel-gfx] [PATCH 4/6] drm/i915: Add support for stealing purgable stolen pages

2015-10-08 Thread Tvrtko Ursulin


On 08/10/15 12:09, Chris Wilson wrote:

On Thu, Oct 08, 2015 at 11:43:29AM +0100, Tvrtko Ursulin wrote:

-struct drm_i915_gem_object *
-i915_gem_object_create_stolen(struct drm_device *dev, u64 size)
+static bool
+mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind)
+{
+   BUG_ON(obj->stolen == NULL);


I am fundamentally opposed to BUG_ONs which can be avoided. In this
I see no value in hanging the machine while we could WARN_ON and
return false.


Don't bother with the WARN_ON. Either take the BUG_ON or accept that to
get to this point the machine is dead anyway and a warning here doesn't
help identify the root cause (better off with list debugging and memory
debugging). I have personally been converting these asserts over to a
dev-only compiletime option as I still find the BUGs more useful than
WARNs in the GEM code.


This is one of the ones which are to be expected in development only. At 
that time I much prefer a WARN_ON since it potentially saves you one 
reboot cycle and there aren't really any downsides to it. Especially if, 
as you say, machine is dead already.



+   if (obj->madv != I915_MADV_DONTNEED)
+   return false;
+
+   if (obj->pin_display)
+   return false;
+
+   list_add(>tmp_link, unwind);
+   return drm_mm_scan_add_block(>stolen->base);
+}



@@ -520,17 +609,59 @@ i915_gem_object_create_stolen(struct drm_device *dev, u64 
size)
if (!stolen)
return ERR_PTR(-ENOMEM);

-   ret = i915_gem_stolen_insert_node(dev_priv, stolen, size, 4096);
+   ret = i915_gem_stolen_insert_node(dev_priv, >base, size, 4096);
+   if (ret == 0)
+   goto out;
+
+   /* No more stolen memory available, or too fragmented.
+* Try evicting purgeable objects and search again.
+*/
+   ret = stolen_evict(dev_priv, size);


I have raised this question of struct_mutex in the previous round.

Correct me if I am wrong, but I thought there was some effort made
to make stolen object allocation run without struct mutex?


Correct. But note that we do GEM operations inside the eviction logic
and the struct_mutex is the only one we have for them.


With this change it requires it again. At the moment callers seem to
hold it anyway. But I think lockdep_assert_held is needed now at
least to document the requirement, probably in top level
i915_gem_object_create_stolen.


And a comment as to why, might as well also try and document the logic
behind such decisions.


Agreed.

Regards,

Tvrtko
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/3] drm/i915: Refactor duplicate object vmap functions

2015-10-08 Thread Chris Wilson
On Thu, Oct 08, 2015 at 03:58:13PM +0300, Ville Syrjälä wrote:
> > +   pages = kmalloc(n*sizeof(*pages), GFP_TEMPORARY);
> 
> Random driveby: kmalloc_array()

That would be scary, imagine having enough pages in the object to
overflow unsigned long :)
 
> Also __GFP_NOWARN?

True.
 
> I wonder if the drm_malloc stuff should do the kmalloc attempt
> regardless fo the size, so we wouldn't have to do it here?

It's a pattern I've reused in a few places, so probably worthy of being
refactored. Something like

-static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
+static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size, gfp_t gfp)
 {
if (size != 0 && nmemb > SIZE_MAX / size)
return NULL;
 
if (size * nmemb <= PAGE_SIZE)
-   return kmalloc(nmemb * size, GFP_KERNEL);
+   return kmalloc(nmemb * size, gfp);
+
+   if (gfp & GFP_TEMPORARY) {
+   void *ptr = kmalloc(nmemb * size, gfp | __GFP_NOWARN);
+   if (ptr)
+   return ptr;
+   }
 
return __vmalloc(size * nmemb,
-GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
+gfp | __GFP_HIGHMEM, PAGE_KERNEL);
 }
 

Would need to call it my_drm_malloc_ab() to avoid having to update
everywhere.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: disable CPU PWM also on LPT/SPT backlight disable

2015-10-08 Thread Jani Nikula

Huang, please try this patch.

BR,
Jani.


On Tue, 29 Sep 2015, Jani Nikula  wrote:
> Also adding Cc: intel-gfx, please include that in follow-ups.
>
> Thanks,
> Jani.
>
> On Tue, 29 Sep 2015, Jani Nikula  wrote:
>> Although we don't support or enable CPU PWM with LPT/SPT based systems,
>> it may have been enabled prior to loading the driver. Disable the CPU
>> PWM on LPT/SPT backlight disable to avoid warnings on LCPLL disable.
>>
>> The issue has been present on BDW since BDW enabling, but was recently
>> introduced on HSW with
>>
>> commit 437b15b8017e0d946453c10794b0c5d4591cf180
>> Author: Jani Nikula 
>> Date:   Fri Sep 4 16:55:13 2015 +0300
>>
>> drm/i915: use pch backlight override on hsw too
>>
>> Reference: http://mid.gmane.org/87y4frhwsn@yhuang-dev.intel.com
>> Reported-by: kernel test robot 
>> Signed-off-by: Jani Nikula 
>> ---
>>  drivers/gpu/drm/i915/intel_panel.c | 14 ++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_panel.c 
>> b/drivers/gpu/drm/i915/intel_panel.c
>> index dd71e7f139e3..c9c94d05f3dd 100644
>> --- a/drivers/gpu/drm/i915/intel_panel.c
>> +++ b/drivers/gpu/drm/i915/intel_panel.c
>> @@ -731,6 +731,20 @@ static void lpt_disable_backlight(struct 
>> intel_connector *connector)
>>  
>>  intel_panel_actually_set_backlight(connector, 0);
>>  
>> +/*
>> + * Although we don't support or enable CPU PWM with LPT/SPT based
>> + * systems, it may have been enabled prior to loading the
>> + * driver. Disable to avoid warnings on LCPLL disable.
>> + *
>> + * This needs rework if we need to add support for CPU PWM on PCH split
>> + * platforms.
>> + */
>> +tmp = I915_READ(BLC_PWM_CPU_CTL2);
>> +if (tmp & BLM_PWM_ENABLE) {
>> +DRM_DEBUG_KMS("cpu backlight was enabled, disabling\n");
>> +I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
>> +}
>> +
>>  tmp = I915_READ(BLC_PWM_PCH_CTL1);
>>  I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
>>  }
>> -- 
>> 2.1.4
>>
>
> -- 
> Jani Nikula, Intel Open Source Technology Center

-- 
Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/3] drm/i915: Refactor duplicate object vmap functions

2015-10-08 Thread Chris Wilson
We now have two implementations for vmapping a whole object, one for
dma-buf and one for the ringbuffer. If we couple the vmapping into the
obj->pages lifetime, then we can reuse an obj->vmapping for both and at
the same time couple it into the shrinker.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_drv.h | 12 ---
 drivers/gpu/drm/i915/i915_gem.c | 41 
 drivers/gpu/drm/i915/i915_gem_dmabuf.c  | 55 +
 drivers/gpu/drm/i915/intel_ringbuffer.c | 53 ++-
 4 files changed, 72 insertions(+), 89 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4093eedfd664..343a0a723d2c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2089,10 +2089,7 @@ struct drm_i915_gem_object {
struct scatterlist *sg;
int last;
} get_page;
-
-   /* prime dma-buf support */
-   void *dma_buf_vmapping;
-   int vmapping_count;
+   void *vmapping;
 
/** Breadcrumb of last rendering to the buffer.
 * There can only be one writer, but we allow for multiple readers.
@@ -2840,12 +2837,19 @@ static inline void i915_gem_object_pin_pages(struct 
drm_i915_gem_object *obj)
BUG_ON(obj->pages == NULL);
obj->pages_pin_count++;
 }
+
 static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
 {
BUG_ON(obj->pages_pin_count == 0);
obj->pages_pin_count--;
 }
 
+void *__must_check i915_gem_object_pin_vmap(struct drm_i915_gem_object *obj);
+static inline void i915_gem_object_unpin_vmap(struct drm_i915_gem_object *obj)
+{
+   i915_gem_object_unpin_pages(obj);
+}
+
 int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
 int i915_gem_object_sync(struct drm_i915_gem_object *obj,
 struct intel_engine_cs *to,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 78640aecf86d..446cf0662a38 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2159,6 +2159,11 @@ i915_gem_object_put_pages(struct drm_i915_gem_object 
*obj)
ops->put_pages(obj);
obj->pages = NULL;
 
+   if (obj->vmapping) {
+   vunmap(obj->vmapping);
+   obj->vmapping = NULL;
+   }
+
i915_gem_object_invalidate(obj);
 
return 0;
@@ -2325,6 +2330,42 @@ i915_gem_object_get_pages(struct drm_i915_gem_object 
*obj)
return 0;
 }
 
+void *i915_gem_object_pin_vmap(struct drm_i915_gem_object *obj)
+{
+   int ret;
+
+   ret = i915_gem_object_get_pages(obj);
+   if (ret)
+   return ERR_PTR(ret);
+
+   i915_gem_object_pin_pages(obj);
+
+   if (obj->vmapping == NULL) {
+   struct sg_page_iter sg_iter;
+   struct page **pages;
+   int n;
+
+   n = obj->base.size >> PAGE_SHIFT;
+   pages = kmalloc(n*sizeof(*pages), GFP_TEMPORARY);
+   if (pages == NULL)
+   pages = drm_malloc_ab(n, sizeof(*pages));
+   if (pages != NULL) {
+   n = 0;
+   for_each_sg_page(obj->pages->sgl, _iter, 
obj->pages->nents, 0)
+   pages[n++] = sg_page_iter_page(_iter);
+
+   obj->vmapping = vmap(pages, n, 0, PAGE_KERNEL);
+   drm_free_large(pages);
+   }
+   if (obj->vmapping == NULL) {
+   i915_gem_object_unpin_pages(obj);
+   return ERR_PTR(-ENOMEM);
+   }
+   }
+
+   return obj->vmapping;
+}
+
 void i915_vma_move_to_active(struct i915_vma *vma,
 struct drm_i915_gem_request *req)
 {
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index e9c2bfd85b52..5c4163d3845a 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -95,14 +95,12 @@ static void i915_gem_unmap_dma_buf(struct 
dma_buf_attachment *attachment,
 {
struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
 
-   mutex_lock(>base.dev->struct_mutex);
-
dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir);
sg_free_table(sg);
kfree(sg);
 
-   i915_gem_object_unpin_pages(obj);
-
+   mutex_lock(>base.dev->struct_mutex);
+   i915_gem_object_unpin_vmap(obj);
mutex_unlock(>base.dev->struct_mutex);
 }
 
@@ -110,51 +108,17 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
 {
struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
struct drm_device *dev = obj->base.dev;
-   struct sg_page_iter sg_iter;
-   struct page **pages;
-   int ret, i;
+   void *addr;
+   int ret;
 
ret = 

[Intel-gfx] [PATCH 1/3] drm/i915: Map the ringbuffer using WB on LLC machines

2015-10-08 Thread Chris Wilson
If we have llc coherency, we can write directly into the ringbuffer
using ordinary cached writes rather than forcing WC access.

v2: An important consequence is that we can forgo the mappable request
for WB ringbuffers, allowing for many more simultaneous contexts.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/intel_ringbuffer.c | 70 ++---
 1 file changed, 56 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/intel_ringbuffer.c
index d608be46ea6e..f81ec7785fac 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1966,11 +1966,35 @@ static int init_phys_status_page(struct intel_engine_cs 
*ring)
 
 void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf)
 {
-   iounmap(ringbuf->virtual_start);
+   if (HAS_LLC(ringbuf->obj->base.dev) && !ringbuf->obj->stolen)
+   vunmap(ringbuf->virtual_start);
+   else
+   iounmap(ringbuf->virtual_start);
ringbuf->virtual_start = NULL;
i915_gem_object_ggtt_unpin(ringbuf->obj);
 }
 
+static u32 *vmap_obj(struct drm_i915_gem_object *obj)
+{
+   struct sg_page_iter sg_iter;
+   struct page **pages;
+   void *addr;
+   int i;
+
+   pages = drm_malloc_ab(obj->base.size >> PAGE_SHIFT, sizeof(*pages));
+   if (pages == NULL)
+   return NULL;
+
+   i = 0;
+   for_each_sg_page(obj->pages->sgl, _iter, obj->pages->nents, 0)
+   pages[i++] = sg_page_iter_page(_iter);
+
+   addr = vmap(pages, i, 0, PAGE_KERNEL);
+   drm_free_large(pages);
+
+   return addr;
+}
+
 int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev,
 struct intel_ringbuffer *ringbuf)
 {
@@ -1978,21 +2002,39 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device 
*dev,
struct drm_i915_gem_object *obj = ringbuf->obj;
int ret;
 
-   ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE);
-   if (ret)
-   return ret;
+   if (HAS_LLC(dev_priv) && !obj->stolen) {
+   ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, 0);
+   if (ret)
+   return ret;
 
-   ret = i915_gem_object_set_to_gtt_domain(obj, true);
-   if (ret) {
-   i915_gem_object_ggtt_unpin(obj);
-   return ret;
-   }
+   ret = i915_gem_object_set_to_cpu_domain(obj, true);
+   if (ret) {
+   i915_gem_object_ggtt_unpin(obj);
+   return ret;
+   }
+
+   ringbuf->virtual_start = vmap_obj(obj);
+   if (ringbuf->virtual_start == NULL) {
+   i915_gem_object_ggtt_unpin(obj);
+   return -ENOMEM;
+   }
+   } else {
+   ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE);
+   if (ret)
+   return ret;
 
-   ringbuf->virtual_start = ioremap_wc(dev_priv->gtt.mappable_base +
-   i915_gem_obj_ggtt_offset(obj), ringbuf->size);
-   if (ringbuf->virtual_start == NULL) {
-   i915_gem_object_ggtt_unpin(obj);
-   return -EINVAL;
+   ret = i915_gem_object_set_to_gtt_domain(obj, true);
+   if (ret) {
+   i915_gem_object_ggtt_unpin(obj);
+   return ret;
+   }
+
+   ringbuf->virtual_start = ioremap_wc(dev_priv->gtt.mappable_base 
+
+   
i915_gem_obj_ggtt_offset(obj), ringbuf->size);
+   if (ringbuf->virtual_start == NULL) {
+   i915_gem_object_ggtt_unpin(obj);
+   return -EINVAL;
+   }
}
 
return 0;
-- 
2.6.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 3/3] drm/i915: Treat ringbuffer writes as write to normal memory

2015-10-08 Thread Chris Wilson
Ringbuffers are now being written to either through LLC or WC paths, so
treating them as simply iomem is no longer adequate. However, for the
older !llc hardware, the hardware is documentated as treating the TAIL
register update as serialising, so we can relax the barriers when filling
the rings (but even if it were not, it is still an uncached register write
and so serialising anyway.).

For simplicity, let's ignore the iomem annotation.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/intel_lrc.c|  7 +--
 drivers/gpu/drm/i915/intel_lrc.h|  6 +++---
 drivers/gpu/drm/i915/intel_ringbuffer.c |  7 +--
 drivers/gpu/drm/i915/intel_ringbuffer.h | 17 -
 4 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index d38746c5370d..10020505be75 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -713,13 +713,8 @@ intel_logical_ring_advance_and_submit(struct 
drm_i915_gem_request *request)
 
 static void __wrap_ring_buffer(struct intel_ringbuffer *ringbuf)
 {
-   uint32_t __iomem *virt;
int rem = ringbuf->size - ringbuf->tail;
-
-   virt = ringbuf->virtual_start + ringbuf->tail;
-   rem /= 4;
-   while (rem--)
-   iowrite32(MI_NOOP, virt++);
+   memset(ringbuf->virtual_start + ringbuf->tail, 0, rem);
 
ringbuf->tail = 0;
intel_ring_update_space(ringbuf);
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index 64f89f9982a2..8b56fb934763 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -53,8 +53,9 @@ int logical_ring_flush_all_caches(struct drm_i915_gem_request 
*req);
  */
 static inline void intel_logical_ring_advance(struct intel_ringbuffer *ringbuf)
 {
-   ringbuf->tail &= ringbuf->size - 1;
+   intel_ringbuffer_advance(ringbuf);
 }
+
 /**
  * intel_logical_ring_emit() - write a DWORD to the ringbuffer.
  * @ringbuf: Ringbuffer to write to.
@@ -63,8 +64,7 @@ static inline void intel_logical_ring_advance(struct 
intel_ringbuffer *ringbuf)
 static inline void intel_logical_ring_emit(struct intel_ringbuffer *ringbuf,
   u32 data)
 {
-   iowrite32(data, ringbuf->virtual_start + ringbuf->tail);
-   ringbuf->tail += 4;
+   intel_ringbuffer_emit(ringbuf, data);
 }
 
 /* Logical Ring Contexts */
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 49aa52440db2..0eaaab92dea0 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2180,13 +2180,8 @@ static int ring_wait_for_space(struct intel_engine_cs 
*ring, int n)
 
 static void __wrap_ring_buffer(struct intel_ringbuffer *ringbuf)
 {
-   uint32_t __iomem *virt;
int rem = ringbuf->size - ringbuf->tail;
-
-   virt = ringbuf->virtual_start + ringbuf->tail;
-   rem /= 4;
-   while (rem--)
-   iowrite32(MI_NOOP, virt++);
+   memset(ringbuf->virtual_start + ringbuf->tail, 0, rem);
 
ringbuf->tail = 0;
intel_ring_update_space(ringbuf);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h 
b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 2e85fda94963..ff290765e6c9 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -427,17 +427,24 @@ int intel_ring_alloc_request_extras(struct 
drm_i915_gem_request *request);
 
 int __must_check intel_ring_begin(struct drm_i915_gem_request *req, int n);
 int __must_check intel_ring_cacheline_align(struct drm_i915_gem_request *req);
+static inline void intel_ringbuffer_emit(struct intel_ringbuffer *rb,
+u32 data)
+{
+   *(uint32_t __force *)(rb->virtual_start + rb->tail) = data;
+   rb->tail += 4;
+}
+static inline void intel_ringbuffer_advance(struct intel_ringbuffer *rb)
+{
+   rb->tail &= rb->size - 1;
+}
 static inline void intel_ring_emit(struct intel_engine_cs *ring,
   u32 data)
 {
-   struct intel_ringbuffer *ringbuf = ring->buffer;
-   iowrite32(data, ringbuf->virtual_start + ringbuf->tail);
-   ringbuf->tail += 4;
+   intel_ringbuffer_emit(ring->buffer, data);
 }
 static inline void intel_ring_advance(struct intel_engine_cs *ring)
 {
-   struct intel_ringbuffer *ringbuf = ring->buffer;
-   ringbuf->tail &= ringbuf->size - 1;
+   intel_ringbuffer_advance(ring->buffer);
 }
 int __intel_ring_space(int head, int tail, int size);
 void intel_ring_update_space(struct intel_ringbuffer *ringbuf);
-- 
2.6.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: 4K audio N value incorrect at 29.97 and 23.98 refresh rate

2015-10-08 Thread Ville Syrjälä
On Thu, Oct 08, 2015 at 03:39:26PM +0300, Jani Nikula wrote:
> On Thu, 08 Oct 2015, Ville Syrjälä  wrote:
> > On Wed, Oct 07, 2015 at 02:38:29PM -0700, clinton.a.tay...@intel.com wrote:
> >> From: Clint Taylor 
> >> 
> >> The TMDS_296M define was computing as 296704 but the mode->clock is
> >> 296700 as defined by EDID. Adjusted define to allow correct detection
> >> of the need to program the correct N value for 29.97 and 23.98 refresh
> >> rate.
> >> 
> >> Signed-off-by: Clint Taylor 
> >> ---
> >>  drivers/gpu/drm/i915/intel_audio.c |2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/intel_audio.c 
> >> b/drivers/gpu/drm/i915/intel_audio.c
> >> index 56c2f54..419c979 100644
> >> --- a/drivers/gpu/drm/i915/intel_audio.c
> >> +++ b/drivers/gpu/drm/i915/intel_audio.c
> >> @@ -75,7 +75,7 @@ static const struct {
> >>  
> >>  /* HDMI N/CTS table */
> >>  #define TMDS_297M 297000
> >> -#define TMDS_296M DIV_ROUND_UP(297000 * 1000, 1001)
> >> +#define TMDS_296M 296700
> >
> > Hmm. I think we might want to fix up the mode instead. Let me post a few
> > patches, and let's see what people think...
> 
> We might actually want to queue this up for v4.3 as the immediate fix,
> as I feel it's doubtful your other patches will make it to v4.3.
> 
> If Someone(tm) provided their r-b that is.

Except this is wrong if the mode came from the CEA/HDMI mode list as
opposed from the EDID detailed timings.

-- 
Ville Syrjälä
Intel OTC
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4] drm/i915: Clean up associated VMAs on context destruction

2015-10-08 Thread Tvrtko Ursulin


Hi,

On 08/10/15 14:45, Ville Syrjälä wrote:

On Mon, Oct 05, 2015 at 01:26:36PM +0100, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

Prevent leaking VMAs and PPGTT VMs when objects are imported
via flink.

Scenario is that any VMAs created by the importer will be left
dangling after the importer exits, or destroys the PPGTT context
with which they are associated.

This is caused by object destruction not running when the
importer closes the buffer object handle due the reference held
by the exporter. This also leaks the VM since the VMA has a
reference on it.

In practice these leaks can be observed by stopping and starting
the X server on a kernel with fbcon compiled in. Every time
X server exits another VMA will be leaked against the fbcon's
frame buffer object.

Also on systems where flink buffer sharing is used extensively,
like Android, this leak has even more serious consequences.

This version is takes a general approach from the  earlier work
by Rafael Barbalho (drm/i915: Clean-up PPGTT on context
destruction) and tries to incorporate the subsequent discussion
between Chris Wilson and Daniel Vetter.

v2:

Removed immediate cleanup on object retire - it was causing a
recursive VMA unbind via i915_gem_object_wait_rendering. And
it is in fact not even needed since by definition context
cleanup worker runs only after the last context reference has
been dropped, hence all VMAs against the VM belonging to the
context are already on the inactive list.

v3:

Previous version could deadlock since VMA unbind waits on any
rendering on an object to complete. Objects can be busy in a
different VM which would mean that the cleanup loop would do
the wait with the struct mutex held.

This is an even simpler approach where we just unbind VMAs
without waiting since we know all VMAs belonging to this VM
are idle, and there is nothing in flight, at the point
context destructor runs.

v4:

Double underscore prefix for __915_vma_unbind_no_wait and a
commit message typo fix. (Michel Thierry)

Signed-off-by: Tvrtko Ursulin 
Testcase: igt/gem_ppgtt.c/flink-and-exit-vma-leak
Reviewed-by: Michel Thierry 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: Rafael Barbalho 
Cc: Michel Thierry 



---
  drivers/gpu/drm/i915/i915_drv.h |  5 +
  drivers/gpu/drm/i915/i915_gem.c | 20 
  drivers/gpu/drm/i915/i915_gem_context.c | 24 
  3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 824e7245044d..58afa1bb2957 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2840,6 +2840,11 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
  int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
  u32 flags);
  int __must_check i915_vma_unbind(struct i915_vma *vma);
+/*
+ * BEWARE: Do not use the function below unless you can _absolutely_
+ * _guarantee_ VMA in question is _not in use_ anywhere.
+ */
+int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma);
  int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
  void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
  void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f0cfbb9ee12c..52642aff1dab 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3208,7 +3208,7 @@ static void i915_gem_object_finish_gtt(struct 
drm_i915_gem_object *obj)
old_write_domain);
  }

-int i915_vma_unbind(struct i915_vma *vma)
+static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
  {
struct drm_i915_gem_object *obj = vma->obj;
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
@@ -3227,9 +3227,11 @@ int i915_vma_unbind(struct i915_vma *vma)

BUG_ON(obj->pages == NULL);

-   ret = i915_gem_object_wait_rendering(obj, false);
-   if (ret)
-   return ret;
+   if (wait) {
+   ret = i915_gem_object_wait_rendering(obj, false);
+   if (ret)
+   return ret;
+   }

if (i915_is_ggtt(vma->vm) &&
vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
@@ -3274,6 +3276,16 @@ int i915_vma_unbind(struct i915_vma *vma)
return 0;
  }

+int i915_vma_unbind(struct i915_vma *vma)
+{
+   return __i915_vma_unbind(vma, true);
+}
+
+int __i915_vma_unbind_no_wait(struct i915_vma *vma)
+{
+   return __i915_vma_unbind(vma, false);
+}
+
  int i915_gpu_idle(struct drm_device *dev)
  {
struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 

Re: [Intel-gfx] [PATCH 2/3] drm/i915: Refactor duplicate object vmap functions

2015-10-08 Thread Ville Syrjälä
On Thu, Oct 08, 2015 at 01:39:55PM +0100, Chris Wilson wrote:
> We now have two implementations for vmapping a whole object, one for
> dma-buf and one for the ringbuffer. If we couple the vmapping into the
> obj->pages lifetime, then we can reuse an obj->vmapping for both and at
> the same time couple it into the shrinker.
> 
> Signed-off-by: Chris Wilson 
> ---
>  drivers/gpu/drm/i915/i915_drv.h | 12 ---
>  drivers/gpu/drm/i915/i915_gem.c | 41 
>  drivers/gpu/drm/i915/i915_gem_dmabuf.c  | 55 
> +
>  drivers/gpu/drm/i915/intel_ringbuffer.c | 53 ++-
>  4 files changed, 72 insertions(+), 89 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 4093eedfd664..343a0a723d2c 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2089,10 +2089,7 @@ struct drm_i915_gem_object {
>   struct scatterlist *sg;
>   int last;
>   } get_page;
> -
> - /* prime dma-buf support */
> - void *dma_buf_vmapping;
> - int vmapping_count;
> + void *vmapping;
>  
>   /** Breadcrumb of last rendering to the buffer.
>* There can only be one writer, but we allow for multiple readers.
> @@ -2840,12 +2837,19 @@ static inline void i915_gem_object_pin_pages(struct 
> drm_i915_gem_object *obj)
>   BUG_ON(obj->pages == NULL);
>   obj->pages_pin_count++;
>  }
> +
>  static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object 
> *obj)
>  {
>   BUG_ON(obj->pages_pin_count == 0);
>   obj->pages_pin_count--;
>  }
>  
> +void *__must_check i915_gem_object_pin_vmap(struct drm_i915_gem_object *obj);
> +static inline void i915_gem_object_unpin_vmap(struct drm_i915_gem_object 
> *obj)
> +{
> + i915_gem_object_unpin_pages(obj);
> +}
> +
>  int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
>  int i915_gem_object_sync(struct drm_i915_gem_object *obj,
>struct intel_engine_cs *to,
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 78640aecf86d..446cf0662a38 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2159,6 +2159,11 @@ i915_gem_object_put_pages(struct drm_i915_gem_object 
> *obj)
>   ops->put_pages(obj);
>   obj->pages = NULL;
>  
> + if (obj->vmapping) {
> + vunmap(obj->vmapping);
> + obj->vmapping = NULL;
> + }
> +
>   i915_gem_object_invalidate(obj);
>  
>   return 0;
> @@ -2325,6 +2330,42 @@ i915_gem_object_get_pages(struct drm_i915_gem_object 
> *obj)
>   return 0;
>  }
>  
> +void *i915_gem_object_pin_vmap(struct drm_i915_gem_object *obj)
> +{
> + int ret;
> +
> + ret = i915_gem_object_get_pages(obj);
> + if (ret)
> + return ERR_PTR(ret);
> +
> + i915_gem_object_pin_pages(obj);
> +
> + if (obj->vmapping == NULL) {
> + struct sg_page_iter sg_iter;
> + struct page **pages;
> + int n;
> +
> + n = obj->base.size >> PAGE_SHIFT;
> + pages = kmalloc(n*sizeof(*pages), GFP_TEMPORARY);

Random driveby: kmalloc_array()

Also __GFP_NOWARN?

I wonder if the drm_malloc stuff should do the kmalloc attempt
regardless fo the size, so we wouldn't have to do it here?

> + if (pages == NULL)
> + pages = drm_malloc_ab(n, sizeof(*pages));
> + if (pages != NULL) {
> + n = 0;
> + for_each_sg_page(obj->pages->sgl, _iter, 
> obj->pages->nents, 0)
> + pages[n++] = sg_page_iter_page(_iter);
> +
> + obj->vmapping = vmap(pages, n, 0, PAGE_KERNEL);
> + drm_free_large(pages);
> + }
> + if (obj->vmapping == NULL) {
> + i915_gem_object_unpin_pages(obj);
> + return ERR_PTR(-ENOMEM);
> + }
> + }
> +
> + return obj->vmapping;
> +}
> +
>  void i915_vma_move_to_active(struct i915_vma *vma,
>struct drm_i915_gem_request *req)
>  {


-- 
Ville Syrjälä
Intel OTC
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH RESEND 1/3] drm/i915: use error path

2015-10-08 Thread Sudip Mukherjee
Use goto to handle the error path to avoid duplicating the same code. In
the error path intel_dig_port is the last one to be released as it was
the first one to be allocated and ideally the error path should be the
reverse of the execution path.

Cc: Daniel Vetter 
Cc: Jani Nikula 
Signed-off-by: Sudip Mukherjee 
---

Sent on 27/07/2015

 drivers/gpu/drm/i915/intel_dp.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 8d34ca7..18bcfbe 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -6168,10 +6168,8 @@ intel_dp_init(struct drm_device *dev, int output_reg, 
enum port port)
return;
 
intel_connector = intel_connector_alloc();
-   if (!intel_connector) {
-   kfree(intel_dig_port);
-   return;
-   }
+   if (!intel_connector)
+   goto err_connector_alloc;
 
intel_encoder = _dig_port->base;
encoder = _encoder->base;
@@ -6219,11 +6217,18 @@ intel_dp_init(struct drm_device *dev, int output_reg, 
enum port port)
intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
dev_priv->hotplug.irq_port[port] = intel_dig_port;
 
-   if (!intel_dp_init_connector(intel_dig_port, intel_connector)) {
-   drm_encoder_cleanup(encoder);
-   kfree(intel_dig_port);
-   kfree(intel_connector);
-   }
+   if (!intel_dp_init_connector(intel_dig_port, intel_connector))
+   goto err_init_connector;
+
+   return;
+
+err_init_connector:
+   drm_encoder_cleanup(encoder);
+   kfree(intel_connector);
+err_connector_alloc:
+   kfree(intel_dig_port);
+
+   return;
 }
 
 void intel_dp_mst_suspend(struct drm_device *dev)
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 5/6] drm/i915: Support for pread/pwrite from/to non shmem backed objects

2015-10-08 Thread Tvrtko Ursulin


Hi,

On 08/10/15 07:24, ankitprasad.r.sha...@intel.com wrote:

From: Ankitprasad Sharma 

This patch adds support for extending the pread/pwrite functionality
for objects not backed by shmem. The access will be made through
gtt interface.
This will cover prime objects as well as stolen memory backed objects
but for userptr objects it is still forbidden.


Where is the part which forbids it for userptr objects?


v2: Drop locks around slow_user_access, prefault the pages before
access (Chris)

v3: Rebased to the latest drm-intel-nightly (Ankit)

v4: Moved page base & offset calculations outside the copy loop,
corrected data types for size and offset variables, corrected if-else
braces format (Tvrtko/kerneldocs)

v5: Enabled pread/pwrite for all non-shmem backed objects including
without tiling restrictions (Ankit)

v6: Using pwrite_fast for non-shmem backed objects as well (Chris)

Testcase: igt/gem_stolen

Signed-off-by: Ankitprasad Sharma 
---
  drivers/gpu/drm/i915/i915_gem.c | 125 +---
  1 file changed, 104 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 91a2e97..2c94e22 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -614,6 +614,99 @@ shmem_pread_slow(struct page *page, int shmem_page_offset, 
int page_length,
return ret ? - EFAULT : 0;
  }

+static inline uint64_t
+slow_user_access(struct io_mapping *mapping,
+uint64_t page_base, int page_offset,
+char __user *user_data,
+int length, bool pwrite)
+{
+   void __iomem *vaddr_inatomic;
+   void *vaddr;
+   uint64_t unwritten;
+
+   vaddr_inatomic = io_mapping_map_wc(mapping, page_base);
+   /* We can use the cpu mem copy function because this is X86. */
+   vaddr = (void __force *)vaddr_inatomic + page_offset;
+   if (pwrite)
+   unwritten = __copy_from_user(vaddr, user_data, length);
+   else
+   unwritten = __copy_to_user(user_data, vaddr, length);
+
+   io_mapping_unmap(vaddr_inatomic);
+   return unwritten;
+}
+
+static int
+i915_gem_gtt_pread(struct drm_device *dev,
+  struct drm_i915_gem_object *obj, uint64_t size,
+  uint64_t data_offset, uint64_t data_ptr)
+{
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   char __user *user_data;
+   uint64_t remain;
+   uint64_t offset, page_base;
+   int page_offset, page_length, ret = 0;
+
+   ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_MAPPABLE);
+   if (ret)
+   goto out;
+
+   ret = i915_gem_object_set_to_gtt_domain(obj, false);
+   if (ret)
+   goto out_unpin;
+
+   ret = i915_gem_object_put_fence(obj);
+   if (ret)
+   goto out_unpin;
+
+   user_data = to_user_ptr(data_ptr);
+   remain = size;
+   offset = i915_gem_obj_ggtt_offset(obj) + data_offset;
+
+   mutex_unlock(>struct_mutex);
+   if (likely(!i915.prefault_disable))
+   ret = fault_in_multipages_writeable(user_data, remain);
+
+   /*
+* page_offset = offset within page
+* page_base = page offset within aperture
+*/
+   page_offset = offset_in_page(offset);
+   page_base = offset & PAGE_MASK;
+
+   while (remain > 0) {
+   /* page_length = bytes to copy for this page */
+   page_length = remain;
+   if ((page_offset + remain) > PAGE_SIZE)
+   page_length = PAGE_SIZE - page_offset;
+
+   /* This is a slow read/write as it tries to read from
+* and write to user memory which may result into page
+* faults
+*/
+   ret = slow_user_access(dev_priv->gtt.mappable, page_base,
+  page_offset, user_data,
+  page_length, false);
+
+   if (ret) {
+   ret = -EFAULT;
+   break;
+   }
+
+   remain -= page_length;
+   user_data += page_length;
+   page_base += page_length;
+   page_offset = 0;
+   }
+
+   mutex_lock(>struct_mutex);
+
+out_unpin:
+   i915_gem_object_ggtt_unpin(obj);
+out:
+   return ret;
+}
+
  static int
  i915_gem_shmem_pread(struct drm_device *dev,
 struct drm_i915_gem_object *obj,
@@ -737,17 +830,14 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
goto out;
}

-   /* prime objects have no backing filp to GEM pread/pwrite
-* pages from.
-*/
-   if (!obj->base.filp) {
-   ret = -EINVAL;
-   goto out;
-   }
-
trace_i915_gem_object_pread(obj, args->offset, args->size);

-   ret = 

[Intel-gfx] [PATCH RESEND 2/3] drm/i915: check for return value

2015-10-08 Thread Sudip Mukherjee
We were not checking the return value of drm_encoder_init() which can
fail. And if it fails then we will be working with an uninitialized
encoder.

Cc: Daniel Vetter 
Cc: Jani Nikula 
Signed-off-by: Sudip Mukherjee 
---

Sent on 27/07/2015

 drivers/gpu/drm/i915/intel_dp.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 18bcfbe..2a8b47e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -6174,8 +6174,9 @@ intel_dp_init(struct drm_device *dev, int output_reg, 
enum port port)
intel_encoder = _dig_port->base;
encoder = _encoder->base;
 
-   drm_encoder_init(dev, _encoder->base, _dp_enc_funcs,
-DRM_MODE_ENCODER_TMDS);
+   if (drm_encoder_init(dev, _encoder->base, _dp_enc_funcs,
+DRM_MODE_ENCODER_TMDS))
+   goto err_encoder_init;
 
intel_encoder->compute_config = intel_dp_compute_config;
intel_encoder->disable = intel_disable_dp;
@@ -6224,6 +6225,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, 
enum port port)
 
 err_init_connector:
drm_encoder_cleanup(encoder);
+err_encoder_init:
kfree(intel_connector);
 err_connector_alloc:
kfree(intel_dig_port);
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/5] drm/i915: Notify user about outdated dmc firmware

2015-10-08 Thread Animesh Manna



On 10/8/2015 5:53 PM, Mika Kuoppala wrote:

Animesh Manna  writes:


On 9/21/2015 2:00 PM, Mika Kuoppala wrote:

Jani Nikula  writes:


On Fri, 18 Sep 2015, Mika Kuoppala  wrote:

If csr/dmc firmware is known to be outdated, notify
user.

What would break if we requested a firmware version that works? Or we've
made it so that we only request the major version because there's not
supposed to be changes like this between minor versions...?


I guess the question is more of a what should we do
if there is only outdated (known bad) firmware available.

Refuse to load and limb onwards, or return with error code
on driver init.

Latter would force firmware and version to be mandatory and the
version to be tightly coupled to kernel driver version.

A softlink is used to use recommended firmware for dmc and the same information 
is published through 01.org for the firmware user.
Imo, we should not have this kind of hack in code which will change over time 
and this is responsibility of repo-owner to link correct recommended firmware 
for new kernel update.


On machines that had 1.19 symlinked, in filesystem, execlist submission
sometimes broke due to interrupt delivery problem. To reach a conclusion
that it was csr firmware, before 1.21 was out, took quite amount of work.

I bet there are still machines with 1.19 only, and we get to
wade through error states trying to connect the dots.

The dmc/csr firmware is part of our driver functionality. Apparently
it is very tightly coupled to our driver functionality as it can
break things outside of its own domain.

And currently it is loosely coupled black box with our driver,
through symlink, accepting any version that happens to be in customers 
filesystem.

So we recommend latest in website and end up in a situation
that user gets what happens to be in filesystem. Even a known
broken version? And we will keep debugging these problems caused by
broken version? I don't want any more dimensions in our triaging
space, the distributio/firmware version dimension.

Symlink also means that bisectability is very close to worthless on these
kind of bugs. Both in our machines and also on customers. We have
loosely coupled, black box entity, affecting our driver depending
on customers filesystem. Symlink threw that valuable tool out, and
we gained what?

So we are left with triaging. Which is true detective work as there are
no traces of firmware versions nor loading success/fails on
logs/error states.

 From where I look at, the version blacklist is not a hack. It is a cure.


I completely understand your concern and we discussed a lot on same during 
firmware naming
convention and finally decided to have symlink.

If we really want to tightly couple firmware and driver then imo putting exact 
firmware name
will be better option.

Next I saw your subsequent patch where you are not loading the firmware if it 
is older than 1.21.
http://lists.freedesktop.org/archives/intel-gfx/2015-September/076422.html
Curious to know the gpu-hang issue present for any version less than 1.21.

-Animesh




-Mika


-Animesh


-Mika


BR,
Jani.




Signed-off-by: Mika Kuoppala 
---
   drivers/gpu/drm/i915/intel_csr.c | 9 +
   1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c
index 58edc3f..73807c3 100644
--- a/drivers/gpu/drm/i915/intel_csr.c
+++ b/drivers/gpu/drm/i915/intel_csr.c
@@ -45,6 +45,9 @@
   
   MODULE_FIRMWARE(I915_CSR_SKL);
   
+#define RECOMMENDED_FW_MAJOR		1

+#define RECOMMENDED_FW_MINOR   21
+
   /*
   * SKL CSR registers for DC5 and DC6
   */
@@ -387,6 +390,12 @@ static void finish_csr_load(const struct firmware *fw, 
void *context)
   
   	DRM_DEBUG_KMS("Finished loading %s v%u.%u\n", dev_priv->csr.fw_path,

  csr->dmc_ver_major, csr->dmc_ver_minor);
+
+   if (csr->dmc_ver_major < RECOMMENDED_FW_MAJOR ||
+   csr->dmc_ver_minor < RECOMMENDED_FW_MINOR)
+   DRM_INFO("Outdated dmc firmware found, please upgrade to %u.%u or 
newer\n",
+RECOMMENDED_FW_MAJOR, RECOMMENDED_FW_MINOR);
+
   out:
if (fw_loaded)
intel_runtime_pm_put(dev_priv);
--
2.1.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

--
Jani Nikula, Intel Open Source Technology Center

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Pin the ifbdev for the info->system_base GGTT mmapping

2015-10-08 Thread Jesse Barnes
On 10/08/2015 02:07 AM, Chris Wilson wrote:
> On Wed, Oct 07, 2015 at 11:34:17AM -0700, Wayne Boyer wrote:
>> From: Chris Wilson 
>>
>> A long time ago (before 3.14) we relied on a permanent pinning of the
>> ifbdev to lock the fb in place inside the GGTT. However, the
>> introduction of stealing the BIOS framebuffer and reusing its address in
>> the GGTT for the fbdev has muddied waters and we use an inherited fb.
>> However, the inherited fb is only pinned whilst it is active and we no
>> longer have an explicit pin for the info->system_base mmapping used by
>> the fbdev. The result is that after some aperture pressure the fbdev may
>> be evicted, but we continue to write the fbcon into the same GGTT
>> address - overwriting anything else that may be put into that offset.
>> The effect is most pronounced across suspend/resume as
>> intel_fbdev_set_suspend() does a full clear over the whole scanout.
>>
>> v2: rebased on latest nightly (Wayne)
>>
>> Signed-off-by: Chris Wilson 
>> Cc: "Goel, Akash" 
>> Cc: Daniel Vetter 
>> Cc: Jesse Barnes 
>> Cc: sta...@vger.kernel.org
>> Reviewed-by: Deepak S 
>> Signed-off-by: Wayne Boyer 
>> ---
>>  drivers/gpu/drm/i915/intel_fbdev.c | 15 +++
>>  1 file changed, 15 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_fbdev.c 
>> b/drivers/gpu/drm/i915/intel_fbdev.c
>> index 6532912..c6aa4f9 100644
>> --- a/drivers/gpu/drm/i915/intel_fbdev.c
>> +++ b/drivers/gpu/drm/i915/intel_fbdev.c
>> @@ -215,6 +215,16 @@ static int intelfb_create(struct drm_fb_helper *helper,
>>  obj = intel_fb->obj;
>>  size = obj->base.size;
>>  
>> +/* The fb constructor will have already pinned us (or inherited a
>> + * GGTT region from the BIOS) suitable for a scanout, so
>> + * this should just be a no-op and increment the pin count for the
>> + * fbdev mmapping. It does have a useful side-effect of validating
>> + * the pin for fbdev's use via a GGTT mmapping.
>> + */
>> +ret = i915_gem_object_ggtt_pin(obj, NULL, 0, PIN_MAPPABLE);
> 
> This should be i915_gem_obj_ggtt_pin(obj, 0, PIN_MAPPABLE);
> At which point I just rage quit.

LOL GEM naming strikes again!

Jesse

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Remove wrong warning from i915_gem_context_clean

2015-10-08 Thread Michel Thierry

On 10/8/2015 3:37 PM, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

commit e9f24d5fb7cf3628b195b18ff3ac4e37937ceeae
Author: Tvrtko Ursulin 
Date:   Mon Oct 5 13:26:36 2015 +0100

 drm/i915: Clean up associated VMAs on context destruction

Introduced a wrong assumption that all contexts have a ppgtt
instance. This is not true when full PPGTT is not active so
remove the WARN_ON_ONCE from the context cleanup code.


Aliasing ppgtt? (for the record, I tried with enable_ppgtt=1 while 
reviewing the patch and didn't see the warning... maybe I didn't try 
hard enough).




Signed-off-by: Tvrtko Ursulin 
Cc: Michel Thierry 
---
  drivers/gpu/drm/i915/i915_gem_context.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 680b4c9f6b73..8c688a5f1589 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -138,7 +138,7 @@ static void i915_gem_context_clean(struct intel_context 
*ctx)
struct i915_hw_ppgtt *ppgtt = ctx->ppgtt;
struct i915_vma *vma, *next;

-   if (WARN_ON_ONCE(!ppgtt))
+   if (!ppgtt)
return;

WARN_ON(!list_empty(>base.active_list));



Reviewed-by: Michel Thierry 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] periodic wakeup from DPMS suspend

2015-10-08 Thread Daniel Vetter
On Thu, Oct 08, 2015 at 12:44:09PM +0200, Johannes Stezenbach wrote:
> On Wed, Oct 07, 2015 at 01:26:32PM +0200, Johannes Stezenbach wrote:
> > On Tue, Oct 06, 2015 at 11:04:53PM -0400, Alex Deucher wrote:
> > > On Tue, Oct 6, 2015 at 11:10 AM, Johannes Stezenbach  
> > > wrote:
> > > >
> > > > I have a NEC EA244WMi monitor connected to an Asus P8H77-V
> > > > mainboard with Ivy Bridge Core i5-3550 via DVI.
> > > > If DPMS suspend is enabled (by xscreensaver, or for testing by
> > > > "xset dpms force off/suspend/standby"), the monitor
> > > > enters standby mode but wakes up every 10...30 seconds for
> > > > 6 seconds to display a "DVI-D: no signal" message.
> > > 
> > > Some monitors periodically scan all of their inputs if they are not
> > > actively being driven by anything to try and automatically switch to
> > > the connected input.  When the monitor scans the DVI input, it sees
> > > load on the pins and turns on, only to realize it's not getting a
> > > signal and then turns off.  If your monitor has an option to turn off
> > > input probing, that might help.
> > 
> > It's not like I didn't try to twiddle just about every
> > available menu item, and also used the monitor's
> > "Reset to Factory Defaults" to no avail.
> > However, while trying again I found a hidden menu item
> > which is only available during the short time the
> > "No Signal" message is displayed, where the left/right
> > touch buttons open a "Scan Time" setting with "Normal"
> > and "Slow" options.  After I changed it, the issue was
> > solved.  I changed it back and the issue doesn't reproduce.
> > So it looks some internal configuration of the monitor
> > was messed up and is now fixed by twiddling the hidden
> > menu item.  "Scan Time" is not documented in the manual
> > nor is there an indication in the "No Signal" popup.
> > 
> > Case closed.
> 
> And I just came back to see the monitor doing the
> wakeup cycling again.  To try something differerent
> I unplugged the charger of the laptop sitting nearby
> in suspend.  Bingo!  So it looks like an EMI issue.
> I tried a few times and could reproduce twice and
> then no more :-(  Now the monitor wakes up once
> every 5min or so...
> 
> Which brings me back to a previous question:
> 
> > maybe it is some floating signal line causing the
> > monitor to misdetect activity?
> 
> Does the Intel hardware have the capability to switch
> the DVI signal lines from high-z to ground during DPMS
> suspend, and if so, does the driver do the right thing?
> Obviously I have no clue about DVI and intel-gfx, but
> I thought to ask anyway.

We have already known fun with EMI from laptop chargers: i915 hase a
hotpug storm detection logic to combat badly-shielded boards. Could just
be another form of that problem. Afaik there's nothing we can do in the
driver about this (except trying to filter out bad noise, which we do
already).
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 6/9] drm/i915: driver based PASID handling

2015-10-08 Thread Chris Wilson
On Fri, Sep 04, 2015 at 09:59:00AM -0700, Jesse Barnes wrote:
> New file with VT-d SVM and PASID handling functions and page table
> management.  This belongs in the IOMMU code (along with some extra bits
> for waiting for invalidations and page faults to complete, flushing the
> device IOTLB, etc.)
> 
> FIXME:
>   need work queue for re-submitting contexts
>   TE bit handling on SKL
> ---
>  drivers/gpu/drm/i915/Makefile   |5 +-
>  drivers/gpu/drm/i915/i915_drv.h |   43 ++
>  drivers/gpu/drm/i915/i915_gem.c |3 +
>  drivers/gpu/drm/i915/i915_gem_context.c |3 +
>  drivers/gpu/drm/i915/i915_irq.c |7 +
>  drivers/gpu/drm/i915/i915_reg.h |   47 ++
>  drivers/gpu/drm/i915/i915_svm.c | 1102 
> +++
>  drivers/gpu/drm/i915/intel_lrc.c|  120 +++-
>  drivers/gpu/drm/i915/intel_lrc.h|1 +
>  9 files changed, 1299 insertions(+), 32 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/i915_svm.c
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 44d290a..e4883a7 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -38,7 +38,8 @@ i915-y += i915_cmd_parser.o \
> intel_lrc.o \
> intel_mocs.o \
> intel_ringbuffer.o \
> -   intel_uncore.o
> +   intel_uncore.o \
> +   i915_svm.o

Correct me if I am wrong, but it looks like i915_svm implements the
lowlevel interface with the hardware, so by convention is intel_svm.c
  
>  # general-purpose microcontroller (GuC) support
>  i915-y += intel_guc_loader.o \
> @@ -93,6 +94,8 @@ i915-y += dvo_ch7017.o \
>  # virtual gpu code
>  i915-y += i915_vgpu.o
>  
> +i915-$(CONFIG_MMU_NOTIFIER) += i915_svm.o

Added twice?

> +
>  # legacy horrors
>  i915-y += i915_dma.o
>  
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 20beb51..ca38a7a 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -47,6 +47,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -848,6 +849,13 @@ struct i915_ctx_hang_stats {
>   bool banned;
>  };
>  
> +struct intel_mm_struct {
> + struct kref kref;
> + struct mmu_notifier notifier;
> + struct drm_i915_private *dev_priv;
> + struct list_head context_list;
> +};

Doesn't this look kind of familiar? struct i915_mm_struct perhaps?

> +
>  /* This must match up with the value previously used for execbuf2.rsvd1. */
>  #define DEFAULT_CONTEXT_HANDLE 0
>  
> @@ -874,6 +882,9 @@ struct i915_ctx_hang_stats {
>  struct intel_context {
>   struct kref ref;
>   int user_handle;
> + bool is_svm; /* shares x86 page tables */
> + u32 pasid; /* 20 bits */
> + struct intel_mm_struct *ims;
>   uint8_t remap_slice;
>   struct drm_i915_private *i915;
>   int flags;
> @@ -895,6 +906,9 @@ struct intel_context {
>   int pin_count;
>   } engine[I915_NUM_RINGS];
>  
> + struct list_head mm_list;

This is a link, name it so.

> + struct task_struct *tsk;

One task? A context can be passed by the device fd to another process.
Do we inherit the VM along with the context? I don't anything to prevent
such.

> +static void gpu_mm_segv(struct task_struct *tsk, unsigned long address,
> + int si_code)
> +{
> + siginfo_t info;
> +
> + /* Need specific signal info here */
> + info.si_signo   = SIGSEGV;
> + info.si_errno   = EIO;
> + info.si_code= si_code;
> + info.si_addr= (void __user *)address;
> +
> + force_sig_info(SIGSEGV, , tsk);

force_sig_info() is not exported, ah you builtin i915-svm.c

> +}
> +
> +/*
> + * Read the fault descriptor and handle the fault:
> + *   get PML4 from PASID
> + *   get mm struct
> + *   get the vma
> + *   verify the address is valid
> + *   call handle_mm_fault after taking the mm->mmap_sem
> + */
> +void intel_gpu_fault_work(struct work_struct *work)
> +{
> + struct i915_svm_state *svm = container_of(work, struct i915_svm_state,
> +   work);
> + struct drm_i915_private *dev_priv =
> + container_of(svm, struct drm_i915_private, svm);
> + struct drm_device *dev = dev_priv->dev;
> + struct intel_ringbuffer *ringbuf;
> + struct page_request_dsc desc;
> + struct page_group_response_dsc resp;
> + struct intel_context *ctx;
> + struct task_struct *tsk;
> + struct mm_struct *mm;
> + struct vm_area_struct *vma;
> + u64 address;
> + int ret;
> +
> + DRM_ERROR("PRQ updated, head 0x%08x, tail 0x%08x\n",
> +   I915_READ(SVM_PRQ_HEAD), I915_READ(SVM_PRQ_TAIL));
> + prq_read_descriptor(dev, );
> + DRM_ERROR("page fault on addr 0x%016llx, PASID %d, srr %d\n",
> +   (u64)(desc.addr << PAGE_SHIFT), desc.pasid, desc.srr);
> +
> + spin_lock(_priv->svm.lock);
> + ctx = 

Re: [Intel-gfx] [PATCH 1/5] drm/i915: Store and print dmc firmware version

2015-10-08 Thread Damien Lespiau
On Thu, Oct 08, 2015 at 12:03:30PM +0100, Damien Lespiau wrote:
> The DMC firmware version decoding was different in my patch and I'm sure
> it worked then. Maye the header has changed :(

By the way, if this is indeed the case, could you fix
intel_firmware_decode as well?

  
http://cgit.freedesktop.org/xorg/app/intel-gpu-tools/tree/tools/intel_firmware_decode.c

Thanks,

-- 
Damien
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Remove wrong warning from i915_gem_context_clean

2015-10-08 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

commit e9f24d5fb7cf3628b195b18ff3ac4e37937ceeae
Author: Tvrtko Ursulin 
Date:   Mon Oct 5 13:26:36 2015 +0100

drm/i915: Clean up associated VMAs on context destruction

Introduced a wrong assumption that all contexts have a ppgtt
instance. This is not true when full PPGTT is not active so
remove the WARN_ON_ONCE from the context cleanup code.

Signed-off-by: Tvrtko Ursulin 
Cc: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_gem_context.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 680b4c9f6b73..8c688a5f1589 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -138,7 +138,7 @@ static void i915_gem_context_clean(struct intel_context 
*ctx)
struct i915_hw_ppgtt *ppgtt = ctx->ppgtt;
struct i915_vma *vma, *next;
 
-   if (WARN_ON_ONCE(!ppgtt))
+   if (!ppgtt)
return;
 
WARN_ON(!list_empty(>base.active_list));
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/6] drm/i915: Add support for stealing purgable stolen pages

2015-10-08 Thread Chris Wilson
On Thu, Oct 08, 2015 at 03:31:08PM +0100, Tvrtko Ursulin wrote:
> 
> On 08/10/15 12:09, Chris Wilson wrote:
> >On Thu, Oct 08, 2015 at 11:43:29AM +0100, Tvrtko Ursulin wrote:
> >>>-struct drm_i915_gem_object *
> >>>-i915_gem_object_create_stolen(struct drm_device *dev, u64 size)
> >>>+static bool
> >>>+mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind)
> >>>+{
> >>>+  BUG_ON(obj->stolen == NULL);
> >>
> >>I am fundamentally opposed to BUG_ONs which can be avoided. In this
> >>I see no value in hanging the machine while we could WARN_ON and
> >>return false.
> >
> >Don't bother with the WARN_ON. Either take the BUG_ON or accept that to
> >get to this point the machine is dead anyway and a warning here doesn't
> >help identify the root cause (better off with list debugging and memory
> >debugging). I have personally been converting these asserts over to a
> >dev-only compiletime option as I still find the BUGs more useful than
> >WARNs in the GEM code.
> 
> This is one of the ones which are to be expected in development
> only. At that time I much prefer a WARN_ON since it potentially
> saves you one reboot cycle and there aren't really any downsides to
> it. Especially if, as you say, machine is dead already.

panic-on-oops ftw :-p
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases

2015-10-08 Thread Jani Nikula
On Thu, 08 Oct 2015, Ville Syrjälä  wrote:
> On Mon, Oct 05, 2015 at 04:43:14PM +0530, Sonika Jindal wrote:
>> For all the encoders, call the hot_plug if it is registered.
>> This is required for connected boot and resume cases to generate
>> fake hpd resulting in reading of edid.
>> Removing the initial sdvo hot_plug call too so that it will be called
>> just once from this loop.
>> 
>> Signed-off-by: Sonika Jindal 
>> ---
>>  drivers/gpu/drm/i915/intel_hotplug.c |   11 +++
>>  drivers/gpu/drm/i915/intel_sdvo.c|1 -
>>  2 files changed, 11 insertions(+), 1 deletion(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c 
>> b/drivers/gpu/drm/i915/intel_hotplug.c
>> index 53c0173..eac4757 100644
>> --- a/drivers/gpu/drm/i915/intel_hotplug.c
>> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
>> @@ -458,6 +458,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>>  {
>>  struct drm_device *dev = dev_priv->dev;
>>  struct drm_mode_config *mode_config = >mode_config;
>> +struct intel_encoder *encoder;
>>  struct drm_connector *connector;
>>  int i;
>>  
>> @@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>>  if (dev_priv->display.hpd_irq_setup)
>>  dev_priv->display.hpd_irq_setup(dev);
>>  spin_unlock_irq(_priv->irq_lock);
>> +
>> +/*
>> + * Connected boot / resume scenarios can't generate new hot plug.
>> + * So, probe it manually.
>> + */
>> +list_for_each_entry(encoder, >mode_config.encoder_list,
>> +base.head) {
>> +if (encoder->hot_plug)
>> +encoder->hot_plug(encoder);
>> +}
>
>
> This breaks the world on CHV

Also patch 2/2 breaks: https://bugs.freedesktop.org/show_bug.cgi?id=88081

BR,
Jani.


>
> [ 3187.575198] [drm:intel_hdmi_hot_plug] Live status not up!
> [ 3187.585154] =
> [ 3187.595010] [ INFO: possible recursive locking detected ]
> [ 3187.604685] 4.3.0-rc4-bsw+ #2488 Tainted: G U  W  
> [ 3187.614366] -
> [ 3187.623892] Xorg/32212 is trying to acquire lock:
> [ 3187.632635]  (_domains->lock){+.+...}, at: [] 
> intel_display_power_get+0x38/0xcb [i915]
> [ 3187.647492] 
> [ 3187.647492] but task is already holding lock:
> [ 3187.661054]  (_domains->lock){+.+...}, at: [] 
> intel_display_power_get+0x38/0xcb [i915]
> [ 3187.675960] 
> [ 3187.675960] other info that might help us debug this:
> [ 3187.690459]  Possible unsafe locking scenario:
> [ 3187.690459] 
> [ 3187.704224]CPU0
> [ 3187.710485]
> [ 3187.716711]   lock(_domains->lock);
> [ 3187.724718]   lock(_domains->lock);
> [ 3187.732663] 
> [ 3187.732663]  *** DEADLOCK ***
> [ 3187.732663] 
> [ 3187.749460]  May be due to missing lock nesting notation
> [ 3187.749460] 
> [ 3187.763833] 5 locks held by Xorg/32212:
> [ 3187.771523]  #0:  (drm_global_mutex){+.+.+.}, at: [] 
> drm_release+0x3b/0x49b [drm]
> [ 3187.785216]  #1:  (>mode_config.mutex){+.+.+.}, at: 
> [] drm_modeset_lock_all+0x54/0xcd [drm]
> [ 3187.800437]  #2:  (crtc_ww_class_acquire){+.+.+.}, at: 
> [] drm_modeset_lock_all+0x5e/0xcd [drm]
> [ 3187.815488]  #3:  (crtc_ww_class_mutex){+.+.+.}, at: [] 
> drm_modeset_lock+0x75/0xfc [drm]
> [ 3187.830094]  #4:  (_domains->lock){+.+...}, at: [] 
> intel_display_power_get+0x38/0xcb [i915]
> [ 3187.845534] 
> [ 3187.845534] stack backtrace:
> [ 3187.857685] CPU: 2 PID: 32212 Comm: Xorg Tainted: G U  W   
> 4.3.0-rc4-bsw+ #2488
> [ 3187.870331] Hardware name: Intel Corporation CHERRYVIEW C0 
> PLATFORM/Braswell CRB, BIOS BRAS.X64.B085.R00.1509110553 09/11/2015
> [ 3187.886827]   880175eff8e0 8128d59e 
> 823f5ee0
> [ 3187.898904]  880175eff958 810a7a08  
> 880179d1c5d0
> [ 3187.910954]  0004 0006 45422a91588a4c3e 
> 0005
> [ 3187.923011] Call Trace:
> [ 3187.929451]  [] dump_stack+0x4e/0x79
> [ 3187.938912]  [] __lock_acquire+0x7ab/0x12af
> [ 3187.949027]  [] lock_acquire+0x10e/0x1a9
> [ 3187.958859]  [] ? intel_display_power_get+0x38/0xcb 
> [i915]
> [ 3187.970476]  [] ? intel_display_power_get+0x38/0xcb 
> [i915]
> [ 3187.982011]  [] mutex_lock_nested+0x71/0x346
> [ 3187.992167]  [] ? intel_display_power_get+0x38/0xcb 
> [i915]
> [ 3188.003655]  [] ? _raw_spin_unlock_irqrestore+0x4b/0x60
> [ 3188.014829]  [] ? __pm_runtime_resume+0x71/0x7e
> [ 3188.025269]  [] intel_display_power_get+0x38/0xcb [i915]
> [ 3188.036544]  [] ? intel_display_power_get+0x38/0xcb 
> [i915]
> [ 3188.047968]  [] intel_hdmi_set_edid+0x3f/0xd6 [i915]
> [ 3188.058766]  [] intel_hdmi_hot_plug+0xbf/0xfb [i915]
> [ 3188.069484]  [] intel_hpd_init+0xfa/0x10b [i915]
> [ 3188.079753]  [] vlv_display_power_well_init+0xdb/0xe8 
> [i915]
> [ 3188.091224]  [] chv_pipe_power_well_enable+0x62/0x67 
> [i915]
> [ 3188.102594]  [] 

Re: [Intel-gfx] [PATCH] drm/i915: Remove wrong warning from i915_gem_context_clean

2015-10-08 Thread Chris Wilson
On Thu, Oct 08, 2015 at 04:12:31PM +0100, Michel Thierry wrote:
> On 10/8/2015 3:37 PM, Tvrtko Ursulin wrote:
> >From: Tvrtko Ursulin 
> >
> >commit e9f24d5fb7cf3628b195b18ff3ac4e37937ceeae
> >Author: Tvrtko Ursulin 
> >Date:   Mon Oct 5 13:26:36 2015 +0100
> >
> > drm/i915: Clean up associated VMAs on context destruction
> >
> >Introduced a wrong assumption that all contexts have a ppgtt
> >instance. This is not true when full PPGTT is not active so
> >remove the WARN_ON_ONCE from the context cleanup code.
> 
> Aliasing ppgtt? (for the record, I tried with enable_ppgtt=1 while
> reviewing the patch and didn't see the warning... maybe I didn't try
> hard enough).

We create a context per-fd on all platforms, as in it we store user
specific information (such as hangstats, process identifiers etc). Think
of a context as a view of driver state not just GPU state.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4] drm/i915: Clean up associated VMAs on context destruction

2015-10-08 Thread Tvrtko Ursulin


On 08/10/15 17:03, Ville Syrjälä wrote:

On Thu, Oct 08, 2015 at 03:03:11PM +0100, Tvrtko Ursulin wrote:


Hi,

On 08/10/15 14:45, Ville Syrjälä wrote:

On Mon, Oct 05, 2015 at 01:26:36PM +0100, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

Prevent leaking VMAs and PPGTT VMs when objects are imported
via flink.

Scenario is that any VMAs created by the importer will be left
dangling after the importer exits, or destroys the PPGTT context
with which they are associated.

This is caused by object destruction not running when the
importer closes the buffer object handle due the reference held
by the exporter. This also leaks the VM since the VMA has a
reference on it.

In practice these leaks can be observed by stopping and starting
the X server on a kernel with fbcon compiled in. Every time
X server exits another VMA will be leaked against the fbcon's
frame buffer object.

Also on systems where flink buffer sharing is used extensively,
like Android, this leak has even more serious consequences.

This version is takes a general approach from the  earlier work
by Rafael Barbalho (drm/i915: Clean-up PPGTT on context
destruction) and tries to incorporate the subsequent discussion
between Chris Wilson and Daniel Vetter.

v2:

Removed immediate cleanup on object retire - it was causing a
recursive VMA unbind via i915_gem_object_wait_rendering. And
it is in fact not even needed since by definition context
cleanup worker runs only after the last context reference has
been dropped, hence all VMAs against the VM belonging to the
context are already on the inactive list.

v3:

Previous version could deadlock since VMA unbind waits on any
rendering on an object to complete. Objects can be busy in a
different VM which would mean that the cleanup loop would do
the wait with the struct mutex held.

This is an even simpler approach where we just unbind VMAs
without waiting since we know all VMAs belonging to this VM
are idle, and there is nothing in flight, at the point
context destructor runs.

v4:

Double underscore prefix for __915_vma_unbind_no_wait and a
commit message typo fix. (Michel Thierry)

Signed-off-by: Tvrtko Ursulin 
Testcase: igt/gem_ppgtt.c/flink-and-exit-vma-leak
Reviewed-by: Michel Thierry 
Cc: Daniel Vetter 
Cc: Chris Wilson 
Cc: Rafael Barbalho 
Cc: Michel Thierry 



---
   drivers/gpu/drm/i915/i915_drv.h |  5 +
   drivers/gpu/drm/i915/i915_gem.c | 20 
   drivers/gpu/drm/i915/i915_gem_context.c | 24 
   3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 824e7245044d..58afa1bb2957 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2840,6 +2840,11 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
   int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
  u32 flags);
   int __must_check i915_vma_unbind(struct i915_vma *vma);
+/*
+ * BEWARE: Do not use the function below unless you can _absolutely_
+ * _guarantee_ VMA in question is _not in use_ anywhere.
+ */
+int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma);
   int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
   void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
   void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f0cfbb9ee12c..52642aff1dab 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3208,7 +3208,7 @@ static void i915_gem_object_finish_gtt(struct 
drm_i915_gem_object *obj)
old_write_domain);
   }

-int i915_vma_unbind(struct i915_vma *vma)
+static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
   {
struct drm_i915_gem_object *obj = vma->obj;
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
@@ -3227,9 +3227,11 @@ int i915_vma_unbind(struct i915_vma *vma)

BUG_ON(obj->pages == NULL);

-   ret = i915_gem_object_wait_rendering(obj, false);
-   if (ret)
-   return ret;
+   if (wait) {
+   ret = i915_gem_object_wait_rendering(obj, false);
+   if (ret)
+   return ret;
+   }

if (i915_is_ggtt(vma->vm) &&
vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
@@ -3274,6 +3276,16 @@ int i915_vma_unbind(struct i915_vma *vma)
return 0;
   }

+int i915_vma_unbind(struct i915_vma *vma)
+{
+   return __i915_vma_unbind(vma, true);
+}
+
+int __i915_vma_unbind_no_wait(struct i915_vma *vma)
+{
+   return __i915_vma_unbind(vma, false);
+}
+
   int i915_gpu_idle(struct drm_device *dev)
   {

Re: [Intel-gfx] [PATCH 1/3] drm/edid: Fix up clock for CEA/HDMI modes specified via detailed timings

2015-10-08 Thread Daniel Vetter
On Thu, Oct 08, 2015 at 12:22:31PM -0400, Adam Jackson wrote:
> On Thu, 2015-10-08 at 11:43 +0300, ville.syrj...@linux.intel.com wrote:
> > From: Ville Syrjälä 
> > 
> > EDID detailed timings have a resolution of 10kHz for the pixel clock, so
> > they can't represent certain CEA/HDMI modes accurately. If we see a mode
> > coming in via detailed timings which otherwise matches one of the
> > CEA/HDMI modes except the clock is just a bit off, let's assume that the
> > intention was for that mode to be one of the CEA/HDMI modes and go ahead
> > and fix up the clock to match the CEA/HDMI spec exactly (well, as close
> > as we can get with the 1 kHz resolution we use).
> > 
> > This should help code that's looking for an exact clock match (eg. i915
> > audio N/CTS setup).
> 
> Looks like a sane set of changes.  Series is:
> 
> Reviewed-by: Adam Jackson 

Merged the first two patches to drm-misc (the later one has conflicts with
the lack of drm-intel-next, so can pull it in only after a rebase).

Thanks, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4] drm/i915: Clean up associated VMAs on context destruction

2015-10-08 Thread Ville Syrjälä
On Thu, Oct 08, 2015 at 03:03:11PM +0100, Tvrtko Ursulin wrote:
> 
> Hi,
> 
> On 08/10/15 14:45, Ville Syrjälä wrote:
> > On Mon, Oct 05, 2015 at 01:26:36PM +0100, Tvrtko Ursulin wrote:
> >> From: Tvrtko Ursulin 
> >>
> >> Prevent leaking VMAs and PPGTT VMs when objects are imported
> >> via flink.
> >>
> >> Scenario is that any VMAs created by the importer will be left
> >> dangling after the importer exits, or destroys the PPGTT context
> >> with which they are associated.
> >>
> >> This is caused by object destruction not running when the
> >> importer closes the buffer object handle due the reference held
> >> by the exporter. This also leaks the VM since the VMA has a
> >> reference on it.
> >>
> >> In practice these leaks can be observed by stopping and starting
> >> the X server on a kernel with fbcon compiled in. Every time
> >> X server exits another VMA will be leaked against the fbcon's
> >> frame buffer object.
> >>
> >> Also on systems where flink buffer sharing is used extensively,
> >> like Android, this leak has even more serious consequences.
> >>
> >> This version is takes a general approach from the  earlier work
> >> by Rafael Barbalho (drm/i915: Clean-up PPGTT on context
> >> destruction) and tries to incorporate the subsequent discussion
> >> between Chris Wilson and Daniel Vetter.
> >>
> >> v2:
> >>
> >> Removed immediate cleanup on object retire - it was causing a
> >> recursive VMA unbind via i915_gem_object_wait_rendering. And
> >> it is in fact not even needed since by definition context
> >> cleanup worker runs only after the last context reference has
> >> been dropped, hence all VMAs against the VM belonging to the
> >> context are already on the inactive list.
> >>
> >> v3:
> >>
> >> Previous version could deadlock since VMA unbind waits on any
> >> rendering on an object to complete. Objects can be busy in a
> >> different VM which would mean that the cleanup loop would do
> >> the wait with the struct mutex held.
> >>
> >> This is an even simpler approach where we just unbind VMAs
> >> without waiting since we know all VMAs belonging to this VM
> >> are idle, and there is nothing in flight, at the point
> >> context destructor runs.
> >>
> >> v4:
> >>
> >> Double underscore prefix for __915_vma_unbind_no_wait and a
> >> commit message typo fix. (Michel Thierry)
> >>
> >> Signed-off-by: Tvrtko Ursulin 
> >> Testcase: igt/gem_ppgtt.c/flink-and-exit-vma-leak
> >> Reviewed-by: Michel Thierry 
> >> Cc: Daniel Vetter 
> >> Cc: Chris Wilson 
> >> Cc: Rafael Barbalho 
> >> Cc: Michel Thierry 
> >
> >> ---
> >>   drivers/gpu/drm/i915/i915_drv.h |  5 +
> >>   drivers/gpu/drm/i915/i915_gem.c | 20 
> >>   drivers/gpu/drm/i915/i915_gem_context.c | 24 
> >>   3 files changed, 45 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/i915_drv.h 
> >> b/drivers/gpu/drm/i915/i915_drv.h
> >> index 824e7245044d..58afa1bb2957 100644
> >> --- a/drivers/gpu/drm/i915/i915_drv.h
> >> +++ b/drivers/gpu/drm/i915/i915_drv.h
> >> @@ -2840,6 +2840,11 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object 
> >> *obj,
> >>   int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level 
> >> cache_level,
> >>  u32 flags);
> >>   int __must_check i915_vma_unbind(struct i915_vma *vma);
> >> +/*
> >> + * BEWARE: Do not use the function below unless you can _absolutely_
> >> + * _guarantee_ VMA in question is _not in use_ anywhere.
> >> + */
> >> +int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma);
> >>   int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
> >>   void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
> >>   void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
> >> diff --git a/drivers/gpu/drm/i915/i915_gem.c 
> >> b/drivers/gpu/drm/i915/i915_gem.c
> >> index f0cfbb9ee12c..52642aff1dab 100644
> >> --- a/drivers/gpu/drm/i915/i915_gem.c
> >> +++ b/drivers/gpu/drm/i915/i915_gem.c
> >> @@ -3208,7 +3208,7 @@ static void i915_gem_object_finish_gtt(struct 
> >> drm_i915_gem_object *obj)
> >>old_write_domain);
> >>   }
> >>
> >> -int i915_vma_unbind(struct i915_vma *vma)
> >> +static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
> >>   {
> >>struct drm_i915_gem_object *obj = vma->obj;
> >>struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
> >> @@ -3227,9 +3227,11 @@ int i915_vma_unbind(struct i915_vma *vma)
> >>
> >>BUG_ON(obj->pages == NULL);
> >>
> >> -  ret = i915_gem_object_wait_rendering(obj, false);
> >> -  if (ret)
> >> -  return ret;
> >> +  if (wait) {
> >> +  ret = i915_gem_object_wait_rendering(obj, false);
> >> +  if (ret)
> >> +  return ret;
> >> +  }
> >>
> 

Re: [Intel-gfx] [PATCH 2/2] drm/i915: Simplify intel_dp_pre_emphasis_max()

2015-10-08 Thread Ander Conselvan De Oliveira
Please ignore these two patches. They contain errors and are superseded by a 
new patch series I just
sent.

Ander

On Mon, 2015-10-05 at 17:44 +0300, Ander Conselvan de Oliveira wrote:
> Simplify intel_dp_pre_emphasis_max() by grouping the conditions for VLV,
> HSW, BDW and gen 9 together, since they all use the same values.
> 
> Signed-off-by: Ander Conselvan de Oliveira 
> 
> ---
>  drivers/gpu/drm/i915/intel_dp.c | 29 ++---
>  1 file changed, 2 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 3fa8a55..c7f93c5 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3085,7 +3085,7 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, 
> uint8_t voltage_swing)
>   struct drm_device *dev = intel_dp_to_dev(intel_dp);
>   enum port port = dp_to_dig_port(intel_dp)->port;
>  
> - if (INTEL_INFO(dev)->gen >= 9) {
> + if (INTEL_INFO(dev)->gen >= 7 || !IS_IVYBRIDGE(dev)) {
>   switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
>   case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
>   return DP_TRAIN_PRE_EMPH_LEVEL_3;
> @@ -3094,35 +3094,10 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, 
> uint8_t 
> voltage_swing)
>   case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
>   return DP_TRAIN_PRE_EMPH_LEVEL_1;
>   case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
> - return DP_TRAIN_PRE_EMPH_LEVEL_0;
>   default:
>   return DP_TRAIN_PRE_EMPH_LEVEL_0;
>   }
> - } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
> - switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
> - case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
> - return DP_TRAIN_PRE_EMPH_LEVEL_3;
> - case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
> - return DP_TRAIN_PRE_EMPH_LEVEL_2;
> - case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
> - return DP_TRAIN_PRE_EMPH_LEVEL_1;
> - case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
> - default:
> - return DP_TRAIN_PRE_EMPH_LEVEL_0;
> - }
> - } else if (IS_VALLEYVIEW(dev)) {
> - switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
> - case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
> - return DP_TRAIN_PRE_EMPH_LEVEL_3;
> - case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
> - return DP_TRAIN_PRE_EMPH_LEVEL_2;
> - case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
> - return DP_TRAIN_PRE_EMPH_LEVEL_1;
> - case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
> - default:
> - return DP_TRAIN_PRE_EMPH_LEVEL_0;
> - }
> - } else if (IS_GEN7(dev) && port == PORT_A) {
> + } else if (IS_IVYBRIDGE(dev) && port == PORT_A) {
>   switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
>   case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
>   return DP_TRAIN_PRE_EMPH_LEVEL_2;
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4] drm/i915: Clean up associated VMAs on context destruction

2015-10-08 Thread Ville Syrjälä
On Thu, Oct 08, 2015 at 05:26:44PM +0100, Tvrtko Ursulin wrote:
> 
> On 08/10/15 17:03, Ville Syrjälä wrote:
> > On Thu, Oct 08, 2015 at 03:03:11PM +0100, Tvrtko Ursulin wrote:
> >>
> >> Hi,
> >>
> >> On 08/10/15 14:45, Ville Syrjälä wrote:
> >>> On Mon, Oct 05, 2015 at 01:26:36PM +0100, Tvrtko Ursulin wrote:
>  From: Tvrtko Ursulin 
> 
>  Prevent leaking VMAs and PPGTT VMs when objects are imported
>  via flink.
> 
>  Scenario is that any VMAs created by the importer will be left
>  dangling after the importer exits, or destroys the PPGTT context
>  with which they are associated.
> 
>  This is caused by object destruction not running when the
>  importer closes the buffer object handle due the reference held
>  by the exporter. This also leaks the VM since the VMA has a
>  reference on it.
> 
>  In practice these leaks can be observed by stopping and starting
>  the X server on a kernel with fbcon compiled in. Every time
>  X server exits another VMA will be leaked against the fbcon's
>  frame buffer object.
> 
>  Also on systems where flink buffer sharing is used extensively,
>  like Android, this leak has even more serious consequences.
> 
>  This version is takes a general approach from the  earlier work
>  by Rafael Barbalho (drm/i915: Clean-up PPGTT on context
>  destruction) and tries to incorporate the subsequent discussion
>  between Chris Wilson and Daniel Vetter.
> 
>  v2:
> 
>  Removed immediate cleanup on object retire - it was causing a
>  recursive VMA unbind via i915_gem_object_wait_rendering. And
>  it is in fact not even needed since by definition context
>  cleanup worker runs only after the last context reference has
>  been dropped, hence all VMAs against the VM belonging to the
>  context are already on the inactive list.
> 
>  v3:
> 
>  Previous version could deadlock since VMA unbind waits on any
>  rendering on an object to complete. Objects can be busy in a
>  different VM which would mean that the cleanup loop would do
>  the wait with the struct mutex held.
> 
>  This is an even simpler approach where we just unbind VMAs
>  without waiting since we know all VMAs belonging to this VM
>  are idle, and there is nothing in flight, at the point
>  context destructor runs.
> 
>  v4:
> 
>  Double underscore prefix for __915_vma_unbind_no_wait and a
>  commit message typo fix. (Michel Thierry)
> 
>  Signed-off-by: Tvrtko Ursulin 
>  Testcase: igt/gem_ppgtt.c/flink-and-exit-vma-leak
>  Reviewed-by: Michel Thierry 
>  Cc: Daniel Vetter 
>  Cc: Chris Wilson 
>  Cc: Rafael Barbalho 
>  Cc: Michel Thierry 
> >>>
>  ---
> drivers/gpu/drm/i915/i915_drv.h |  5 +
> drivers/gpu/drm/i915/i915_gem.c | 20 
> drivers/gpu/drm/i915/i915_gem_context.c | 24 
> 3 files changed, 45 insertions(+), 4 deletions(-)
> 
>  diff --git a/drivers/gpu/drm/i915/i915_drv.h 
>  b/drivers/gpu/drm/i915/i915_drv.h
>  index 824e7245044d..58afa1bb2957 100644
>  --- a/drivers/gpu/drm/i915/i915_drv.h
>  +++ b/drivers/gpu/drm/i915/i915_drv.h
>  @@ -2840,6 +2840,11 @@ i915_gem_object_ggtt_pin(struct 
>  drm_i915_gem_object *obj,
> int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level 
>  cache_level,
> u32 flags);
> int __must_check i915_vma_unbind(struct i915_vma *vma);
>  +/*
>  + * BEWARE: Do not use the function below unless you can _absolutely_
>  + * _guarantee_ VMA in question is _not in use_ anywhere.
>  + */
>  +int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma);
> int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
> void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
> void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
>  diff --git a/drivers/gpu/drm/i915/i915_gem.c 
>  b/drivers/gpu/drm/i915/i915_gem.c
>  index f0cfbb9ee12c..52642aff1dab 100644
>  --- a/drivers/gpu/drm/i915/i915_gem.c
>  +++ b/drivers/gpu/drm/i915/i915_gem.c
>  @@ -3208,7 +3208,7 @@ static void i915_gem_object_finish_gtt(struct 
>  drm_i915_gem_object *obj)
>   old_write_domain);
> }
> 
>  -int i915_vma_unbind(struct i915_vma *vma)
>  +static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
> {
>   struct drm_i915_gem_object *obj = vma->obj;
>   struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
>  @@ -3227,9 

Re: [Intel-gfx] [PATCH] drm/i915: 4K audio N value incorrect at 29.97 and 23.98 refresh rate

2015-10-08 Thread Clint Taylor

On 10/08/2015 05:44 AM, Ville Syrjälä wrote:

On Thu, Oct 08, 2015 at 03:39:26PM +0300, Jani Nikula wrote:

On Thu, 08 Oct 2015, Ville Syrjälä  wrote:

On Wed, Oct 07, 2015 at 02:38:29PM -0700, clinton.a.tay...@intel.com wrote:

From: Clint Taylor 

The TMDS_296M define was computing as 296704 but the mode->clock is
296700 as defined by EDID. Adjusted define to allow correct detection
of the need to program the correct N value for 29.97 and 23.98 refresh
rate.

Signed-off-by: Clint Taylor 
---
  drivers/gpu/drm/i915/intel_audio.c |2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_audio.c 
b/drivers/gpu/drm/i915/intel_audio.c
index 56c2f54..419c979 100644
--- a/drivers/gpu/drm/i915/intel_audio.c
+++ b/drivers/gpu/drm/i915/intel_audio.c
@@ -75,7 +75,7 @@ static const struct {

  /* HDMI N/CTS table */
  #define TMDS_297M 297000
-#define TMDS_296M DIV_ROUND_UP(297000 * 1000, 1001)
+#define TMDS_296M 296700


Hmm. I think we might want to fix up the mode instead. Let me post a few
patches, and let's see what people think...


We might actually want to queue this up for v4.3 as the immediate fix,
as I feel it's doubtful your other patches will make it to v4.3.

If Someone(tm) provided their r-b that is.


Except this is wrong if the mode came from the CEA/HDMI mode list as
opposed from the EDID detailed timings.

The original patch was generated from a monitor with 296700 in the DTD. 
Ville's approach is more sane for the long term. We could also just add 
a third check in the 4K audio fixup for the DTD based pixel clock.



___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/3] drm/edid: Fix up clock for CEA/HDMI modes specified via detailed timings

2015-10-08 Thread Adam Jackson
On Thu, 2015-10-08 at 11:43 +0300, ville.syrj...@linux.intel.com wrote:
> From: Ville Syrjälä 
> 
> EDID detailed timings have a resolution of 10kHz for the pixel clock, so
> they can't represent certain CEA/HDMI modes accurately. If we see a mode
> coming in via detailed timings which otherwise matches one of the
> CEA/HDMI modes except the clock is just a bit off, let's assume that the
> intention was for that mode to be one of the CEA/HDMI modes and go ahead
> and fix up the clock to match the CEA/HDMI spec exactly (well, as close
> as we can get with the 1 kHz resolution we use).
> 
> This should help code that's looking for an exact clock match (eg. i915
> audio N/CTS setup).

Looks like a sane set of changes.  Series is:

Reviewed-by: Adam Jackson 

- ajax
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 00/11] Mixed bag of ioctl and agp cleanups

2015-10-08 Thread Daniel Vetter
On Tue, Sep 08, 2015 at 02:58:52PM +0200, Christian König wrote:
> Patches #1, #6, #7, #8 and #10 are Reviewed-by: Christian König
> .
> 
> That should be everything touching radeon/amdgpu if I missed something leave
> me a note.

Ok with an irc r-b from Chris and David I and yours here I pulled in the
remaining patches from this series.

Thanks, Daniel

> 
> Regards,
> Christian.
> 
> On 08.09.2015 13:56, Daniel Vetter wrote:
> >Hi all,
> >
> >Big thing for sure is deprecating DRM_UNLOCKED for DRIVER_MODESET (i.e. 
> >modern
> >drivers) since all of them have their own locking. Besides that a few random
> >things that kind where in the same area/files.
> >
> >Of course kerneldoc is updated too.
> >
> >Feedback highly welcome.
> >
> >Cheers, Daniel
> >
> >Daniel Vetter (11):
> >   drm: Remove __OS_HAS_AGP
> >   drm/i915: Kill cross-module option depencies
> >   drm/i915: Mark debug mod options as _unsafe
> >   drm/i915: Remove setparam ioctl
> >   drm/i915: Mark getparam ioctl as DRM_UNLOCKED
> >   drm: Define a drm_invalid_op ioctl implementation
> >   drm/drm_ioctl.c: kerneldoc
> >   drm: Enforce unlocked ioctl operation for kms driver ioctls
> >   drm/vmwgfx: Stop checking for DRM_UNLOCKED
> >   drm/: Drop DRM_UNLOCKED from modeset drivers
> >   drm: Remove dummy agp ioctl wrappers
> >
> >  Documentation/DocBook/drm.tmpl  |   5 +-
> >  drivers/gpu/drm/Makefile|   3 +-
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c |  24 +++
> >  drivers/gpu/drm/armada/armada_drv.c |   9 +--
> >  drivers/gpu/drm/drm_agpsupport.c|   4 +-
> >  drivers/gpu/drm/drm_bufs.c  |   6 +-
> >  drivers/gpu/drm/drm_ioc32.c |   6 +-
> >  drivers/gpu/drm/drm_ioctl.c |  89 +--
> >  drivers/gpu/drm/drm_memory.c|   6 +-
> >  drivers/gpu/drm/drm_vm.c|   8 +--
> >  drivers/gpu/drm/exynos/exynos_drm_drv.c |  20 +++---
> >  drivers/gpu/drm/i915/i915_dma.c | 101 ++
> >  drivers/gpu/drm/i915/i915_gem_gtt.c |   2 +-
> >  drivers/gpu/drm/i915/i915_params.c  |  30 
> >  drivers/gpu/drm/i915/intel_lrc.c|   3 +-
> >  drivers/gpu/drm/mga/mga_dma.c   |   4 +-
> >  drivers/gpu/drm/msm/msm_drv.c   |  14 ++--
> >  drivers/gpu/drm/nouveau/nouveau_bo.c|   8 +--
> >  drivers/gpu/drm/nouveau/nouveau_drm.c   |  24 +++
> >  drivers/gpu/drm/omapdrm/omap_drv.c  |  12 ++--
> >  drivers/gpu/drm/qxl/qxl_ioctl.c |  14 ++--
> >  drivers/gpu/drm/r128/r128_cce.c |  12 ++--
> >  drivers/gpu/drm/radeon/r600_cp.c|  14 ++--
> >  drivers/gpu/drm/radeon/radeon_agp.c |   8 +--
> >  drivers/gpu/drm/radeon/radeon_cp.c  |  16 ++---
> >  drivers/gpu/drm/radeon/radeon_kms.c | 124 
> > +++-
> >  drivers/gpu/drm/radeon/radeon_ttm.c |  10 +--
> >  drivers/gpu/drm/tegra/drm.c |  28 
> >  drivers/gpu/drm/vmwgfx/vmwgfx_drv.c |  62 +++-
> >  include/drm/drmP.h  |   2 +
> >  include/drm/drm_agpsupport.h|  54 +-
> >  31 files changed, 321 insertions(+), 401 deletions(-)
> >
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Partial revert of atomic watermark series

2015-10-08 Thread Matt Roper
It's been reported that the atomic watermark series triggers some
regressions on SKL, which we haven't been able to track down yet.  Let's
temporarily revert these patches while we track down the root cause.

This commit squashes the reverts of:
  76305b1 drm/i915: Calculate watermark configuration during atomic check (v2)
  a4611e4 drm/i915: Don't set plane visible during HW readout if CRTC is off
  a28170f drm/i915: Calculate ILK-style watermarks during atomic check (v3)
  de4a9f8 drm/i915: Calculate pipe watermarks into CRTC state (v3)
  de165e0 drm/i915: Refactor ilk_update_wm (v3)

Reference: 
http://lists.freedesktop.org/archives/intel-gfx/2015-October/077190.html
Cc: "Zanoni, Paulo R" 
Cc: "Vetter, Daniel" 
Signed-off-by: Matt Roper 
---
I just got access to BXT hardware, so I'm hoping that the SKL problems reported
by Paulo will also be reproducible on BXT.  However I'm not going to be able to
work on this for a couple days, so it's probably better to do some reverts now
so that we don't leave di-nightly in a broken state in the meantime.

Also note that this is a different regression than the one reported by Jani
(for which we've already reverted a couple patches); his issue happens on the
ILK-style watermark path which isn't relevant for Paulo's issues here.

 drivers/gpu/drm/i915/i915_drv.h  |  12 --
 drivers/gpu/drm/i915/intel_display.c |  60 +
 drivers/gpu/drm/i915/intel_drv.h |  49 +++-
 drivers/gpu/drm/i915/intel_pm.c  | 232 +++
 4 files changed, 151 insertions(+), 202 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fbf0ae9..4b02be7 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -627,8 +627,6 @@ struct drm_i915_display_funcs {
  int target, int refclk,
  struct dpll *match_clock,
  struct dpll *best_clock);
-   int (*compute_pipe_wm)(struct intel_crtc *crtc,
-  struct drm_atomic_state *state);
void (*update_wm)(struct drm_crtc *crtc);
int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
@@ -1692,13 +1690,6 @@ struct i915_execbuffer_params {
struct drm_i915_gem_request *request;
 };
 
-/* used in computing the new watermarks state */
-struct intel_wm_config {
-   unsigned int num_pipes_active;
-   bool sprites_enabled;
-   bool sprites_scaled;
-};
-
 struct drm_i915_private {
struct drm_device *dev;
struct kmem_cache *objects;
@@ -1923,9 +1914,6 @@ struct drm_i915_private {
 */
uint16_t skl_latency[8];
 
-   /* Committed wm config */
-   struct intel_wm_config config;
-
/*
 * The skl_wm_values structure is a bit too big for stack
 * allocation, so we keep the staging struct where we store
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 539c373..d84d5c0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11837,12 +11837,6 @@ static int intel_crtc_atomic_check(struct drm_crtc 
*crtc,
}
 
ret = 0;
-   if (dev_priv->display.compute_pipe_wm) {
-   ret = dev_priv->display.compute_pipe_wm(intel_crtc, state);
-   if (ret)
-   return ret;
-   }
-
if (INTEL_INFO(dev)->gen >= 9) {
if (mode_changed)
ret = skl_update_scaler_crtc(pipe_config);
@@ -13048,45 +13042,6 @@ static int intel_modeset_checks(struct 
drm_atomic_state *state)
return 0;
 }
 
-/*
- * Handle calculation of various watermark data at the end of the atomic check
- * phase.  The code here should be run after the per-crtc and per-plane 'check'
- * handlers to ensure that all derived state has been updated.
- */
-static void calc_watermark_data(struct drm_atomic_state *state)
-{
-   struct drm_device *dev = state->dev;
-   struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
-   struct drm_crtc *crtc;
-   struct drm_crtc_state *cstate;
-   struct drm_plane *plane;
-   struct drm_plane_state *pstate;
-
-   /*
-* Calculate watermark configuration details now that derived
-* plane/crtc state is all properly updated.
-*/
-   drm_for_each_crtc(crtc, dev) {
-   cstate = drm_atomic_get_existing_crtc_state(state, crtc) ?:
-   crtc->state;
-
-   if (cstate->active)
-   intel_state->wm_config.num_pipes_active++;
-   }
-   drm_for_each_legacy_plane(plane, dev) {
-   pstate = drm_atomic_get_existing_plane_state(state, plane) ?:
-

Re: [Intel-gfx] [PATCH 6/9] drm/i915: driver based PASID handling

2015-10-08 Thread David Woodhouse
On Thu, 2015-10-08 at 12:29 +0100, Tomas Elf wrote:
> 
> Could someone clarify what this means from the TDR point of view, 
> please? When you say "context blew up" I'm guessing that you mean that 
> come context caused the fault handler to get involved somehow?
> 
> Does this imply that the offending context will hang and the driver will 
> have to detect this hang? If so, then yes - if we have the per-engine 
> hang recovery mode as part of the upcoming TDR work in place then we 
> could handle it by stepping over the offending batch buffer and moving 
> on with a minimum of side-effects on the rest of the driver/GPU.

I don't think the context does hang.

I've made the page-request code artificially fail and report that it
was an invalid page fault. The gem_svm_fault test seems to complete
(albeit complaining that the test failed). Whereas if I just don't
service the page-request at all, *then* the GPU hang is detected.

I haven't actually looked at precisely what *is* happening.

-- 
dwmw2



smime.p7s
Description: S/MIME cryptographic signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 3/7] drm/i915: don't allocate fbcon from stolen memory if it's too big

2015-10-08 Thread Jesse Barnes
On 09/23/2015 08:52 AM, Paulo Zanoni wrote:
> Technology has evolved and now we have eDP panels with 3200x1800
> resolution. In the meantime, the BIOS guys didn't change the default
> 32mb for stolen memory. On top of that, we can't assume our users will
> be able to increase the default stolen memory size to more than 32mb -
> I'm not even sure all BIOSes allow that.
> 
> So just the fbcon buffer alone eats 22mb of my stolen memroy, and due
> to the BDW/SKL restriction of not using the last 8mb of stolen memory,
> all that's left for FBC is 2mb! Since fbcon is not the coolest feature
> ever, I think it's better to save our precious stolen resource to FBC
> and the other guys.
> 
> On the other hand, we really want to use as much stolen memory as
> possible, since on some older systems the stolen memory may be a
> considerable percentage of the total available memory.
> 
> This patch tries to achieve a little balance using a simple heuristic:
> if the fbcon wants more than half of the available stolen memory,
> don't use stolen memory in order to leave some for FBC and the other
> features.
> 
> The long term plan should be to implement a way to set priorities for
> stolen memory allocation and then evict low priority users when the
> high priority ones need the memory. While we still don't have that,
> let's try to make FBC usable with the simple solution.
> 
> Cc: Chris Wilson 
> Signed-off-by: Paulo Zanoni 
> ---
>  drivers/gpu/drm/i915/intel_display.c |  7 +++
>  drivers/gpu/drm/i915/intel_fbdev.c   | 10 --
>  2 files changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 2a1fab3..24b8a72 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2486,6 +2486,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
> struct intel_initial_plane_config *plane_config)
>  {
>   struct drm_device *dev = crtc->base.dev;
> + struct drm_i915_private *dev_priv = to_i915(dev);
>   struct drm_i915_gem_object *obj = NULL;
>   struct drm_mode_fb_cmd2 mode_cmd = { 0 };
>   struct drm_framebuffer *fb = _config->fb->base;
> @@ -2498,6 +2499,12 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
>   if (plane_config->size == 0)
>   return false;
>  
> + /* If the FB is too big, just don't use it since fbdev is not very
> +  * important and we should probably use that space with FBC or other
> +  * features. */
> + if (size_aligned * 2 > dev_priv->gtt.stolen_usable_size)
> + return false;
> +
>   obj = i915_gem_object_create_stolen_for_preallocated(dev,
>base_aligned,
>base_aligned,
> diff --git a/drivers/gpu/drm/i915/intel_fbdev.c 
> b/drivers/gpu/drm/i915/intel_fbdev.c
> index 6532912..4fd5fdf 100644
> --- a/drivers/gpu/drm/i915/intel_fbdev.c
> +++ b/drivers/gpu/drm/i915/intel_fbdev.c
> @@ -121,8 +121,9 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
>   container_of(helper, struct intel_fbdev, helper);
>   struct drm_framebuffer *fb;
>   struct drm_device *dev = helper->dev;
> + struct drm_i915_private *dev_priv = to_i915(dev);
>   struct drm_mode_fb_cmd2 mode_cmd = {};
> - struct drm_i915_gem_object *obj;
> + struct drm_i915_gem_object *obj = NULL;
>   int size, ret;
>  
>   /* we don't do packed 24bpp */
> @@ -139,7 +140,12 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
>  
>   size = mode_cmd.pitches[0] * mode_cmd.height;
>   size = PAGE_ALIGN(size);
> - obj = i915_gem_object_create_stolen(dev, size);
> +
> + /* If the FB is too big, just don't use it since fbdev is not very
> +  * important and we should probably use that space with FBC or other
> +  * features. */
> + if (size * 2 < dev_priv->gtt.stolen_usable_size)
> + obj = i915_gem_object_create_stolen(dev, size);
>   if (obj == NULL)
>   obj = i915_gem_alloc_object(dev, size);
>   if (!obj) {
> 

I agree with Chris that we should make this smarter too, but I don't
think this hurts in the meantime, so:

Reviewed-by: Jesse Barnes 

Might be nice to macro-ize the size comparison too, both for readability
and to change our threshold in one place if we ever need to.

Thanks,
Jesse
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/3] drm/i915: fix CFB size calculation

2015-10-08 Thread Ville Syrjälä
On Thu, Oct 01, 2015 at 07:55:57PM -0300, Paulo Zanoni wrote:
> We were considering the whole framebuffer height, but the spec says we
> should only consider the active display height size. There were still
> some unclear questions based on the spec, but the hardware guys
> clarified them for us. According to them:
> 
> - CFB size = CFB stride * Number of lines FBC writes to CFB
> - CFB stride = plane stride / compression limit
> - Number of lines FBC writes to CFB = MIN(plane source height, maximum
>   number of lines FBC writes to CFB)
> - Plane source height =
>   - pipe source height (PIPE_SRCSZ register) (before SKL)
>   - plane size register height (PLANE_SIZE register) (SKL+)
> - Maximum number of lines FBC writes to CFB =
>   - plane source height (before HSW)
>   - 2048 (HSW+)
> 
> For the plane source height, I could just have made our code do
> I915_READ() in order to be more future proof, but since it's not cool
> to do register reads I decided to just recalculate the values we use
> when we actually write to those registers.
> 
> With this patch, depending on your machine configuration, a lot of the
> kms_frontbuffer_tracking subtests that used to result in a SKIP due to
> not enough stolen memory still start resulting in a PASS.
> 
> v2: Use the clipped src size instead of pipe_src_h (Ville).
> v3: Use the appropriate information provided by the hardware guys.
> v4: Bikesheds: s/sizes/size/, s/fb_cpp/cpp/ (Ville).
> v5: - Don't use crtc->config->pipe_src_x for BDW- (Ville).
> - Fix the register name written in the comment.
> 
> Signed-off-by: Paulo Zanoni 
> ---
>  drivers/gpu/drm/i915/intel_fbc.c | 54 
> 
>  1 file changed, 49 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_fbc.c 
> b/drivers/gpu/drm/i915/intel_fbc.c
> index 1b2ebb2..18e228b 100644
> --- a/drivers/gpu/drm/i915/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/intel_fbc.c
> @@ -698,16 +698,61 @@ void intel_fbc_cleanup_cfb(struct drm_i915_private 
> *dev_priv)
>   mutex_unlock(_priv->fbc.lock);
>  }
>  
> -static int intel_fbc_setup_cfb(struct drm_i915_private *dev_priv, int size,
> -int fb_cpp)
> +/*
> + * For SKL+, the plane source size used by the hardware is based on the 
> value we
> + * write to the PLANE_SIZE register. For BDW-, the hardware looks at the 
> value
> + * we wrote to PIPESRC.
> + */
> +static void intel_fbc_get_plane_source_size(struct intel_crtc *crtc,
> + int *width, int *height)
>  {
> + struct intel_plane_state *plane_state =
> + to_intel_plane_state(crtc->base.primary->state);
> + int w, h;
> +
> + if (intel_rotation_90_or_270(plane_state->base.rotation)) {
> + w = drm_rect_height(_state->src) >> 16;
> + h = drm_rect_width(_state->src) >> 16;
> + } else {
> + w = drm_rect_width(_state->src) >> 16;
> + h = drm_rect_height(_state->src) >> 16;
> + }
> +
> + if (width)
> + *width = w;
> + if (height)
> + *height = h;
> +}

Yep, I like this much better. 

Reviewed-by: Ville Syrjälä 

> +
> +static int intel_fbc_calculate_cfb_size(struct intel_crtc *crtc)
> +{
> + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> + struct drm_framebuffer *fb = crtc->base.primary->fb;
> + int lines;
> +
> + intel_fbc_get_plane_source_size(crtc, NULL, );
> + if (INTEL_INFO(dev_priv)->gen >= 7)
> + lines = min(lines, 2048);
> +
> + return lines * fb->pitches[0];
> +}
> +
> +static int intel_fbc_setup_cfb(struct intel_crtc *crtc)
> +{
> + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> + struct drm_framebuffer *fb = crtc->base.primary->fb;
> + int size, cpp;
> +
> + size = intel_fbc_calculate_cfb_size(crtc);
> + cpp = drm_format_plane_cpp(fb->pixel_format, 0);
> +
>   if (size <= dev_priv->fbc.uncompressed_size)
>   return 0;
>  
>   /* Release any current block */
>   __intel_fbc_cleanup_cfb(dev_priv);
>  
> - return intel_fbc_alloc_cfb(dev_priv, size, fb_cpp);
> + return intel_fbc_alloc_cfb(dev_priv, size, cpp);
>  }
>  
>  static bool stride_is_valid(struct drm_i915_private *dev_priv,
> @@ -897,8 +942,7 @@ static void __intel_fbc_update(struct drm_i915_private 
> *dev_priv)
>   goto out_disable;
>   }
>  
> - if (intel_fbc_setup_cfb(dev_priv, obj->base.size,
> - drm_format_plane_cpp(fb->pixel_format, 0))) {
> + if (intel_fbc_setup_cfb(intel_crtc)) {
>   set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL);
>   goto out_disable;
>   }
> -- 
> 2.5.3
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 

Re: [Intel-gfx] [PATCH 04/16] drm/i915: set ILK_DPFC_FENCE_YOFF to 0 on SNB

2015-10-08 Thread Ville Syrjälä
On Thu, Oct 08, 2015 at 09:26:19PM +, Zanoni, Paulo R wrote:
> Em Sex, 2015-08-28 às 17:46 +0300, Ville Syrjälä escreveu:
> > On Fri, Aug 14, 2015 at 06:34:09PM -0300, Paulo Zanoni wrote:
> > > The doc is pretty clear that this register should be set to 0 on
> > > SNB.
> > > We already write y_offset to DPFC_CPU_FENCE_OFFSET a few lines
> > > below.
> > 
> > Bspec says:
> > "Restriction : The CPU fence is always programmed to match the
> > Display
> >  Buffer base, so this offset must be programmed to 0 to match.  
> > DevSNB"
> > 
> > We definitely don't program the fence to match DSPSURF, so it's not
> > very
> > clear that this is really the right thing to do. I suppose it depends
> > on
> > how the Y offset in the SA register interacts with this one. I never
> > got
> > around to fixing the Y offset stuff in my FBC efforts, so I've not
> > tried
> > it on real hardware and so I have no sure answer here.
> 
> The BSpec page for DPFC Control on SNB says:
> 
> 8<-
> Project :DEVSNB
> iMPH will only send the host modify message when modifications are in
> the fence selected in the DPFC_CONTROL_SA register CPUFNCNUM field. The
> fence field in the FBC Host Modification message will always be 0 and
> this field must be programmed to 0 to match.
> 8<-

That's about the fence number, it doesn't say anything about the offset
IIRC.

I guess it could be tested by, say:
- set the SA fence offset to some high number and leave this one low
- do the opposite
and in each case see if GTT tracking still works.

And to make sure were testin the right thing, probably repeat with
both offsets set high and make sure the tracking really does not work.

> 
> (and DPFC_CONTROL_SA is register 0x100100)
> 
> > 
> > > 
> > > Signed-off-by: Paulo Zanoni 
> > > ---
> > >  drivers/gpu/drm/i915/intel_fbc.c | 7 ++-
> > >  1 file changed, 6 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > > b/drivers/gpu/drm/i915/intel_fbc.c
> > > index 9ffa7dc..f7be9ab8 100644
> > > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > > @@ -216,7 +216,12 @@ static void ilk_fbc_enable(struct intel_crtc
> > > *crtc)
> > >   dpfc_ctl |= obj->fence_reg;
> > >  
> > >   y_offset = get_crtc_fence_y_offset(crtc);
> > > - I915_WRITE(ILK_DPFC_FENCE_YOFF, y_offset);
> > > +
> > > + if (IS_GEN5(dev_priv))
> > > + I915_WRITE(ILK_DPFC_FENCE_YOFF, y_offset);
> > > + else
> > > + I915_WRITE(ILK_DPFC_FENCE_YOFF, 0);
> > > +
> > >   I915_WRITE(ILK_FBC_RT_BASE, i915_gem_obj_ggtt_offset(obj)
> > > | ILK_FBC_RT_VALID);
> > >   /* enable it... */
> > >   I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
> > > -- 
> > > 2.4.6
> > > 
> > > ___
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 

-- 
Ville Syrjälä
Intel OTC
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 04/16] drm/i915: set ILK_DPFC_FENCE_YOFF to 0 on SNB

2015-10-08 Thread Zanoni, Paulo R
Em Sex, 2015-08-28 às 17:46 +0300, Ville Syrjälä escreveu:
> On Fri, Aug 14, 2015 at 06:34:09PM -0300, Paulo Zanoni wrote:
> > The doc is pretty clear that this register should be set to 0 on
> > SNB.
> > We already write y_offset to DPFC_CPU_FENCE_OFFSET a few lines
> > below.
> 
> Bspec says:
> "Restriction : The CPU fence is always programmed to match the
> Display
>  Buffer base, so this offset must be programmed to 0 to match.
> DevSNB"
> 
> We definitely don't program the fence to match DSPSURF, so it's not
> very
> clear that this is really the right thing to do. I suppose it depends
> on
> how the Y offset in the SA register interacts with this one. I never
> got
> around to fixing the Y offset stuff in my FBC efforts, so I've not
> tried
> it on real hardware and so I have no sure answer here.

The BSpec page for DPFC Control on SNB says:

8<-
Project :DEVSNB
iMPH will only send the host modify message when modifications are in
the fence selected in the DPFC_CONTROL_SA register CPUFNCNUM field. The
fence field in the FBC Host Modification message will always be 0 and
this field must be programmed to 0 to match.
8<-

(and DPFC_CONTROL_SA is register 0x100100)

> 
> > 
> > Signed-off-by: Paulo Zanoni 
> > ---
> >  drivers/gpu/drm/i915/intel_fbc.c | 7 ++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > b/drivers/gpu/drm/i915/intel_fbc.c
> > index 9ffa7dc..f7be9ab8 100644
> > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > @@ -216,7 +216,12 @@ static void ilk_fbc_enable(struct intel_crtc
> > *crtc)
> > dpfc_ctl |= obj->fence_reg;
> >  
> > y_offset = get_crtc_fence_y_offset(crtc);
> > -   I915_WRITE(ILK_DPFC_FENCE_YOFF, y_offset);
> > +
> > +   if (IS_GEN5(dev_priv))
> > +   I915_WRITE(ILK_DPFC_FENCE_YOFF, y_offset);
> > +   else
> > +   I915_WRITE(ILK_DPFC_FENCE_YOFF, 0);
> > +
> > I915_WRITE(ILK_FBC_RT_BASE, i915_gem_obj_ggtt_offset(obj)
> > | ILK_FBC_RT_VALID);
> > /* enable it... */
> > I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
> > -- 
> > 2.4.6
> > 
> > ___
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Pin the ifbdev for the info->system_base GGTT mmapping

2015-10-08 Thread Wayne Boyer
From: Chris Wilson 

A long time ago (before 3.14) we relied on a permanent pinning of the
ifbdev to lock the fb in place inside the GGTT. However, the
introduction of stealing the BIOS framebuffer and reusing its address in
the GGTT for the fbdev has muddied waters and we use an inherited fb.
However, the inherited fb is only pinned whilst it is active and we no
longer have an explicit pin for the info->system_base mmapping used by
the fbdev. The result is that after some aperture pressure the fbdev may
be evicted, but we continue to write the fbcon into the same GGTT
address - overwriting anything else that may be put into that offset.
The effect is most pronounced across suspend/resume as
intel_fbdev_set_suspend() does a full clear over the whole scanout.

v2: rebased on latest nightly (Wayne)
v3: changed i915_gem_object_ggtt_pin() to i915_gem_obj_ggtt_pin() based
on Chris' review. (Wayne)

Signed-off-by: Chris Wilson 
Cc: "Goel, Akash" 
Cc: Daniel Vetter 
Cc: Jesse Barnes 
Cc: sta...@vger.kernel.org
Reviewed-by: Deepak S 
Signed-off-by: Wayne Boyer 
---
 drivers/gpu/drm/i915/intel_fbdev.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_fbdev.c 
b/drivers/gpu/drm/i915/intel_fbdev.c
index 6532912..0ad46521 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -215,6 +215,16 @@ static int intelfb_create(struct drm_fb_helper *helper,
obj = intel_fb->obj;
size = obj->base.size;
 
+   /* The fb constructor will have already pinned us (or inherited a
+* GGTT region from the BIOS) suitable for a scanout, so
+* this should just be a no-op and increment the pin count for the
+* fbdev mmapping. It does have a useful side-effect of validating
+* the pin for fbdev's use via a GGTT mmapping.
+*/
+   ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_MAPPABLE);
+   if (ret)
+   goto out_unlock;
+
info = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(info)) {
ret = PTR_ERR(info);
@@ -274,6 +284,9 @@ static int intelfb_create(struct drm_fb_helper *helper,
 out_destroy_fbi:
drm_fb_helper_release_fbi(helper);
 out_unpin:
+   /* Once for info->screen_base mmaping... */
+   i915_gem_object_ggtt_unpin(obj);
+   /* ...and once for the intel_fb */
i915_gem_object_ggtt_unpin(obj);
drm_gem_object_unreference(>base);
 out_unlock:
@@ -514,6 +527,8 @@ static const struct drm_fb_helper_funcs 
intel_fb_helper_funcs = {
 static void intel_fbdev_destroy(struct drm_device *dev,
struct intel_fbdev *ifbdev)
 {
+   /* Release the pinning for the info->screen_base mmaping. */
+   i915_gem_object_ggtt_unpin(ifbdev->fb->obj);
 
drm_fb_helper_unregister_fbi(>helper);
drm_fb_helper_release_fbi(>helper);
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 7/7] iommu/vt-d: Implement page request handling

2015-10-08 Thread David Woodhouse
Signed-off-by: David Woodhouse 
---
 drivers/iommu/intel-svm.c   | 115 +++-
 include/linux/intel-iommu.h |  21 
 2 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index 1260e87..ace1e32 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -356,10 +356,121 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
 }
 EXPORT_SYMBOL_GPL(intel_svm_unbind_mm);
 
+/* Page request queue descriptor */
+struct page_req_dsc {
+   u64 srr:1;
+   u64 bof:1;
+   u64 pasid_present:1;
+   u64 lpig:1;
+   u64 pasid:20;
+   u64 bus:8;
+   u64 private:23;
+   u64 prg_index:9;
+   u64 rd_req:1;
+   u64 wr_req:1;
+   u64 exe_req:1;
+   u64 priv_req:1;
+   u64 devfn:8;
+   u64 addr:52;
+};
 
+#define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x10)
 static irqreturn_t prq_event_thread(int irq, void *d)
 {
struct intel_iommu *iommu = d;
-   printk("PRQ event on %s\n", iommu->name);
-   return IRQ_HANDLED;
+   struct intel_svm *svm = NULL;
+   int head, tail, handled = 0;
+
+   tail = dmar_readq(iommu->reg + DMAR_PQT_REG) & PRQ_RING_MASK;
+   head = dmar_readq(iommu->reg + DMAR_PQH_REG) & PRQ_RING_MASK;
+   while (head != tail) {
+   struct vm_area_struct *vma;
+   struct page_req_dsc *req;
+   struct qi_desc resp;
+   int ret, result;
+   u64 address;
+
+   handled = 1;
+
+   req = >prq[head / sizeof(*req)];
+
+   result = QI_RESP_INVALID;
+   address = req->addr << PAGE_SHIFT;
+   if (!req->pasid_present) {
+   pr_err("%s: Page request without PASID: %08llx 
%08llx\n",
+  iommu->name, ((unsigned long long *)req)[0],
+  ((unsigned long long *)req)[1]);
+   goto inval_req;
+   }
+
+   if (!svm || svm->pasid != req->pasid) {
+   mutex_lock(_mutex);
+   if (svm)
+   kref_put(>kref, _mm_free);
+
+   svm = idr_find(>pasid_idr, req->pasid);
+   if (!svm) {
+   pr_err("%s: Page request for invalid PASID %d: 
%08llx %08llx\n",
+  iommu->name, req->pasid, ((unsigned long 
long *)req)[0],
+  ((unsigned long long *)req)[1]);
+   mutex_unlock(_mutex);
+   goto inval_req;
+   }
+   /* Strictly speaking, we shouldn't need this. It is 
forbidden
+  to unbind the PASID while there may still be 
requests in
+  flight. But let's do it anyway. */
+   kref_get(>kref);
+   mutex_unlock(_mutex);
+   }
+
+   result = QI_RESP_FAILURE;
+   down_read(>mm->mmap_sem);
+   vma = find_extend_vma(svm->mm, address);
+   if (!vma || address < vma->vm_start)
+   goto hard_fault;
+
+   ret = handle_mm_fault(svm->mm, vma, address,
+ req->wr_req ? FAULT_FLAG_WRITE : 0);
+   if (ret & VM_FAULT_ERROR)
+   goto hard_fault;
+
+   result = QI_RESP_SUCCESS;
+   hard_fault:
+   up_read(>mm->mmap_sem);
+   inval_req:
+   /* Accounting for major/minor faults? */
+
+   if (req->lpig) {
+   /* Page Group Response */
+   resp.low = QI_PGRP_PASID(req->pasid) |
+   QI_PGRP_DID((req->bus << 8) | req->devfn) |
+   QI_PGRP_PASID_P(req->pasid_present) |
+   QI_PGRP_RESP_TYPE;
+   resp.high = QI_PGRP_IDX(req->prg_index) |
+   QI_PGRP_PRIV(req->private) | 
QI_PGRP_RESP_CODE(result);
+
+   qi_submit_sync(, svm->iommu);
+   } else if (req->srr) {
+   /* Page Stream Response */
+   resp.low = QI_PSTRM_IDX(req->prg_index) |
+   QI_PSTRM_PRIV(req->private) | 
QI_PSTRM_BUS(req->bus) |
+   QI_PSTRM_PASID(req->pasid) | QI_PSTRM_RESP_TYPE;
+   resp.high = QI_PSTRM_ADDR(address) | 
QI_PSTRM_DEVFN(req->devfn) |
+   QI_PSTRM_RESP_CODE(result);
+
+   qi_submit_sync(, svm->iommu);
+   }
+
+   head = (head + sizeof(*req)) & PRQ_RING_MASK;
+   }
+
+   if (svm) {
+   mutex_lock(_mutex);
+   

[Intel-gfx] [PATCH 6/7] iommu/vt-d: Enable page request interrupt

2015-10-08 Thread David Woodhouse
Signed-off-by: David Woodhouse 
---
 drivers/iommu/intel-iommu.c | 22 +-
 drivers/iommu/intel-svm.c   | 71 +
 include/linux/intel-iommu.h |  5 
 3 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index b5ab009..e27b9c6 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -1687,8 +1687,11 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
free_context_table(iommu);
 
 #ifdef CONFIG_INTEL_IOMMU_SVM
-   if (pasid_enabled(iommu))
+   if (pasid_enabled(iommu)) {
+   if (ecap_prs(iommu->ecap))
+   intel_svm_finish_prq(iommu);
intel_svm_free_pasid_tables(iommu);
+   }
 #endif
 }
 
@@ -3204,6 +3207,13 @@ domains_done:
 
iommu_flush_write_buffer(iommu);
 
+#ifdef CONFIG_INTEL_IOMMU_SVM
+   if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
+   ret = intel_svm_enable_prq(iommu);
+   if (ret)
+   goto free_iommu;
+   }
+#endif
ret = dmar_set_interrupt(iommu);
if (ret)
goto free_iommu;
@@ -4148,6 +4158,14 @@ static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
 
intel_iommu_init_qi(iommu);
iommu_flush_write_buffer(iommu);
+
+#ifdef CONFIG_INTEL_IOMMU_SVM
+   if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
+   ret = intel_svm_enable_prq(iommu);
+   if (ret)
+   goto disable_iommu;
+   }
+#endif
ret = dmar_set_interrupt(iommu);
if (ret)
goto disable_iommu;
@@ -4952,6 +4970,8 @@ int intel_iommu_enable_pasid(struct intel_svm *svm)
ctx_lo |= CONTEXT_TT_PT_PASID << 2;
}
ctx_lo |= CONTEXT_PASIDE;
+   if (svm->dev_iotlb && ecap_prs(svm->iommu->ecap))
+   ctx_lo |= CONTEXT_PRS;
context[0].lo = ctx_lo;
wmb();
svm->iommu->flush.flush_context(svm->iommu, svm->did,
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index 913c3a1..1260e87 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -18,6 +18,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+
+static irqreturn_t prq_event_thread(int irq, void *d);
 
 struct pasid_entry {
u64 val;
@@ -75,6 +79,65 @@ int intel_svm_free_pasid_tables(struct intel_iommu *iommu)
return 0;
 }
 
+#define PRQ_ORDER 0
+int intel_svm_enable_prq(struct intel_iommu *iommu)
+{
+   struct page *pages;
+   int irq, ret;
+
+   pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, PRQ_ORDER);
+   if (!pages) {
+   pr_warn("IOMMU: %s: Failed to allocate page request queue\n",
+   iommu->name);
+   return -ENOMEM;
+   }
+   iommu->prq = page_address(pages);
+
+   irq = dmar_alloc_hwirq(DMAR_UNITS_SUPPORTED + iommu->seq_id, 
iommu->node, iommu);
+   if (irq <= 0) {
+   pr_err("IOMMU: %s: Failed to create IRQ vector for page request 
queue\n",
+  iommu->name);
+   ret = -EINVAL;
+   err:
+   free_pages((unsigned long)iommu->prq, PRQ_ORDER);
+   iommu->prq = 0;
+   return ret;
+   }
+   iommu->pr_irq = irq;
+
+   snprintf(iommu->prq_name, sizeof(iommu->prq_name), "dmar%d-prq", 
iommu->seq_id);
+
+   ret = request_threaded_irq(irq, NULL, prq_event_thread, IRQF_ONESHOT,
+  iommu->prq_name, iommu);
+   if (ret) {
+   pr_err("IOMMU: %s: Failed to request IRQ for page request 
queue\n",
+  iommu->name);
+   dmar_free_hwirq(irq);
+   goto err;
+   }
+   dmar_writeq(iommu->reg + DMAR_PQH_REG, 0ULL);
+   dmar_writeq(iommu->reg + DMAR_PQT_REG, 0ULL);
+   dmar_writeq(iommu->reg + DMAR_PQA_REG, virt_to_phys(iommu->prq) | 
PRQ_ORDER);
+
+   return 0;
+}
+
+int intel_svm_finish_prq(struct intel_iommu *iommu)
+{
+   dmar_writeq(iommu->reg + DMAR_PQH_REG, 0ULL);
+   dmar_writeq(iommu->reg + DMAR_PQT_REG, 0ULL);
+   dmar_writeq(iommu->reg + DMAR_PQA_REG, 0ULL);
+
+   free_irq(iommu->pr_irq, iommu);
+   dmar_free_hwirq(iommu->pr_irq);
+   iommu->pr_irq = 0;
+
+   free_pages((unsigned long)iommu->prq, PRQ_ORDER);
+   iommu->prq = 0;
+
+   return 0;
+}
+
 static void intel_flush_svm_range(struct intel_svm *svm,
  unsigned long address, int pages, int ih)
 {
@@ -292,3 +355,11 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
return ret;
 }
 EXPORT_SYMBOL_GPL(intel_svm_unbind_mm);
+
+
+static irqreturn_t prq_event_thread(int irq, void *d)
+{
+   

[Intel-gfx] [PATCH 5/7] iommu/vt-d: Assume BIOS lies about ATSR for integrated gfx

2015-10-08 Thread David Woodhouse
If the device itself reports ATS in its PCIe capabilities, but the BIOS
neglects to provide an ATSR structure to indicate that the root port can
also cope, then assume the latter is lying.

Signed-off-by: David Woodhouse 
---
 drivers/iommu/intel-iommu.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a6fd639..b5ab009 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -1447,9 +1447,14 @@ iommu_support_dev_iotlb (struct dmar_domain *domain, 
struct intel_iommu *iommu,
if (!pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS))
return NULL;
 
-   if (!dmar_find_matched_atsr_unit(pdev))
-   return NULL;
-
+   if (!dmar_find_matched_atsr_unit(pdev)) {
+   if (intel_iommu_pasid28 && IS_GFX_DEVICE(pdev) &&
+   pdev->vendor == 0x8086) {
+   pr_warn("BIOS denies ATSR capability for %s; assuming 
it lies\n",
+   dev_name(info->dev));
+   } else
+   return NULL;
+   }
return info;
 }
 
-- 
2.4.3

-- 
David WoodhouseOpen Source Technology Centre
david.woodho...@intel.com  Intel Corporation


smime.p7s
Description: S/MIME cryptographic signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 0/7] Enable SVM for Intel VT-d

2015-10-08 Thread David Woodhouse
This patch set enables PASID support for the Intel IOMMU, along with
page request support.

Like its AMD counterpart, it exposes an IOMMU-specific API. I believe
we'll have a session at the Kernel Summit later this month in which we
can work out a generic API which will cover the two (now) existing
implementations as well as upcoming ARM (and other?) versions.

For the time being, however, exposing an Intel-specific API is good
enough, especially as we don't have the required TLP prefix support on
our PCIe root ports and we *can't* support discrete PCIe devices with
PASID support. It's purely on-chip stuff right now, which is basically
only Intel graphics.

The AMD implementation allows a per-device PASID space, and managing
the PASID space is left entirely to the device driver. In contrast,
this implementation maintains a per-IOMMU PASID space, and drivers
calling intel_svm_bind_mm() will be *given* the PASID that they are to
use. In general we seem to be converging on using a single PASID space
across *all* IOMMUs in the system, and this will support that mode of
operation.

-- 
David WoodhouseOpen Source Technology Centre
david.woodho...@intel.com  Intel Corporation



smime.p7s
Description: S/MIME cryptographic signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/7] iommu/vt-d: Add initial support for PASID tables

2015-10-08 Thread David Woodhouse
Add CONFIG_INTEL_IOMMU_SVM, and allocate PASID tables on supported hardware.

Signed-off-by: David Woodhouse 
---
 drivers/iommu/Kconfig   |  8 ++
 drivers/iommu/Makefile  |  1 +
 drivers/iommu/intel-iommu.c | 14 ++
 drivers/iommu/intel-svm.c   | 65 +
 include/linux/intel-iommu.h | 15 +++
 5 files changed, 103 insertions(+)
 create mode 100644 drivers/iommu/intel-svm.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index d9da766..e3b2c2e 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -135,6 +135,14 @@ config INTEL_IOMMU
  and include PCI device scope covered by these DMA
  remapping devices.
 
+config INTEL_IOMMU_SVM
+   bool "Support for Shared Virtual Memory with Intel IOMMU"
+   depends on INTEL_IOMMU && X86
+   help
+ Shared Virtual Memory (SVM) provides a facility for devices
+ to access DMA resources through process address space by
+ means of a Process Address Space ID (PASID).
+
 config INTEL_IOMMU_DEFAULT_ON
def_bool y
prompt "Enable Intel DMA Remapping Devices by default"
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index c6dcc51..dc6f511 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
 obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o
+obj-$(CONFIG_INTEL_IOMMU_SVM) += intel-svm.o
 obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
 obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a1514a5..1f89064 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -1680,6 +1680,11 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
 
/* free context mapping */
free_context_table(iommu);
+
+#ifdef CONFIG_INTEL_IOMMU_SVM
+   if (pasid_enabled(iommu))
+   intel_svm_free_pasid_tables(iommu);
+#endif
 }
 
 static struct dmar_domain *alloc_domain(int flags)
@@ -3103,6 +3108,10 @@ static int __init init_dmars(void)
 
if (!ecap_pass_through(iommu->ecap))
hw_pass_through = 0;
+#ifdef CONFIG_INTEL_IOMMU_SVM
+   if (pasid_enabled(iommu))
+   intel_svm_alloc_pasid_tables(iommu);
+#endif
}
 
if (iommu_pass_through)
@@ -4118,6 +4127,11 @@ static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
if (ret)
goto out;
 
+#ifdef CONFIG_INTEL_IOMMU_SVM
+   if (pasid_enabled(iommu))
+   intel_svm_alloc_pasid_tables(iommu);
+#endif
+
if (dmaru->ignored) {
/*
 * we always have to disable PMRs or DMA may fail on this device
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
new file mode 100644
index 000..9b40ad6
--- /dev/null
+++ b/drivers/iommu/intel-svm.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * Authors: David Woodhouse 
+ */
+
+#include 
+
+int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu)
+{
+   struct page *pages;
+   int order;
+
+   order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT;
+   if (order < 0)
+   order = 0;
+
+   pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+   if (!pages) {
+   pr_warn("IOMMU: %s: Failed to allocate PASID table\n",
+   iommu->name);
+   return -ENOMEM;
+   }
+   iommu->pasid_table = page_address(pages);
+   pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+   if (!pages) {
+   pr_warn("IOMMU: %s: Failed to allocate PASID state table\n",
+   iommu->name);
+   free_pages((unsigned long)iommu->pasid_table, order);
+   iommu->pasid_table = NULL;
+   return -ENOMEM;
+   }
+   iommu->pasid_state_table = page_address(pages);
+   pr_info("%s: Allocated order %d PASID table.\n", iommu->name, order);
+
+   return 0;
+}
+
+int intel_svm_free_pasid_tables(struct intel_iommu *iommu)
+{
+   int order;
+
+   order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT;
+   if (order < 0)
+   order = 0;
+
+   if (iommu->pasid_table) {
+   free_pages((unsigned 

[Intel-gfx] [PATCH 1/7] iommu/vt-d: Introduce intel_iommu=pasid28, and pasid_enabled() macro

2015-10-08 Thread David Woodhouse
As long as we use an identity mapping to work around the worst of the
hardware bugs which caused us to defeature it and change the definition
of the capability bit, we *can* use PASID support on the devices which
advertised it in bit 28 of the Extended Capability Register.

Allow people to do so with 'intel_iommu=pasid28' on the command line.

Signed-off-by: David Woodhouse 
---
 drivers/iommu/intel-iommu.c | 20 ++--
 include/linux/intel-iommu.h |  2 +-
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 041bc18..a1514a5 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -497,13 +497,21 @@ static int dmar_forcedac;
 static int intel_iommu_strict;
 static int intel_iommu_superpage = 1;
 static int intel_iommu_ecs = 1;
+static int intel_iommu_pasid28;
+static int iommu_identity_mapping;
+
+#define IDENTMAP_ALL   1
+#define IDENTMAP_GFX   2
+#define IDENTMAP_AZALIA4
 
 /* We only actually use ECS when PASID support (on the new bit 40)
  * is also advertised. Some early implementations — the ones with
  * PASID support on bit 28 — have issues even when we *only* use
  * extended root/context tables. */
+#define pasid_enabled(iommu) (ecap_pasid(iommu->ecap) || \
+ (intel_iommu_pasid28 && 
ecap_broken_pasid(iommu->ecap)))
 #define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap) && \
-   ecap_pasid(iommu->ecap))
+   pasid_enabled(iommu))
 
 int intel_iommu_gfx_mapped;
 EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
@@ -566,6 +574,11 @@ static int __init intel_iommu_setup(char *str)
printk(KERN_INFO
"Intel-IOMMU: disable extended context table 
support\n");
intel_iommu_ecs = 0;
+   } else if (!strncmp(str, "pasid28", 7)) {
+   printk(KERN_INFO
+   "Intel-IOMMU: enable pre-production PASID 
support\n");
+   intel_iommu_pasid28 = 1;
+   iommu_identity_mapping |= IDENTMAP_GFX;
}
 
str += strcspn(str, ",");
@@ -2399,11 +2412,6 @@ found_domain:
return domain;
 }
 
-static int iommu_identity_mapping;
-#define IDENTMAP_ALL   1
-#define IDENTMAP_GFX   2
-#define IDENTMAP_AZALIA4
-
 static int iommu_domain_identity_map(struct dmar_domain *domain,
 unsigned long long start,
 unsigned long long end)
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 6240063..c03316d 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -123,7 +123,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
 #define ecap_srs(e)((e >> 31) & 0x1)
 #define ecap_ers(e)((e >> 30) & 0x1)
 #define ecap_prs(e)((e >> 29) & 0x1)
-/* PASID support used to be on bit 28 */
+#define ecap_broken_pasid(e)   ((e >> 28) & 0x1)
 #define ecap_dis(e)((e >> 27) & 0x1)
 #define ecap_nest(e)   ((e >> 26) & 0x1)
 #define ecap_mts(e)((e >> 25) & 0x1)
-- 
2.4.3

-- 
David WoodhouseOpen Source Technology Centre
david.woodho...@intel.com  Intel Corporation



smime.p7s
Description: S/MIME cryptographic signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 4/7] iommu/vt-d: Generalise DMAR MSI setup to allow for page request events

2015-10-08 Thread David Woodhouse
Signed-off-by: David Woodhouse 
---
 drivers/iommu/dmar.c| 42 +++---
 include/linux/intel-iommu.h | 10 +-
 2 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 8757f8d..80e3c17 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -1086,6 +1086,11 @@ static void free_iommu(struct intel_iommu *iommu)
iommu_device_destroy(iommu->iommu_dev);
 
if (iommu->irq) {
+   if (iommu->pr_irq) {
+   free_irq(iommu->pr_irq, iommu);
+   dmar_free_hwirq(iommu->pr_irq);
+   iommu->pr_irq = 0;
+   }
free_irq(iommu->irq, iommu);
dmar_free_hwirq(iommu->irq);
iommu->irq = 0;
@@ -1493,53 +1498,68 @@ static const char *dmar_get_fault_reason(u8 
fault_reason, int *fault_type)
}
 }
 
+
+static inline int dmar_msi_reg(struct intel_iommu *iommu, int irq)
+{
+   if (iommu->irq == irq)
+   return DMAR_FECTL_REG;
+   else if (iommu->pr_irq == irq)
+   return DMAR_PECTL_REG;
+   else
+   BUG();
+}
+
 void dmar_msi_unmask(struct irq_data *data)
 {
struct intel_iommu *iommu = irq_data_get_irq_handler_data(data);
+   int reg = dmar_msi_reg(iommu, data->irq);
unsigned long flag;
 
/* unmask it */
raw_spin_lock_irqsave(>register_lock, flag);
-   writel(0, iommu->reg + DMAR_FECTL_REG);
+   writel(0, iommu->reg + reg);
/* Read a reg to force flush the post write */
-   readl(iommu->reg + DMAR_FECTL_REG);
+   readl(iommu->reg + reg);
raw_spin_unlock_irqrestore(>register_lock, flag);
 }
 
 void dmar_msi_mask(struct irq_data *data)
 {
-   unsigned long flag;
struct intel_iommu *iommu = irq_data_get_irq_handler_data(data);
+   int reg = dmar_msi_reg(iommu, data->irq);
+   unsigned long flag;
 
/* mask it */
raw_spin_lock_irqsave(>register_lock, flag);
-   writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG);
+   writel(DMA_FECTL_IM, iommu->reg + reg);
/* Read a reg to force flush the post write */
-   readl(iommu->reg + DMAR_FECTL_REG);
+   readl(iommu->reg + reg);
raw_spin_unlock_irqrestore(>register_lock, flag);
 }
 
 void dmar_msi_write(int irq, struct msi_msg *msg)
 {
struct intel_iommu *iommu = irq_get_handler_data(irq);
+   int reg = dmar_msi_reg(iommu, irq);
unsigned long flag;
 
raw_spin_lock_irqsave(>register_lock, flag);
-   writel(msg->data, iommu->reg + DMAR_FEDATA_REG);
-   writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG);
-   writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG);
+   writel(msg->data, iommu->reg + reg + 4);
+   writel(msg->address_lo, iommu->reg + reg + 8);
+   writel(msg->address_hi, iommu->reg + reg + 12);
raw_spin_unlock_irqrestore(>register_lock, flag);
 }
 
 void dmar_msi_read(int irq, struct msi_msg *msg)
 {
struct intel_iommu *iommu = irq_get_handler_data(irq);
+   int reg = dmar_msi_reg(iommu, irq);
unsigned long flag;
 
raw_spin_lock_irqsave(>register_lock, flag);
-   msg->data = readl(iommu->reg + DMAR_FEDATA_REG);
-   msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG);
-   msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG);
+   msg->data = readl(iommu->reg + reg + 4);
+   msg->address_lo = readl(iommu->reg + reg + 8);
+   msg->address_hi = readl(iommu->reg + reg + 12);
raw_spin_unlock_irqrestore(>register_lock, flag);
 }
 
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index b0df572..564a61b 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -59,6 +59,14 @@
 #define DMAR_IQA_REG   0x90/* Invalidation queue addr register */
 #define DMAR_ICS_REG   0x9c/* Invalidation complete status register */
 #define DMAR_IRTA_REG  0xb8/* Interrupt remapping table addr register */
+#define DMAR_PQH_REG   0xc0/* Page request queue head register */
+#define DMAR_PQT_REG   0xc8/* Page request queue tail register */
+#define DMAR_PQA_REG   0xd0/* Page request queue address register */
+#define DMAR_PRS_REG   0xdc/* Page request status register */
+#define DMAR_PECTL_REG 0xe0/* Page request event control register */
+#defineDMAR_PEDATA_REG 0xe4/* Page request event interrupt data 
register */
+#defineDMAR_PEADDR_REG 0xe8/* Page request event interrupt addr 
register */
+#defineDMAR_PEUADDR_REG 0xec   /* Page request event Upper address 
register */
 
 #define OFFSET_STRIDE  (9)
 /*
@@ -374,7 +382,7 @@ struct intel_iommu {
int seq_id; /* sequence id of the iommu */
int agaw; /* agaw of this iommu */
int msagaw; /* max sagaw of this iommu 

[Intel-gfx] [PATCH 3/7] iommu/vt-d: Add intel_svm_{un, }bind_mm() functions

2015-10-08 Thread David Woodhouse
This provides basic PASID support for endpoint devices, tested with a
version of the i915 driver.

A given process can bind to only one device per IOMMU for now. Making
that more generic isn't particularly difficult but isn't needed yet, and
can come later once the basic functionality is stable.

Eventually we'll also want the PASID space to be system-wide, not just
per-IOMMU. But when we have that requirement we'll also have a way to
achieve it.

Signed-off-by: David Woodhouse 
---
 drivers/iommu/intel-iommu.c   | 100 ++
 drivers/iommu/intel-svm.c | 229 ++
 include/linux/dma_remapping.h |   7 ++
 include/linux/intel-iommu.h   |  59 ++-
 include/linux/intel-svm.h |  68 +
 5 files changed, 458 insertions(+), 5 deletions(-)
 create mode 100644 include/linux/intel-svm.h

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 1f89064..a6fd639 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4882,6 +4882,106 @@ static void intel_iommu_remove_device(struct device 
*dev)
iommu_device_unlink(iommu->iommu_dev, dev);
 }
 
+#ifdef CONFIG_INTEL_IOMMU_SVM
+int intel_iommu_enable_pasid(struct intel_svm *svm)
+{
+   struct device_domain_info *info = NULL;
+   struct context_entry *context;
+   struct dmar_domain *domain;
+   unsigned long flags;
+   u8 bus, devfn;
+   u64 ctx_lo;
+
+   if (iommu_dummy(svm->dev)) {
+   dev_warn(svm->dev,
+"No IOMMU translation for device; cannot enable 
SVM\n");
+   return -EINVAL;
+   }
+
+   domain = get_valid_domain_for_dev(svm->dev);
+   if (!domain) {
+   dev_warn(svm->dev, "Cannot get IOMMU domain to enable SVM\n");
+   return -EINVAL;
+   }
+
+   svm->iommu = device_to_iommu(svm->dev, , );
+   if (!ecs_enabled(svm->iommu)) {
+   dev_dbg(svm->dev, "No ECS support on IOMMU; cannot enable 
SVM\n");
+   return -EINVAL;
+   }
+   svm->did = domain->iommu_did[svm->iommu->seq_id];
+
+   spin_lock_irqsave(_domain_lock, flags);
+   spin_lock(>iommu->lock);
+   context = iommu_context_addr(svm->iommu, bus, devfn, 0);
+   if (WARN_ON(!context)) {
+   spin_unlock(>iommu->lock);
+   spin_unlock_irqrestore(_domain_lock, flags);
+   return -EINVAL;
+   }
+
+   ctx_lo = context[0].lo;
+   /* Modes in which the device IOTLB is enabled are 1 and 5. Modes
+* 3 and 7 are invalid. so we only need to test the low bit of TT */
+   svm->dev_iotlb = (ctx_lo >> 2) & 1;
+
+   if (!(ctx_lo & CONTEXT_PASIDE)) {
+   context[1].hi = 
(u64)virt_to_phys(svm->iommu->pasid_state_table);
+   context[1].lo = (u64)virt_to_phys(svm->iommu->pasid_table) | 
ecap_pss(svm->iommu->ecap);
+   wmb();
+   /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
+* extended to permit requests-with-PASID if the PASIDE bit
+* is set. which makes sense. For CONTEXT_TT_PASS_THROUGH,
+* however, the PASIDE bit is ignored and requests-with-PASID
+* are unconditionally blocked. Which makes less sense.
+* So convert from CONTEXT_TT_PASS_THROUGH to one of the new
+* "guest mode" translation types depending on whether ATS
+* is available or not. */
+   if ((ctx_lo & CONTEXT_TT_MASK) == (CONTEXT_TT_PASS_THROUGH << 
2)) {
+   ctx_lo &= ~CONTEXT_TT_MASK;
+   info = iommu_support_dev_iotlb(domain, svm->iommu, bus, 
devfn);
+   if (info) {
+   ctx_lo |= CONTEXT_TT_PT_PASID_DEV_IOTLB << 2;
+   svm->dev_iotlb = 1;
+   } else
+   ctx_lo |= CONTEXT_TT_PT_PASID << 2;
+   }
+   ctx_lo |= CONTEXT_PASIDE;
+   context[0].lo = ctx_lo;
+   wmb();
+   svm->iommu->flush.flush_context(svm->iommu, svm->did,
+   (((u16)bus) << 8) | devfn,
+   DMA_CCMD_MASK_NOBIT,
+   DMA_CCMD_DEVICE_INVL);
+   }
+   spin_unlock(>iommu->lock);
+   spin_unlock_irqrestore(_domain_lock, flags);
+
+   /* This only happens if we just switched from CONTEXT_TT_PASS_THROUGH */
+   if (info)
+   iommu_enable_dev_iotlb(info);
+
+   /* This can also happen when we were already in a dev-iotlb mode */
+   if (svm->dev_iotlb) {
+   svm->qdep = pci_ats_queue_depth(to_pci_dev(svm->dev));
+   if (svm->qdep >= QI_DEV_EIOTLB_MAX_INVS)
+   svm->qdep = 0;
+   svm->sid = (((u16)bus) 

Re: [Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases

2015-10-08 Thread Jindal, Sonika



On 10/9/2015 1:24 AM, Daniel Vetter wrote:

On Thu, Oct 08, 2015 at 05:38:58PM +0300, Jani Nikula wrote:

On Thu, 08 Oct 2015, Ville Syrjälä  wrote:

On Mon, Oct 05, 2015 at 04:43:14PM +0530, Sonika Jindal wrote:

For all the encoders, call the hot_plug if it is registered.
This is required for connected boot and resume cases to generate
fake hpd resulting in reading of edid.
Removing the initial sdvo hot_plug call too so that it will be called
just once from this loop.

Signed-off-by: Sonika Jindal 
---
  drivers/gpu/drm/i915/intel_hotplug.c |   11 +++
  drivers/gpu/drm/i915/intel_sdvo.c|1 -
  2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_hotplug.c 
b/drivers/gpu/drm/i915/intel_hotplug.c
index 53c0173..eac4757 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -458,6 +458,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
  {
struct drm_device *dev = dev_priv->dev;
struct drm_mode_config *mode_config = >mode_config;
+   struct intel_encoder *encoder;
struct drm_connector *connector;
int i;

@@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
if (dev_priv->display.hpd_irq_setup)
dev_priv->display.hpd_irq_setup(dev);
spin_unlock_irq(_priv->irq_lock);
+
+   /*
+* Connected boot / resume scenarios can't generate new hot plug.
+* So, probe it manually.
+*/
+   list_for_each_entry(encoder, >mode_config.encoder_list,
+   base.head) {
+   if (encoder->hot_plug)
+   encoder->hot_plug(encoder);
+   }



This breaks the world on CHV


Also patch 2/2 breaks: https://bugs.freedesktop.org/show_bug.cgi?id=88081



Hmm, will check why live status is not up for chv..

Regards,
Sonika

Both reverted, thanks for the reveport.
-Daniel



BR,
Jani.




[ 3187.575198] [drm:intel_hdmi_hot_plug] Live status not up!
[ 3187.585154] =
[ 3187.595010] [ INFO: possible recursive locking detected ]
[ 3187.604685] 4.3.0-rc4-bsw+ #2488 Tainted: G U  W
[ 3187.614366] -
[ 3187.623892] Xorg/32212 is trying to acquire lock:
[ 3187.632635]  (_domains->lock){+.+...}, at: [] 
intel_display_power_get+0x38/0xcb [i915]
[ 3187.647492]
[ 3187.647492] but task is already holding lock:
[ 3187.661054]  (_domains->lock){+.+...}, at: [] 
intel_display_power_get+0x38/0xcb [i915]
[ 3187.675960]
[ 3187.675960] other info that might help us debug this:
[ 3187.690459]  Possible unsafe locking scenario:
[ 3187.690459]
[ 3187.704224]CPU0
[ 3187.710485]
[ 3187.716711]   lock(_domains->lock);
[ 3187.724718]   lock(_domains->lock);
[ 3187.732663]
[ 3187.732663]  *** DEADLOCK ***
[ 3187.732663]
[ 3187.749460]  May be due to missing lock nesting notation
[ 3187.749460]
[ 3187.763833] 5 locks held by Xorg/32212:
[ 3187.771523]  #0:  (drm_global_mutex){+.+.+.}, at: [] 
drm_release+0x3b/0x49b [drm]
[ 3187.785216]  #1:  (>mode_config.mutex){+.+.+.}, at: 
[] drm_modeset_lock_all+0x54/0xcd [drm]
[ 3187.800437]  #2:  (crtc_ww_class_acquire){+.+.+.}, at: [] 
drm_modeset_lock_all+0x5e/0xcd [drm]
[ 3187.815488]  #3:  (crtc_ww_class_mutex){+.+.+.}, at: [] 
drm_modeset_lock+0x75/0xfc [drm]
[ 3187.830094]  #4:  (_domains->lock){+.+...}, at: [] 
intel_display_power_get+0x38/0xcb [i915]
[ 3187.845534]
[ 3187.845534] stack backtrace:
[ 3187.857685] CPU: 2 PID: 32212 Comm: Xorg Tainted: G U  W   
4.3.0-rc4-bsw+ #2488
[ 3187.870331] Hardware name: Intel Corporation CHERRYVIEW C0 PLATFORM/Braswell 
CRB, BIOS BRAS.X64.B085.R00.1509110553 09/11/2015
[ 3187.886827]   880175eff8e0 8128d59e 
823f5ee0
[ 3187.898904]  880175eff958 810a7a08  
880179d1c5d0
[ 3187.910954]  0004 0006 45422a91588a4c3e 
0005
[ 3187.923011] Call Trace:
[ 3187.929451]  [] dump_stack+0x4e/0x79
[ 3187.938912]  [] __lock_acquire+0x7ab/0x12af
[ 3187.949027]  [] lock_acquire+0x10e/0x1a9
[ 3187.958859]  [] ? intel_display_power_get+0x38/0xcb [i915]
[ 3187.970476]  [] ? intel_display_power_get+0x38/0xcb [i915]
[ 3187.982011]  [] mutex_lock_nested+0x71/0x346
[ 3187.992167]  [] ? intel_display_power_get+0x38/0xcb [i915]
[ 3188.003655]  [] ? _raw_spin_unlock_irqrestore+0x4b/0x60
[ 3188.014829]  [] ? __pm_runtime_resume+0x71/0x7e
[ 3188.025269]  [] intel_display_power_get+0x38/0xcb [i915]
[ 3188.036544]  [] ? intel_display_power_get+0x38/0xcb [i915]
[ 3188.047968]  [] intel_hdmi_set_edid+0x3f/0xd6 [i915]
[ 3188.058766]  [] intel_hdmi_hot_plug+0xbf/0xfb [i915]
[ 3188.069484]  [] intel_hpd_init+0xfa/0x10b [i915]
[ 3188.079753]  [] vlv_display_power_well_init+0xdb/0xe8 
[i915]
[ 3188.091224]  [] chv_pipe_power_well_enable+0x62/0x67 [i915]
[ 3188.102594]  [] 

[Intel-gfx] [PATCH 0/8] Stability improvements to error state capture

2015-10-08 Thread Tomas Elf
In preparation for the upcoming TDR per-engine hang recovery enablement the
stability of the error state capture code needs to be addressed. The biggest
reason for this is that in order to test TDR a long-duration test needs to be
run for several hours during which a large number of hangs is handled together
with the associated error state captures. In its current state the i915 driver
experiences various forms of kernel panics and other kinds of fatal errors
within the first hour(s) of the hang testing. The patches in this series have
been tested with a long-duration hang testing clocking in at 12+ hours and
should suffice as an initial improvement.

The underlying issue of trying to capture the driver state without
synchronization is still a problem that remains to be fixed. One way of at
least further alleviating this problem that has been suggested by John Harrison
is to do a mutex_trylock() of the struct_mutex for a while (give it a second or
so) before going into the error state capture from i915_handle_error(). Then,
if nobody is holding the struct_mutex, the error state capture is considerably
more safe from sudden state changes. If some thread has hung while holding the
struct_mutex one could at least hope that there would be no sudden state
changes during error state capture due to the hung state (unless some thread
has been caught in a livelock or is perhaps not stuck at all but is simply
running for a very long time - still some improvements might be expected here).

One fix that has been omitted from this patch series is in regards to the
broken ring space calculation following a full GPU reset. Two independent
patches to solve this are: "[PATCH] drm/i915: Update ring space correctly on
lrc context reset" by Mika Kuoppala and "[51/70] drm/i915: Record the position
of the start of the request" by Chris Wilson. Since the solution is currently
in review I'll simply mention it here as a pre-requistite for long-duration
operations stability testing. Without a fix for this problem the ring space is
terminally depleted within the first iterations of the hang test, simply
because the ring space is miscalculated following every GPU hang recovery and
traversal of the GEM init hw path gradually leading to a terminally hung state.

Tomas Elf (8):
  drm/i915: Early exit from semaphore_waits_for for execlist mode.
  drm/i915: Migrate to safe iterators in error state capture
  drm/i915: Cope with request list state change during error state
capture
  drm/i915: NULL checking when capturing buffer objects during error
state capture
  drm/i915: vma NULL pointer check
  drm/i915: Use safe list iterators
  drm/i915: Grab execlist spinlock to avoid post-reset concurrency
issues.
  drm/i915: NULL check of unpin_work

 drivers/gpu/drm/i915/i915_gem.c   | 18 ---
 drivers/gpu/drm/i915/i915_gpu_error.c | 61 +++
 drivers/gpu/drm/i915/i915_irq.c   | 20 
 drivers/gpu/drm/i915/intel_display.c  |  5 +++
 4 files changed, 80 insertions(+), 24 deletions(-)

-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/8] drm/i915: Migrate to safe iterators in error state capture

2015-10-08 Thread Tomas Elf
Using safe list iterators alleviates the problem of unsynchronized driver list
manipulations while error state capture is in the process of traversing lists.

Signed-off-by: Tomas Elf 
---
 drivers/gpu/drm/i915/i915_gpu_error.c | 38 +--
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index 2f04e4f..32c1799 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -718,10 +718,10 @@ static void capture_bo(struct drm_i915_error_buffer *err,
 static u32 capture_active_bo(struct drm_i915_error_buffer *err,
 int count, struct list_head *head)
 {
-   struct i915_vma *vma;
+   struct i915_vma *vma, *tmpvma;
int i = 0;
 
-   list_for_each_entry(vma, head, mm_list) {
+   list_for_each_entry_safe(vma, tmpvma, head, mm_list) {
capture_bo(err++, vma);
if (++i == count)
break;
@@ -734,17 +734,17 @@ static u32 capture_pinned_bo(struct drm_i915_error_buffer 
*err,
 int count, struct list_head *head,
 struct i915_address_space *vm)
 {
-   struct drm_i915_gem_object *obj;
+   struct drm_i915_gem_object *obj, *tmpobj;
struct drm_i915_error_buffer * const first = err;
struct drm_i915_error_buffer * const last = err + count;
 
-   list_for_each_entry(obj, head, global_list) {
-   struct i915_vma *vma;
+   list_for_each_entry_safe(obj, tmpobj, head, global_list) {
+   struct i915_vma *vma, *tmpvma;
 
if (err == last)
break;
 
-   list_for_each_entry(vma, >vma_list, vma_link)
+   list_for_each_entry_safe(vma, tmpvma, >vma_list, vma_link)
if (vma->vm == vm && vma->pin_count > 0)
capture_bo(err++, vma);
}
@@ -958,13 +958,13 @@ static void i915_gem_record_active_context(struct 
intel_engine_cs *ring,
   struct drm_i915_error_ring *ering)
 {
struct drm_i915_private *dev_priv = ring->dev->dev_private;
-   struct drm_i915_gem_object *obj;
+   struct drm_i915_gem_object *obj, *tmpobj;
 
/* Currently render ring is the only HW context user */
if (ring->id != RCS || !error->ccid)
return;
 
-   list_for_each_entry(obj, _priv->mm.bound_list, global_list) {
+   list_for_each_entry_safe(obj, tmpobj, _priv->mm.bound_list, 
global_list) {
if (!i915_gem_obj_ggtt_bound(obj))
continue;
 
@@ -979,7 +979,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
  struct drm_i915_error_state *error)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
-   struct drm_i915_gem_request *request;
+   struct drm_i915_gem_request *request, *tmpreq;
int i, count;
 
for (i = 0; i < I915_NUM_RINGS; i++) {
@@ -1055,7 +1055,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
i915_gem_record_active_context(ring, error, >ring[i]);
 
count = 0;
-   list_for_each_entry(request, >request_list, list)
+   list_for_each_entry_safe(request, tmpreq, >request_list, 
list)
count++;
 
error->ring[i].num_requests = count;
@@ -1068,7 +1068,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
}
 
count = 0;
-   list_for_each_entry(request, >request_list, list) {
+   list_for_each_entry_safe(request, tmpreq, >request_list, 
list) {
struct drm_i915_error_request *erq;
 
erq = >ring[i].requests[count++];
@@ -1088,17 +1088,17 @@ static void i915_gem_capture_vm(struct drm_i915_private 
*dev_priv,
const int ndx)
 {
struct drm_i915_error_buffer *active_bo = NULL, *pinned_bo = NULL;
-   struct drm_i915_gem_object *obj;
-   struct i915_vma *vma;
+   struct drm_i915_gem_object *obj, *tmpobj;
+   struct i915_vma *vma, *tmpvma;
int i;
 
i = 0;
-   list_for_each_entry(vma, >active_list, mm_list)
+   list_for_each_entry_safe(vma, tmpvma, >active_list, mm_list)
i++;
error->active_bo_count[ndx] = i;
 
-   list_for_each_entry(obj, _priv->mm.bound_list, global_list) {
-   list_for_each_entry(vma, >vma_list, vma_link)
+   list_for_each_entry_safe(obj, tmpobj, _priv->mm.bound_list, 
global_list) {
+   list_for_each_entry_safe(vma, tmpvma, >vma_list, vma_link)
if (vma->vm == vm && vma->pin_count > 0)
i++;
}
@@ -1128,10 +1128,10 @@ static void 

[Intel-gfx] [PATCH 3/8] drm/i915: Cope with request list state change during error state capture

2015-10-08 Thread Tomas Elf
Since we're not synchronizing the ring request list during error state capture
the request list state might change between the time the corresponding error
request list was allocated and dimensioned to the time when the ring request
list is actually captured into the error state. If this happens, throw a
WARNING and do early exit and be aware that the captured error state might not
be fully reliable.

Signed-off-by: Tomas Elf 
---
 drivers/gpu/drm/i915/i915_gpu_error.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index 32c1799..cc75ca4 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1071,6 +1071,19 @@ static void i915_gem_record_rings(struct drm_device *dev,
list_for_each_entry_safe(request, tmpreq, >request_list, 
list) {
struct drm_i915_error_request *erq;
 
+   if (WARN_ON(!request || count >= 
error->ring[i].num_requests)) {
+   /*
+* If the ring request list was changed in
+* between the point where the error request
+* list was created and dimensioned and this
+* point then just update the num_requests
+* field to reflect this.
+*/
+   error->ring[i].num_requests =
+   min(count, error->ring[i].num_requests);
+   break;
+   }
+
erq = >ring[i].requests[count++];
erq->seqno = request->seqno;
erq->jiffies = request->emitted_jiffies;
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


  1   2   >