Re: [Intel-gfx] [PATCH 0/6] drm/i915: drmP.h include removal w/ drm prep work

2019-01-02 Thread Laurent Pinchart
Hi Jani,

On Wednesday, 2 January 2019 09:47:58 EET Jani Nikula wrote:
> On Fri, 28 Dec 2018, Jani Nikula  wrote:
> > Thanks for all the reviews, pushed patches 1-5 to topic/drmp-cleanup
> > with $(git merge-base drm-misc-next drm-intel-next-queued) as the
> > starting point. It's also included in drm-tip now.
> 
> So I did this *before* I got the review feedback from Laurent, based on
> Daniel's review only. Would you all like me to redo the branch with
> Laurent's comments addressed and r-b added?

If you think my comments are valuable, that may be a good idea :-)

-- 
Regards,

Laurent Pinchart



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


Re: [Intel-gfx] [PATCH 0/6] drm/i915: start splitting off runtime device info

2019-01-02 Thread Jani Nikula
On Tue, 01 Jan 2019, Chris Wilson  wrote:
> Quoting Jani Nikula (2018-12-31 14:56:40)
>> The mkwrite_device_info removal series [1] seems to have stalled. I'm
>> trying to nudge things forward a bit with this series. This isn't near
>> as complete as Tvrtko's work, but does some of the prep work I wanted,
>> specifically using INTEL_INFO() and RUNTIME_INFO() to access the
>> fields. There are obviously conflicts, but mostly I think this should
>> make the rest of Tvrtko's work easier, not harder.
>> 
>> BR,
>> Jani.
>> 
>> 
>> [1] https://patchwork.freedesktop.org/series/52381/
>> 
>> Cc: Tvrtko Ursulin 
>> 
>> 
>> Jani Nikula (6):
>>   drm/i915: start moving runtime device info to a separate struct
>>   drm/i915/reg: abstract display_mmio_offset access
>>   drm/i915: pass dev_priv to intel_device_info_runtime_init()
>>   drm/i915: always use INTEL_INFO() to access device info
>>   drm/i915: drop intel_device_info_dump()
>>   drm/i915: rename dev_priv info to __info to avoid usage
>
> Looked ok, and didn't see anything odd compared to my own attempts.
> Reviewed-by: Chris Wilson 

Thanks for the review.

Tvrtko, I'd still like to get your ack before I go ahead and push
these. Also, do you think you'll have time in the near future to pick up
your series, or shall I?

BR,
Jani.


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


Re: [Intel-gfx] [PATCH 1/6] drm/i915: start moving runtime device info to a separate struct

2019-01-02 Thread Tvrtko Ursulin


On 31/12/2018 14:56, Jani Nikula wrote:

First move the low hanging fruit, the fields that are only initialized
runtime. Use RUNTIME_INFO() exclusively to access the fields.

Cc: Tvrtko Ursulin 
Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/i915/i915_debugfs.c   | 26 +-
  drivers/gpu/drm/i915/i915_drv.c   | 16 +++---
  drivers/gpu/drm/i915/i915_drv.h   |  4 +-
  drivers/gpu/drm/i915/i915_gpu_error.c |  9 +++-
  drivers/gpu/drm/i915/i915_gpu_error.h |  1 +
  drivers/gpu/drm/i915/i915_perf.c  |  4 +-
  drivers/gpu/drm/i915/i915_query.c |  2 +-
  drivers/gpu/drm/i915/intel_device_info.c  | 60 +++
  drivers/gpu/drm/i915/intel_device_info.h  | 25 ++
  drivers/gpu/drm/i915/intel_display.c  |  2 +-
  drivers/gpu/drm/i915/intel_display.h  |  6 +--
  drivers/gpu/drm/i915/intel_engine_cs.c|  4 +-
  drivers/gpu/drm/i915/intel_lrc.c  | 14 +++---
  drivers/gpu/drm/i915/intel_pm.c   |  2 +-
  drivers/gpu/drm/i915/intel_ringbuffer.c   |  2 +-
  drivers/gpu/drm/i915/intel_ringbuffer.h   |  4 +-
  drivers/gpu/drm/i915/intel_uncore.c   |  4 +-
  drivers/gpu/drm/i915/intel_workarounds.c  |  6 +--
  drivers/gpu/drm/i915/selftests/i915_gem_context.c |  6 +--
  drivers/gpu/drm/i915/selftests/intel_lrc.c|  4 +-
  20 files changed, 107 insertions(+), 94 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index b89abbba4604..193823048f96 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -48,7 +48,7 @@ static int i915_capabilities(struct seq_file *m, void *data)
seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev_priv));
  
  	intel_device_info_dump_flags(info, &p);

-   intel_device_info_dump_runtime(info, &p);
+   intel_device_info_dump_runtime(RUNTIME_INFO(dev_priv), &p);
intel_driver_caps_print(&dev_priv->caps, &p);
  
  	kernel_param_lock(THIS_MODULE);

@@ -3157,7 +3157,7 @@ static int i915_engine_info(struct seq_file *m, void 
*unused)
seq_printf(m, "Global active requests: %d\n",
   dev_priv->gt.active_requests);
seq_printf(m, "CS timestamp frequency: %u kHz\n",
-  dev_priv->info.cs_timestamp_frequency_khz);
+  RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_khz);
  
  	p = drm_seq_file_printer(m);

for_each_engine(engine, dev_priv, id)
@@ -3173,7 +3173,7 @@ static int i915_rcs_topology(struct seq_file *m, void 
*unused)
struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct drm_printer p = drm_seq_file_printer(m);
  
-	intel_device_info_dump_topology(&INTEL_INFO(dev_priv)->sseu, &p);

+   intel_device_info_dump_topology(&RUNTIME_INFO(dev_priv)->sseu, &p);
  
  	return 0;

  }
@@ -4209,7 +4209,7 @@ static void gen10_sseu_device_status(struct 
drm_i915_private *dev_priv,
 struct sseu_dev_info *sseu)
  {
  #define SS_MAX 6
-   const struct intel_device_info *info = INTEL_INFO(dev_priv);
+   const struct intel_runtime_info *info = RUNTIME_INFO(dev_priv);
u32 s_reg[SS_MAX], eu_reg[2 * SS_MAX], eu_mask[2];
int s, ss;
  
@@ -4265,7 +4265,7 @@ static void gen9_sseu_device_status(struct drm_i915_private *dev_priv,

struct sseu_dev_info *sseu)
  {
  #define SS_MAX 3
-   const struct intel_device_info *info = INTEL_INFO(dev_priv);
+   const struct intel_runtime_info *info = RUNTIME_INFO(dev_priv);
u32 s_reg[SS_MAX], eu_reg[2 * SS_MAX], eu_mask[2];
int s, ss;
  
@@ -4293,7 +4293,7 @@ static void gen9_sseu_device_status(struct drm_i915_private *dev_priv,
  
  		if (IS_GEN9_BC(dev_priv))

sseu->subslice_mask[s] =
-   INTEL_INFO(dev_priv)->sseu.subslice_mask[s];
+   RUNTIME_INFO(dev_priv)->sseu.subslice_mask[s];
  
  		for (ss = 0; ss < info->sseu.max_subslices; ss++) {

unsigned int eu_cnt;
@@ -4327,10 +4327,10 @@ static void broadwell_sseu_device_status(struct 
drm_i915_private *dev_priv,
  
  	if (sseu->slice_mask) {

sseu->eu_per_subslice =
-   INTEL_INFO(dev_priv)->sseu.eu_per_subslice;
+   RUNTIME_INFO(dev_priv)->sseu.eu_per_subslice;
for (s = 0; s < fls(sseu->slice_mask); s++) {
sseu->subslice_mask[s] =
-   INTEL_INFO(dev_priv)->sseu.subslice_mask[s];
+   RUNTIME_INFO(dev_priv)->sseu.subslice_mask[s];
}
sseu->eu_total = sseu->eu_per_subslice *
 sseu_subslice_total(sseu);
@@ -4338,7 +4338,7 @@ static void broadwell_

Re: [Intel-gfx] [PATCH] drm/i915: Fix the HDMI hot plug disconnection failure (v4)

2019-01-02 Thread Chris Chiu
Happy New Year.
Sorry for bothering you guys again, I don't really want to make myself
a nuisance.
Is there any better idea for fixing this issue?

Chris

On Mon, Dec 3, 2018 at 6:38 PM Chris Chiu  wrote:
>
> On Fri, Nov 30, 2018 at 1:15 AM Guang Bai  wrote:
> >
> > On Thu, 29 Nov 2018 10:17:49 +0200
> > Jani Nikula  wrote:
> >
> > > On Wed, 28 Nov 2018, Guang Bai  wrote:
> > > > On some GEN9 platforms, slowly unplugging (wiggling) the HDMI cable
> > > > makes the kernel to believe the HDMI display is still connected.
> > > > This is because the HDMI DDC lines are disconnected a little bit
> > > > later after the hot-plug interrupt triggered thus an immediate edid
> > > > fetch can be made. This problem has been identified by more than
> > > > one customer recently. Use digital port live states to authorize
> > > > the edid read at HDMI detection point will ensure most of the
> > > > display related software states updated and rest of them will be
> > > > renewed accordingly when the port is connected.
> > > >
> > > > v2: Fix the formatting issue
> > > > v3: Use digital port states to authorize the edid read
> > > > v4: Add comments on issue histories and rationale of the fix (Chris
> > > > W)
> > >
> > > You're not answering Chris Wilson's question.
> > >
> > > Why do you think the problems we've historically had with live status
> > > are no longer a problem? We've tried and reverted live status checks
> > > at least twice before because of regressions. Why do you think this
> > > time there won't be regressions? Why do you think this patch makes
> > > forward progress?
> > Jani,
> > I'm still new to kernel developments compared with all of you working
> > in this area for many years - Haven't got any feedbacks on how
> > exactly the HDMI live statue *not* fit for HDMI hot-plug related port
> > status checking, neither had time to track all upstream bugzilla, plus
> > not working directly with Intel OTC teams
> > - What are those failing cases/regressions you mentioned above?
> > - what were the kernel versions related with those developments?
> > - Given the fact i915 architecture and implementation are constantly
> >   evolving - Should we re-visit those issues with current kernel
> >   implementation?
> > - Fundamentally, do you think the edid fetch is still *valid* when the
> >   HDMI is unplugged (status either from PCH or DE)? Or other platform
> >   configurations may present more complexities such as kvm switches are
> >   used along with HDMI?
> > Again, if you could provide me more historical issue details, I'd like
> > to have some reviews/re-investigation for those cases with current 4.20
> > kernel.
> > Thanks,
> > -Guang
>
> Hi Jani,
> I don't know the history and what kind of painful regression that you
> had run into. Could you maybe provide a test plan or some test cases
> for the regression verification? I can follow steps to try to verify whether
> if the patch can work on all cases.
>
> Chris
>
> > >
> > > I've *repeatedly* said from the beginning that I am very sceptical of
> > > using live status because we've been burned by it so many times
> > > before. I don't much care to repeat this anymore.
> > >
> > >
> > > BR,
> > > Jani.
> > >
> > >
> > > >
> > > > Cc: Jani Nikula 
> > > > Cc: Chris Chiu 
> > > > Cc: Chris Wilson 
> > > > Signed-off-by: Guang Bai 
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_hdmi.c | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> > > > b/drivers/gpu/drm/i915/intel_hdmi.c index e2c6a2b..8cf7c78 100644
> > > > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > > > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > > > @@ -1929,7 +1929,7 @@ intel_hdmi_detect(struct drm_connector
> > > > *connector, bool force)
> > > > intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
> > > >
> > > > -   if (IS_ICELAKE(dev_priv) &&
> > > > +   if ((IS_ICELAKE(dev_priv) || IS_GEN9_BC(dev_priv)) &&
> > > > !intel_digital_port_connected(encoder))
> > > > goto out;
> > >
> >
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [regression from v4.19] Re: 4.20.0-rc6-next-20181210, v4.20-rc1: list_del corruption on thinkpad x220, graphics related?

2019-01-02 Thread Joonas Lahtinen
Quoting Pavel Machek (2018-12-27 10:34:39)
> Hi!
> 
> > > > > If you think it is useful, I can try to update my machine to
> > > > > linux-next.
> > > > 
> > > > linux-next is closer to drm-tip, so it's better. Do you have some
> > > > specific reason for not wanting to run drm-tip (but linux-next is still
> > > > ok)?
> > > 
> > > I already have build/update scripts for -next, and I trust -next not
> > > to store screenshots of my desktop in my master boot record :-).
> > > 
> > > Anyway, it does happen with -next. This time, chromiums were running,
> > > and crash happened minute? after I exited flightgear. It can be seen
> > > in the logs.
> > > 
> > > Oh and I might want to mention -- machine was rather deep in swap this
> > > time, as in "mouse jumping when starting fgfs" and "could feel the
> > > chromium being swapped back in". I might have had this situation
> > > before, and just powercycled the machine "because it is so deep in
> > > swap that it will not recover".
> > > 
> > > top says:
> > > 
> > > top - 19:18:24 up 2 days,  8:03,  2 users,  load average: 3.02, 3.45,
> > > 3.21
> > > Tasks: 141 total,   1 running,  86 sleeping,   0 stopped,   2 zombie
> > > %Cpu(s): 18.8 us,  7.6 sy,  3.0 ni, 68.4 id,  1.3 wa,  0.0 hi,  0.9
> > > si,  0.0 st
> > > KiB Mem:   5967968 total,   663244 used,  5304724 free,48876
> > > buffers
> > > KiB Swap:  1681428 total,   170904 used,  1510524 free.   446280
> > > cached Mem
> > > 
> > > but of course that memory is free once everything died.
> > > 
> > > Any ideas? Should I go back to v4.19 to see if it happens there, too?
> > 
> > linux-next includes very much the same code as drm-tip. There's nobody
> > magically reviewing the code more than it is reviewed for inclusion into
> > drm-tip, when it is fed into linux-next. So thinking linux-next would be
> > some way safer is an illusion.
> > 
> > It sounds like having memory pressure expedites the corruption, which
> > should make it easier to reproduce and thus fix.
> > 
> > So if you could please try drm-tip reproducing AND open a bug in Bugzilla.
> > If you are unwilling to do that, it is very difficult to help you
> > more.
> 
> Website says I have to read and agree to two different pieces of
> legalesee, and I'd need to keep track of yet another password... so
> you can "communicate" with me.
> 
> But you can already communicate with me, over email.

I've listed all the reasons why our bug handling process is what it is.

If registering to the Bugzilla is too much of an effort for you, then I
won't be able to help you further on this.

Regards, Joonas

> I verified v4.19 is stable -- it worked ok for way more than two days
> it usually takes to crash.
> 
> Pavel
> -- 
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) 
> http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/6] drm/i915/reg: abstract display_mmio_offset access

2019-01-02 Thread Tvrtko Ursulin


On 31/12/2018 14:56, Jani Nikula wrote:

Add a macro wrapper for display_mmio_offset access in register
definitions. Prep work for reducing direct dev_priv->info usage. No
functional changes.

Cc: Tvrtko Ursulin 
Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/i915/i915_reg.h | 188 
  1 file changed, 95 insertions(+), 93 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 02af9b5add34..de1c9d495808 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -139,6 +139,12 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
return !i915_mmio_reg_equal(reg, INVALID_MMIO_REG);
  }
  
+#define VLV_DISPLAY_BASE		0x18

+#define VLV_MIPI_BASE  VLV_DISPLAY_BASE
+#define BXT_MIPI_BASE  0x6
+
+#define DISPLAY_MMIO_BASE(dev_priv)
(INTEL_INFO(dev_priv)->display_mmio_offset)
+
  /*
   * Given the first two numbers __a and __b of arbitrarily many evenly spaced
   * numbers, pick the 0-based __index'th value.
@@ -181,13 +187,13 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
   */
  #define _MMIO_PIPE2(pipe, reg)
_MMIO(dev_priv->info.pipe_offsets[pipe] - \
  
dev_priv->info.pipe_offsets[PIPE_A] + (reg) + \
- 
dev_priv->info.display_mmio_offset)
+ DISPLAY_MMIO_BASE(dev_priv))
  #define _MMIO_TRANS2(pipe, reg)   
_MMIO(dev_priv->info.trans_offsets[(pipe)] - \
  
dev_priv->info.trans_offsets[TRANSCODER_A] + (reg) + \
- 
dev_priv->info.display_mmio_offset)
+ DISPLAY_MMIO_BASE(dev_priv))
  #define _CURSOR2(pipe, reg)   
_MMIO(dev_priv->info.cursor_offsets[(pipe)] - \
  
dev_priv->info.cursor_offsets[PIPE_A] + (reg) + \
- 
dev_priv->info.display_mmio_offset)
+ DISPLAY_MMIO_BASE(dev_priv))
  
  #define __MASKED_FIELD(mask, value) ((mask) << 16 | (value))

  #define _MASKED_FIELD(mask, value) ({\
@@ -2614,10 +2620,6 @@ enum i915_power_well_id {
  
  #define   GEN11_GFX_DISABLE_LEGACY_MODE	(1 << 3)
  
-#define VLV_DISPLAY_BASE 0x18

-#define VLV_MIPI_BASE VLV_DISPLAY_BASE
-#define BXT_MIPI_BASE 0x6
-
  #define VLV_GU_CTL0   _MMIO(VLV_DISPLAY_BASE + 0x2030)
  #define VLV_GU_CTL1   _MMIO(VLV_DISPLAY_BASE + 0x2034)
  #define SCPD0 _MMIO(0x209c) /* 915+ only */
@@ -3174,9 +3176,9 @@ enum i915_power_well_id {
  /*
   * Clock control & power management
   */
-#define _DPLL_A (dev_priv->info.display_mmio_offset + 0x6014)
-#define _DPLL_B (dev_priv->info.display_mmio_offset + 0x6018)
-#define _CHV_DPLL_C (dev_priv->info.display_mmio_offset + 0x6030)
+#define _DPLL_A (DISPLAY_MMIO_BASE(dev_priv) + 0x6014)
+#define _DPLL_B (DISPLAY_MMIO_BASE(dev_priv) + 0x6018)
+#define _CHV_DPLL_C (DISPLAY_MMIO_BASE(dev_priv) + 0x6030)
  #define DPLL(pipe) _MMIO_PIPE3((pipe), _DPLL_A, _DPLL_B, _CHV_DPLL_C)
  
  #define VGA0	_MMIO(0x6000)

@@ -3273,9 +3275,9 @@ enum i915_power_well_id {
  #define   SDVO_MULTIPLIER_SHIFT_HIRES 4
  #define   SDVO_MULTIPLIER_SHIFT_VGA   0
  
-#define _DPLL_A_MD (dev_priv->info.display_mmio_offset + 0x601c)

-#define _DPLL_B_MD (dev_priv->info.display_mmio_offset + 0x6020)
-#define _CHV_DPLL_C_MD (dev_priv->info.display_mmio_offset + 0x603c)
+#define _DPLL_A_MD (DISPLAY_MMIO_BASE(dev_priv) + 0x601c)
+#define _DPLL_B_MD (DISPLAY_MMIO_BASE(dev_priv) + 0x6020)
+#define _CHV_DPLL_C_MD (DISPLAY_MMIO_BASE(dev_priv) + 0x603c)
  #define DPLL_MD(pipe) _MMIO_PIPE3((pipe), _DPLL_A_MD, _DPLL_B_MD, 
_CHV_DPLL_C_MD)
  
  /*

@@ -3347,7 +3349,7 @@ enum i915_power_well_id {
  #define  DSTATE_PLL_D3_OFF(1 << 3)
  #define  DSTATE_GFX_CLOCK_GATING  (1 << 1)
  #define  DSTATE_DOT_CLOCK_GATING  (1 << 0)
-#define DSPCLK_GATE_D  _MMIO(dev_priv->info.display_mmio_offset + 0x6200)
+#define DSPCLK_GATE_D  _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x6200)
  # define DPUNIT_B_CLOCK_GATE_DISABLE  (1 << 30) /* 965 */
  # define VSUNIT_CLOCK_GATE_DISABLE(1 << 29) /* 965 */
  # define VRHUNIT_CLOCK_GATE_DISABLE   (1 << 28) /* 965 */
@@ -3487,7 +3489,7 @@ enum i915_power_well_id {
  #define _PALETTE_A0xa000
  #define _PALETTE_B0xa800
  #define _CHV_PALETTE_C0xc000
-#define PALETTE(pipe, i)   _MMIO(dev_priv->info.display_mmio_offset + \
+#define PALETTE(pipe, i)   _MMIO(DISPLAY_MMIO_BASE(dev_priv) + \
  _PICK((pipe), _PALETTE_A, \
_PALETTE_B, _CHV_PALETTE_C) + \

Re: [Intel-gfx] [PATCH 3/6] drm/i915: pass dev_priv to intel_device_info_runtime_init()

2019-01-02 Thread Tvrtko Ursulin


On 31/12/2018 14:56, Jani Nikula wrote:

With the static/runtime device info split, this makes more sense.

Cc: Tvrtko Ursulin 
Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/i915/i915_drv.c  | 2 +-
  drivers/gpu/drm/i915/intel_device_info.c | 5 ++---
  drivers/gpu/drm/i915/intel_device_info.h | 2 +-
  3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index f884b9a138cd..261932ee6837 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1374,7 +1374,7 @@ static int i915_driver_init_hw(struct drm_i915_private 
*dev_priv)
if (i915_inject_load_failure())
return -ENODEV;
  
-	intel_device_info_runtime_init(mkwrite_device_info(dev_priv));

+   intel_device_info_runtime_init(dev_priv);
  
  	if (HAS_PPGTT(dev_priv)) {

if (intel_vgpu_active(dev_priv) &&
diff --git a/drivers/gpu/drm/i915/intel_device_info.c 
b/drivers/gpu/drm/i915/intel_device_info.c
index ffc5d75aa690..f35e8cff4b99 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -738,10 +738,9 @@ static u32 read_timestamp_frequency(struct 
drm_i915_private *dev_priv)
   *   - after the PCH has been detected,
   *   - before the first usage of the fields it can tweak.
   */
-void intel_device_info_runtime_init(struct intel_device_info *info)
+void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
  {
-   struct drm_i915_private *dev_priv =
-   container_of(info, struct drm_i915_private, info);
+   struct intel_device_info *info = mkwrite_device_info(dev_priv);
struct intel_runtime_info *runtime = RUNTIME_INFO(dev_priv);
enum pipe pipe;
  
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h

index fa81ee15dfa1..f0e6d374d4ec 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -266,7 +266,7 @@ static inline void sseu_set_eus(struct sseu_dev_info *sseu,
  
  const char *intel_platform_name(enum intel_platform platform);
  
-void intel_device_info_runtime_init(struct intel_device_info *info);

+void intel_device_info_runtime_init(struct drm_i915_private *dev_priv);
  void intel_device_info_dump(const struct intel_device_info *info,
struct drm_printer *p);
  void intel_device_info_dump_flags(const struct intel_device_info *info,



Reviewed-by: Tvrtko Ursulin 

Regards,

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


[Intel-gfx] [PATCH 39/39] drm/i915: Replace global breadcrumbs with per-context interrupt tracking

2019-01-02 Thread Chris Wilson
A few years ago, see commit 688e6c725816 ("drm/i915: Slaughter the
thundering i915_wait_request herd"), the issue of handling multiple
clients waiting in parallel was brought to our attention. The
requirement was that every client should be woken immediately upon its
request being signaled, without incurring any cpu overhead.

To handle certain fragility of our hw meant that we could not do a
simple check inside the irq handler (some generations required almost
unbounded delays before we could be sure of seqno coherency) and so
request completion checking required delegation.

Before commit 688e6c725816, the solution was simple. Every client waking
on a request would be woken on every interrupt and each would do a
heavyweight check to see if their request was complete. Commit
688e6c725816 introduced an rbtree so that only the earliest waiter on
the global timeline would woken, and would wake the next and so on.
(Along with various complications to handle requests being reordered
along the global timeline, and also a requirement for kthread to provide
a delegate for fence signaling that had no process context.)

The global rbtree depends on knowing the execution timeline (and global
seqno). Without knowing that order, we must instead check all contexts
queued to the HW to see which may have advanced. We trim that list by
only checking queued contexts that are being waited on, but still we
keep a list of all active contexts and their active signalers that we
inspect from inside the irq handler. By moving the waiters onto the fence
signal list, we can combine the client wakeup with the dma_fence
signaling (a dramatic reduction in complexity, but does require the HW
being coherent, the seqno must be visible from the cpu before the
interrupt is raised - we keep a timer backup just in case).

Having previously fixed all the issues with irq-seqno serialisation (by
inserting delays onto the GPU after each request instead of random delays
on the CPU after each interrupt), we can rely on the seqno state to
perfom direct wakeups from the interrupt handler. This allows us to
preserve our single context switch behaviour of the current routine,
with the only downside that we lose the RT priority sorting of wakeups.
In general, direct wakeup latency of multiple clients is about the same
(about 10% better in most cases) with a reduction in total CPU time spent
in the waiter (about 20-50% depending on gen). Average herd behaviour is
improved, but at the cost of not delegating wakeups on task_prio.

References: 688e6c725816 ("drm/i915: Slaughter the thundering i915_wait_request 
herd")
Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_debugfs.c   |  28 +-
 drivers/gpu/drm/i915/i915_gem_context.c   |   2 +
 drivers/gpu/drm/i915/i915_gem_context.h   |   2 +
 drivers/gpu/drm/i915/i915_gpu_error.c |  73 --
 drivers/gpu/drm/i915/i915_gpu_error.h |   8 -
 drivers/gpu/drm/i915/i915_irq.c   |  88 +-
 drivers/gpu/drm/i915/i915_request.c   | 128 +--
 drivers/gpu/drm/i915/i915_request.h   |  22 +-
 drivers/gpu/drm/i915/i915_reset.c |  13 +-
 drivers/gpu/drm/i915/intel_breadcrumbs.c  | 798 +-
 drivers/gpu/drm/i915/intel_engine_cs.c|  27 +-
 drivers/gpu/drm/i915/intel_ringbuffer.c   |   2 +-
 drivers/gpu/drm/i915/intel_ringbuffer.h   |  88 +-
 .../drm/i915/selftests/i915_mock_selftests.h  |   1 -
 drivers/gpu/drm/i915/selftests/i915_request.c | 398 +
 drivers/gpu/drm/i915/selftests/igt_spinner.c  |   5 -
 .../drm/i915/selftests/intel_breadcrumbs.c| 470 ---
 .../gpu/drm/i915/selftests/intel_hangcheck.c  |   2 +-
 drivers/gpu/drm/i915/selftests/lib_sw_fence.c |  54 ++
 drivers/gpu/drm/i915/selftests/lib_sw_fence.h |   3 +
 drivers/gpu/drm/i915/selftests/mock_context.c |   2 +
 drivers/gpu/drm/i915/selftests/mock_engine.c  |  16 +-
 drivers/gpu/drm/i915/selftests/mock_engine.h  |   6 -
 23 files changed, 755 insertions(+), 1481 deletions(-)
 delete mode 100644 drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 8059f6dd3886..8ef62c576e3c 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1315,29 +1315,16 @@ static int i915_hangcheck_info(struct seq_file *m, void 
*unused)
seq_printf(m, "GT active? %s\n", yesno(dev_priv->gt.awake));
 
for_each_engine(engine, dev_priv, id) {
-   struct intel_breadcrumbs *b = &engine->breadcrumbs;
-   struct rb_node *rb;
-
seq_printf(m, "%s:\n", engine->name);
seq_printf(m, "\tseqno = %x [current %x, last %x]\n",
   engine->hangcheck.seqno, seqno[id],
   intel_engine_last_submit(engine));
-   seq_printf(m, "\twaiters? %s, fake irq active? %s, stalled? %s, 
wedged? %s\n",
-  yesno(intel

[Intel-gfx] [PATCH 01/39] drm: Reorder set_property_atomic to avoid returning with an active ww_ctx

2019-01-02 Thread Chris Wilson
Delay the drm_modeset_acquire_init() until after we check for an
allocation failure so that we can return immediately upon error without
having to unwind.

WARNING: lock held when returning to user space!
4.20.0+ #174 Not tainted

syz-executor556/8153 is leaving the kernel with locks still held!
1 lock held by syz-executor556/8153:
  #0: 5100c85c (crtc_ww_class_acquire){+.+.}, at:
set_property_atomic+0xb3/0x330 drivers/gpu/drm/drm_mode_object.c:462

Reported-by: syzbot+6ea337c427f5083eb...@syzkaller.appspotmail.com
Fixes: 144a7999d633 ("drm: Handle properties in the core for atomic drivers")
Signed-off-by: Chris Wilson 
Cc: Daniel Vetter 
Cc: Maarten Lankhorst 
Cc: Sean Paul 
Cc: David Airlie 
Cc:  # v4.14+
---
 drivers/gpu/drm/drm_mode_object.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_mode_object.c 
b/drivers/gpu/drm/drm_mode_object.c
index bb1dd46496cd..a9005c1c2384 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -459,12 +459,13 @@ static int set_property_atomic(struct drm_mode_object 
*obj,
struct drm_modeset_acquire_ctx ctx;
int ret;
 
-   drm_modeset_acquire_init(&ctx, 0);
-
state = drm_atomic_state_alloc(dev);
if (!state)
return -ENOMEM;
+
+   drm_modeset_acquire_init(&ctx, 0);
state->acquire_ctx = &ctx;
+
 retry:
if (prop == state->dev->mode_config.dpms_property) {
if (obj->type != DRM_MODE_OBJECT_CONNECTOR) {
-- 
2.20.1

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


[Intel-gfx] [PATCH 37/39] drm/i915: Track the context's seqno in its own timeline HWSP

2019-01-02 Thread Chris Wilson
Now that we have allocated ourselves a cacheline to store a breadcrumb,
we can emit a write from the GPU into the timeline's HWSP of the
per-context seqno as we complete each request. This drops the mirroring
of the per-engine HWSP and allows each context to operate independently.
We do not need to unwind the per-context timeline, and so requests are
always consistent with the timeline breadcrumb, greatly simplifying the
completion checks as we no longer need to be concerned about the
global_seqno changing mid check.

At this point, we are emitting both per-context and global seqno and
still using the single per-engine execution timeline for resolving
interrupts.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_gem.c  |   2 +-
 drivers/gpu/drm/i915/i915_request.c  |   2 +-
 drivers/gpu/drm/i915/i915_request.h  |  29 ++---
 drivers/gpu/drm/i915/i915_reset.c|   1 +
 drivers/gpu/drm/i915/i915_vma.h  |   7 ++
 drivers/gpu/drm/i915/intel_lrc.c |  32 --
 drivers/gpu/drm/i915/intel_ringbuffer.c  | 106 +++
 drivers/gpu/drm/i915/selftests/mock_engine.c |   8 +-
 8 files changed, 126 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ae9ccf5f6019..781f8319e81b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3041,7 +3041,7 @@ i915_gem_find_active_request(struct intel_engine_cs 
*engine)
 */
spin_lock_irqsave(&engine->timeline.lock, flags);
list_for_each_entry(request, &engine->timeline.requests, link) {
-   if (__i915_request_completed(request, request->global_seqno))
+   if (i915_request_completed(request))
continue;
 
active = request;
diff --git a/drivers/gpu/drm/i915/i915_request.c 
b/drivers/gpu/drm/i915/i915_request.c
index e481b48e07b5..ec4dbc67ef9e 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -590,7 +590,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct 
i915_gem_context *ctx)
rq->ring = ce->ring;
rq->timeline = ce->ring->timeline;
GEM_BUG_ON(rq->timeline == &engine->timeline);
-   rq->hwsp_seqno = &engine->status_page.page_addr[I915_GEM_HWS_INDEX];
+   rq->hwsp_seqno = rq->timeline->hwsp_seqno;
 
spin_lock_init(&rq->lock);
dma_fence_init(&rq->fence,
diff --git a/drivers/gpu/drm/i915/i915_request.h 
b/drivers/gpu/drm/i915/i915_request.h
index e2b209a26a8e..344e52b53ccd 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -295,6 +295,11 @@ static inline u32 i915_request_hwsp(const struct 
i915_request *rq)
return READ_ONCE(*rq->hwsp_seqno);
 }
 
+static inline void i915_request_fake_complete(const struct i915_request *rq)
+{
+   *(u32 *)rq->hwsp_seqno = rq->fence.seqno;
+}
+
 /**
  * i915_request_started - check if the request has begun being executed
  * @rq: the request
@@ -306,32 +311,12 @@ static inline u32 i915_request_hwsp(const struct 
i915_request *rq)
  */
 static inline bool i915_request_started(const struct i915_request *rq)
 {
-   u32 seqno;
-
-   seqno = i915_request_global_seqno(rq);
-   if (!seqno) /* not yet submitted to HW */
-   return false;
-
-   return i915_seqno_passed(i915_request_hwsp(rq), seqno - 1);
-}
-
-static inline bool
-__i915_request_completed(const struct i915_request *rq, u32 seqno)
-{
-   GEM_BUG_ON(!seqno);
-   return i915_seqno_passed(i915_request_hwsp(rq), seqno) &&
-   seqno == i915_request_global_seqno(rq);
+   return i915_seqno_passed(i915_request_hwsp(rq), rq->fence.seqno - 1);
 }
 
 static inline bool i915_request_completed(const struct i915_request *rq)
 {
-   u32 seqno;
-
-   seqno = i915_request_global_seqno(rq);
-   if (!seqno)
-   return false;
-
-   return __i915_request_completed(rq, seqno);
+   return i915_seqno_passed(i915_request_hwsp(rq), rq->fence.seqno);
 }
 
 void i915_retire_requests(struct drm_i915_private *i915);
diff --git a/drivers/gpu/drm/i915/i915_reset.c 
b/drivers/gpu/drm/i915/i915_reset.c
index 3736a1121237..8c86806d80d8 100644
--- a/drivers/gpu/drm/i915/i915_reset.c
+++ b/drivers/gpu/drm/i915/i915_reset.c
@@ -756,6 +756,7 @@ static void nop_submit_request(struct i915_request *request)
 
spin_lock_irqsave(&request->engine->timeline.lock, flags);
__i915_request_submit(request);
+   i915_request_fake_complete(request);
intel_engine_write_global_seqno(request->engine, request->global_seqno);
spin_unlock_irqrestore(&request->engine->timeline.lock, flags);
 }
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 266b226ebef2..ea9b85576e2d 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -198,6 +198,13 @@ static inline

[Intel-gfx] [PATCH 09/39] drm/i915: Markup paired operations on wakerefs

2019-01-02 Thread Chris Wilson
The majority of runtime-pm operations are bounded and scoped within a
function; these are easy to verify that the wakeref are handled
correctly. We can employ the compiler to help us, and reduce the number
of wakerefs tracked when debugging, by passing around cookies provided
by the various rpm_get functions to their rpm_put counterpart. This
makes the pairing explicit, and given the required wakeref cookie the
compiler can verify that we pass an initialised value to the rpm_put
(quite handy for double checking error paths).

For regular builds, the compiler should be able to eliminate the unused
local variables and the program growth should be minimal. Fwiw, it came
out as a net improvement as gcc was able to refactor rpm_get and
rpm_get_if_in_use together,

add/remove: 1/1 grow/shrink: 20/9 up/down: 191/-268 (-77)
Function old new   delta
intel_runtime_pm_put_unchecked - 136+136
i915_gem_unpark  396 406 +10
intel_runtime_pm_get 135 141  +6
intel_runtime_pm_get_noresume136 141  +5
i915_perf_open_ioctl43754379  +4
i915_gpu_busy 72  76  +4
i915_gem_idle_work_handler   954 958  +4
capture 68146818  +4
mock_gem_device 14331436  +3
__execlists_submission_tasklet  25732576  +3
i915_sample  756 758  +2
intel_guc_submission_disable 364 365  +1
igt_mmap_offset_exhaustion  10351036  +1
i915_runtime_pm_status   257 258  +1
i915_rps_boost_info 13581359  +1
i915_hangcheck_info 12291230  +1
i915_gem_switch_to_kernel_context682 683  +1
i915_gem_suspend 410 411  +1
i915_gem_resume  254 255  +1
i915_gem_park190 191  +1
i915_engine_info 279 280  +1
intel_rps_mark_interactive   194 193  -1
i915_hangcheck_elapsed  15261525  -1
i915_gem_wait_for_idle   298 297  -1
i915_drop_caches_set 555 554  -1
execlists_submission_tasklet 126 125  -1
aliasing_gtt_bind_vma235 234  -1
i915_gem_retire_work_handler 144 142  -2
igt_evict_contexts.part  916 910  -6
intel_runtime_pm_get_if_in_use   141  23-118
intel_runtime_pm_put 136   --136

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/Kconfig.debug|   1 +
 drivers/gpu/drm/i915/gvt/aperture_gm.c|   8 +-
 drivers/gpu/drm/i915/gvt/gvt.h|   2 +-
 drivers/gpu/drm/i915/gvt/sched_policy.c   |   2 +-
 drivers/gpu/drm/i915/gvt/scheduler.c  |   4 +-
 drivers/gpu/drm/i915/i915_debugfs.c   | 137 +++---
 drivers/gpu/drm/i915/i915_drv.h   |   6 +-
 drivers/gpu/drm/i915/i915_gem.c   |  58 +---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c|   5 +-
 drivers/gpu/drm/i915/i915_gem_fence_reg.c |   6 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c   |  22 ++-
 drivers/gpu/drm/i915/i915_gem_shrinker.c  |  27 ++--
 drivers/gpu/drm/i915/i915_irq.c   |   5 +-
 drivers/gpu/drm/i915/i915_perf.c  |  10 +-
 drivers/gpu/drm/i915/i915_pmu.c   |  26 ++--
 drivers/gpu/drm/i915/i915_sysfs.c |  24 +--
 drivers/gpu/drm/i915/intel_display.c  |   5 +-
 drivers/gpu/drm/i915/intel_drv.h  |  15 +-
 drivers/gpu/drm/i915/intel_engine_cs.c|  12 +-
 drivers/gpu/drm/i915/intel_fbdev.c|   9 +-
 drivers/gpu/drm/i915/intel_guc_log.c  |  15 +-
 drivers/gpu/drm/i915/intel_hotplug.c  |   5 +-
 drivers/gpu/drm/i915/intel_huc.c  |   5 +-
 drivers/gpu/drm/i915/intel_panel.c|   5 +-
 drivers/gpu/drm/i915/intel_runtime_pm.c   |  89 +---
 drivers/gpu/drm/i915/intel_uncore.c   |   5 +-
 drivers/gpu/drm/i915/selftests/huge_pages.c   |   5 +-
 drivers/gpu/drm/i915/selftests/i915_gem.c |  29 ++--
 .../drm/i915/selftests/i915_gem_coherency.c   |   5 +-
 .../gpu/drm/i915/selftests/i915_gem_context.c |  27 ++--
 .../gpu/drm/i915/selftests/i915_gem_evict.c   |  11 +-
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  10 +-
 .../gpu/drm/i915/selftests/i915_gem_object.c  |  18 ++-
 drivers/gpu/drm/i915/selftests/i915_request.c |  22 +--
 drivers/gpu/drm/i915/selftests/intel_guc.c|  10 +-
 .../gpu/drm/i915/selftests/intel_hangcheck.c  |  15 +

[Intel-gfx] [PATCH 08/39] drm/i915: Track all held rpm wakerefs

2019-01-02 Thread Chris Wilson
Everytime we take a wakeref, record the stack trace of where it was
taken; clearing the set if we ever drop back to no owners. For debugging
a rpm leak, we can look at all the current wakerefs and check if they
have a matching rpm_put.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/Kconfig.debug|   2 +-
 drivers/gpu/drm/i915/i915_debugfs.c   |   6 +
 drivers/gpu/drm/i915/i915_drv.c   |   8 +-
 drivers/gpu/drm/i915/i915_drv.h   |   7 +
 drivers/gpu/drm/i915/intel_drv.h  |  44 ++-
 drivers/gpu/drm/i915/intel_runtime_pm.c   | 267 --
 .../gpu/drm/i915/selftests/mock_gem_device.c  |   8 +-
 7 files changed, 292 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/i915/Kconfig.debug 
b/drivers/gpu/drm/i915/Kconfig.debug
index 9e36ffb5eb7c..a97929c47466 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -21,11 +21,11 @@ config DRM_I915_DEBUG
 select DEBUG_FS
 select PREEMPT_COUNT
 select I2C_CHARDEV
+select STACKDEPOT
 select DRM_DP_AUX_CHARDEV
 select X86_MSR # used by igt/pm_rpm
 select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
 select DRM_DEBUG_MM if DRM=y
-select STACKDEPOT if DRM=y # for DRM_DEBUG_MM
select DRM_DEBUG_SELFTEST
select SW_SYNC # signaling validation framework (igt/syncobj*)
select DRM_I915_SW_FENCE_DEBUG_OBJECTS
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index c2f56c1c8199..ac63c74cd86a 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2702,6 +2702,12 @@ static int i915_runtime_pm_status(struct seq_file *m, 
void *unused)
   pci_power_name(pdev->current_state),
   pdev->current_state);
 
+   if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)) {
+   struct drm_printer p = drm_seq_file_printer(m);
+
+   print_intel_runtime_pm_wakeref(dev_priv, &p);
+   }
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a96169acdb07..1af88534ee0d 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -906,6 +906,7 @@ static int i915_driver_init_early(struct drm_i915_private 
*dev_priv)
mutex_init(&dev_priv->pps_mutex);
 
i915_memcpy_init_early(dev_priv);
+   intel_runtime_pm_init_early(dev_priv);
 
ret = i915_workqueues_init(dev_priv);
if (ret < 0)
@@ -1802,8 +1803,7 @@ void i915_driver_unload(struct drm_device *dev)
i915_driver_cleanup_mmio(dev_priv);
 
enable_rpm_wakeref_asserts(dev_priv);
-
-   WARN_ON(atomic_read(&dev_priv->runtime_pm.wakeref_count));
+   intel_runtime_pm_cleanup(dev_priv);
 }
 
 static void i915_driver_release(struct drm_device *dev)
@@ -2005,6 +2005,8 @@ static int i915_drm_suspend_late(struct drm_device *dev, 
bool hibernation)
 
 out:
enable_rpm_wakeref_asserts(dev_priv);
+   if (!dev_priv->uncore.user_forcewake.count)
+   intel_runtime_pm_cleanup(dev_priv);
 
return ret;
 }
@@ -2960,7 +2962,7 @@ static int intel_runtime_suspend(struct device *kdev)
}
 
enable_rpm_wakeref_asserts(dev_priv);
-   WARN_ON_ONCE(atomic_read(&dev_priv->runtime_pm.wakeref_count));
+   intel_runtime_pm_cleanup(dev_priv);
 
if (intel_uncore_arm_unclaimed_mmio_detection(dev_priv))
DRM_ERROR("Unclaimed access detected prior to suspending\n");
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fb34febe3954..d7ff6e401453 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -45,6 +45,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -1156,6 +1157,12 @@ struct i915_runtime_pm {
atomic_t wakeref_count;
bool suspended;
bool irqs_enabled;
+
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
+   spinlock_t debug_lock;
+   depot_stack_handle_t *debug_owners;
+   unsigned long debug_count;
+#endif
 };
 
 enum intel_pipe_crc_source {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1a11c2beb7f3..ac513fd70315 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -41,6 +41,8 @@
 #include 
 #include 
 
+struct drm_printer;
+
 /**
  * __wait_for - magic wait macro
  *
@@ -2084,6 +2086,7 @@ bool intel_psr_enabled(struct intel_dp *intel_dp);
 void intel_init_quirks(struct drm_i915_private *dev_priv);
 
 /* intel_runtime_pm.c */
+void intel_runtime_pm_init_early(struct drm_i915_private *dev_priv);
 int intel_power_domains_init(struct drm_i915_private *);
 void intel_power_domains_cleanup(struct drm_i915_private *dev_priv);
 void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool 
resume);
@@ -2106,6 +210

[Intel-gfx] [PATCH 31/39] drm/i915/selftests: Make evict tolerant of foreign objects

2019-01-02 Thread Chris Wilson
The evict selftests presumed that all objects in use had been allocated
by itself. This is a dubious claim and so instead of asserting complete
control over the object lists, take (temporary) ownership of them
instead.

Signed-off-by: Chris Wilson 
---
 .../gpu/drm/i915/selftests/i915_gem_evict.c   | 64 +++
 1 file changed, 53 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
index 8750cfbf1486..337aa96908a8 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
@@ -31,33 +31,75 @@
 
 static int populate_ggtt(struct drm_i915_private *i915)
 {
-   struct drm_i915_gem_object *obj;
+   struct drm_i915_gem_object *obj, *on;
+   unsigned long expected_unbound, expected_bound;
+   unsigned long unbound, bound, count;
u64 size;
+   int err;
+
+   expected_unbound = 0;
+   list_for_each_entry(obj, &i915->mm.unbound_list, mm.link) {
+   i915_gem_object_get(obj);
+   expected_unbound++;
+   }
+
+   expected_bound = 0;
+   list_for_each_entry(obj, &i915->mm.bound_list, mm.link) {
+   i915_gem_object_get(obj);
+   expected_bound++;
+   }
 
+   count = 0;
for (size = 0;
 size + I915_GTT_PAGE_SIZE <= i915->ggtt.vm.total;
 size += I915_GTT_PAGE_SIZE) {
struct i915_vma *vma;
 
obj = i915_gem_object_create_internal(i915, I915_GTT_PAGE_SIZE);
-   if (IS_ERR(obj))
-   return PTR_ERR(obj);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   goto cleanup;
+   }
 
vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);
-   if (IS_ERR(vma))
-   return PTR_ERR(vma);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto cleanup;
+   }
+
+   count++;
}
 
-   if (!list_empty(&i915->mm.unbound_list)) {
-   size = 0;
-   list_for_each_entry(obj, &i915->mm.unbound_list, mm.link)
-   size++;
+   unbound = 0;
+   list_for_each_entry(obj, &i915->mm.unbound_list, mm.link)
+   unbound++;
+   if (unbound != expected_unbound) {
+   pr_err("%s: Found %lu objects unbound, expected %lu!\n",
+  __func__, unbound, expected_unbound);
+   err = -EINVAL;
+   goto cleanup;
+   }
 
-   pr_err("Found %lld objects unbound!\n", size);
-   return -EINVAL;
+   bound = 0;
+   list_for_each_entry(obj, &i915->mm.bound_list, mm.link)
+   bound++;
+   if (bound != expected_bound + count) {
+   pr_err("%s: Found %lu objects bound, expected %lu!\n",
+  __func__, bound, expected_bound + count);
+   err = -EINVAL;
+   goto cleanup;
}
 
return 0;
+
+cleanup:
+   list_for_each_entry_safe(obj, on, &i915->mm.unbound_list, mm.link)
+   i915_gem_object_put(obj);
+
+   list_for_each_entry_safe(obj, on, &i915->mm.bound_list, mm.link)
+   i915_gem_object_put(obj);
+
+   return err;
 }
 
 static void unpin_ggtt(struct drm_i915_private *i915)
-- 
2.20.1

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


[Intel-gfx] [PATCH 10/39] drm/i915: Syntatic sugar for using intel_runtime_pm

2019-01-02 Thread Chris Wilson
Frequently, we use intel_runtime_pm_get/_put around a small block.
Formalise that usage by providing a macro to define such a block with an
automatic closure to scope the intel_runtime_pm wakeref to that block,
i.e. macro abuse smelling of python.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_debugfs.c   | 162 --
 drivers/gpu/drm/i915/i915_gem.c   |  10 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c   |  23 ++-
 drivers/gpu/drm/i915/i915_gem_shrinker.c  |  44 ++---
 drivers/gpu/drm/i915/i915_pmu.c   |   7 +-
 drivers/gpu/drm/i915/i915_sysfs.c |   7 +-
 drivers/gpu/drm/i915/intel_drv.h  |   8 +
 drivers/gpu/drm/i915/intel_guc_log.c  |  26 ++-
 drivers/gpu/drm/i915/intel_huc.c  |   7 +-
 drivers/gpu/drm/i915/intel_panel.c|  18 +-
 drivers/gpu/drm/i915/intel_uncore.c   |  30 ++--
 drivers/gpu/drm/i915/selftests/i915_gem.c |  34 ++--
 .../gpu/drm/i915/selftests/i915_gem_context.c |  12 +-
 .../gpu/drm/i915/selftests/i915_gem_object.c  |  11 +-
 .../drm/i915/selftests/intel_workarounds.c|  28 +--
 15 files changed, 200 insertions(+), 227 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 18f2800fd7d3..463fa75c8032 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -953,9 +953,9 @@ static int i915_gpu_info_open(struct inode *inode, struct 
file *file)
struct i915_gpu_state *gpu;
intel_wakeref_t wakeref;
 
-   wakeref = intel_runtime_pm_get(i915);
-   gpu = i915_capture_gpu_state(i915);
-   intel_runtime_pm_put(i915, wakeref);
+   gpu = NULL;
+   with_intel_runtime_pm(i915, wakeref)
+   gpu = i915_capture_gpu_state(i915);
if (IS_ERR(gpu))
return PTR_ERR(gpu);
 
@@ -1287,17 +1287,15 @@ static int i915_hangcheck_info(struct seq_file *m, void 
*unused)
return 0;
}
 
-   wakeref = intel_runtime_pm_get(dev_priv);
+   with_intel_runtime_pm(dev_priv, wakeref) {
+   for_each_engine(engine, dev_priv, id) {
+   acthd[id] = intel_engine_get_active_head(engine);
+   seqno[id] = intel_engine_get_seqno(engine);
+   }
 
-   for_each_engine(engine, dev_priv, id) {
-   acthd[id] = intel_engine_get_active_head(engine);
-   seqno[id] = intel_engine_get_seqno(engine);
+   intel_engine_get_instdone(dev_priv->engine[RCS], &instdone);
}
 
-   intel_engine_get_instdone(dev_priv->engine[RCS], &instdone);
-
-   intel_runtime_pm_put(dev_priv, wakeref);
-
if (timer_pending(&dev_priv->gpu_error.hangcheck_work.timer))
seq_printf(m, "Hangcheck active, timer fires in %dms\n",
   
jiffies_to_msecs(dev_priv->gpu_error.hangcheck_work.timer.expires -
@@ -1573,18 +1571,16 @@ static int i915_drpc_info(struct seq_file *m, void 
*unused)
 {
struct drm_i915_private *dev_priv = node_to_i915(m->private);
intel_wakeref_t wakeref;
-   int err;
-
-   wakeref = intel_runtime_pm_get(dev_priv);
-
-   if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-   err = vlv_drpc_info(m);
-   else if (INTEL_GEN(dev_priv) >= 6)
-   err = gen6_drpc_info(m);
-   else
-   err = ironlake_drpc_info(m);
+   int err = -ENODEV;
 
-   intel_runtime_pm_put(dev_priv, wakeref);
+   with_intel_runtime_pm(dev_priv, wakeref) {
+   if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+   err = vlv_drpc_info(m);
+   else if (INTEL_GEN(dev_priv) >= 6)
+   err = gen6_drpc_info(m);
+   else
+   err = ironlake_drpc_info(m);
+   }
 
return err;
 }
@@ -2068,8 +2064,7 @@ static int i915_rps_boost_info(struct seq_file *m, void 
*data)
intel_wakeref_t wakeref;
struct drm_file *file;
 
-   wakeref = intel_runtime_pm_get_if_in_use(dev_priv);
-   if (wakeref) {
+   with_intel_runtime_pm_if_in_use(dev_priv, wakeref) {
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
mutex_lock(&dev_priv->pcu_lock);
act_freq = vlv_punit_read(dev_priv,
@@ -2080,7 +2075,6 @@ static int i915_rps_boost_info(struct seq_file *m, void 
*data)
act_freq = intel_get_cagf(dev_priv,
  I915_READ(GEN6_RPSTAT1));
}
-   intel_runtime_pm_put(dev_priv, wakeref);
}
 
seq_printf(m, "RPS enabled? %d\n", rps->enabled);
@@ -2172,9 +2166,8 @@ static int i915_huc_load_status_info(struct seq_file *m, 
void *data)
p = drm_seq_file_printer(m);
intel_uc_fw_dump(&dev_priv->huc.fw, &p);
 
-   wakeref = intel_runtime_pm_

[Intel-gfx] [PATCH 24/39] drm/i915: Stop tracking MRU activity on VMA

2019-01-02 Thread Chris Wilson
Our goal is to remove struct_mutex and replace it with fine grained
locking. One of the thorny issues is our eviction logic for reclaiming
space for an execbuffer (or GTT mmaping, among a few other examples).
While eviction itself is easy to move under a per-VM mutex, performing
the activity tracking is less agreeable. One solution is not to do any
MRU tracking and do a simple coarse evaluation during eviction of
active/inactive, with a loose temporal ordering of last
insertion/evaluation. That keeps all the locking constrained to when we
are manipulating the VM itself, neatly avoiding the tricky handling of
possible recursive locking during execbuf and elsewhere.

Note that discarding the MRU is unlikely to impact upon our efficiency
to reclaim VM space (where we think a LRU model is best) as our
current strategy is to use random idle replacement first before doing
a search, and over time the use of softpinned 48b per-ppGTT is growing
(thereby eliminating any need to perform any eviction searches, in
theory at least).

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_gem.c   | 10 +---
 drivers/gpu/drm/i915/i915_gem_evict.c | 56 ++-
 drivers/gpu/drm/i915/i915_gem_gtt.c   | 15 ++---
 drivers/gpu/drm/i915/i915_gem_gtt.h   | 26 +
 drivers/gpu/drm/i915/i915_gem_shrinker.c  |  8 ++-
 drivers/gpu/drm/i915/i915_gem_stolen.c|  3 +-
 drivers/gpu/drm/i915/i915_gpu_error.c | 37 ++--
 drivers/gpu/drm/i915/i915_vma.c   |  9 +--
 .../gpu/drm/i915/selftests/i915_gem_evict.c   |  4 +-
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  2 +-
 10 files changed, 69 insertions(+), 101 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 800b2c770dce..d9e1dcee176c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -254,10 +254,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void 
*data,
 
pinned = ggtt->vm.reserved;
mutex_lock(&dev->struct_mutex);
-   list_for_each_entry(vma, &ggtt->vm.active_list, vm_link)
-   if (i915_vma_is_pinned(vma))
-   pinned += vma->node.size;
-   list_for_each_entry(vma, &ggtt->vm.inactive_list, vm_link)
+   list_for_each_entry(vma, &ggtt->vm.bound_list, vm_link)
if (i915_vma_is_pinned(vma))
pinned += vma->node.size;
mutex_unlock(&dev->struct_mutex);
@@ -1690,13 +1687,10 @@ static void i915_gem_object_bump_inactive_ggtt(struct 
drm_i915_gem_object *obj)
GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
 
for_each_ggtt_vma(vma, obj) {
-   if (i915_vma_is_active(vma))
-   continue;
-
if (!drm_mm_node_allocated(&vma->node))
continue;
 
-   list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
+   list_move_tail(&vma->vm_link, &vma->vm->bound_list);
}
 
i915 = to_i915(obj->base.dev);
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c 
b/drivers/gpu/drm/i915/i915_gem_evict.c
index 02b83a5ed96c..6a3608398d2a 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -127,14 +127,10 @@ i915_gem_evict_something(struct i915_address_space *vm,
struct drm_i915_private *dev_priv = vm->i915;
struct drm_mm_scan scan;
struct list_head eviction_list;
-   struct list_head *phases[] = {
-   &vm->inactive_list,
-   &vm->active_list,
-   NULL,
-   }, **phase;
struct i915_vma *vma, *next;
struct drm_mm_node *node;
enum drm_mm_insert_mode mode;
+   struct i915_vma *active;
int ret;
 
lockdep_assert_held(&vm->i915->drm.struct_mutex);
@@ -170,17 +166,31 @@ i915_gem_evict_something(struct i915_address_space *vm,
 */
if (!(flags & PIN_NONBLOCK))
i915_retire_requests(dev_priv);
-   else
-   phases[1] = NULL;
 
 search_again:
+   active = NULL;
INIT_LIST_HEAD(&eviction_list);
-   phase = phases;
-   do {
-   list_for_each_entry(vma, *phase, vm_link)
-   if (mark_free(&scan, vma, flags, &eviction_list))
-   goto found;
-   } while (*++phase);
+   list_for_each_entry_safe(vma, next, &vm->bound_list, vm_link) {
+   if (i915_vma_is_active(vma)) {
+   if (vma == active) {
+   if (flags & PIN_NONBLOCK)
+   break;
+
+   active = ERR_PTR(-EAGAIN);
+   }
+
+   if (active != ERR_PTR(-EAGAIN)) {
+   if (!active)
+   active = vma;
+
+   list_move_tail(&vma->vm_link, &vm->bound

[Intel-gfx] [PATCH 15/39] drm/i915: Complain if hsw_get_pipe_config acquires the same power well twice

2019-01-02 Thread Chris Wilson
As we only release each power well once, we assume that each transcoder
maps to a different domain. Complain if this is not so.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/intel_display.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 9c8911c4d11f..87dbfd059343 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9570,6 +9570,8 @@ static bool hsw_get_transcoder_state(struct intel_crtc 
*crtc,
power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder);
if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
return false;
+
+   WARN_ON(*power_domain_mask & BIT_ULL(power_domain));
*power_domain_mask |= BIT_ULL(power_domain);
 
tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder));
@@ -9597,6 +9599,8 @@ static bool bxt_get_dsi_transcoder_state(struct 
intel_crtc *crtc,
power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
continue;
+
+   WARN_ON(*power_domain_mask & BIT_ULL(power_domain));
*power_domain_mask |= BIT_ULL(power_domain);
 
/*
@@ -9713,7 +9717,9 @@ static bool haswell_get_pipe_config(struct intel_crtc 
*crtc,
 
power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
+   WARN_ON(power_domain_mask & BIT_ULL(power_domain));
power_domain_mask |= BIT_ULL(power_domain);
+
if (INTEL_GEN(dev_priv) >= 9)
skylake_get_pfit_config(crtc, pipe_config);
else
-- 
2.20.1

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


[Intel-gfx] [PATCH 03/39] drm/i915: Return immediately if trylock fails for direct-reclaim

2019-01-02 Thread Chris Wilson
Ignore trying to shrink from i915 if we fail to acquire the struct_mutex
in the shrinker while performing direct-reclaim. The trade-off being
(much) lower latency for non-i915 clients at an increased risk of being
unable to obtain a page from direct-reclaim without hitting the
oom-notifier. The proviso being that we still keep trying to hard
obtain the lock for oom so that we can reap under heavy memory pressure.

Signed-off-by: Chris Wilson 
Cc: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_drv.h  |  4 ++--
 drivers/gpu/drm/i915/i915_gem_shrinker.c | 24 +++-
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 13116909fe0d..101c3aa18740 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2903,9 +2903,9 @@ i915_gem_object_unpin_pages(struct drm_i915_gem_object 
*obj)
__i915_gem_object_unpin_pages(obj);
 }
 
-enum i915_mm_subclass { /* lockdep subclass for obj->mm.lock */
+enum i915_mm_subclass { /* lockdep subclass for obj->mm.lock/struct_mutex */
I915_MM_NORMAL = 0,
-   I915_MM_SHRINKER
+   I915_MM_SHRINKER /* called "recursively" from direct-reclaim-esque */
 };
 
 void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c 
b/drivers/gpu/drm/i915/i915_gem_shrinker.c
index ea90d3a0d511..d461f458f4af 100644
--- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
@@ -36,7 +36,9 @@
 #include "i915_drv.h"
 #include "i915_trace.h"
 
-static bool shrinker_lock(struct drm_i915_private *i915, bool *unlock)
+static bool shrinker_lock(struct drm_i915_private *i915,
+ unsigned int flags,
+ bool *unlock)
 {
switch (mutex_trylock_recursive(&i915->drm.struct_mutex)) {
case MUTEX_TRYLOCK_RECURSIVE:
@@ -45,15 +47,11 @@ static bool shrinker_lock(struct drm_i915_private *i915, 
bool *unlock)
 
case MUTEX_TRYLOCK_FAILED:
*unlock = false;
-   preempt_disable();
-   do {
-   cpu_relax();
-   if (mutex_trylock(&i915->drm.struct_mutex)) {
-   *unlock = true;
-   break;
-   }
-   } while (!need_resched());
-   preempt_enable();
+   if (flags & I915_SHRINK_ACTIVE) {
+   mutex_lock_nested(&i915->drm.struct_mutex,
+ I915_MM_SHRINKER);
+   *unlock = true;
+   }
return *unlock;
 
case MUTEX_TRYLOCK_SUCCESS:
@@ -160,7 +158,7 @@ i915_gem_shrink(struct drm_i915_private *i915,
unsigned long scanned = 0;
bool unlock;
 
-   if (!shrinker_lock(i915, &unlock))
+   if (!shrinker_lock(i915, flags, &unlock))
return 0;
 
/*
@@ -357,7 +355,7 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct 
shrink_control *sc)
 
sc->nr_scanned = 0;
 
-   if (!shrinker_lock(i915, &unlock))
+   if (!shrinker_lock(i915, 0, &unlock))
return SHRINK_STOP;
 
freed = i915_gem_shrink(i915,
@@ -397,7 +395,7 @@ shrinker_lock_uninterruptible(struct drm_i915_private 
*i915, bool *unlock,
do {
if (i915_gem_wait_for_idle(i915,
   0, MAX_SCHEDULE_TIMEOUT) == 0 &&
-   shrinker_lock(i915, unlock))
+   shrinker_lock(i915, 0, unlock))
break;
 
schedule_timeout_killable(1);
-- 
2.20.1

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


[Intel-gfx] [PATCH 06/39] drm/i915: Always try to reset the GPU on takeover

2019-01-02 Thread Chris Wilson
When we first introduced the reset to sanitize the GPU on taking over
from the BIOS and before returning control to third parties (the BIOS!),
we restricted it to only systems utilizing HW contexts as we were
uncertain of how stable our reset mechanism truly was. We now have
reasonable coverage across all machines that expose a GPU reset method,
and so we should be safe to sanitize the GPU state everywhere.

v2: We _have_ to skip the reset if it would clobber the display.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_drv.c   |  2 +-
 drivers/gpu/drm/i915/i915_gem.c   | 11 ++-
 drivers/gpu/drm/i915/i915_pci.c   |  5 +
 drivers/gpu/drm/i915/intel_device_info.h  |  1 +
 drivers/gpu/drm/i915/intel_display.c  |  4 ++--
 drivers/gpu/drm/i915/intel_engine_cs.c| 14 +-
 drivers/gpu/drm/i915/intel_ringbuffer.h   |  2 +-
 drivers/gpu/drm/i915/selftests/i915_gem.c |  2 +-
 8 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index dcb935338c63..a96169acdb07 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2174,7 +2174,7 @@ static int i915_drm_resume_early(struct drm_device *dev)
 
intel_power_domains_resume(dev_priv);
 
-   intel_engines_sanitize(dev_priv);
+   intel_engines_sanitize(dev_priv, true);
 
enable_rpm_wakeref_asserts(dev_priv);
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e46a25747ab7..0ebde13620cb 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3432,8 +3432,7 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915)
i915_retire_requests(i915);
GEM_BUG_ON(i915->gt.active_requests);
 
-   if (!intel_gpu_reset(i915, ALL_ENGINES))
-   intel_engines_sanitize(i915);
+   intel_engines_sanitize(i915, false);
 
/*
 * Undo nop_submit_request. We prevent all new i915 requests from
@@ -5037,8 +5036,6 @@ void __i915_gem_object_release_unless_active(struct 
drm_i915_gem_object *obj)
 
 void i915_gem_sanitize(struct drm_i915_private *i915)
 {
-   int err;
-
GEM_TRACE("\n");
 
mutex_lock(&i915->drm.struct_mutex);
@@ -5063,11 +5060,7 @@ void i915_gem_sanitize(struct drm_i915_private *i915)
 * it may impact the display and we are uncertain about the stability
 * of the reset, so this could be applied to even earlier gen.
 */
-   err = -ENODEV;
-   if (INTEL_GEN(i915) >= 5 && intel_has_gpu_reset(i915))
-   err = WARN_ON(intel_gpu_reset(i915, ALL_ENGINES));
-   if (!err)
-   intel_engines_sanitize(i915);
+   intel_engines_sanitize(i915, false);
 
intel_uncore_forcewake_put(i915, FORCEWAKE_ALL);
intel_runtime_pm_put(i915);
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 0d342f2b44a5..dd4aff2b256e 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -82,6 +82,7 @@
.display.has_overlay = 1, \
.display.overlay_needs_physical = 1, \
.display.has_gmch_display = 1, \
+   .gpu_reset_clobbers_display = true, \
.hws_needs_physical = 1, \
.unfenced_needs_alignment = 1, \
.ring_mask = RENDER_RING, \
@@ -122,6 +123,7 @@ static const struct intel_device_info intel_i865g_info = {
GEN(3), \
.num_pipes = 2, \
.display.has_gmch_display = 1, \
+   .gpu_reset_clobbers_display = true, \
.ring_mask = RENDER_RING, \
.has_snoop = true, \
.has_coherent_ggtt = true, \
@@ -198,6 +200,7 @@ static const struct intel_device_info intel_pineview_info = 
{
.num_pipes = 2, \
.display.has_hotplug = 1, \
.display.has_gmch_display = 1, \
+   .gpu_reset_clobbers_display = true, \
.ring_mask = RENDER_RING, \
.has_snoop = true, \
.has_coherent_ggtt = true, \
@@ -228,6 +231,7 @@ static const struct intel_device_info intel_g45_info = {
GEN4_FEATURES,
PLATFORM(INTEL_G45),
.ring_mask = RENDER_RING | BSD_RING,
+   .gpu_reset_clobbers_display = false,
 };
 
 static const struct intel_device_info intel_gm45_info = {
@@ -237,6 +241,7 @@ static const struct intel_device_info intel_gm45_info = {
.display.has_fbc = 1,
.display.supports_tv = 1,
.ring_mask = RENDER_RING | BSD_RING,
+   .gpu_reset_clobbers_display = false,
 };
 
 #define GEN5_FEATURES \
diff --git a/drivers/gpu/drm/i915/intel_device_info.h 
b/drivers/gpu/drm/i915/intel_device_info.h
index dd34f974a857..8fd683497956 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -89,6 +89,7 @@ enum intel_ppgtt {
func(is_alpha_support); \
/* Keep has_* in alphabetical order */ \
func(has_64bit_reloc); \
+   func(gpu_reset_clobbers_

[Intel-gfx] [PATCH 02/39] drm/i915/selftests: Take a breath during check_partial_mappings()

2019-01-02 Thread Chris Wilson
With kasan on a slow machine, it can take an age to check all the
partial mappings in a single iteration, so break it up with a
cond_resched) to avoid RCU stall reports.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/selftests/i915_gem_object.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
index c3999dd2021e..be7ecb66ad11 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
@@ -238,6 +238,7 @@ static int check_partial_mapping(struct drm_i915_gem_object 
*obj,
u32 *cpu;
 
GEM_BUG_ON(view.partial.size > nreal);
+   cond_resched();
 
err = i915_gem_object_set_to_gtt_domain(obj, true);
if (err) {
-- 
2.20.1

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


[Intel-gfx] [PATCH 04/39] drm/i915/userptr: Avoid struct_mutex recursion for mmu_invalidate_range_start

2019-01-02 Thread Chris Wilson
Since commit 93065ac753e4 ("mm, oom: distinguish blockable mode for mmu
notifiers") we have been able to report failure from
mmu_invalidate_range_start which allows us to use a trylock on the
struct_mutex to avoid potential recursion and report -EBUSY instead.
Furthermore, this allows us to pull the work into the main callback and
avoid the sleight-of-hand in using a workqueue to avoid lockdep.

However, not all paths to mmu_invalidate_range_start are prepared to
handle failure, so instead of reporting the recursion, deal with it by
propagating the failure upwards, who can decide themselves to handle it
or report it.

v2: Mark up the recursive lock behaviour and comment on the various weak
points.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108375
References: 93065ac753e4 ("mm, oom: distinguish blockable mode for mmu 
notifiers")
Signed-off-by: Chris Wilson 
Cc: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_drv.h |   4 +-
 drivers/gpu/drm/i915/i915_gem.c |  30 +++-
 drivers/gpu/drm/i915/i915_gem_object.h  |   7 +
 drivers/gpu/drm/i915/i915_gem_userptr.c | 221 +++-
 4 files changed, 136 insertions(+), 126 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 101c3aa18740..fb34febe3954 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2908,8 +2908,8 @@ enum i915_mm_subclass { /* lockdep subclass for 
obj->mm.lock/struct_mutex */
I915_MM_SHRINKER /* called "recursively" from direct-reclaim-esque */
 };
 
-void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
-enum i915_mm_subclass subclass);
+int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
+   enum i915_mm_subclass subclass);
 void __i915_gem_object_invalidate(struct drm_i915_gem_object *obj);
 
 enum i915_map_type {
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7ea87c7a0e8c..e46a25747ab7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2447,8 +2447,8 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object 
*obj)
struct sg_table *pages;
 
pages = fetch_and_zero(&obj->mm.pages);
-   if (!pages)
-   return NULL;
+   if (IS_ERR_OR_NULL(pages))
+   return pages;
 
spin_lock(&i915->mm.obj_lock);
list_del(&obj->mm.link);
@@ -2472,22 +2472,23 @@ __i915_gem_object_unset_pages(struct 
drm_i915_gem_object *obj)
return pages;
 }
 
-void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
-enum i915_mm_subclass subclass)
+int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
+   enum i915_mm_subclass subclass)
 {
struct sg_table *pages;
+   int ret;
 
if (i915_gem_object_has_pinned_pages(obj))
-   return;
+   return -EBUSY;
 
GEM_BUG_ON(obj->bind_count);
-   if (!i915_gem_object_has_pages(obj))
-   return;
 
/* May be called by shrinker from within get_pages() (on another bo) */
mutex_lock_nested(&obj->mm.lock, subclass);
-   if (unlikely(atomic_read(&obj->mm.pages_pin_count)))
+   if (unlikely(atomic_read(&obj->mm.pages_pin_count))) {
+   ret = -EBUSY;
goto unlock;
+   }
 
/*
 * ->put_pages might need to allocate memory for the bit17 swizzle
@@ -2495,11 +2496,24 @@ void __i915_gem_object_put_pages(struct 
drm_i915_gem_object *obj,
 * lists early.
 */
pages = __i915_gem_object_unset_pages(obj);
+
+   /*
+* XXX Temporary hijinx to avoid updating all backends to handle
+* NULL pages. In the future, when we have more asynchronous
+* get_pages backends we should be better able to handle the
+* cancellation of the async task in a more uniform manner.
+*/
+   if (!pages && !i915_gem_object_needs_async_cancel(obj))
+   pages = ERR_PTR(-EINVAL);
+
if (!IS_ERR(pages))
obj->ops->put_pages(obj, pages);
 
+   ret = 0;
 unlock:
mutex_unlock(&obj->mm.lock);
+
+   return ret;
 }
 
 bool i915_sg_trim(struct sg_table *orig_st)
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h 
b/drivers/gpu/drm/i915/i915_gem_object.h
index a6dd7c46de0d..49ce797173b5 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -56,6 +56,7 @@ struct drm_i915_gem_object_ops {
 #define I915_GEM_OBJECT_HAS_STRUCT_PAGEBIT(0)
 #define I915_GEM_OBJECT_IS_SHRINKABLE  BIT(1)
 #define I915_GEM_OBJECT_IS_PROXY   BIT(2)
+#define I915_GEM_OBJECT_ASYNC_CANCEL   BIT(3)
 
/* Interface between the GEM object and its backing storage.
 * get_pages() is called once prior to the use of the associated set
@@ -386,6 +387,12 @@ i915_gem_object_is_pro

[Intel-gfx] [PATCH 11/39] drm/i915: Markup paired operations on display power domains

2019-01-02 Thread Chris Wilson
The majority of runtime-pm operations are bounded and scoped within a
function; these are easy to verify that the wakeref are handled
correctly. We can employ the compiler to help us, and reduce the number
of wakerefs tracked when debugging, by passing around cookies provided
by the various rpm_get functions to their rpm_put counterpart. This
makes the pairing explicit, and given the required wakeref cookie the
compiler can verify that we pass an initialised value to the rpm_put
(quite handy for double checking error paths).

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_debugfs.c | 35 ++--
 drivers/gpu/drm/i915/i915_drv.h |  2 +
 drivers/gpu/drm/i915/i915_gem.c |  4 +-
 drivers/gpu/drm/i915/icl_dsi.c  | 36 -
 drivers/gpu/drm/i915/intel_audio.c  |  3 +-
 drivers/gpu/drm/i915/intel_cdclk.c  | 10 ++--
 drivers/gpu/drm/i915/intel_crt.c| 25 +
 drivers/gpu/drm/i915/intel_csr.c| 25 +++--
 drivers/gpu/drm/i915/intel_ddi.c| 36 -
 drivers/gpu/drm/i915/intel_display.c| 68 ++-
 drivers/gpu/drm/i915/intel_dp.c | 38 +++--
 drivers/gpu/drm/i915/intel_dpll_mgr.c   | 66 +++
 drivers/gpu/drm/i915/intel_drv.h| 17 --
 drivers/gpu/drm/i915/intel_dsi.h|  1 +
 drivers/gpu/drm/i915/intel_hdmi.c   | 18 ---
 drivers/gpu/drm/i915/intel_i2c.c| 20 +++
 drivers/gpu/drm/i915/intel_lvds.c   |  8 +--
 drivers/gpu/drm/i915/intel_pipe_crc.c   |  6 ++-
 drivers/gpu/drm/i915/intel_pm.c |  6 ++-
 drivers/gpu/drm/i915/intel_runtime_pm.c | 71 -
 drivers/gpu/drm/i915/intel_sprite.c | 24 ++---
 drivers/gpu/drm/i915/intel_vdsc.c   |  4 +-
 drivers/gpu/drm/i915/vlv_dsi.c  | 14 +++--
 23 files changed, 347 insertions(+), 190 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 463fa75c8032..e5b846732853 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -626,10 +626,12 @@ static void gen8_display_interrupt_info(struct seq_file 
*m)
 
for_each_pipe(dev_priv, pipe) {
enum intel_display_power_domain power_domain;
+   intel_wakeref_t wakeref;
 
power_domain = POWER_DOMAIN_PIPE(pipe);
-   if (!intel_display_power_get_if_enabled(dev_priv,
-   power_domain)) {
+   wakeref = intel_display_power_get_if_enabled(dev_priv,
+power_domain);
+   if (!wakeref) {
seq_printf(m, "Pipe %c power disabled\n",
   pipe_name(pipe));
continue;
@@ -644,7 +646,7 @@ static void gen8_display_interrupt_info(struct seq_file *m)
   pipe_name(pipe),
   I915_READ(GEN8_DE_PIPE_IER(pipe)));
 
-   intel_display_power_put(dev_priv, power_domain);
+   intel_display_power_put(dev_priv, power_domain, wakeref);
}
 
seq_printf(m, "Display Engine port interrupt mask:\t%08x\n",
@@ -680,6 +682,8 @@ static int i915_interrupt_info(struct seq_file *m, void 
*data)
wakeref = intel_runtime_pm_get(dev_priv);
 
if (IS_CHERRYVIEW(dev_priv)) {
+   intel_wakeref_t pref;
+
seq_printf(m, "Master Interrupt Control:\t%08x\n",
   I915_READ(GEN8_MASTER_IRQ));
 
@@ -695,8 +699,9 @@ static int i915_interrupt_info(struct seq_file *m, void 
*data)
enum intel_display_power_domain power_domain;
 
power_domain = POWER_DOMAIN_PIPE(pipe);
-   if (!intel_display_power_get_if_enabled(dev_priv,
-   power_domain)) {
+   pref = intel_display_power_get_if_enabled(dev_priv,
+ power_domain);
+   if (!pref) {
seq_printf(m, "Pipe %c power disabled\n",
   pipe_name(pipe));
continue;
@@ -706,17 +711,17 @@ static int i915_interrupt_info(struct seq_file *m, void 
*data)
   pipe_name(pipe),
   I915_READ(PIPESTAT(pipe)));
 
-   intel_display_power_put(dev_priv, power_domain);
+   intel_display_power_put(dev_priv, power_domain, pref);
}
 
-   intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
+   pref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
seq_printf(m, "Port hotplug:\t%08x\n",
   I915_READ(PORT_HOTPLUG_EN));
 

[Intel-gfx] [PATCH 30/39] drm/i915/selftests: Allocate mock ring/timeline per context

2019-01-02 Thread Chris Wilson
To correctly simulate preemption between contexts, we need independent
timelines along each context. Make it so.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/selftests/mock_engine.c | 90 ++--
 1 file changed, 47 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c 
b/drivers/gpu/drm/i915/selftests/mock_engine.c
index 9fe5b2c8f8d4..8b8d51af7d6a 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.c
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
@@ -30,6 +30,36 @@ struct mock_ring {
struct i915_timeline timeline;
 };
 
+static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
+{
+   const unsigned long sz = PAGE_SIZE / 2;
+   struct mock_ring *ring;
+
+   ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
+   if (!ring)
+   return NULL;
+
+   i915_timeline_init(engine->i915, &ring->timeline, engine->name);
+
+   ring->base.size = sz;
+   ring->base.effective_size = sz;
+   ring->base.vaddr = (void *)(ring + 1);
+   ring->base.timeline = &ring->timeline;
+
+   INIT_LIST_HEAD(&ring->base.request_list);
+   intel_ring_update_space(&ring->base);
+
+   return &ring->base;
+}
+
+static void mock_ring_free(struct intel_ring *base)
+{
+   struct mock_ring *ring = container_of(base, typeof(*ring), base);
+
+   i915_timeline_fini(&ring->timeline);
+   kfree(ring);
+}
+
 static struct mock_request *first_request(struct mock_engine *engine)
 {
return list_first_entry_or_null(&engine->hw_queue,
@@ -80,6 +110,9 @@ static void mock_context_unpin(struct intel_context *ce)
 static void mock_context_destroy(struct intel_context *ce)
 {
GEM_BUG_ON(ce->pin_count);
+
+   if (ce->ring)
+   mock_ring_free(ce->ring);
 }
 
 static const struct intel_context_ops mock_context_ops = {
@@ -93,13 +126,22 @@ mock_context_pin(struct intel_engine_cs *engine,
 {
struct intel_context *ce = to_intel_context(ctx, engine);
 
-   if (!ce->pin_count++) {
-   i915_gem_context_get(ctx);
-   ce->ring = engine->buffer;
-   ce->ops = &mock_context_ops;
+   if (ce->pin_count++)
+   return ce;
+
+   if (!ce->ring) {
+   ce->ring = mock_ring(engine);
+   if (!ce->ring)
+   goto err;
}
 
+   ce->ops = &mock_context_ops;
+   i915_gem_context_get(ctx);
return ce;
+
+err:
+   ce->pin_count = 0;
+   return ERR_PTR(-ENOMEM);
 }
 
 static int mock_request_alloc(struct i915_request *request)
@@ -143,36 +185,6 @@ static void mock_submit_request(struct i915_request 
*request)
spin_unlock_irq(&engine->hw_lock);
 }
 
-static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
-{
-   const unsigned long sz = PAGE_SIZE / 2;
-   struct mock_ring *ring;
-
-   ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
-   if (!ring)
-   return NULL;
-
-   i915_timeline_init(engine->i915, &ring->timeline, engine->name);
-
-   ring->base.size = sz;
-   ring->base.effective_size = sz;
-   ring->base.vaddr = (void *)(ring + 1);
-   ring->base.timeline = &ring->timeline;
-
-   INIT_LIST_HEAD(&ring->base.request_list);
-   intel_ring_update_space(&ring->base);
-
-   return &ring->base;
-}
-
-static void mock_ring_free(struct intel_ring *base)
-{
-   struct mock_ring *ring = container_of(base, typeof(*ring), base);
-
-   i915_timeline_fini(&ring->timeline);
-   kfree(ring);
-}
-
 struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
const char *name,
int id)
@@ -207,17 +219,11 @@ struct intel_engine_cs *mock_engine(struct 
drm_i915_private *i915,
timer_setup(&engine->hw_delay, hw_delay_complete, 0);
INIT_LIST_HEAD(&engine->hw_queue);
 
-   engine->base.buffer = mock_ring(&engine->base);
-   if (!engine->base.buffer)
-   goto err_breadcrumbs;
-
if (IS_ERR(intel_context_pin(i915->kernel_context, &engine->base)))
-   goto err_ring;
+   goto err_breadcrumbs;
 
return &engine->base;
 
-err_ring:
-   mock_ring_free(engine->base.buffer);
 err_breadcrumbs:
intel_engine_fini_breadcrumbs(&engine->base);
i915_timeline_fini(&engine->base.timeline);
@@ -260,8 +266,6 @@ void mock_engine_free(struct intel_engine_cs *engine)
 
__intel_context_unpin(engine->i915->kernel_context, engine);
 
-   mock_ring_free(engine->buffer);
-
intel_engine_fini_breadcrumbs(engine);
i915_timeline_fini(&engine->timeline);
 
-- 
2.20.1

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


[Intel-gfx] [PATCH 20/39] drm/i915: Make all GPU resets atomic

2019-01-02 Thread Chris Wilson
In preparation for the next few commits, make resetting the GPU atomic.
Currently, we have prepared gen6+ for atomic resetting of individual
engines, but now there is a requirement to perform the whole device
level reset (just the register poking) from inside an atomic context.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_reset.c | 50 +--
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reset.c 
b/drivers/gpu/drm/i915/i915_reset.c
index eb8e206b025e..f5da67f1bc04 100644
--- a/drivers/gpu/drm/i915/i915_reset.c
+++ b/drivers/gpu/drm/i915/i915_reset.c
@@ -144,14 +144,14 @@ static int i915_do_reset(struct drm_i915_private *i915,
 
/* Assert reset for at least 20 usec, and wait for acknowledgement. */
pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE);
-   usleep_range(50, 200);
-   err = wait_for(i915_in_reset(pdev), 500);
+   udelay(50);
+   err = wait_for_atomic(i915_in_reset(pdev), 50);
 
/* Clear the reset request. */
pci_write_config_byte(pdev, I915_GDRST, 0);
-   usleep_range(50, 200);
+   udelay(50);
if (!err)
-   err = wait_for(!i915_in_reset(pdev), 500);
+   err = wait_for_atomic(!i915_in_reset(pdev), 50);
 
return err;
 }
@@ -171,7 +171,7 @@ static int g33_do_reset(struct drm_i915_private *i915,
struct pci_dev *pdev = i915->drm.pdev;
 
pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE);
-   return wait_for(g4x_reset_complete(pdev), 500);
+   return wait_for_atomic(g4x_reset_complete(pdev), 50);
 }
 
 static int g4x_do_reset(struct drm_i915_private *dev_priv,
@@ -182,13 +182,13 @@ static int g4x_do_reset(struct drm_i915_private *dev_priv,
int ret;
 
/* WaVcpClkGateDisableForMediaReset:ctg,elk */
-   I915_WRITE(VDECCLK_GATE_D,
-  I915_READ(VDECCLK_GATE_D) | VCP_UNIT_CLOCK_GATE_DISABLE);
-   POSTING_READ(VDECCLK_GATE_D);
+   I915_WRITE_FW(VDECCLK_GATE_D,
+ I915_READ(VDECCLK_GATE_D) | VCP_UNIT_CLOCK_GATE_DISABLE);
+   POSTING_READ_FW(VDECCLK_GATE_D);
 
pci_write_config_byte(pdev, I915_GDRST,
  GRDOM_MEDIA | GRDOM_RESET_ENABLE);
-   ret =  wait_for(g4x_reset_complete(pdev), 500);
+   ret =  wait_for_atomic(g4x_reset_complete(pdev), 50);
if (ret) {
DRM_DEBUG_DRIVER("Wait for media reset failed\n");
goto out;
@@ -196,7 +196,7 @@ static int g4x_do_reset(struct drm_i915_private *dev_priv,
 
pci_write_config_byte(pdev, I915_GDRST,
  GRDOM_RENDER | GRDOM_RESET_ENABLE);
-   ret =  wait_for(g4x_reset_complete(pdev), 500);
+   ret =  wait_for_atomic(g4x_reset_complete(pdev), 50);
if (ret) {
DRM_DEBUG_DRIVER("Wait for render reset failed\n");
goto out;
@@ -205,9 +205,9 @@ static int g4x_do_reset(struct drm_i915_private *dev_priv,
 out:
pci_write_config_byte(pdev, I915_GDRST, 0);
 
-   I915_WRITE(VDECCLK_GATE_D,
-  I915_READ(VDECCLK_GATE_D) & ~VCP_UNIT_CLOCK_GATE_DISABLE);
-   POSTING_READ(VDECCLK_GATE_D);
+   I915_WRITE_FW(VDECCLK_GATE_D,
+ I915_READ(VDECCLK_GATE_D) & ~VCP_UNIT_CLOCK_GATE_DISABLE);
+   POSTING_READ_FW(VDECCLK_GATE_D);
 
return ret;
 }
@@ -218,27 +218,29 @@ static int ironlake_do_reset(struct drm_i915_private 
*dev_priv,
 {
int ret;
 
-   I915_WRITE(ILK_GDSR, ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE);
-   ret = intel_wait_for_register(dev_priv,
- ILK_GDSR, ILK_GRDOM_RESET_ENABLE, 0,
- 500);
+   I915_WRITE_FW(ILK_GDSR, ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE);
+   ret = __intel_wait_for_register_fw(dev_priv, ILK_GDSR,
+  ILK_GRDOM_RESET_ENABLE, 0,
+  5000, 0,
+  NULL);
if (ret) {
DRM_DEBUG_DRIVER("Wait for render reset failed\n");
goto out;
}
 
-   I915_WRITE(ILK_GDSR, ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE);
-   ret = intel_wait_for_register(dev_priv,
- ILK_GDSR, ILK_GRDOM_RESET_ENABLE, 0,
- 500);
+   I915_WRITE_FW(ILK_GDSR, ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE);
+   ret = __intel_wait_for_register_fw(dev_priv, ILK_GDSR,
+  ILK_GRDOM_RESET_ENABLE, 0,
+  5000, 0,
+  NULL);
if (ret) {
DRM_DEBUG_DRIVER("Wait for media reset failed\n");
goto out;
}
 
 out:
-   I915_WRITE(ILK_GDSR, 0);
-   POSTING_READ(ILK_GDSR);
+   I915_WRITE_FW(ILK_GDSR, 0);
+   POS

Re: [Intel-gfx] [PATCH 0/6] drm/i915: drmP.h include removal w/ drm prep work

2019-01-02 Thread Jani Nikula
On Wed, 02 Jan 2019, Laurent Pinchart  wrote:
> Hi Jani,
>
> On Wednesday, 2 January 2019 09:47:58 EET Jani Nikula wrote:
>> On Fri, 28 Dec 2018, Jani Nikula  wrote:
>> > Thanks for all the reviews, pushed patches 1-5 to topic/drmp-cleanup
>> > with $(git merge-base drm-misc-next drm-intel-next-queued) as the
>> > starting point. It's also included in drm-tip now.
>> 
>> So I did this *before* I got the review feedback from Laurent, based on
>> Daniel's review only. Would you all like me to redo the branch with
>> Laurent's comments addressed and r-b added?
>
> If you think my comments are valuable, that may be a good idea :-)

Put that way... apologies for even thinking I have an option here! :)

I took the liberty of force pushing the topic branch, with just the
commit messages updated to reflect your review.

Thanks,
Jani.

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


[Intel-gfx] [PATCH 17/39] drm/i915: Serialise concurrent calls to i915_gem_set_wedged()

2019-01-02 Thread Chris Wilson
Make i915_gem_set_wedged() and i915_gem_unset_wedged() behaviour more
consistently if called concurrently.

Signed-off-by: Chris Wilson 
Cc: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem.c   | 32 ++-
 drivers/gpu/drm/i915/i915_gpu_error.h |  4 ++-
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  1 +
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index c001889eaa36..4525ffad643b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3338,10 +3338,15 @@ static void nop_submit_request(struct i915_request 
*request)
 
 void i915_gem_set_wedged(struct drm_i915_private *i915)
 {
+   struct i915_gpu_error *error = &i915->gpu_error;
struct intel_engine_cs *engine;
enum intel_engine_id id;
 
-   GEM_TRACE("start\n");
+   mutex_lock(&error->wedge_mutex);
+   if (test_bit(I915_WEDGED, &error->flags)) {
+   mutex_unlock(&error->wedge_mutex);
+   return;
+   }
 
if (GEM_SHOW_DEBUG()) {
struct drm_printer p = drm_debug_printer(__func__);
@@ -3350,8 +3355,7 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
intel_engine_dump(engine, &p, "%s\n", engine->name);
}
 
-   if (test_and_set_bit(I915_WEDGED, &i915->gpu_error.flags))
-   goto out;
+   GEM_TRACE("start\n");
 
/*
 * First, stop submission to hw, but do not yet complete requests by
@@ -3387,20 +3391,28 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
intel_engine_wakeup(engine);
}
 
-out:
+   smp_mb__before_atomic();
+   set_bit(I915_WEDGED, &error->flags);
+
GEM_TRACE("end\n");
+   mutex_unlock(&error->wedge_mutex);
 
-   wake_up_all(&i915->gpu_error.reset_queue);
+   wake_up_all(&error->reset_queue);
 }
 
 bool i915_gem_unset_wedged(struct drm_i915_private *i915)
 {
+   struct i915_gpu_error *error = &i915->gpu_error;
struct i915_timeline *tl;
+   bool ret = false;
 
lockdep_assert_held(&i915->drm.struct_mutex);
-   if (!test_bit(I915_WEDGED, &i915->gpu_error.flags))
+
+   if (!test_bit(I915_WEDGED, &error->flags))
return true;
 
+   mutex_lock(&error->wedge_mutex);
+
GEM_TRACE("start\n");
 
/*
@@ -3434,7 +3446,7 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915)
 */
if (dma_fence_default_wait(&rq->fence, true,
   MAX_SCHEDULE_TIMEOUT) < 0)
-   return false;
+   goto unlock;
}
i915_retire_requests(i915);
GEM_BUG_ON(i915->gt.active_requests);
@@ -3457,8 +3469,11 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915)
 
smp_mb__before_atomic(); /* complete takeover before enabling execbuf */
clear_bit(I915_WEDGED, &i915->gpu_error.flags);
+   ret = true;
+unlock:
+   mutex_unlock(&i915->gpu_error.wedge_mutex);
 
-   return true;
+   return ret;
 }
 
 static void
@@ -5854,6 +5869,7 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
  i915_gem_idle_work_handler);
init_waitqueue_head(&dev_priv->gpu_error.wait_queue);
init_waitqueue_head(&dev_priv->gpu_error.reset_queue);
+   mutex_init(&dev_priv->gpu_error.wedge_mutex);
 
atomic_set(&dev_priv->mm.bsd_engine_dispatch_index, 0);
 
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h 
b/drivers/gpu/drm/i915/i915_gpu_error.h
index ff2652bbb0b0..9b61037baa43 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.h
+++ b/drivers/gpu/drm/i915/i915_gpu_error.h
@@ -270,8 +270,8 @@ struct i915_gpu_error {
 #define I915_RESET_BACKOFF 0
 #define I915_RESET_HANDOFF 1
 #define I915_RESET_MODESET 2
+#define I915_RESET_ENGINE  3
 #define I915_WEDGED(BITS_PER_LONG - 1)
-#define I915_RESET_ENGINE  (I915_WEDGED - I915_NUM_ENGINES)
 
/** Number of times an engine has been reset */
u32 reset_engine_count[I915_NUM_ENGINES];
@@ -282,6 +282,8 @@ struct i915_gpu_error {
/** Reason for the current *global* reset */
const char *reason;
 
+   struct mutex wedge_mutex; /* serialises wedging/unwedging */
+
/**
 * Waitqueue to signal when a hang is detected. Used to for waiters
 * to release the struct_mutex for the reset to procede.
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c 
b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index aa4ddae94aca..4a25d2a344f2 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -189,6 +189,7 @@ struct drm_i915_private *mock_gem_device(void)
 
init_waitqueue_head(&i915->gpu_error.wait_queue);
init_waitqueue_head(&i915->gpu_error.reset_queue);
+   mute

[Intel-gfx] [PATCH 14/39] drm/i915/dp: Markup pps lock power well

2019-01-02 Thread Chris Wilson
Track where and when we acquire and release the power well for pps
access along the dp aux link, with a view to detecting if we leak any
wakerefs.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/intel_dp.c | 231 +---
 1 file changed, 121 insertions(+), 110 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e8031daacee2..25c101e7f992 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -602,30 +602,39 @@ intel_dp_init_panel_power_sequencer_registers(struct 
intel_dp *intel_dp,
 static void
 intel_dp_pps_init(struct intel_dp *intel_dp);
 
-static void pps_lock(struct intel_dp *intel_dp)
+static intel_wakeref_t
+pps_lock(struct intel_dp *intel_dp)
 {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+   intel_wakeref_t wakeref;
 
/*
 * See intel_power_sequencer_reset() why we need
 * a power domain reference here.
 */
-   intel_display_power_get(dev_priv,
-   
intel_aux_power_domain(dp_to_dig_port(intel_dp)));
+   wakeref = intel_display_power_get(dev_priv,
+ 
intel_aux_power_domain(dp_to_dig_port(intel_dp)));
 
mutex_lock(&dev_priv->pps_mutex);
+
+   return wakeref;
 }
 
-static void pps_unlock(struct intel_dp *intel_dp)
+static intel_wakeref_t
+pps_unlock(struct intel_dp *intel_dp, intel_wakeref_t wakeref)
 {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
mutex_unlock(&dev_priv->pps_mutex);
-
-   intel_display_power_put_unchecked(dev_priv,
- 
intel_aux_power_domain(dp_to_dig_port(intel_dp)));
+   intel_display_power_put(dev_priv,
+   
intel_aux_power_domain(dp_to_dig_port(intel_dp)),
+   wakeref);
+   return 0;
 }
 
+#define with_pps_lock(dp, wf) \
+   for (wf = pps_lock(dp); wf; wf = pps_unlock(dp, wf))
+
 static void
 vlv_power_sequencer_kick(struct intel_dp *intel_dp)
 {
@@ -974,30 +983,30 @@ static int edp_notify_handler(struct notifier_block 
*this, unsigned long code,
struct intel_dp *intel_dp = container_of(this, typeof(* intel_dp),
 edp_notifier);
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+   intel_wakeref_t wakeref;
 
if (!intel_dp_is_edp(intel_dp) || code != SYS_RESTART)
return 0;
 
-   pps_lock(intel_dp);
-
-   if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
-   enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
-   i915_reg_t pp_ctrl_reg, pp_div_reg;
-   u32 pp_div;
-
-   pp_ctrl_reg = PP_CONTROL(pipe);
-   pp_div_reg  = PP_DIVISOR(pipe);
-   pp_div = I915_READ(pp_div_reg);
-   pp_div &= PP_REFERENCE_DIVIDER_MASK;
-
-   /* 0x1F write to PP_DIV_REG sets max cycle delay */
-   I915_WRITE(pp_div_reg, pp_div | 0x1F);
-   I915_WRITE(pp_ctrl_reg, PANEL_UNLOCK_REGS | PANEL_POWER_OFF);
-   msleep(intel_dp->panel_power_cycle_delay);
+   with_pps_lock(intel_dp, wakeref) {
+   if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+   enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
+   i915_reg_t pp_ctrl_reg, pp_div_reg;
+   u32 pp_div;
+
+   pp_ctrl_reg = PP_CONTROL(pipe);
+   pp_div_reg  = PP_DIVISOR(pipe);
+   pp_div = I915_READ(pp_div_reg);
+   pp_div &= PP_REFERENCE_DIVIDER_MASK;
+
+   /* 0x1F write to PP_DIV_REG sets max cycle delay */
+   I915_WRITE(pp_div_reg, pp_div | 0x1F);
+   I915_WRITE(pp_ctrl_reg,
+  PANEL_UNLOCK_REGS | PANEL_POWER_OFF);
+   msleep(intel_dp->panel_power_cycle_delay);
+   }
}
 
-   pps_unlock(intel_dp);
-
return 0;
 }
 
@@ -1185,16 +1194,17 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
to_i915(intel_dig_port->base.base.dev);
i915_reg_t ch_ctl, ch_data[5];
uint32_t aux_clock_divider;
+   intel_wakeref_t wakeref;
int i, ret, recv_bytes;
-   uint32_t status;
int try, clock = 0;
+   uint32_t status;
bool vdd;
 
ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
for (i = 0; i < ARRAY_SIZE(ch_data); i++)
ch_data[i] = intel_dp->aux_ch_data_reg(intel_dp, i);
 
-   pps_lock(intel_dp);
+   wakeref = pps_lock(intel_dp);
 
/*
 * We will be called with VDD already enabled for dpcd/edid/oui reads.
@@ -1338,7 +1348,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
if (vdd)
edp_panel_vdd_off(inte

Re: [Intel-gfx] iommu_intel or i915 regression in 4.18, 4.19.12 and drm-tip

2019-01-02 Thread Joonas Lahtinen
Quoting Eric Wong (2018-12-27 13:49:48)
> I just got a used Thinkpad X201 (Core i5 M 520, Intel QM57
> chipset) and hit some kernel panics while trying to view
> image/animation-intensive stuff in Firefox (X11) unless I use
> "iommu_intel=igfx_off".
> 
> With Debian stable backport kernels, "linux-image-4.17.0-0.bpo.3-amd64"
> (4.17.17-1~bpo9+1) has no problems.  But "linux-image-4.18.0-0.bpo.3-amd64"
> (4.18.20-2~bpo9+1) gives a blank screen before I can login via agetty
> and run startx.

Could you open a new bug at (and attach relevant information there):

https://01.org/linuxgraphics/documentation/how-report-bugs

Most confusing about this is that 4.17 would have worked to begin with,
without intel_iommu=igfx_off (unless it was the default for older
kernel?)

Did you maybe update other parts of the system while updating the
kernel?

If you could attach full boot dmesg from working and non-working kernel +
have config file of both kernel's in Bugzilla. That'd be a good start!

Regards, Joonas

> Building 4.19.12 myself got me into X11 and able to start
> Firefox to panic the kernel.  I also updated to the latest BIOS
> (1.40), but it's an EOL laptop (but it's still the most powerful
> laptop I use).  I intend to replace the BIOS with Coreboot soon...
> 
> Initially, I thought I was hitting another GPU hang from 4.18+:
> 
> https://bugs.freedesktop.org/show_bug.cgi?id=107945
> 
> But building drm-tip @ commit 28bb1fc015cedadf3b099b8bd0bb27609849f362
> ("drm-tip: 2018y-12m-25d-08h-12m-37s UTC integration manifest")
> I was still able to reproduce the panic unless I use iommu_intel=igfx_off
> "i915.reset=1" did not help matters, either.
> 
> Below is what I got from netconsole while on drm-tip:
> 
> Kernel panic - not syncing: DMAR hardware is malfunctioning
> Shutting down cpus with NMI
> Kernel Offset: disabled
> ---[ end Kernel panic - not syncing: DMAR hardware is malfunctioning ]---
> [ cut here ]
> sched: Unexpected reschedule of offline CPU#3!
> WARNING: CPU: 0 PID: 105 at native_smp_send_reschedule+0x34/0x40
> Modules linked in: netconsole ccm snd_hda_codec_hdmi snd_hda_codec_conexant 
> snd_hda_codec_generic intel_powerclamp coretemp kvm_intel kvm irqbypass 
> crc32_pclmul crc32c_intel ghash_clmulni_intel arc4 iwldvm aesni_intel 
> aes_x86_64 crypto_simd cryptd mac80211 glue_helper intel_cstate iwlwifi 
> intel_uncore i915 intel_gtt i2c_algo_bit iosf_mbi drm_kms_helper cfbfillrect 
> syscopyarea intel_ips cfbimgblt sysfillrect sysimgblt fb_sys_fops cfbcopyarea 
> thinkpad_acpi prime_numbers cfg80211 ledtrig_audio i2c_i801 sg snd_hda_intel 
> led_class snd_hda_codec drm ac drm_panel_orientation_quirks snd_hwdep battery 
> e1000e agpgart snd_hda_core snd_pcm snd_timer ptp snd soundcore pps_core 
> ehci_pci ehci_hcd lpc_ich video mfd_core button acpi_cpufreq ecryptfs 
> ip_tables x_tables ipv6 evdev thermal [last unloaded: netconsole]
> CPU: 0 PID: 105 Comm: kworker/u8:3 Not tainted 4.20.0-rc7b1+ #1
> Hardware name: LENOVO 3680FBU/3680FBU, BIOS 6QET70WW (1.40 ) 10/11/2012
> Workqueue: i915 __i915_gem_free_work [i915]
> RIP: 0010:native_smp_send_reschedule+0x34/0x40
> Code: 05 69 c6 c9 00 73 15 48 8b 05 18 2d b3 00 be fd 00 00 00 48 8b 40 30 e9 
> 9a 58 7d 00 89 fe 48 c7 c7 78 73 af 81 e8 dc c2 01 00 <0f> 0b c3 66 0f 1f 84 
> 00 00 00 00 00 66 66 66 66 90 8b 05 0d 7d df
> RSP: 0018:888075003d98 EFLAGS: 00010092
> RAX: 002e RBX: 8880751a0740 RCX: 0006
> RDX: 0007 RSI: 0082 RDI: 888075015440
> RBP: 88806e823700 R08:  R09: 888072fc07c0
> R10: 888075003d60 R11: fff5c002 R12: 8880751a0740
> R13: 8880751a0740 R14:  R15: 0003
> FS:  () GS:88807500() knlGS:
> CS:  0010 DS:  ES:  CR0: 80050033
> CR2: 7fdb1f53f000 CR3: 01c0a004 CR4: 000206f0
> Call Trace:
>  
>  ? check_preempt_curr+0x4e/0x90
>  ? ttwu_do_wakeup.isra.19+0x14/0xf0
>  ? try_to_wake_up+0x323/0x410
>  ? autoremove_wake_function+0xe/0x30
>  ? __wake_up_common+0x8d/0x140
>  ? __wake_up_common_lock+0x6c/0x90
>  ? irq_work_run_list+0x49/0x80
>  ? tick_sched_handle.isra.6+0x50/0x50
>  ? update_process_times+0x3b/0x50
>  ? tick_sched_handle.isra.6+0x30/0x50
>  ? tick_sched_timer+0x3b/0x80
>  ? __hrtimer_run_queues+0xea/0x270
>  ? hrtimer_interrupt+0x101/0x240
>  ? smp_apic_timer_interrupt+0x6a/0x150
>  ? apic_timer_interrupt+0xf/0x20
>  
>  ? panic+0x1ca/0x212
>  ? panic+0x1c7/0x212
>  ? __iommu_flush_iotlb+0x19e/0x1c0
>  ? iommu_flush_iotlb_psi+0x96/0xf0
>  ? intel_unmap+0xbf/0xf0
>  ? i915_gem_object_put_pages_gtt+0x36/0x220 [i915]
>  ? drm_ht_remove+0x20/0x20 [drm]
>  ? drm_mm_remove_node+0x1ad/0x310 [drm]
>  ? __pm_runtime_resume+0x54/0x70
>  ? __i915_gem_object_unset_pages+0x129/0x170 [i915]
>  ? __i915_gem_object_put_pages+0x70/0xa0 [i915]
>  ? __i915_gem_free_objects+0x245/0x4e0 [i915]
>  ? __switch_to_a

Re: [Intel-gfx] [PATCH 4/6] drm/i915: always use INTEL_INFO() to access device info

2019-01-02 Thread Tvrtko Ursulin


On 31/12/2018 14:56, Jani Nikula wrote:

Hide the way device info is stored, in preparation of making device info
a pointer to the const rodata in i915_pci.c. No functional changes.

Cc: Tvrtko Ursulin 
Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/i915/i915_drv.c |  2 +-
  drivers/gpu/drm/i915/i915_drv.h | 90 ++---
  drivers/gpu/drm/i915/i915_reg.h | 12 ++---
  drivers/gpu/drm/i915/intel_uncore.c |  2 +-
  4 files changed, 53 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 261932ee6837..8d7a3a852c10 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1636,7 +1636,7 @@ static void i915_welcome_messages(struct drm_i915_private 
*dev_priv)
if (drm_debug & DRM_UT_DRIVER) {
struct drm_printer p = drm_debug_printer("i915 device info:");
  
-		intel_device_info_dump(&dev_priv->info, &p);

+   intel_device_info_dump(INTEL_INFO(dev_priv), &p);
intel_device_info_dump_runtime(RUNTIME_INFO(dev_priv), &p);
}
  
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h

index 4534beeed6f9..ce8d7a97e26b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2202,7 +2202,7 @@ intel_info(const struct drm_i915_private *dev_priv)
  #define RUNTIME_INFO(dev_priv)(&(dev_priv)->__runtime)
  #define DRIVER_CAPS(dev_priv) (&(dev_priv)->caps)
  
-#define INTEL_GEN(dev_priv)	((dev_priv)->info.gen)

+#define INTEL_GEN(dev_priv)(INTEL_INFO(dev_priv)->gen)
  #define INTEL_DEVID(dev_priv) (RUNTIME_INFO(dev_priv)->device_id)
  
  #define REVID_FOREVER		0xff

@@ -2215,11 +2215,11 @@ intel_info(const struct drm_i915_private *dev_priv)
  
  /* Returns true if Gen is in inclusive range [Start, End] */

  #define IS_GEN_RANGE(dev_priv, s, e) \
-   (!!((dev_priv)->info.gen_mask & INTEL_GEN_MASK((s), (e
+   (!!(INTEL_INFO(dev_priv)->gen_mask & INTEL_GEN_MASK((s), (e
  
  #define IS_GEN(dev_priv, n) \

(BUILD_BUG_ON_ZERO(!__builtin_constant_p(n)) + \
-(dev_priv)->info.gen == (n))
+INTEL_INFO(dev_priv)->gen == (n))
  
  /*

   * Return true if revision is in range [since,until] inclusive.
@@ -2229,7 +2229,7 @@ intel_info(const struct drm_i915_private *dev_priv)
  #define IS_REVID(p, since, until) \
(INTEL_REVID(p) >= (since) && INTEL_REVID(p) <= (until))
  
-#define IS_PLATFORM(dev_priv, p) ((dev_priv)->info.platform_mask & BIT(p))

+#define IS_PLATFORM(dev_priv, p) (INTEL_INFO(dev_priv)->platform_mask & BIT(p))
  
  #define IS_I830(dev_priv)	IS_PLATFORM(dev_priv, INTEL_I830)

  #define IS_I845G(dev_priv)IS_PLATFORM(dev_priv, INTEL_I845G)
@@ -2251,7 +2251,7 @@ intel_info(const struct drm_i915_private *dev_priv)
  #define IS_IRONLAKE_M(dev_priv)   (INTEL_DEVID(dev_priv) == 0x0046)
  #define IS_IVYBRIDGE(dev_priv)IS_PLATFORM(dev_priv, INTEL_IVYBRIDGE)
  #define IS_IVB_GT1(dev_priv)  (IS_IVYBRIDGE(dev_priv) && \
-(dev_priv)->info.gt == 1)
+INTEL_INFO(dev_priv)->gt == 1)
  #define IS_VALLEYVIEW(dev_priv)   IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW)
  #define IS_CHERRYVIEW(dev_priv)   IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)
  #define IS_HASWELL(dev_priv)  IS_PLATFORM(dev_priv, INTEL_HASWELL)
@@ -2263,7 +2263,7 @@ intel_info(const struct drm_i915_private *dev_priv)
  #define IS_COFFEELAKE(dev_priv)   IS_PLATFORM(dev_priv, INTEL_COFFEELAKE)
  #define IS_CANNONLAKE(dev_priv)   IS_PLATFORM(dev_priv, INTEL_CANNONLAKE)
  #define IS_ICELAKE(dev_priv)  IS_PLATFORM(dev_priv, INTEL_ICELAKE)
-#define IS_MOBILE(dev_priv)((dev_priv)->info.is_mobile)
+#define IS_MOBILE(dev_priv)(INTEL_INFO(dev_priv)->is_mobile)
  #define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \
(INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00)
  #define IS_BDW_ULT(dev_priv)  (IS_BROADWELL(dev_priv) && \
@@ -2274,13 +2274,13 @@ intel_info(const struct drm_i915_private *dev_priv)
  #define IS_BDW_ULX(dev_priv)  (IS_BROADWELL(dev_priv) && \
 (INTEL_DEVID(dev_priv) & 0xf) == 0xe)
  #define IS_BDW_GT3(dev_priv)  (IS_BROADWELL(dev_priv) && \
-(dev_priv)->info.gt == 3)
+INTEL_INFO(dev_priv)->gt == 3)
  #define IS_HSW_ULT(dev_priv)  (IS_HASWELL(dev_priv) && \
 (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0A00)
  #define IS_HSW_GT3(dev_priv)  (IS_HASWELL(dev_priv) && \
-(dev_priv)->info.gt == 3)
+INTEL_INFO(dev_priv)->gt == 3)
  #define IS_HSW_GT1(dev_priv)  (IS_HASWELL(dev_priv) && \
-(dev_priv)->info.gt == 1)
+INTEL_INFO(dev_priv)->gt == 1)
  /* ULX machines are also considered ULT. */
  #define I

[Intel-gfx] [PATCH 27/39] drm/i915: Move vma lookup to its own lock

2019-01-02 Thread Chris Wilson
Remove the struct_mutex requirement for looking up the vma for an
object.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_debugfs.c   |  6 +--
 drivers/gpu/drm/i915/i915_gem.c   | 33 +++--
 drivers/gpu/drm/i915/i915_gem_object.h| 45 ++---
 drivers/gpu/drm/i915/i915_vma.c   | 60 +++
 drivers/gpu/drm/i915/i915_vma.h   |  2 +-
 drivers/gpu/drm/i915/selftests/i915_vma.c |  4 +-
 6 files changed, 92 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 5e2d5c8d7e02..8059f6dd3886 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -159,14 +159,14 @@ describe_obj(struct seq_file *m, struct 
drm_i915_gem_object *obj)
   obj->mm.madv == I915_MADV_DONTNEED ? " purgeable" : "");
if (obj->base.name)
seq_printf(m, " (name: %d)", obj->base.name);
-   list_for_each_entry(vma, &obj->vma_list, obj_link) {
+   list_for_each_entry(vma, &obj->vma.list, obj_link) {
if (i915_vma_is_pinned(vma))
pin_count++;
}
seq_printf(m, " (pinned x %d)", pin_count);
if (obj->pin_global)
seq_printf(m, " (global)");
-   list_for_each_entry(vma, &obj->vma_list, obj_link) {
+   list_for_each_entry(vma, &obj->vma.list, obj_link) {
if (!drm_mm_node_allocated(&vma->node))
continue;
 
@@ -322,7 +322,7 @@ static int per_file_stats(int id, void *ptr, void *data)
if (obj->base.name || obj->base.dma_buf)
stats->shared += obj->base.size;
 
-   list_for_each_entry(vma, &obj->vma_list, obj_link) {
+   list_for_each_entry(vma, &obj->vma.list, obj_link) {
if (!drm_mm_node_allocated(&vma->node))
continue;
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a954e15c0315..e42ad20d6328 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -438,15 +438,19 @@ int i915_gem_object_unbind(struct drm_i915_gem_object 
*obj)
if (ret)
return ret;
 
-   while ((vma = list_first_entry_or_null(&obj->vma_list,
-  struct i915_vma,
-  obj_link))) {
+   spin_lock(&obj->vma.lock);
+   while (!ret && (vma = list_first_entry_or_null(&obj->vma.list,
+  struct i915_vma,
+  obj_link))) {
list_move_tail(&vma->obj_link, &still_in_list);
+   spin_unlock(&obj->vma.lock);
+
ret = i915_vma_unbind(vma);
-   if (ret)
-   break;
+
+   spin_lock(&obj->vma.lock);
}
-   list_splice(&still_in_list, &obj->vma_list);
+   list_splice(&still_in_list, &obj->vma.list);
+   spin_unlock(&obj->vma.lock);
 
return ret;
 }
@@ -3640,7 +3644,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
 * reading an invalid PTE on older architectures.
 */
 restart:
-   list_for_each_entry(vma, &obj->vma_list, obj_link) {
+   list_for_each_entry(vma, &obj->vma.list, obj_link) {
if (!drm_mm_node_allocated(&vma->node))
continue;
 
@@ -3718,7 +3722,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
 */
}
 
-   list_for_each_entry(vma, &obj->vma_list, obj_link) {
+   list_for_each_entry(vma, &obj->vma.list, obj_link) {
if (!drm_mm_node_allocated(&vma->node))
continue;
 
@@ -3728,7 +3732,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
}
}
 
-   list_for_each_entry(vma, &obj->vma_list, obj_link)
+   list_for_each_entry(vma, &obj->vma.list, obj_link)
vma->node.color = cache_level;
i915_gem_object_set_cache_coherency(obj, cache_level);
obj->cache_dirty = true; /* Always invalidate stale cachelines */
@@ -4304,7 +4308,9 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
 {
mutex_init(&obj->mm.lock);
 
-   INIT_LIST_HEAD(&obj->vma_list);
+   spin_lock_init(&obj->vma.lock);
+   INIT_LIST_HEAD(&obj->vma.list);
+
INIT_LIST_HEAD(&obj->lut_list);
INIT_LIST_HEAD(&obj->batch_pool_link);
 
@@ -4470,14 +4476,13 @@ static void __i915_gem_free_objects(struct 
drm_i915_private *i915,
mutex_lock(&i915->drm.struct_mutex);
 
GEM_BUG_ON(i915_gem_object_is_active(obj));
-   list_for_each_entry_safe(vma, vn,
-&obj->vma_list, obj_link) {
+   list_for_

[Intel-gfx] [PATCH 28/39] drm/i915: Move intel_execlists_show_requests() aside

2019-01-02 Thread Chris Wilson
Move the debug pretty printer into a standalone routine prior to
extending it in upcoming feature work.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/intel_engine_cs.c | 55 ++--
 drivers/gpu/drm/i915/intel_lrc.c   | 58 ++
 drivers/gpu/drm/i915/intel_lrc.h   | 10 -
 3 files changed, 71 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index 59b9349012e3..36177546f68b 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1421,15 +1421,12 @@ void intel_engine_dump(struct intel_engine_cs *engine,
   struct drm_printer *m,
   const char *header, ...)
 {
-   const int MAX_REQUESTS_TO_SHOW = 8;
struct intel_breadcrumbs * const b = &engine->breadcrumbs;
-   const struct intel_engine_execlists * const execlists = 
&engine->execlists;
struct i915_gpu_error * const error = &engine->i915->gpu_error;
-   struct i915_request *rq, *last;
+   struct i915_request *rq;
intel_wakeref_t wakeref;
unsigned long flags;
struct rb_node *rb;
-   int count;
 
if (header) {
va_list ap;
@@ -1493,52 +1490,9 @@ void intel_engine_dump(struct intel_engine_cs *engine,
drm_printf(m, "\tDevice is asleep; skipping register dump\n");
}
 
-   local_irq_save(flags);
-   spin_lock(&engine->timeline.lock);
-
-   last = NULL;
-   count = 0;
-   list_for_each_entry(rq, &engine->timeline.requests, link) {
-   if (count++ < MAX_REQUESTS_TO_SHOW - 1)
-   print_request(m, rq, "\t\tE ");
-   else
-   last = rq;
-   }
-   if (last) {
-   if (count > MAX_REQUESTS_TO_SHOW) {
-   drm_printf(m,
-  "\t\t...skipping %d executing requests...\n",
-  count - MAX_REQUESTS_TO_SHOW);
-   }
-   print_request(m, last, "\t\tE ");
-   }
-
-   last = NULL;
-   count = 0;
-   drm_printf(m, "\t\tQueue priority: %d\n", execlists->queue_priority);
-   for (rb = rb_first_cached(&execlists->queue); rb; rb = rb_next(rb)) {
-   struct i915_priolist *p = rb_entry(rb, typeof(*p), node);
-   int i;
-
-   priolist_for_each_request(rq, p, i) {
-   if (count++ < MAX_REQUESTS_TO_SHOW - 1)
-   print_request(m, rq, "\t\tQ ");
-   else
-   last = rq;
-   }
-   }
-   if (last) {
-   if (count > MAX_REQUESTS_TO_SHOW) {
-   drm_printf(m,
-  "\t\t...skipping %d queued requests...\n",
-  count - MAX_REQUESTS_TO_SHOW);
-   }
-   print_request(m, last, "\t\tQ ");
-   }
-
-   spin_unlock(&engine->timeline.lock);
+   intel_execlists_show_requests(engine, m, print_request, 8);
 
-   spin_lock(&b->rb_lock);
+   spin_lock_irqsave(&b->rb_lock, flags);
for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) {
struct intel_wait *w = rb_entry(rb, typeof(*w), node);
 
@@ -1547,8 +1501,7 @@ void intel_engine_dump(struct intel_engine_cs *engine,
   task_state_to_char(w->tsk),
   w->seqno);
}
-   spin_unlock(&b->rb_lock);
-   local_irq_restore(flags);
+   spin_unlock_irqrestore(&b->rb_lock, flags);
 
drm_printf(m, "HWSP:\n");
hexdump(m, engine->status_page.page_addr, PAGE_SIZE);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 9bdd7ec12991..bcc5e0d88130 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -2676,6 +2676,64 @@ void intel_lr_context_resume(struct drm_i915_private 
*i915)
}
 }
 
+void intel_execlists_show_requests(struct intel_engine_cs *engine,
+  struct drm_printer *m,
+  void (*show_request)(struct drm_printer *m,
+   struct i915_request *rq,
+   const char *prefix),
+  unsigned int max)
+{
+   const struct intel_engine_execlists *execlists = &engine->execlists;
+   struct i915_request *rq, *last;
+   unsigned long flags;
+   unsigned int count;
+   struct rb_node *rb;
+
+   spin_lock_irqsave(&engine->timeline.lock, flags);
+
+   last = NULL;
+   count = 0;
+   list_for_each_entry(rq, &engine->timeline.requests, link) {
+   if (count++ < max - 1)
+   show_request(m, rq, "\t\tE ");
+   else

[Intel-gfx] [PATCH 29/39] drm/i915: Use b->irq_enable() as predicate for mock engine

2019-01-02 Thread Chris Wilson
References: d4ccceb05591 ("drm/i915/icl: Ringbuffer interrupt handling")
Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/intel_breadcrumbs.c | 39 
 drivers/gpu/drm/i915/intel_engine_cs.c   | 11 ++
 drivers/gpu/drm/i915/intel_ringbuffer.h  |  1 -
 drivers/gpu/drm/i915/selftests/mock_engine.c |  1 -
 4 files changed, 20 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c 
b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 4ed7105d7ff5..7b517bf83507 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -158,6 +158,9 @@ static void intel_breadcrumbs_fake_irq(struct timer_list *t)
 
 static void irq_enable(struct intel_engine_cs *engine)
 {
+   if (!engine->irq_enable)
+   return;
+
/*
 * FIXME: Ideally we want this on the API boundary, but for the
 * sake of testing with mock breadcrumbs (no HW so unable to
@@ -167,21 +170,20 @@ static void irq_enable(struct intel_engine_cs *engine)
GEM_BUG_ON(!intel_irqs_enabled(engine->i915));
 
/* Caller disables interrupts */
-   if (engine->irq_enable) {
-   spin_lock(&engine->i915->irq_lock);
-   engine->irq_enable(engine);
-   spin_unlock(&engine->i915->irq_lock);
-   }
+   spin_lock(&engine->i915->irq_lock);
+   engine->irq_enable(engine);
+   spin_unlock(&engine->i915->irq_lock);
 }
 
 static void irq_disable(struct intel_engine_cs *engine)
 {
+   if (!engine->irq_disable)
+   return;
+
/* Caller disables interrupts */
-   if (engine->irq_disable) {
-   spin_lock(&engine->i915->irq_lock);
-   engine->irq_disable(engine);
-   spin_unlock(&engine->i915->irq_lock);
-   }
+   spin_lock(&engine->i915->irq_lock);
+   engine->irq_disable(engine);
+   spin_unlock(&engine->i915->irq_lock);
 }
 
 void __intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine)
@@ -293,25 +295,16 @@ static bool __intel_breadcrumbs_enable_irq(struct 
intel_breadcrumbs *b)
if (b->irq_armed)
return false;
 
-   /* The breadcrumb irq will be disarmed on the interrupt after the
+   /*
+* The breadcrumb irq will be disarmed on the interrupt after the
 * waiters are signaled. This gives us a single interrupt window in
 * which we can add a new waiter and avoid the cost of re-enabling
 * the irq.
 */
b->irq_armed = true;
 
-   if (I915_SELFTEST_ONLY(b->mock)) {
-   /* For our mock objects we want to avoid interaction
-* with the real hardware (which is not set up). So
-* we simply pretend we have enabled the powerwell
-* and the irq, and leave it up to the mock
-* implementation to call intel_engine_wakeup()
-* itself when it wants to simulate a user interrupt,
-*/
-   return true;
-   }
-
-   /* Since we are waiting on a request, the GPU should be busy
+   /*
+* Since we are waiting on a request, the GPU should be busy
 * and should have its own rpm reference. This is tracked
 * by i915->gt.awake, we can forgo holding our own wakref
 * for the interrupt as before i915->gt.awake is released (when
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index 36177546f68b..7b80a087cc32 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -917,6 +917,9 @@ static bool ring_is_idle(struct intel_engine_cs *engine)
intel_wakeref_t wakeref;
bool idle = true;
 
+   if (I915_SELFTEST_ONLY(!engine->mmio_base))
+   return true;
+
/* If the whole device is asleep, the engine must be idle */
wakeref = intel_runtime_pm_get_if_in_use(dev_priv);
if (!wakeref)
@@ -955,9 +958,6 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
if (!intel_engine_signaled(engine, intel_engine_last_submit(engine)))
return false;
 
-   if (I915_SELFTEST_ONLY(engine->breadcrumbs.mock))
-   return true;
-
/* Waiting to drain ELSP? */
if (READ_ONCE(engine->execlists.active)) {
struct tasklet_struct *t = &engine->execlists.tasklet;
@@ -983,10 +983,7 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
return false;
 
/* Ring stopped? */
-   if (!ring_is_idle(engine))
-   return false;
-
-   return true;
+   return ring_is_idle(engine);
 }
 
 bool intel_engines_are_idle(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h 
b/drivers/gpu/drm/i915/intel_ringbuffer.h
index bedb25d27469..452c13f3dded 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/int

[Intel-gfx] [PATCH 36/39] drm/i915: Allocate a status page for each timeline

2019-01-02 Thread Chris Wilson
Allocate a page for use as a status page by a group of timelines, as we
only need a dword of storage for each (rounded up to the cacheline for
safety) we can pack multiple timelines into the same page. Each timeline
will then be able to track its own HW seqno.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_drv.h   |   4 +
 drivers/gpu/drm/i915/i915_timeline.c  | 149 ++-
 drivers/gpu/drm/i915/i915_timeline.h  |  16 +-
 drivers/gpu/drm/i915/intel_engine_cs.c|  11 +-
 drivers/gpu/drm/i915/intel_lrc.c  |  20 +-
 drivers/gpu/drm/i915/intel_ringbuffer.c   |   4 +-
 drivers/gpu/drm/i915/intel_ringbuffer.h   |   2 +-
 .../drm/i915/selftests/i915_live_selftests.h  |   1 +
 .../drm/i915/selftests/i915_mock_selftests.h  |   2 +-
 .../gpu/drm/i915/selftests/i915_timeline.c| 373 +-
 drivers/gpu/drm/i915/selftests/mock_engine.c  |  11 +-
 11 files changed, 569 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e7c35d84aeeb..435e26e44d13 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1960,6 +1960,10 @@ struct drm_i915_private {
struct mutex timeline_lock;
struct list_head timelines;
 
+   /* Pack multiple timelines' seqnos into the same page */
+   struct i915_vma *timeline_hwsp;
+   u64 timeline_free;
+
struct list_head active_rings;
struct list_head closed_vma;
u32 active_requests;
diff --git a/drivers/gpu/drm/i915/i915_timeline.c 
b/drivers/gpu/drm/i915/i915_timeline.c
index 60658edad00d..640adea61f18 100644
--- a/drivers/gpu/drm/i915/i915_timeline.c
+++ b/drivers/gpu/drm/i915/i915_timeline.c
@@ -9,10 +9,85 @@
 #include "i915_timeline.h"
 #include "i915_syncmap.h"
 
-void i915_timeline_init(struct drm_i915_private *i915,
-   struct i915_timeline *timeline,
-   const char *name)
+#define NBITS BITS_PER_TYPE(typeof(i915->gt.timeline_free))
+
+static int find_first_cacheline(struct drm_i915_private *i915)
+{
+   return find_first_bit((unsigned long *)&i915->gt.timeline_free, NBITS);
+}
+
+static int alloc_hwsp(struct i915_timeline *timeline)
+{
+   struct drm_i915_private *i915 = timeline->i915;
+   struct i915_vma *vma;
+   void *vaddr;
+   int offset;
+
+   mutex_lock(&i915->gt.timeline_lock);
+
+restart:
+   offset = find_first_cacheline(i915);
+   if (offset == NBITS && i915->gt.timeline_hwsp) {
+   i915_vma_put(i915->gt.timeline_hwsp);
+   i915->gt.timeline_hwsp = NULL;
+   }
+
+   vma = i915->gt.timeline_hwsp;
+   if (!vma) {
+   struct drm_i915_gem_object *bo;
+
+   /* Drop the lock before allocations */
+   mutex_unlock(&i915->gt.timeline_lock);
+
+   BUILD_BUG_ON(NBITS * CACHELINE_BYTES > PAGE_SIZE);
+   bo = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(bo))
+   return PTR_ERR(bo);
+
+   i915_gem_object_set_cache_level(bo, I915_CACHE_LLC);
+
+   vma = i915_vma_instance(bo, &i915->ggtt.vm, NULL);
+   if (IS_ERR(vma))
+   return PTR_ERR(vma);
+
+   mutex_lock(&i915->gt.timeline_lock);
+   if (i915->gt.timeline_hwsp) {
+   i915_gem_object_put(bo);
+   goto restart;
+   }
+
+   i915->gt.timeline_hwsp = vma;
+   i915->gt.timeline_free = ~0ull;
+   offset = 0;
+   }
+
+   i915->gt.timeline_free &= ~BIT_ULL(offset);
+
+   timeline->hwsp_ggtt = i915_vma_get(vma);
+   timeline->hwsp_offset = offset * CACHELINE_BYTES;
+
+   mutex_unlock(&i915->gt.timeline_lock);
+
+   vaddr = i915_gem_object_pin_map(vma->obj, I915_MAP_WB);
+   if (IS_ERR(vaddr)) { /* leak the cacheline, but will clean up later */
+   i915_vma_put(vma);
+   return PTR_ERR(vaddr);
+   }
+
+   timeline->hwsp_seqno =
+   memset(vaddr + timeline->hwsp_offset,
+  0,
+  sizeof(*timeline->hwsp_seqno));
+
+   return 0;
+}
+
+int i915_timeline_init(struct drm_i915_private *i915,
+  struct i915_timeline *timeline,
+  const char *name)
 {
+   int err;
+
/*
 * Ideally we want a set of engines on a single leaf as we expect
 * to mostly be tracking synchronisation between engines. It is not
@@ -23,10 +98,11 @@ void i915_timeline_init(struct drm_i915_private *i915,
 
timeline->i915 = i915;
timeline->name = name;
+   timeline->pin_count = 0;
 
-   mutex_lock(&i915->gt.timeline_lock);
-   list_add(&timeline->link, &i915->gt.timelines);
-   mutex_unlock(&i915->gt.timeline

[Intel-gfx] [PATCH 34/39] drm/i915: Introduce concept of per-timeline (context) HWSP

2019-01-02 Thread Chris Wilson
Supplement the per-engine HWSP with a per-timeline HWSP. That is a
per-request pointer through which we can check a local seqno,
abstracting away the presumption of a global seqno. In this first step,
we point each request back into the engine's HWSP so everything
continues to work with the global timeline.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_request.c | 16 +++-
 drivers/gpu/drm/i915/i915_request.h | 16 +---
 drivers/gpu/drm/i915/intel_lrc.c|  9 ++---
 3 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_request.c 
b/drivers/gpu/drm/i915/i915_request.c
index c467392f62d7..e481b48e07b5 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -182,10 +182,11 @@ static void free_capture_list(struct i915_request 
*request)
 static void __retire_engine_request(struct intel_engine_cs *engine,
struct i915_request *rq)
 {
-   GEM_TRACE("%s(%s) fence %llx:%lld, global=%d, current %d\n",
+   GEM_TRACE("%s(%s) fence %llx:%lld, global=%d, current %d:%d\n",
  __func__, engine->name,
  rq->fence.context, rq->fence.seqno,
  rq->global_seqno,
+ i915_request_hwsp(rq),
  intel_engine_get_seqno(engine));
 
GEM_BUG_ON(!i915_request_completed(rq));
@@ -244,10 +245,11 @@ static void i915_request_retire(struct i915_request 
*request)
 {
struct i915_gem_active *active, *next;
 
-   GEM_TRACE("%s fence %llx:%lld, global=%d, current %d\n",
+   GEM_TRACE("%s fence %llx:%lld, global=%d, current %d:%d\n",
  request->engine->name,
  request->fence.context, request->fence.seqno,
  request->global_seqno,
+ i915_request_hwsp(request),
  intel_engine_get_seqno(request->engine));
 
lockdep_assert_held(&request->i915->drm.struct_mutex);
@@ -307,10 +309,11 @@ void i915_request_retire_upto(struct i915_request *rq)
struct intel_ring *ring = rq->ring;
struct i915_request *tmp;
 
-   GEM_TRACE("%s fence %llx:%lld, global=%d, current %d\n",
+   GEM_TRACE("%s fence %llx:%lld, global=%d, current %d:%d\n",
  rq->engine->name,
  rq->fence.context, rq->fence.seqno,
  rq->global_seqno,
+ i915_request_hwsp(rq),
  intel_engine_get_seqno(rq->engine));
 
lockdep_assert_held(&rq->i915->drm.struct_mutex);
@@ -348,10 +351,11 @@ void __i915_request_submit(struct i915_request *request)
struct intel_engine_cs *engine = request->engine;
u32 seqno;
 
-   GEM_TRACE("%s fence %llx:%lld -> global=%d, current %d\n",
+   GEM_TRACE("%s fence %llx:%lld -> global=%d, current %d:%d\n",
  engine->name,
  request->fence.context, request->fence.seqno,
  engine->timeline.seqno + 1,
+ i915_request_hwsp(request),
  intel_engine_get_seqno(engine));
 
GEM_BUG_ON(!irqs_disabled());
@@ -398,10 +402,11 @@ void __i915_request_unsubmit(struct i915_request *request)
 {
struct intel_engine_cs *engine = request->engine;
 
-   GEM_TRACE("%s fence %llx:%lld <- global=%d, current %d\n",
+   GEM_TRACE("%s fence %llx:%lld <- global=%d, current %d:%d\n",
  engine->name,
  request->fence.context, request->fence.seqno,
  request->global_seqno,
+ i915_request_hwsp(request),
  intel_engine_get_seqno(engine));
 
GEM_BUG_ON(!irqs_disabled());
@@ -585,6 +590,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct 
i915_gem_context *ctx)
rq->ring = ce->ring;
rq->timeline = ce->ring->timeline;
GEM_BUG_ON(rq->timeline == &engine->timeline);
+   rq->hwsp_seqno = &engine->status_page.page_addr[I915_GEM_HWS_INDEX];
 
spin_lock_init(&rq->lock);
dma_fence_init(&rq->fence,
diff --git a/drivers/gpu/drm/i915/i915_request.h 
b/drivers/gpu/drm/i915/i915_request.h
index d014b0605445..e2b209a26a8e 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -130,6 +130,8 @@ struct i915_request {
struct i915_sched_node sched;
struct i915_dependency dep;
 
+   const u32 *hwsp_seqno;
+
/**
 * GEM sequence number associated with this request on the
 * global execution timeline. It is zero when the request is not
@@ -280,11 +282,6 @@ long i915_request_wait(struct i915_request *rq,
 #define I915_WAIT_ALL  BIT(3) /* used by i915_gem_object_wait() */
 #define I915_WAIT_FOR_IDLE_BOOST BIT(4)
 
-static inline bool intel_engine_has_started(struct intel_engine_cs *engine,
-   u32 seqno);
-static inline bool intel_engine_has_completed(struct intel_engine_cs *engine,
-   

[Intel-gfx] [PATCH 32/39] drm/i915: Remove the intel_engine_notify tracepoint

2019-01-02 Thread Chris Wilson
The global seqno is defunct and so we have no meaningful indicator of
forward progress for an engine. You need to listen to the request
signaling tracepoints instead.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_irq.c   |  2 --
 drivers/gpu/drm/i915/i915_trace.h | 25 -
 2 files changed, 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index d1727bcac776..46c742d71610 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1211,8 +1211,6 @@ static void notify_ring(struct intel_engine_cs *engine)
wake_up_process(tsk);
 
rcu_read_unlock();
-
-   trace_intel_engine_notify(engine, wait);
 }
 
 static void vlv_c0_read(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/i915_trace.h 
b/drivers/gpu/drm/i915/i915_trace.h
index 5cf378936b05..4b35b0b9462c 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -751,31 +751,6 @@ trace_i915_request_out(struct i915_request *rq)
 #endif
 #endif
 
-TRACE_EVENT(intel_engine_notify,
-   TP_PROTO(struct intel_engine_cs *engine, bool waiters),
-   TP_ARGS(engine, waiters),
-
-   TP_STRUCT__entry(
-__field(u32, dev)
-__field(u16, class)
-__field(u16, instance)
-__field(u32, seqno)
-__field(bool, waiters)
-),
-
-   TP_fast_assign(
-  __entry->dev = engine->i915->drm.primary->index;
-  __entry->class = engine->uabi_class;
-  __entry->instance = engine->instance;
-  __entry->seqno = intel_engine_get_seqno(engine);
-  __entry->waiters = waiters;
-  ),
-
-   TP_printk("dev=%u, engine=%u:%u, seqno=%u, waiters=%u",
- __entry->dev, __entry->class, __entry->instance,
- __entry->seqno, __entry->waiters)
-);
-
 DEFINE_EVENT(i915_request, i915_request_retire,
TP_PROTO(struct i915_request *rq),
TP_ARGS(rq)
-- 
2.20.1

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


[Intel-gfx] [PATCH 38/39] drm/i915: Identify active requests

2019-01-02 Thread Chris Wilson
To allow requests to forgo a common execution timeline, one question we
need to be able to answer is "is this request running?". To track
whether a request has started on HW, we can emit a breadcrumb at the
beginning of the request and check its timeline's HWSP to see if the
breadcrumb has advanced past the start of this request. (This is in
contrast to the global timeline where we need only ask if we are on the
global timeline and if the timeline has advanced past the end of the
previous request.)

There is still confusion from a preempted request, which has already
started but relinquished the HW to a high priority request. For the
common case, this discrepancy should be negligible. However, for
identification of hung requests, knowing which one was running at the
time of the hang will be much more important.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_request.c |  8 +++
 drivers/gpu/drm/i915/i915_request.h |  1 +
 drivers/gpu/drm/i915/intel_engine_cs.c  |  4 +++-
 drivers/gpu/drm/i915/intel_lrc.c| 21 +++
 drivers/gpu/drm/i915/intel_ringbuffer.c | 28 +
 5 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_request.c 
b/drivers/gpu/drm/i915/i915_request.c
index ec4dbc67ef9e..6ab72679c44c 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -597,7 +597,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct 
i915_gem_context *ctx)
   &i915_fence_ops,
   &rq->lock,
   rq->timeline->fence_context,
-  timeline_get_seqno(rq->timeline));
+  2 * timeline_get_seqno(rq->timeline));
 
/* We bump the ref for the fence chain */
i915_sw_fence_init(&i915_request_get(rq)->submit, submit_notify);
@@ -645,7 +645,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct 
i915_gem_context *ctx)
rq->infix = rq->ring->emit; /* end of header; start of user payload */
 
/* Check that we didn't interrupt ourselves with a new request */
-   GEM_BUG_ON(rq->timeline->seqno != rq->fence.seqno);
+   GEM_BUG_ON(2 * rq->timeline->seqno != rq->fence.seqno);
return rq;
 
 err_unwind:
@@ -860,7 +860,7 @@ void i915_request_add(struct i915_request *request)
 * our i915_request_alloc() and called __i915_request_add() before
 * us, the timeline will hold its seqno which is later than ours.
 */
-   GEM_BUG_ON(timeline->seqno != request->fence.seqno);
+   GEM_BUG_ON(2 * timeline->seqno != request->fence.seqno);
 
/*
 * To ensure that this call will not fail, space for its emissions
@@ -903,7 +903,7 @@ void i915_request_add(struct i915_request *request)
list_add_tail(&request->link, &timeline->requests);
spin_unlock_irq(&timeline->lock);
 
-   GEM_BUG_ON(timeline->seqno != request->fence.seqno);
+   GEM_BUG_ON(2 * timeline->seqno != request->fence.seqno);
i915_gem_active_set(&timeline->last_request, request);
 
list_add_tail(&request->ring_link, &ring->request_list);
diff --git a/drivers/gpu/drm/i915/i915_request.h 
b/drivers/gpu/drm/i915/i915_request.h
index 344e52b53ccd..084d174ba83b 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -311,6 +311,7 @@ static inline void i915_request_fake_complete(const struct 
i915_request *rq)
  */
 static inline bool i915_request_started(const struct i915_request *rq)
 {
+   /* Remember: started but may have since been preempted! */
return i915_seqno_passed(i915_request_hwsp(rq), rq->fence.seqno - 1);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index 8c30fc91a92e..f894da66aba8 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1234,7 +1234,9 @@ static void print_request(struct drm_printer *m,
drm_printf(m, "%s%x%s [%llx:%llx]%s @ %dms: %s\n",
   prefix,
   rq->global_seqno,
-  i915_request_completed(rq) ? "!" : "",
+  i915_request_completed(rq) ? "!" :
+  i915_request_started(rq) ? "*" :
+  "",
   rq->fence.context, rq->fence.seqno,
   buf,
   jiffies_to_msecs(jiffies - rq->emitted_jiffies),
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 1c1dfc87ff81..9a9768258efb 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1259,6 +1259,23 @@ execlists_context_pin(struct intel_engine_cs *engine,
return __execlists_context_pin(engine, ctx, ce);
 }
 
+static int emit_initial_breadcrumb(struct i915_request *rq)
+{
+   u32 *cs;
+
+   cs = intel_ring_begin(rq, 4);
+   if (IS_ERR(cs))
+   return PTR_ERR(cs);
+
+ 

[Intel-gfx] [PATCH 33/39] drm/i915: Move list of timelines under its own lock

2019-01-02 Thread Chris Wilson
Currently, the list of timelines is serialised by the struct_mutex, but
to alleviate difficulties with using that mutex in future, move the
list management under its own dedicated mutex.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_drv.h   |  1 +
 drivers/gpu/drm/i915/i915_gem.c   | 89 +--
 drivers/gpu/drm/i915/i915_timeline.c  | 27 +-
 drivers/gpu/drm/i915/i915_timeline.h  |  3 +
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  7 +-
 .../gpu/drm/i915/selftests/mock_timeline.c|  3 +-
 6 files changed, 76 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 70289b2447bb..e7c35d84aeeb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1957,6 +1957,7 @@ struct drm_i915_private {
void (*resume)(struct drm_i915_private *);
void (*cleanup_engine)(struct intel_engine_cs *engine);
 
+   struct mutex timeline_lock;
struct list_head timelines;
 
struct list_head active_rings;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e42ad20d6328..ae9ccf5f6019 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3373,33 +3373,6 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, 
struct drm_file *file)
return ret;
 }
 
-static long wait_for_timeline(struct i915_timeline *tl,
- unsigned int flags, long timeout)
-{
-   struct i915_request *rq;
-
-   rq = i915_gem_active_get_unlocked(&tl->last_request);
-   if (!rq)
-   return timeout;
-
-   /*
-* "Race-to-idle".
-*
-* Switching to the kernel context is often used a synchronous
-* step prior to idling, e.g. in suspend for flushing all
-* current operations to memory before sleeping. These we
-* want to complete as quickly as possible to avoid prolonged
-* stalls, so allow the gpu to boost to maximum clocks.
-*/
-   if (flags & I915_WAIT_FOR_IDLE_BOOST)
-   gen6_rps_boost(rq, NULL);
-
-   timeout = i915_request_wait(rq, flags, timeout);
-   i915_request_put(rq);
-
-   return timeout;
-}
-
 static int wait_for_engines(struct drm_i915_private *i915)
 {
if (wait_for(intel_engines_are_idle(i915), I915_IDLE_ENGINES_TIMEOUT)) {
@@ -3416,6 +3389,8 @@ static int wait_for_engines(struct drm_i915_private *i915)
 int i915_gem_wait_for_idle(struct drm_i915_private *i915,
   unsigned int flags, long timeout)
 {
+   struct i915_timeline *tl;
+
GEM_TRACE("flags=%x (%s), timeout=%ld%s\n",
  flags, flags & I915_WAIT_LOCKED ? "locked" : "unlocked",
  timeout, timeout == MAX_SCHEDULE_TIMEOUT ? " (forever)" : "");
@@ -3424,17 +3399,45 @@ int i915_gem_wait_for_idle(struct drm_i915_private 
*i915,
if (!READ_ONCE(i915->gt.awake))
return 0;
 
+   mutex_lock(&i915->gt.timeline_lock);
+   list_for_each_entry(tl, &i915->gt.timelines, link) {
+   struct i915_request *rq;
+
+   rq = i915_gem_active_get_unlocked(&tl->last_request);
+   if (!rq)
+   continue;
+
+   mutex_unlock(&i915->gt.timeline_lock);
+
+   /*
+* "Race-to-idle".
+*
+* Switching to the kernel context is often used a synchronous
+* step prior to idling, e.g. in suspend for flushing all
+* current operations to memory before sleeping. These we
+* want to complete as quickly as possible to avoid prolonged
+* stalls, so allow the gpu to boost to maximum clocks.
+*/
+   if (flags & I915_WAIT_FOR_IDLE_BOOST)
+   gen6_rps_boost(rq, NULL);
+
+   timeout = i915_request_wait(rq, flags, timeout);
+   i915_request_put(rq);
+   if (timeout < 0)
+   return timeout;
+
+   mutex_lock(&i915->gt.timeline_lock);
+
+   /* restart after dropping the lock */
+   tl = list_entry(&i915->gt.timelines, typeof(*tl), link);
+   }
+   mutex_unlock(&i915->gt.timeline_lock);
+
if (flags & I915_WAIT_LOCKED) {
-   struct i915_timeline *tl;
int err;
 
lockdep_assert_held(&i915->drm.struct_mutex);
 
-   list_for_each_entry(tl, &i915->gt.timelines, link) {
-   timeout = wait_for_timeline(tl, flags, timeout);
-   if (timeout < 0)
-   return timeout;
-   }
if (GEM_SHOW_DEBUG() && !timeout) {
/* Presume that timeout was non-zero to begin with! */
dev_warn(&

[Intel-gfx] [PATCH 35/39] drm/i915: Enlarge vma->pin_count

2019-01-02 Thread Chris Wilson
Previously we only accommodated having a vma pinned by a small number of
users, with the maximum being pinned for use by the display engine. As
such, we used a small bitfield only large enough to allow the vma to
be pinned twice (for back/front buffers) in each scanout plane. Keeping
the maximum permissible pin_count small allows us to quickly catch a
potential leak. However, as we want to split a 4096B page into 64
different cachelines and pin each cacheline for use by a different
timeline, we will exceed the current maximum permissible vma->pin_count
and so time has come to enlarge it.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_gem_gtt.h | 26 +-
 drivers/gpu/drm/i915/i915_vma.h | 28 +---
 2 files changed, 22 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index ac11f2bce2d5..10da341cc038 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -634,19 +634,19 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
 
 /* Flags used by pin/bind&friends. */
 #define PIN_NONBLOCK   BIT_ULL(0)
-#define PIN_MAPPABLE   BIT_ULL(1)
-#define PIN_ZONE_4GBIT_ULL(2)
-#define PIN_NONFAULT   BIT_ULL(3)
-#define PIN_NOEVICTBIT_ULL(4)
-
-#define PIN_MBZBIT_ULL(5) /* I915_VMA_PIN_OVERFLOW */
-#define PIN_GLOBAL BIT_ULL(6) /* I915_VMA_GLOBAL_BIND */
-#define PIN_USER   BIT_ULL(7) /* I915_VMA_LOCAL_BIND */
-#define PIN_UPDATE BIT_ULL(8)
-
-#define PIN_HIGH   BIT_ULL(9)
-#define PIN_OFFSET_BIASBIT_ULL(10)
-#define PIN_OFFSET_FIXED   BIT_ULL(11)
+#define PIN_NONFAULT   BIT_ULL(1)
+#define PIN_NOEVICTBIT_ULL(2)
+#define PIN_MAPPABLE   BIT_ULL(3)
+#define PIN_ZONE_4GBIT_ULL(4)
+#define PIN_HIGH   BIT_ULL(5)
+#define PIN_OFFSET_BIASBIT_ULL(6)
+#define PIN_OFFSET_FIXED   BIT_ULL(7)
+
+#define PIN_MBZBIT_ULL(8) /* I915_VMA_PIN_OVERFLOW */
+#define PIN_GLOBAL BIT_ULL(9) /* I915_VMA_GLOBAL_BIND */
+#define PIN_USER   BIT_ULL(10) /* I915_VMA_LOCAL_BIND */
+#define PIN_UPDATE BIT_ULL(11)
+
 #define PIN_OFFSET_MASK(-I915_GTT_PAGE_SIZE)
 
 #endif
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 7252abc73d3e..266b226ebef2 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -70,30 +70,20 @@ struct i915_vma {
 */
unsigned int open_count;
unsigned long flags;
-   /**
-* How many users have pinned this object in GTT space. The following
-* users can each hold at most one reference: pwrite/pread, execbuffer
-* (objects are not allowed multiple times for the same batchbuffer),
-* and the framebuffer code. When switching/pageflipping, the
-* framebuffer code has at most two buffers pinned per crtc.
-*
-* In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3
-* bits with absolutely no headroom. So use 4 bits.
-*/
-#define I915_VMA_PIN_MASK 0xf
-#define I915_VMA_PIN_OVERFLOW  BIT(5)
+#define I915_VMA_PIN_MASK 0xff
+#define I915_VMA_PIN_OVERFLOW  BIT(8)
 
/** Flags and address space this VMA is bound to */
-#define I915_VMA_GLOBAL_BIND   BIT(6)
-#define I915_VMA_LOCAL_BINDBIT(7)
+#define I915_VMA_GLOBAL_BIND   BIT(9)
+#define I915_VMA_LOCAL_BINDBIT(10)
 #define I915_VMA_BIND_MASK (I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND | 
I915_VMA_PIN_OVERFLOW)
 
-#define I915_VMA_GGTT  BIT(8)
-#define I915_VMA_CAN_FENCE BIT(9)
-#define I915_VMA_CLOSEDBIT(10)
-#define I915_VMA_USERFAULT_BIT 11
+#define I915_VMA_GGTT  BIT(11)
+#define I915_VMA_CAN_FENCE BIT(12)
+#define I915_VMA_CLOSEDBIT(13)
+#define I915_VMA_USERFAULT_BIT 14
 #define I915_VMA_USERFAULT BIT(I915_VMA_USERFAULT_BIT)
-#define I915_VMA_GGTT_WRITEBIT(12)
+#define I915_VMA_GGTT_WRITEBIT(15)
 
unsigned int active_count;
struct rb_root active;
-- 
2.20.1

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


[Intel-gfx] [PULL] topic/drmp-cleanup for drm-misc-next and drm-intel-next-queued

2019-01-02 Thread Jani Nikula

Hi Sean, Maarten & Maxime -

I embarked on removing drmP.h includes from i915, but that requires a
bunch of drm header cleanup to add relevant includes and forward
declarations. Due to the timing, propagating the patches back to i915
would take eons, so Daniel suggested a topic branch to be merged both to
drm-misc-next and drm-intel-next-queued. So here it is, with $(git
merge-base drm-misc-next drm-intel-next-queued) as the starting point.

The topic branch has been part of drm-tip since, uh, last year, but I
did just force push it to update the commit messages to reflect
Laurent's review. No code changes.

I'll merge the same thing to i915 after it's been pulled to
drm-misc-next, and with this, I should be able to get rid of all drmP.h
includes in i915.


BR,
Jani.

The following changes since commit b4bf44d2dcbd6c35d9651bc6286e4940b8b3df95:

  drm/i915: Update DRIVER_DATE to 20181122 (2018-11-22 16:49:47 +0200)

are available in the git repository at:

  git://anongit.freedesktop.org/drm/drm-intel tags/topic/drmp-cleanup-2019-01-02

for you to fetch changes up to dd7ece7f6e220e4d1a2a8ba4c42622d7d73e6376:

  drm: forward declare struct drm_file in drm_syncobj.h (2019-01-02 11:38:08 
+0200)


Make some drm headers self-contained with includes and forward declarations


Jani Nikula (5):
  drm: un-inline drm_legacy_findmap()
  drm: include kernel.h and agp_backend.h from intel-gtt.h
  drm: include idr.h from drm_file.h
  drm: include types.h from drm_hdcp.h
  drm: forward declare struct drm_file in drm_syncobj.h

 drivers/gpu/drm/drm_bufs.c | 11 +++
 include/drm/drm_file.h |  1 +
 include/drm/drm_hdcp.h |  2 ++
 include/drm/drm_legacy.h   | 14 --
 include/drm/drm_syncobj.h  |  4 +++-
 include/drm/intel-gtt.h|  3 +++
 6 files changed, 24 insertions(+), 11 deletions(-)

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


[Intel-gfx] [PATCH 13/39] drm/i915: Combined gt.awake/gt.power wakerefs

2019-01-02 Thread Chris Wilson
As the GT_IRQ power domain implies a wakeref, we can use it inplace of
our existing redundant rpm grab.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_drv.h  |  1 -
 drivers/gpu/drm/i915/i915_gem.c  | 11 ---
 drivers/gpu/drm/i915/intel_lrc.c |  2 +-
 drivers/gpu/drm/i915/selftests/mock_gem_device.c |  1 +
 4 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 45bdc8252ac2..3e9aee4bad65 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1971,7 +1971,6 @@ struct drm_i915_private {
 * is a slight delay before we do so.
 */
intel_wakeref_t awake;
-   intel_wakeref_t power;
 
/**
 * The number of times we have woken up.
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 711eba57afda..c001889eaa36 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -177,9 +177,7 @@ static u32 __i915_gem_park(struct drm_i915_private *i915)
if (INTEL_GEN(i915) >= 6)
gen6_rps_idle(i915);
 
-   intel_display_power_put(i915, POWER_DOMAIN_GT_IRQ, i915->gt.power);
-
-   intel_runtime_pm_put(i915, wakeref);
+   intel_display_power_put(i915, POWER_DOMAIN_GT_IRQ, wakeref);
 
return i915->gt.epoch;
 }
@@ -204,13 +202,11 @@ void i915_gem_unpark(struct drm_i915_private *i915)
 
lockdep_assert_held(&i915->drm.struct_mutex);
GEM_BUG_ON(!i915->gt.active_requests);
+   assert_rpm_wakelock_held(i915);
 
if (i915->gt.awake)
return;
 
-   i915->gt.awake = intel_runtime_pm_get_noresume(i915);
-   GEM_BUG_ON(!i915->gt.awake);
-
/*
 * It seems that the DMC likes to transition between the DC states a lot
 * when there are no connected displays (no active power domains) during
@@ -222,7 +218,8 @@ void i915_gem_unpark(struct drm_i915_private *i915)
 * Work around it by grabbing a GT IRQ power domain whilst there is any
 * GT activity, preventing any DC state transitions.
 */
-   i915->gt.power = intel_display_power_get(i915, POWER_DOMAIN_GT_IRQ);
+   i915->gt.awake = intel_display_power_get(i915, POWER_DOMAIN_GT_IRQ);
+   GEM_BUG_ON(!i915->gt.awake);
 
if (unlikely(++i915->gt.epoch == 0)) /* keep 0 as invalid */
i915->gt.epoch = 1;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index ff08e5d600d4..9d5dfd0b4496 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1046,7 +1046,7 @@ static void execlists_submission_tasklet(unsigned long 
data)
 
GEM_TRACE("%s awake?=%d, active=%x\n",
  engine->name,
- engine->i915->gt.awake,
+ !!engine->i915->gt.awake,
  engine->execlists.active);
 
spin_lock_irqsave(&engine->timeline.lock, flags);
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c 
b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 0eb283e7fc96..aa4ddae94aca 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -164,6 +164,7 @@ struct drm_i915_private *mock_gem_device(void)
pm_runtime_dont_use_autosuspend(&pdev->dev);
if (pm_runtime_enabled(&pdev->dev))
WARN_ON(pm_runtime_get_sync(&pdev->dev));
+   disable_rpm_wakeref_asserts(i915);
 
err = drm_dev_init(&i915->drm, &mock_driver, &pdev->dev);
if (err) {
-- 
2.20.1

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


[Intel-gfx] [PATCH 07/39] drm/i915: Report the number of closed vma held by each context in debugfs

2019-01-02 Thread Chris Wilson
Include the total size of closed vma when reporting the per_ctx_stats of
debugfs/i915_gem_objects.

Whilst adjusting the context tracking, note that we can simply use our
list of contexts in i915->contexts rather than circumlocute via
dev->filelist and the per-file context idr, with the result that we can
show objects allocated to different vm (i.e. contexts within a file).

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_debugfs.c | 124 +++-
 1 file changed, 47 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index b89abbba4604..c2f56c1c8199 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -297,11 +297,12 @@ static int i915_gem_stolen_list_info(struct seq_file *m, 
void *data)
 }
 
 struct file_stats {
-   struct drm_i915_file_private *file_priv;
+   struct i915_address_space *vm;
unsigned long count;
u64 total, unbound;
u64 global, shared;
u64 active, inactive;
+   u64 closed;
 };
 
 static int per_file_stats(int id, void *ptr, void *data)
@@ -326,9 +327,7 @@ static int per_file_stats(int id, void *ptr, void *data)
if (i915_vma_is_ggtt(vma)) {
stats->global += vma->node.size;
} else {
-   struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vma->vm);
-
-   if (ppgtt->vm.file != stats->file_priv)
+   if (vma->vm != stats->vm)
continue;
}
 
@@ -336,6 +335,9 @@ static int per_file_stats(int id, void *ptr, void *data)
stats->active += vma->node.size;
else
stats->inactive += vma->node.size;
+
+   if (i915_vma_is_closed(vma))
+   stats->closed += vma->node.size;
}
 
return 0;
@@ -343,7 +345,7 @@ static int per_file_stats(int id, void *ptr, void *data)
 
 #define print_file_stats(m, name, stats) do { \
if (stats.count) \
-   seq_printf(m, "%s: %lu objects, %llu bytes (%llu active, %llu 
inactive, %llu global, %llu shared, %llu unbound)\n", \
+   seq_printf(m, "%s: %lu objects, %llu bytes (%llu active, %llu 
inactive, %llu global, %llu shared, %llu unbound, %llu closed)\n", \
   name, \
   stats.count, \
   stats.total, \
@@ -351,20 +353,19 @@ static int per_file_stats(int id, void *ptr, void *data)
   stats.inactive, \
   stats.global, \
   stats.shared, \
-  stats.unbound); \
+  stats.unbound, \
+  stats.closed); \
 } while (0)
 
 static void print_batch_pool_stats(struct seq_file *m,
   struct drm_i915_private *dev_priv)
 {
struct drm_i915_gem_object *obj;
-   struct file_stats stats;
struct intel_engine_cs *engine;
+   struct file_stats stats = {};
enum intel_engine_id id;
int j;
 
-   memset(&stats, 0, sizeof(stats));
-
for_each_engine(engine, dev_priv, id) {
for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) 
{
list_for_each_entry(obj,
@@ -377,44 +378,47 @@ static void print_batch_pool_stats(struct seq_file *m,
print_file_stats(m, "[k]batch pool", stats);
 }
 
-static int per_file_ctx_stats(int idx, void *ptr, void *data)
+static void print_context_stats(struct seq_file *m,
+   struct drm_i915_private *i915)
 {
-   struct i915_gem_context *ctx = ptr;
-   struct intel_engine_cs *engine;
-   enum intel_engine_id id;
+   struct file_stats kstats = {};
+   struct i915_gem_context *ctx;
 
-   for_each_engine(engine, ctx->i915, id) {
-   struct intel_context *ce = to_intel_context(ctx, engine);
+   list_for_each_entry(ctx, &i915->contexts.list, link) {
+   struct intel_engine_cs *engine;
+   enum intel_engine_id id;
 
-   if (ce->state)
-   per_file_stats(0, ce->state->obj, data);
-   if (ce->ring)
-   per_file_stats(0, ce->ring->vma->obj, data);
-   }
+   for_each_engine(engine, i915, id) {
+   struct intel_context *ce = to_intel_context(ctx, 
engine);
 
-   return 0;
-}
+   if (ce->state)
+   per_file_stats(0, ce->state->obj, &kstats);
+   if (ce->ring)
+   per_file_stats(0, ce->ring->vma->obj, &kstats);
+   }
 
-static void print_context_stats(struct seq_file *m,
-   struct drm_i915_private *dev_priv)
-{
-   struct drm_device *dev = &dev

[Intel-gfx] [PATCH 05/39] drm/i915/userptr: Probe vma range before gup

2019-01-02 Thread Chris Wilson
We want to exclude any GGTT objects from being present on our internal
lists to avoid the deadlock we may run into with our requirement for
struct_mutex during invalidate. However, if the gup_fast fails, we put
the userptr onto the workqueue and mark it as active, so that we
remember to serialise the worker upon mmu_invalidate.

Note that despite the previous fix, it is still better to avoid the
struct_mutex recursion where possible, leaving the recursion only to
handle the shrinker-esque paths.

v2: Hold mmap_sem to prevent modifications to the mm while we probe and
add ourselves to the interval-tree for notificiation.
v3: Rely on mmap_sem for a simpler patch.
v4: Mark up the mmap_sem nesting
v5: Don't deactivate on -EAGAIN as that means the worker is queued
v6: Fight the indentation and chained if-else error handling
v7: Fight again.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104209
Signed-off-by: Chris Wilson 
Cc: Tvrtko Ursulin 
Cc: Michał Winiarski 
---
 drivers/gpu/drm/i915/i915_gem_userptr.c | 158 
 1 file changed, 106 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c 
b/drivers/gpu/drm/i915/i915_gem_userptr.c
index 8b07fd44731f..744aa538d5db 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -439,7 +439,7 @@ struct get_pages_work {
struct task_struct *task;
 };
 
-static struct sg_table *
+static int
 __i915_gem_userptr_alloc_pages(struct drm_i915_gem_object *obj,
   struct page **pvec, int num_pages)
 {
@@ -450,7 +450,7 @@ __i915_gem_userptr_alloc_pages(struct drm_i915_gem_object 
*obj,
 
st = kmalloc(sizeof(*st), GFP_KERNEL);
if (!st)
-   return ERR_PTR(-ENOMEM);
+   return -ENOMEM;
 
 alloc_table:
ret = __sg_alloc_table_from_pages(st, pvec, num_pages,
@@ -459,7 +459,7 @@ __i915_gem_userptr_alloc_pages(struct drm_i915_gem_object 
*obj,
  GFP_KERNEL);
if (ret) {
kfree(st);
-   return ERR_PTR(ret);
+   return ret;
}
 
ret = i915_gem_gtt_prepare_pages(obj, st);
@@ -472,14 +472,14 @@ __i915_gem_userptr_alloc_pages(struct drm_i915_gem_object 
*obj,
}
 
kfree(st);
-   return ERR_PTR(ret);
+   return ret;
}
 
sg_page_sizes = i915_sg_page_sizes(st->sgl);
 
__i915_gem_object_set_pages(obj, st, sg_page_sizes);
 
-   return st;
+   return 0;
 }
 
 static void
@@ -524,19 +524,14 @@ __i915_gem_userptr_get_pages_worker(struct work_struct 
*_work)
 
mutex_lock(&obj->mm.lock);
if (obj->userptr.work == &work->work) {
-   struct sg_table *pages = ERR_PTR(ret);
-
if (pinned == npages) {
-   pages = __i915_gem_userptr_alloc_pages(obj, pvec,
-  npages);
-   if (!IS_ERR(pages)) {
+   ret = __i915_gem_userptr_alloc_pages(obj, pvec, npages);
+   if (!ret)
pinned = 0;
-   pages = NULL;
-   }
}
 
-   obj->userptr.work = ERR_CAST(pages);
-   if (IS_ERR(pages))
+   obj->userptr.work = ERR_PTR(ret);
+   if (ret)
__i915_gem_userptr_set_active(obj, false);
}
mutex_unlock(&obj->mm.lock);
@@ -549,7 +544,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct 
*_work)
kfree(work);
 }
 
-static struct sg_table *
+static int
 __i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj)
 {
struct get_pages_work *work;
@@ -575,7 +570,7 @@ __i915_gem_userptr_get_pages_schedule(struct 
drm_i915_gem_object *obj)
 */
work = kmalloc(sizeof(*work), GFP_KERNEL);
if (work == NULL)
-   return ERR_PTR(-ENOMEM);
+   return -ENOMEM;
 
obj->userptr.work = &work->work;
 
@@ -587,19 +582,89 @@ __i915_gem_userptr_get_pages_schedule(struct 
drm_i915_gem_object *obj)
INIT_WORK(&work->work, __i915_gem_userptr_get_pages_worker);
queue_work(to_i915(obj->base.dev)->mm.userptr_wq, &work->work);
 
-   return ERR_PTR(-EAGAIN);
+   return -EAGAIN;
 }
 
-static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
+static int
+probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len)
+{
+   const unsigned long end = addr + len;
+   struct vm_area_struct *vma;
+   int ret = -EFAULT;
+
+   for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
+   if (vma->vm_start > addr)
+   break;
+
+   /*
+* Exclude any VMA that is not backed only by struct_page, i.e.
+* IO regions that include ou

[Intel-gfx] [PATCH 12/39] drm/i915: Track the wakeref used to initialise display power domains

2019-01-02 Thread Chris Wilson
On module load and unload, we grab the POWER_DOMAIN_INIT powerwells and
transfer them to the runtime-pm code. We can use our wakeref tracking to
verify that the wakeref is indeed passed from init to enable, and
disable to fini; and across suspend.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_debugfs.c |   3 +
 drivers/gpu/drm/i915/i915_drv.h |   2 +
 drivers/gpu/drm/i915/intel_runtime_pm.c | 151 +---
 3 files changed, 88 insertions(+), 68 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index e5b846732853..58994f12cfa8 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2699,6 +2699,9 @@ static int i915_runtime_pm_status(struct seq_file *m, 
void *unused)
if (!HAS_RUNTIME_PM(dev_priv))
seq_puts(m, "Runtime power management not supported\n");
 
+   seq_printf(m, "Runtime power management: %s\n",
+  enableddisabled(!dev_priv->power_domains.wakeref));
+
seq_printf(m, "GPU idle: %s (epoch %u)\n",
   yesno(!dev_priv->gt.awake), dev_priv->gt.epoch);
seq_printf(m, "IRQs disabled: %s\n",
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 312aa5ca4637..45bdc8252ac2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -822,6 +822,8 @@ struct i915_power_domains {
bool display_core_suspended;
int power_well_count;
 
+   intel_wakeref_t wakeref;
+
struct mutex lock;
int domain_use_count[POWER_DOMAIN_NUM];
struct i915_power_well *power_wells;
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c 
b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 60bd310f8358..9c971feaa459 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -3967,7 +3967,7 @@ static void intel_power_domains_verify_state(struct 
drm_i915_private *dev_priv);
 
 /**
  * intel_power_domains_init_hw - initialize hardware power domain state
- * @dev_priv: i915 device instance
+ * @i915: i915 device instance
  * @resume: Called from resume code paths or not
  *
  * This function initializes the hardware power domain state and enables all
@@ -3981,30 +3981,31 @@ static void intel_power_domains_verify_state(struct 
drm_i915_private *dev_priv);
  * intel_power_domains_enable()) and must be paired with
  * intel_power_domains_fini_hw().
  */
-void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool 
resume)
+void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume)
 {
-   struct i915_power_domains *power_domains = &dev_priv->power_domains;
+   struct i915_power_domains *power_domains = &i915->power_domains;
 
power_domains->initializing = true;
 
-   if (IS_ICELAKE(dev_priv)) {
-   icl_display_core_init(dev_priv, resume);
-   } else if (IS_CANNONLAKE(dev_priv)) {
-   cnl_display_core_init(dev_priv, resume);
-   } else if (IS_GEN9_BC(dev_priv)) {
-   skl_display_core_init(dev_priv, resume);
-   } else if (IS_GEN9_LP(dev_priv)) {
-   bxt_display_core_init(dev_priv, resume);
-   } else if (IS_CHERRYVIEW(dev_priv)) {
+   if (IS_ICELAKE(i915)) {
+   icl_display_core_init(i915, resume);
+   } else if (IS_CANNONLAKE(i915)) {
+   cnl_display_core_init(i915, resume);
+   } else if (IS_GEN9_BC(i915)) {
+   skl_display_core_init(i915, resume);
+   } else if (IS_GEN9_LP(i915)) {
+   bxt_display_core_init(i915, resume);
+   } else if (IS_CHERRYVIEW(i915)) {
mutex_lock(&power_domains->lock);
-   chv_phy_control_init(dev_priv);
+   chv_phy_control_init(i915);
mutex_unlock(&power_domains->lock);
-   } else if (IS_VALLEYVIEW(dev_priv)) {
+   } else if (IS_VALLEYVIEW(i915)) {
mutex_lock(&power_domains->lock);
-   vlv_cmnlane_wa(dev_priv);
+   vlv_cmnlane_wa(i915);
mutex_unlock(&power_domains->lock);
-   } else if (IS_IVYBRIDGE(dev_priv) || INTEL_GEN(dev_priv) >= 7)
-   intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv));
+   } else if (IS_IVYBRIDGE(i915) || INTEL_GEN(i915) >= 7) {
+   intel_pch_reset_handshake(i915, !HAS_PCH_NOP(i915));
+   }
 
/*
 * Keep all power wells enabled for any dependent HW access during
@@ -4012,18 +4013,20 @@ void intel_power_domains_init_hw(struct 
drm_i915_private *dev_priv, bool resume)
 * resources powered until display HW readout is complete. We drop
 * this reference in intel_power_domains_enable().
 */
-   intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
+   power_domains->wakeref =
+   intel_display_power_get(i915, POWER_DOMAIN_INIT);
+
/* Disable power support

Re: [Intel-gfx] [PATCH 5/6] drm/i915: drop intel_device_info_dump()

2019-01-02 Thread Tvrtko Ursulin


On 31/12/2018 14:56, Jani Nikula wrote:

The debugfs, error state and regular dmesg logging dump needs seem to be
different. Remove the generic dump function only used for the welcome
message. This may be added back later when better abstractions are
identified, but at the moment this seems to be the simplest considering
the device info rework in progress. No longer rely on device info being
a substruct of dev_priv.


Why not just make intel_device_info_dump take dev_priv?

Regards,

Tvrtko



Cc: Tvrtko Ursulin 
Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/i915/i915_drv.c  |  8 +++-
  drivers/gpu/drm/i915/intel_device_info.c | 15 ---
  drivers/gpu/drm/i915/intel_device_info.h |  2 --
  3 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 8d7a3a852c10..fe01d090f9bb 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1636,7 +1636,13 @@ static void i915_welcome_messages(struct 
drm_i915_private *dev_priv)
if (drm_debug & DRM_UT_DRIVER) {
struct drm_printer p = drm_debug_printer("i915 device info:");
  
-		intel_device_info_dump(INTEL_INFO(dev_priv), &p);

+   drm_printf(&p, "pciid=0x%04x rev=0x%02x platform=%s gen=%i\n",
+  INTEL_DEVID(dev_priv),
+  INTEL_REVID(dev_priv),
+  intel_platform_name(INTEL_INFO(dev_priv)->platform),
+  INTEL_GEN(dev_priv));
+
+   intel_device_info_dump_flags(INTEL_INFO(dev_priv), &p);
intel_device_info_dump_runtime(RUNTIME_INFO(dev_priv), &p);
}
  
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c

index f35e8cff4b99..e0ce0c9791fc 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -113,21 +113,6 @@ void intel_device_info_dump_runtime(const struct 
intel_runtime_info *info,
   info->cs_timestamp_frequency_khz);
  }
  
-void intel_device_info_dump(const struct intel_device_info *info,

-   struct drm_printer *p)
-{
-   struct drm_i915_private *dev_priv =
-   container_of(info, struct drm_i915_private, info);
-
-   drm_printf(p, "pciid=0x%04x rev=0x%02x platform=%s gen=%i\n",
-  INTEL_DEVID(dev_priv),
-  INTEL_REVID(dev_priv),
-  intel_platform_name(info->platform),
-  info->gen);
-
-   intel_device_info_dump_flags(info, p);
-}
-
  void intel_device_info_dump_topology(const struct sseu_dev_info *sseu,
 struct drm_printer *p)
  {
diff --git a/drivers/gpu/drm/i915/intel_device_info.h 
b/drivers/gpu/drm/i915/intel_device_info.h
index f0e6d374d4ec..76735869e32d 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -267,8 +267,6 @@ static inline void sseu_set_eus(struct sseu_dev_info *sseu,
  const char *intel_platform_name(enum intel_platform platform);
  
  void intel_device_info_runtime_init(struct drm_i915_private *dev_priv);

-void intel_device_info_dump(const struct intel_device_info *info,
-   struct drm_printer *p);
  void intel_device_info_dump_flags(const struct intel_device_info *info,
  struct drm_printer *p);
  void intel_device_info_dump_runtime(const struct intel_runtime_info *info,


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


Re: [Intel-gfx] [PATCH 6/6] drm/i915: rename dev_priv info to __info to avoid usage

2019-01-02 Thread Tvrtko Ursulin


On 31/12/2018 14:56, Jani Nikula wrote:

Encourage use of INTEL_INFO() to access dev_priv->info to not accumulate
more direct users of ->info, making further changes easier.

Cc: Tvrtko Ursulin 
Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/i915/i915_drv.h | 10 ++
  1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ce8d7a97e26b..18e67aaef764 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1431,7 +1431,7 @@ struct drm_i915_private {
struct kmem_cache *dependencies;
struct kmem_cache *priorities;
  
-	const struct intel_device_info info;

+   const struct intel_device_info __info; /* Use INTEL_INFO() to access. */
struct intel_runtime_info __runtime; /* Use RUNTIME_INFO() to access. */
struct intel_driver_caps caps;
  
@@ -2192,13 +2192,7 @@ static inline unsigned int i915_sg_segment_size(void)

return size;
  }
  
-static inline const struct intel_device_info *

-intel_info(const struct drm_i915_private *dev_priv)
-{
-   return &dev_priv->info;
-}
-


What was this helper for, who remembers? :)

Regards,

Tvrtko


-#define INTEL_INFO(dev_priv)   intel_info((dev_priv))
+#define INTEL_INFO(dev_priv)   (&(dev_priv)->__info)
  #define RUNTIME_INFO(dev_priv)(&(dev_priv)->__runtime)
  #define DRIVER_CAPS(dev_priv) (&(dev_priv)->caps)
  



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


Re: [Intel-gfx] [RESEND PATCH 1/5] drm/i915/backlight: Restore backlight on resume, v2.

2019-01-02 Thread Maarten Lankhorst
Op 28-12-2018 om 11:10 schreef Jani Nikula:
> On Mon, 17 Dec 2018, Maarten Lankhorst  
> wrote:
>> Restore our saved values for backlight. This way even with fastset on
>> S4 resume we will correctly restore the backlight to the active values.
> I think this is a non-trivial commit that requires more explanation in
> the commit message and comments.
>
> What does this do for non-fastset resume? It seems to me this
> enables/disables backlight twice in that case.
>
> This doesn't take panel power sequencing into account at all. You can't
> just go ahead and enable the PWM with no consideration of how that is
> fed to the panel. That in turn is encoder code, so I'm not sure how that
> could be bolted on here.
>
> So I'm afraid I'm not convinced this will work.

Neither, I've seen a very nice encoder update_pipe hook for fastset.

I think using this for S4 resume would solve the issue.

https://patchwork.kernel.org/patch/10738879/

> One more detail in-line below.
>
>> Changes since v1:
>> - Call enable_backlight() when backlight.level is set. On suspend
>>   backlight.enabled is always cleared, this makes it not a good
>>   indicator. Also check for crtc->state->active.
>>
>> Signed-off-by: Maarten Lankhorst 
>> Cc: Tolga Cakir 
>> Cc: Basil Eric Rabi 
>> Cc: Hans de Goede 
>> Cc: Ville Syrjälä 
>> Reported-by: Ville Syrjälä 
>> ---
>>  drivers/gpu/drm/i915/intel_display.c |  2 ++
>>  drivers/gpu/drm/i915/intel_drv.h |  1 +
>>  drivers/gpu/drm/i915/intel_panel.c   | 30 
>>  3 files changed, 33 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c 
>> b/drivers/gpu/drm/i915/intel_display.c
>> index 2c3f3f68d506..86e7b145fd98 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -15887,7 +15887,9 @@ void intel_display_resume(struct drm_device *dev)
>>  if (!ret)
>>  ret = __intel_display_resume(dev, state, &ctx);
>>  
>> +intel_panel_restore_backlight(dev_priv);
>>  intel_enable_ipc(dev_priv);
>> +
>>  drm_modeset_drop_locks(&ctx);
>>  drm_modeset_acquire_fini(&ctx);
>>  
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
>> b/drivers/gpu/drm/i915/intel_drv.h
>> index cb3a055f18c8..a0551742bcf4 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -2003,6 +2003,7 @@ int intel_panel_init(struct intel_panel *panel,
>>   struct drm_display_mode *fixed_mode,
>>   struct drm_display_mode *downclock_mode);
>>  void intel_panel_fini(struct intel_panel *panel);
>> +void intel_panel_restore_backlight(struct drm_i915_private *dev_priv);
>>  void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
>>  struct drm_display_mode *adjusted_mode);
>>  void intel_pch_panel_fitting(struct intel_crtc *crtc,
>> diff --git a/drivers/gpu/drm/i915/intel_panel.c 
>> b/drivers/gpu/drm/i915/intel_panel.c
>> index ee3e0842d542..799284fcd57d 100644
>> --- a/drivers/gpu/drm/i915/intel_panel.c
>> +++ b/drivers/gpu/drm/i915/intel_panel.c
>> @@ -1903,6 +1903,36 @@ intel_panel_init_backlight_funcs(struct intel_panel 
>> *panel)
>>  }
>>  }
>>  
>> +void intel_panel_restore_backlight(struct drm_i915_private *dev_priv)
>> +{
>> +struct intel_connector *connector;
>> +struct drm_connector_list_iter conn_iter;
>> +
>> +/* Kill all the work that may have been queued by hpd. */
>> +drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
>> +for_each_intel_connector_iter(connector, &conn_iter) {
>> +struct intel_panel *panel = &connector->panel;
>> +const struct drm_connector_state *conn_state =
>> +connector->base.state;
>> +
>> +if (!panel->backlight.present)
>> +continue;
>> +
>> +if (panel->backlight.level && conn_state->crtc &&
> panel->backlight.level is not necessarily 0-based, it's between
> panel->backlight.{min,max}.
Yeah, this part can be removed.
> BR,
> Jani.
>
>> +conn_state->crtc->state->active) {
>> +const struct intel_crtc_state *crtc_state =
>> +to_intel_crtc_state(conn_state->crtc->state);
>> +
>> +intel_panel_enable_backlight(crtc_state, conn_state);
>> +} else {
>> +WARN(panel->backlight.enabled, "Backlight enabled 
>> without crtc\n");
>> +
>> +intel_panel_disable_backlight(conn_state);
>> +}
>> +}
>> +drm_connector_list_iter_end(&conn_iter);
>> +}
>> +
>>  int intel_panel_init(struct intel_panel *panel,
>>   struct drm_display_mode *fixed_mode,
>>   struct drm_display_mode *downclock_mode)


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


Re: [Intel-gfx] [PATCH 0/6] drm/i915: start splitting off runtime device info

2019-01-02 Thread Tvrtko Ursulin


On 02/01/2019 09:13, Jani Nikula wrote:

On Tue, 01 Jan 2019, Chris Wilson  wrote:

Quoting Jani Nikula (2018-12-31 14:56:40)

The mkwrite_device_info removal series [1] seems to have stalled. I'm
trying to nudge things forward a bit with this series. This isn't near
as complete as Tvrtko's work, but does some of the prep work I wanted,
specifically using INTEL_INFO() and RUNTIME_INFO() to access the
fields. There are obviously conflicts, but mostly I think this should
make the rest of Tvrtko's work easier, not harder.

BR,
Jani.


[1] https://patchwork.freedesktop.org/series/52381/

Cc: Tvrtko Ursulin 


Jani Nikula (6):
   drm/i915: start moving runtime device info to a separate struct
   drm/i915/reg: abstract display_mmio_offset access
   drm/i915: pass dev_priv to intel_device_info_runtime_init()
   drm/i915: always use INTEL_INFO() to access device info
   drm/i915: drop intel_device_info_dump()
   drm/i915: rename dev_priv info to __info to avoid usage


Looked ok, and didn't see anything odd compared to my own attempts.
Reviewed-by: Chris Wilson 


Thanks for the review.

Tvrtko, I'd still like to get your ack before I go ahead and push
these. Also, do you think you'll have time in the near future to pick up
your series, or shall I?


I missed Chris had already reviewed it. Yeah, series looks fine to me.

With regards to the second part, after your work what I think would be 
left from mine is:


 * move some more fields/flags to runtime info
 * subplatform/devid consolidation
 * looking at how to wean selftests off modifying the gen field
 * maybe introducting INTEL_SSEU to avoid many RUNTIME_INFO(...)->sseu

If you are in a hurry and have time you can take over, or if you are 
just in a hurry I might be able to do within a week or two.


Regards,

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


Re: [Intel-gfx] [PATCH 1/6] drm/i915: start moving runtime device info to a separate struct

2019-01-02 Thread Jani Nikula
On Wed, 02 Jan 2019, Tvrtko Ursulin  wrote:
> On 31/12/2018 14:56, Jani Nikula wrote:
>> @@ -2198,10 +2199,11 @@ intel_info(const struct drm_i915_private *dev_priv)
>>   }
>>   
>>   #define INTEL_INFO(dev_priv)   intel_info((dev_priv))
>> +#define RUNTIME_INFO(dev_priv)  (&(dev_priv)->__runtime)
>
> Do we want to keep the const trick like with INTEL_INFO in order to make 
> accidental modifications harder? Argument is different there than with 
> static info.

I did think about it, but I don't want to repeat mkwrite_device_info().

I understand we have three classes of data:

1) immutable
2) immutable after one-time runtime init
3) mutable

Currently we mix all of them, the intention here is to split out 1 from
2&3, the latter two remaining conflated. I'd like to see how this pans
out before worrying about the difference between 2&3.

>> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
>> b/drivers/gpu/drm/i915/i915_gpu_error.c
>> index 2bd7991ec9af..6238a06b6d4e 100644
>> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
>> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
>> @@ -594,13 +594,14 @@ static void print_error_obj(struct 
>> drm_i915_error_state_buf *m,
>>   
>>   static void err_print_capabilities(struct drm_i915_error_state_buf *m,
>> const struct intel_device_info *info,
>> +   const struct intel_runtime_info *runtime,
>> const struct intel_driver_caps *caps)
>>   {
>>  struct drm_printer p = i915_error_printer(m);
>>   
>>  intel_device_info_dump_flags(info, &p);
>
> If I am not missing something here we now miss the runtime flags being 
> dumped.
>
> A bit later: Ah ok, you haven't yet added any flags to runtime info in 
> this patch.

*grin* Like I said, not as complete as your series.

> Looks okay to me.
>
> The only thing which worries me is that one day we end up with too 
> little in static vs runtime and decide having two separate sources of 
> info is only a hassle. (Like if the DCE/LTO path either does not happen, 
> or ends up not needing this completely.)
>
> I suppose it is worth exploring and we can always go back easily if all 
> else fails. I at least want to have another go at the subplatform/devid 
> centralization.
>
> Reviewed-by: Tvrtko Ursulin 

Thanks,
Jani.

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


Re: [Intel-gfx] [PATCH 5/6] drm/i915: drop intel_device_info_dump()

2019-01-02 Thread Jani Nikula
On Wed, 02 Jan 2019, Tvrtko Ursulin  wrote:
> On 31/12/2018 14:56, Jani Nikula wrote:
>> The debugfs, error state and regular dmesg logging dump needs seem to be
>> different. Remove the generic dump function only used for the welcome
>> message. This may be added back later when better abstractions are
>> identified, but at the moment this seems to be the simplest considering
>> the device info rework in progress. No longer rely on device info being
>> a substruct of dev_priv.
>
> Why not just make intel_device_info_dump take dev_priv?

I'm thinking the device info dumpers will need some refactoring in the
future anyway to best suit all the needs of dmesg logging, debugfs, and
error state dumping. The last one especially wants to use data copied to
the error state instead of drm_i915_private.

I admittedly took the easy way out here, and removed the function
altogether because there's currently only one user. I didn't want to
change now, and then change again later.

BR,
Jani.

>
> Regards,
>
> Tvrtko
>
>> 
>> Cc: Tvrtko Ursulin 
>> Signed-off-by: Jani Nikula 
>> ---
>>   drivers/gpu/drm/i915/i915_drv.c  |  8 +++-
>>   drivers/gpu/drm/i915/intel_device_info.c | 15 ---
>>   drivers/gpu/drm/i915/intel_device_info.h |  2 --
>>   3 files changed, 7 insertions(+), 18 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/i915_drv.c 
>> b/drivers/gpu/drm/i915/i915_drv.c
>> index 8d7a3a852c10..fe01d090f9bb 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.c
>> +++ b/drivers/gpu/drm/i915/i915_drv.c
>> @@ -1636,7 +1636,13 @@ static void i915_welcome_messages(struct 
>> drm_i915_private *dev_priv)
>>  if (drm_debug & DRM_UT_DRIVER) {
>>  struct drm_printer p = drm_debug_printer("i915 device info:");
>>   
>> -intel_device_info_dump(INTEL_INFO(dev_priv), &p);
>> +drm_printf(&p, "pciid=0x%04x rev=0x%02x platform=%s gen=%i\n",
>> +   INTEL_DEVID(dev_priv),
>> +   INTEL_REVID(dev_priv),
>> +   intel_platform_name(INTEL_INFO(dev_priv)->platform),
>> +   INTEL_GEN(dev_priv));
>> +
>> +intel_device_info_dump_flags(INTEL_INFO(dev_priv), &p);
>>  intel_device_info_dump_runtime(RUNTIME_INFO(dev_priv), &p);
>>  }
>>   
>> diff --git a/drivers/gpu/drm/i915/intel_device_info.c 
>> b/drivers/gpu/drm/i915/intel_device_info.c
>> index f35e8cff4b99..e0ce0c9791fc 100644
>> --- a/drivers/gpu/drm/i915/intel_device_info.c
>> +++ b/drivers/gpu/drm/i915/intel_device_info.c
>> @@ -113,21 +113,6 @@ void intel_device_info_dump_runtime(const struct 
>> intel_runtime_info *info,
>> info->cs_timestamp_frequency_khz);
>>   }
>>   
>> -void intel_device_info_dump(const struct intel_device_info *info,
>> -struct drm_printer *p)
>> -{
>> -struct drm_i915_private *dev_priv =
>> -container_of(info, struct drm_i915_private, info);
>> -
>> -drm_printf(p, "pciid=0x%04x rev=0x%02x platform=%s gen=%i\n",
>> -   INTEL_DEVID(dev_priv),
>> -   INTEL_REVID(dev_priv),
>> -   intel_platform_name(info->platform),
>> -   info->gen);
>> -
>> -intel_device_info_dump_flags(info, p);
>> -}
>> -
>>   void intel_device_info_dump_topology(const struct sseu_dev_info *sseu,
>>   struct drm_printer *p)
>>   {
>> diff --git a/drivers/gpu/drm/i915/intel_device_info.h 
>> b/drivers/gpu/drm/i915/intel_device_info.h
>> index f0e6d374d4ec..76735869e32d 100644
>> --- a/drivers/gpu/drm/i915/intel_device_info.h
>> +++ b/drivers/gpu/drm/i915/intel_device_info.h
>> @@ -267,8 +267,6 @@ static inline void sseu_set_eus(struct sseu_dev_info 
>> *sseu,
>>   const char *intel_platform_name(enum intel_platform platform);
>>   
>>   void intel_device_info_runtime_init(struct drm_i915_private *dev_priv);
>> -void intel_device_info_dump(const struct intel_device_info *info,
>> -struct drm_printer *p);
>>   void intel_device_info_dump_flags(const struct intel_device_info *info,
>>struct drm_printer *p);
>>   void intel_device_info_dump_runtime(const struct intel_runtime_info *info,
>> 

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


Re: [Intel-gfx] [PATCH 6/6] drm/i915: rename dev_priv info to __info to avoid usage

2019-01-02 Thread Jani Nikula
On Wed, 02 Jan 2019, Tvrtko Ursulin  wrote:
> On 31/12/2018 14:56, Jani Nikula wrote:
>> Encourage use of INTEL_INFO() to access dev_priv->info to not accumulate
>> more direct users of ->info, making further changes easier.
>> 
>> Cc: Tvrtko Ursulin 
>> Signed-off-by: Jani Nikula 
>> ---
>>   drivers/gpu/drm/i915/i915_drv.h | 10 ++
>>   1 file changed, 2 insertions(+), 8 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h 
>> b/drivers/gpu/drm/i915/i915_drv.h
>> index ce8d7a97e26b..18e67aaef764 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -1431,7 +1431,7 @@ struct drm_i915_private {
>>  struct kmem_cache *dependencies;
>>  struct kmem_cache *priorities;
>>   
>> -const struct intel_device_info info;
>> +const struct intel_device_info __info; /* Use INTEL_INFO() to access. */
>>  struct intel_runtime_info __runtime; /* Use RUNTIME_INFO() to access. */
>>  struct intel_driver_caps caps;
>>   
>> @@ -2192,13 +2192,7 @@ static inline unsigned int i915_sg_segment_size(void)
>>  return size;
>>   }
>>   
>> -static inline const struct intel_device_info *
>> -intel_info(const struct drm_i915_private *dev_priv)
>> -{
>> -return &dev_priv->info;
>> -}
>> -
>
> What was this helper for, who remembers? :)

Didn't dig through the git logs, but I presume it's a leftover from the
days we were migrating to subclassing drm_device in drm_i915_private...

BR,
Jani.


>
> Regards,
>
> Tvrtko
>
>> -#define INTEL_INFO(dev_priv)intel_info((dev_priv))
>> +#define INTEL_INFO(dev_priv)(&(dev_priv)->__info)
>>   #define RUNTIME_INFO(dev_priv) (&(dev_priv)->__runtime)
>>   #define DRIVER_CAPS(dev_priv)  (&(dev_priv)->caps)
>>   
>> 
>

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


[Intel-gfx] [PATCH 25/39] drm/i915: Pull VM lists under the VM mutex.

2019-01-02 Thread Chris Wilson
Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_gem.c | 14 --
 drivers/gpu/drm/i915/i915_gem_evict.c   |  2 ++
 drivers/gpu/drm/i915/i915_gem_gtt.c | 15 +--
 drivers/gpu/drm/i915/i915_gem_shrinker.c|  4 
 drivers/gpu/drm/i915/i915_gem_stolen.c  |  2 ++
 drivers/gpu/drm/i915/i915_vma.c | 11 +++
 drivers/gpu/drm/i915/selftests/i915_gem_evict.c |  3 +++
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c   |  3 +++
 8 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d9e1dcee176c..66445e34c93c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -246,18 +246,19 @@ int
 i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
 {
-   struct drm_i915_private *dev_priv = to_i915(dev);
-   struct i915_ggtt *ggtt = &dev_priv->ggtt;
+   struct i915_ggtt *ggtt = &to_i915(dev)->ggtt;
struct drm_i915_gem_get_aperture *args = data;
struct i915_vma *vma;
u64 pinned;
 
+   mutex_lock(&ggtt->vm.mutex);
+
pinned = ggtt->vm.reserved;
-   mutex_lock(&dev->struct_mutex);
list_for_each_entry(vma, &ggtt->vm.bound_list, vm_link)
if (i915_vma_is_pinned(vma))
pinned += vma->node.size;
-   mutex_unlock(&dev->struct_mutex);
+
+   mutex_unlock(&ggtt->vm.mutex);
 
args->aper_size = ggtt->vm.total;
args->aper_available_size = args->aper_size - pinned;
@@ -1680,20 +1681,21 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void 
*data,
 
 static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj)
 {
-   struct drm_i915_private *i915;
+   struct drm_i915_private *i915 = to_i915(obj->base.dev);
struct list_head *list;
struct i915_vma *vma;
 
GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
 
+   mutex_lock(&i915->ggtt.vm.mutex);
for_each_ggtt_vma(vma, obj) {
if (!drm_mm_node_allocated(&vma->node))
continue;
 
list_move_tail(&vma->vm_link, &vma->vm->bound_list);
}
+   mutex_unlock(&i915->ggtt.vm.mutex);
 
-   i915 = to_i915(obj->base.dev);
spin_lock(&i915->mm.obj_lock);
list = obj->bind_count ? &i915->mm.bound_list : &i915->mm.unbound_list;
list_move_tail(&obj->mm.link, list);
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c 
b/drivers/gpu/drm/i915/i915_gem_evict.c
index 6a3608398d2a..b7c2a396a63f 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -418,6 +418,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
}
 
INIT_LIST_HEAD(&eviction_list);
+   mutex_lock(&vm->mutex);
list_for_each_entry(vma, &vm->bound_list, vm_link) {
if (i915_vma_is_pinned(vma))
continue;
@@ -425,6 +426,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
__i915_vma_pin(vma);
list_add(&vma->evict_link, &eviction_list);
}
+   mutex_unlock(&vm->mutex);
 
ret = 0;
list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index e5e23c4ac769..7ae10fbb2ee0 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1932,7 +1932,10 @@ static struct i915_vma *pd_vma_create(struct 
gen6_hw_ppgtt *ppgtt, int size)
vma->ggtt_view.type = I915_GGTT_VIEW_ROTATED; /* prevent fencing */
 
INIT_LIST_HEAD(&vma->obj_link);
+
+   mutex_lock(&vma->vm->mutex);
list_add(&vma->vm_link, &vma->vm->unbound_list);
+   mutex_unlock(&vma->vm->mutex);
 
return vma;
 }
@@ -3504,9 +3507,10 @@ void i915_gem_restore_gtt_mappings(struct 
drm_i915_private *dev_priv)
 
i915_check_and_clear_faults(dev_priv);
 
+   mutex_lock(&ggtt->vm.mutex);
+
/* First fill our portion of the GTT with scratch pages */
ggtt->vm.clear_range(&ggtt->vm, 0, ggtt->vm.total);
-
ggtt->vm.closed = true; /* skip rewriting PTE on VMA unbind */
 
/* clflush objects bound into the GGTT and rebind them. */
@@ -3516,19 +3520,26 @@ void i915_gem_restore_gtt_mappings(struct 
drm_i915_private *dev_priv)
if (!(vma->flags & I915_VMA_GLOBAL_BIND))
continue;
 
+   mutex_unlock(&ggtt->vm.mutex);
+
if (!i915_vma_unbind(vma))
-   continue;
+   goto lock;
 
WARN_ON(i915_vma_bind(vma,
  obj ? obj->cache_level : 0,
  PIN_UPDATE));
if (obj)
WARN_ON(i915_gem_obj

[Intel-gfx] [PATCH 18/39] drm/i915: Differentiate between ggtt->mutex and ppgtt->mutex

2019-01-02 Thread Chris Wilson
We have two classes of VM, global GTT and per-process GTT. In order to
allow ourselves the freedom to mix both along call chains, distinguish
the two classes with regards to their mutex and lockdep maps.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c   | 10 +-
 drivers/gpu/drm/i915/i915_gem_gtt.h   |  2 ++
 drivers/gpu/drm/i915/selftests/mock_gtt.c |  6 +++---
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 852dbc1f185f..8f93b1dffbb9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -474,8 +474,7 @@ static void vm_free_page(struct i915_address_space *vm, 
struct page *page)
spin_unlock(&vm->free_pages.lock);
 }
 
-static void i915_address_space_init(struct i915_address_space *vm,
-   struct drm_i915_private *dev_priv)
+static void i915_address_space_init(struct i915_address_space *vm, int 
subclass)
 {
/*
 * The vm->mutex must be reclaim safe (for use in the shrinker).
@@ -483,6 +482,7 @@ static void i915_address_space_init(struct 
i915_address_space *vm,
 * attempt holding the lock is immediately reported by lockdep.
 */
mutex_init(&vm->mutex);
+   lockdep_set_subclass(&vm->mutex, subclass);
i915_gem_shrinker_taints_mutex(&vm->mutex);
 
GEM_BUG_ON(!vm->total);
@@ -1548,7 +1548,7 @@ static struct i915_hw_ppgtt *gen8_ppgtt_create(struct 
drm_i915_private *i915)
/* From bdw, there is support for read-only pages in the PPGTT. */
ppgtt->vm.has_read_only = true;
 
-   i915_address_space_init(&ppgtt->vm, i915);
+   i915_address_space_init(&ppgtt->vm, VM_CLASS_PPGTT);
 
/* There are only few exceptions for gen >=6. chv and bxt.
 * And we are not sure about the latter so play safe for now.
@@ -1997,7 +1997,7 @@ static struct i915_hw_ppgtt *gen6_ppgtt_create(struct 
drm_i915_private *i915)
 
ppgtt->base.vm.total = I915_PDES * GEN6_PTES * I915_GTT_PAGE_SIZE;
 
-   i915_address_space_init(&ppgtt->base.vm, i915);
+   i915_address_space_init(&ppgtt->base.vm, VM_CLASS_PPGTT);
 
ppgtt->base.vm.allocate_va_range = gen6_alloc_va_range;
ppgtt->base.vm.clear_range = gen6_ppgtt_clear_range;
@@ -3434,7 +3434,7 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv)
 * and beyond the end of the GTT if we do not provide a guard.
 */
mutex_lock(&dev_priv->drm.struct_mutex);
-   i915_address_space_init(&ggtt->vm, dev_priv);
+   i915_address_space_init(&ggtt->vm, VM_CLASS_GGTT);
 
ggtt->vm.is_ggtt = true;
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index e2360f16427a..9229b03d629b 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -288,6 +288,8 @@ struct i915_address_space {
bool closed;
 
struct mutex mutex; /* protects vma and our lists */
+#define VM_CLASS_GGTT 0
+#define VM_CLASS_PPGTT 1
 
u64 scratch_pte;
struct i915_page_dma scratch_page;
diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c 
b/drivers/gpu/drm/i915/selftests/mock_gtt.c
index 6ae418c76015..976c862b3842 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c
@@ -70,7 +70,7 @@ mock_ppgtt(struct drm_i915_private *i915,
ppgtt->vm.total = round_down(U64_MAX, PAGE_SIZE);
ppgtt->vm.file = ERR_PTR(-ENODEV);
 
-   i915_address_space_init(&ppgtt->vm, i915);
+   i915_address_space_init(&ppgtt->vm, VM_CLASS_PPGTT);
 
ppgtt->vm.clear_range = nop_clear_range;
ppgtt->vm.insert_page = mock_insert_page;
@@ -102,6 +102,7 @@ void mock_init_ggtt(struct drm_i915_private *i915)
struct i915_ggtt *ggtt = &i915->ggtt;
 
ggtt->vm.i915 = i915;
+   ggtt->vm.is_ggtt = true;
 
ggtt->gmadr = (struct resource) DEFINE_RES_MEM(0, 2048 * PAGE_SIZE);
ggtt->mappable_end = resource_size(&ggtt->gmadr);
@@ -117,9 +118,8 @@ void mock_init_ggtt(struct drm_i915_private *i915)
ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
ggtt->vm.vma_ops.clear_pages = clear_pages;
 
-   i915_address_space_init(&ggtt->vm, i915);
 
-   ggtt->vm.is_ggtt = true;
+   i915_address_space_init(&ggtt->vm, VM_CLASS_GGTT);
 }
 
 void mock_fini_ggtt(struct drm_i915_private *i915)
-- 
2.20.1

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


[Intel-gfx] [PATCH 22/39] drm/i915: Remove GPU reset dependence on struct_mutex

2019-01-02 Thread Chris Wilson
Now that the submission backends are controlled via their own spinlocks,
with a wave of a magic wand we can lift the struct_mutex requirement
around GPU reset. That is we allow the submission frontend (userspace)
to keep on submitting while we process the GPU reset as we can suspend
the backend independently.

The major change is around the backoff/handoff strategy for performing
the reset. With no mutex deadlock, we no longer have to coordinate with
any waiter, and just perform the reset immediately.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_debugfs.c   |  14 +-
 drivers/gpu/drm/i915/i915_drv.h   |   5 -
 drivers/gpu/drm/i915/i915_gem.c   |  18 +-
 drivers/gpu/drm/i915/i915_gem_fence_reg.h |   1 -
 drivers/gpu/drm/i915/i915_gem_gtt.h   |   1 +
 drivers/gpu/drm/i915/i915_gpu_error.h |  24 +-
 drivers/gpu/drm/i915/i915_request.c   |  47 ---
 drivers/gpu/drm/i915/i915_reset.c | 397 --
 drivers/gpu/drm/i915/i915_reset.h |   3 +
 drivers/gpu/drm/i915/intel_engine_cs.c|   6 +-
 drivers/gpu/drm/i915/intel_guc_submission.c   |   5 +-
 drivers/gpu/drm/i915/intel_lrc.c  |  92 ++--
 drivers/gpu/drm/i915/intel_overlay.c  |   2 -
 drivers/gpu/drm/i915/intel_ringbuffer.c   |  91 ++--
 drivers/gpu/drm/i915/intel_ringbuffer.h   |  13 +-
 .../gpu/drm/i915/selftests/intel_hangcheck.c  |  57 +--
 .../drm/i915/selftests/intel_workarounds.c|   3 -
 17 files changed, 317 insertions(+), 462 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index e162ad357b17..5e2d5c8d7e02 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1284,8 +1284,6 @@ static int i915_hangcheck_info(struct seq_file *m, void 
*unused)
seq_puts(m, "Wedged\n");
if (test_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags))
seq_puts(m, "Reset in progress: struct_mutex backoff\n");
-   if (test_bit(I915_RESET_HANDOFF, &dev_priv->gpu_error.flags))
-   seq_puts(m, "Reset in progress: reset handoff to waiter\n");
if (waitqueue_active(&dev_priv->gpu_error.wait_queue))
seq_puts(m, "Waiter holding struct mutex\n");
if (waitqueue_active(&dev_priv->gpu_error.reset_queue))
@@ -3914,11 +3912,6 @@ i915_wedged_set(void *data, u64 val)
 
i915_handle_error(i915, val, I915_ERROR_CAPTURE,
  "Manually set wedged engine mask = %llx", val);
-
-   wait_on_bit(&i915->gpu_error.flags,
-   I915_RESET_HANDOFF,
-   TASK_UNINTERRUPTIBLE);
-
return 0;
 }
 
@@ -4073,13 +4066,8 @@ i915_drop_caches_set(void *data, u64 val)
mutex_unlock(&i915->drm.struct_mutex);
}
 
-   if (val & DROP_RESET_ACTIVE &&
-   i915_terminally_wedged(&i915->gpu_error)) {
+   if (val & DROP_RESET_ACTIVE && i915_terminally_wedged(&i915->gpu_error))
i915_handle_error(i915, ALL_ENGINES, 0, NULL);
-   wait_on_bit(&i915->gpu_error.flags,
-   I915_RESET_HANDOFF,
-   TASK_UNINTERRUPTIBLE);
-   }
 
fs_reclaim_acquire(GFP_KERNEL);
if (val & DROP_BOUND)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d50577e01d6f..70289b2447bb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2988,11 +2988,6 @@ static inline bool i915_reset_backoff(struct 
i915_gpu_error *error)
return unlikely(test_bit(I915_RESET_BACKOFF, &error->flags));
 }
 
-static inline bool i915_reset_handoff(struct i915_gpu_error *error)
-{
-   return unlikely(test_bit(I915_RESET_HANDOFF, &error->flags));
-}
-
 static inline bool i915_terminally_wedged(struct i915_gpu_error *error)
 {
return unlikely(test_bit(I915_WEDGED, &error->flags));
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index c70f1780c91f..800b2c770dce 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -658,11 +658,6 @@ i915_gem_object_wait(struct drm_i915_gem_object *obj,
 struct intel_rps_client *rps_client)
 {
might_sleep();
-#if IS_ENABLED(CONFIG_LOCKDEP)
-   GEM_BUG_ON(debug_locks &&
-  !!lockdep_is_held(&obj->base.dev->struct_mutex) !=
-  !!(flags & I915_WAIT_LOCKED));
-#endif
GEM_BUG_ON(timeout < 0);
 
timeout = i915_gem_object_wait_reservation(obj->resv,
@@ -4644,8 +4639,6 @@ void i915_gem_sanitize(struct drm_i915_private *i915)
 
GEM_TRACE("\n");
 
-   mutex_lock(&i915->drm.struct_mutex);
-
wakeref = intel_runtime_pm_get(i915);
intel_uncore_forcewake_get(i915, FORCEWAKE_ALL);
 
@@ -4671,6 +4664,7 @@ void i915_gem_sanitize(struct drm_i915_private *i915)
intel_uncore_forcewake_put(i

[Intel-gfx] [PATCH 21/39] drm/i915/guc: Disable global reset

2019-01-02 Thread Chris Wilson
The guc (and huc) currently inexcruitably depend on struct_mutex for
device reinitialisation from inside the reset, and indeed taking any
mutex here is verboten (as we must be able to reset from underneath any
of our mutexes). That makes recovering the guc unviable without, for
example, reserving contiguous vma space and pages for it to use.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_reset.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reset.c 
b/drivers/gpu/drm/i915/i915_reset.c
index f5da67f1bc04..77fc2f74e427 100644
--- a/drivers/gpu/drm/i915/i915_reset.c
+++ b/drivers/gpu/drm/i915/i915_reset.c
@@ -590,6 +590,9 @@ int intel_gpu_reset(struct drm_i915_private *i915, unsigned 
int engine_mask)
 
 bool intel_has_gpu_reset(struct drm_i915_private *i915)
 {
+   if (USES_GUC(i915))
+   return false;
+
return intel_get_gpu_reset(i915);
 }
 
-- 
2.20.1

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


Re: [Intel-gfx] [PATCH 02/39] drm/i915/selftests: Take a breath during check_partial_mappings()

2019-01-02 Thread Mika Kuoppala
Chris Wilson  writes:

> With kasan on a slow machine, it can take an age to check all the
> partial mappings in a single iteration, so break it up with a
> cond_resched) to avoid RCU stall reports.
>
> Signed-off-by: Chris Wilson 
> ---
>  drivers/gpu/drm/i915/selftests/i915_gem_object.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c 
> b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
> index c3999dd2021e..be7ecb66ad11 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_gem_object.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
> @@ -238,6 +238,7 @@ static int check_partial_mapping(struct 
> drm_i915_gem_object *obj,
>   u32 *cpu;
>  
>   GEM_BUG_ON(view.partial.size > nreal);
> + cond_resched();

Didn't get all the intricacies of rcu, but looks of it
this marks up the need of urgent quiescent state, even
if there is nothing to reschedule so should help for stall
reports.

Reviewed-by: Mika Kuoppala 


>  
>   err = i915_gem_object_set_to_gtt_domain(obj, true);
>   if (err) {
> -- 
> 2.20.1
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 5/6] drm/i915: drop intel_device_info_dump()

2019-01-02 Thread Tvrtko Ursulin


On 02/01/2019 10:42, Jani Nikula wrote:

On Wed, 02 Jan 2019, Tvrtko Ursulin  wrote:

On 31/12/2018 14:56, Jani Nikula wrote:

The debugfs, error state and regular dmesg logging dump needs seem to be
different. Remove the generic dump function only used for the welcome
message. This may be added back later when better abstractions are
identified, but at the moment this seems to be the simplest considering
the device info rework in progress. No longer rely on device info being
a substruct of dev_priv.


Why not just make intel_device_info_dump take dev_priv?


I'm thinking the device info dumpers will need some refactoring in the
future anyway to best suit all the needs of dmesg logging, debugfs, and
error state dumping. The last one especially wants to use data copied to
the error state instead of drm_i915_private.

I admittedly took the easy way out here, and removed the function
altogether because there's currently only one user. I didn't want to
change now, and then change again later.


Okay, makes sense.

Reviewed-by: Tvrtko Ursulin 

Regards,

Tvrtko



BR,
Jani.



Regards,

Tvrtko



Cc: Tvrtko Ursulin 
Signed-off-by: Jani Nikula 
---
   drivers/gpu/drm/i915/i915_drv.c  |  8 +++-
   drivers/gpu/drm/i915/intel_device_info.c | 15 ---
   drivers/gpu/drm/i915/intel_device_info.h |  2 --
   3 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 8d7a3a852c10..fe01d090f9bb 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1636,7 +1636,13 @@ static void i915_welcome_messages(struct 
drm_i915_private *dev_priv)
if (drm_debug & DRM_UT_DRIVER) {
struct drm_printer p = drm_debug_printer("i915 device info:");
   
-		intel_device_info_dump(INTEL_INFO(dev_priv), &p);

+   drm_printf(&p, "pciid=0x%04x rev=0x%02x platform=%s gen=%i\n",
+  INTEL_DEVID(dev_priv),
+  INTEL_REVID(dev_priv),
+  intel_platform_name(INTEL_INFO(dev_priv)->platform),
+  INTEL_GEN(dev_priv));
+
+   intel_device_info_dump_flags(INTEL_INFO(dev_priv), &p);
intel_device_info_dump_runtime(RUNTIME_INFO(dev_priv), &p);
}
   
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c

index f35e8cff4b99..e0ce0c9791fc 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -113,21 +113,6 @@ void intel_device_info_dump_runtime(const struct 
intel_runtime_info *info,
   info->cs_timestamp_frequency_khz);
   }
   
-void intel_device_info_dump(const struct intel_device_info *info,

-   struct drm_printer *p)
-{
-   struct drm_i915_private *dev_priv =
-   container_of(info, struct drm_i915_private, info);
-
-   drm_printf(p, "pciid=0x%04x rev=0x%02x platform=%s gen=%i\n",
-  INTEL_DEVID(dev_priv),
-  INTEL_REVID(dev_priv),
-  intel_platform_name(info->platform),
-  info->gen);
-
-   intel_device_info_dump_flags(info, p);
-}
-
   void intel_device_info_dump_topology(const struct sseu_dev_info *sseu,
 struct drm_printer *p)
   {
diff --git a/drivers/gpu/drm/i915/intel_device_info.h 
b/drivers/gpu/drm/i915/intel_device_info.h
index f0e6d374d4ec..76735869e32d 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -267,8 +267,6 @@ static inline void sseu_set_eus(struct sseu_dev_info *sseu,
   const char *intel_platform_name(enum intel_platform platform);
   
   void intel_device_info_runtime_init(struct drm_i915_private *dev_priv);

-void intel_device_info_dump(const struct intel_device_info *info,
-   struct drm_printer *p);
   void intel_device_info_dump_flags(const struct intel_device_info *info,
  struct drm_printer *p);
   void intel_device_info_dump_runtime(const struct intel_runtime_info *info,




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


Re: [Intel-gfx] [PATCH 6/6] drm/i915: rename dev_priv info to __info to avoid usage

2019-01-02 Thread Tvrtko Ursulin


On 02/01/2019 10:44, Jani Nikula wrote:

On Wed, 02 Jan 2019, Tvrtko Ursulin  wrote:

On 31/12/2018 14:56, Jani Nikula wrote:

Encourage use of INTEL_INFO() to access dev_priv->info to not accumulate
more direct users of ->info, making further changes easier.

Cc: Tvrtko Ursulin 
Signed-off-by: Jani Nikula 
---
   drivers/gpu/drm/i915/i915_drv.h | 10 ++
   1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ce8d7a97e26b..18e67aaef764 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1431,7 +1431,7 @@ struct drm_i915_private {
struct kmem_cache *dependencies;
struct kmem_cache *priorities;
   
-	const struct intel_device_info info;

+   const struct intel_device_info __info; /* Use INTEL_INFO() to access. */
struct intel_runtime_info __runtime; /* Use RUNTIME_INFO() to access. */
struct intel_driver_caps caps;
   
@@ -2192,13 +2192,7 @@ static inline unsigned int i915_sg_segment_size(void)

return size;
   }
   
-static inline const struct intel_device_info *

-intel_info(const struct drm_i915_private *dev_priv)
-{
-   return &dev_priv->info;
-}
-


What was this helper for, who remembers? :)


Didn't dig through the git logs, but I presume it's a leftover from the
days we were migrating to subclassing drm_device in drm_i915_private...


Hm yeah, could be. So the last one:

Reviewed-by: Tvrtko Ursulin 

Regards,

Tvrtko



BR,
Jani.




Regards,

Tvrtko


-#define INTEL_INFO(dev_priv)   intel_info((dev_priv))
+#define INTEL_INFO(dev_priv)   (&(dev_priv)->__info)
   #define RUNTIME_INFO(dev_priv)   (&(dev_priv)->__runtime)
   #define DRIVER_CAPS(dev_priv)(&(dev_priv)->caps)
   






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


Re: [Intel-gfx] [PATCH 02/39] drm/i915/selftests: Take a breath during check_partial_mappings()

2019-01-02 Thread Chris Wilson
Quoting Mika Kuoppala (2019-01-02 11:07:31)
> Chris Wilson  writes:
> 
> > With kasan on a slow machine, it can take an age to check all the
> > partial mappings in a single iteration, so break it up with a
> > cond_resched) to avoid RCU stall reports.
> >
> > Signed-off-by: Chris Wilson 
> > ---
> >  drivers/gpu/drm/i915/selftests/i915_gem_object.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c 
> > b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
> > index c3999dd2021e..be7ecb66ad11 100644
> > --- a/drivers/gpu/drm/i915/selftests/i915_gem_object.c
> > +++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
> > @@ -238,6 +238,7 @@ static int check_partial_mapping(struct 
> > drm_i915_gem_object *obj,
> >   u32 *cpu;
> >  
> >   GEM_BUG_ON(view.partial.size > nreal);
> > + cond_resched();
> 
> Didn't get all the intricacies of rcu, but looks of it
> this marks up the need of urgent quiescent state, even
> if there is nothing to reschedule so should help for stall
> reports.

RCU is just the reporter of the stall in this case, it's just one of the
hung task detectors. Think of this in terms of the soft NMI watchdog, we
are inside the kernel for too long without giving userspace a chance (by
calling schedule()).
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 0/6] drm/i915: start splitting off runtime device info

2019-01-02 Thread Jani Nikula
On Wed, 02 Jan 2019, Tvrtko Ursulin  wrote:
> On 02/01/2019 09:13, Jani Nikula wrote:
>> On Tue, 01 Jan 2019, Chris Wilson  wrote:
>>> Quoting Jani Nikula (2018-12-31 14:56:40)
 The mkwrite_device_info removal series [1] seems to have stalled. I'm
 trying to nudge things forward a bit with this series. This isn't near
 as complete as Tvrtko's work, but does some of the prep work I wanted,
 specifically using INTEL_INFO() and RUNTIME_INFO() to access the
 fields. There are obviously conflicts, but mostly I think this should
 make the rest of Tvrtko's work easier, not harder.

 BR,
 Jani.


 [1] https://patchwork.freedesktop.org/series/52381/

 Cc: Tvrtko Ursulin 


 Jani Nikula (6):
drm/i915: start moving runtime device info to a separate struct
drm/i915/reg: abstract display_mmio_offset access
drm/i915: pass dev_priv to intel_device_info_runtime_init()
drm/i915: always use INTEL_INFO() to access device info
drm/i915: drop intel_device_info_dump()
drm/i915: rename dev_priv info to __info to avoid usage
>>>
>>> Looked ok, and didn't see anything odd compared to my own attempts.
>>> Reviewed-by: Chris Wilson 
>> 
>> Thanks for the review.
>> 
>> Tvrtko, I'd still like to get your ack before I go ahead and push
>> these. Also, do you think you'll have time in the near future to pick up
>> your series, or shall I?
>
> I missed Chris had already reviewed it. Yeah, series looks fine to me.

Thanks for your reviews too, pushed the series.

> With regards to the second part, after your work what I think would be 
> left from mine is:
>
>   * move some more fields/flags to runtime info
>   * subplatform/devid consolidation
>   * looking at how to wean selftests off modifying the gen field

Once we make dev_priv->info a pointer to the static const structs, I
think the selftests can make a copy, and point dev_priv->info at that
instead, and go wild. There might be a slight chicken and egg issue to
deal with in the patch series ordering though to keep it clean.

>   * maybe introducting INTEL_SSEU to avoid many RUNTIME_INFO(...)->sseu
>
> If you are in a hurry and have time you can take over, or if you are 
> just in a hurry I might be able to do within a week or two.

I'll eyeball it a bit, and let you know if I do anything to avoid
duplicating the effort.

BR,
Jani.


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


[Intel-gfx] [PATCH] drm/i915/selftests: Take a breath during check_partial_mappings()

2019-01-02 Thread Chris Wilson
With kasan on a slow machine, it can take an age to check all the
partial mappings in a single iteration, so break it up with a
cond_resched) to avoid RCU stall reports.

Signed-off-by: Chris Wilson 
Reviewed-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/selftests/i915_gem_object.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
index c3999dd2021e..be7ecb66ad11 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
@@ -238,6 +238,7 @@ static int check_partial_mapping(struct drm_i915_gem_object 
*obj,
u32 *cpu;
 
GEM_BUG_ON(view.partial.size > nreal);
+   cond_resched();
 
err = i915_gem_object_set_to_gtt_domain(obj, true);
if (err) {
-- 
2.20.1

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


[Intel-gfx] [PATCH 26/39] drm/i915: Consolidate the bound/unbound vma lists into one

2019-01-02 Thread Chris Wilson
Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_gem.c   |  4 +--
 drivers/gpu/drm/i915/i915_gem_evict.c | 12 ++---
 drivers/gpu/drm/i915/i915_gem_gtt.c   | 27 ++-
 drivers/gpu/drm/i915/i915_gem_gtt.h   | 10 +--
 drivers/gpu/drm/i915/i915_gem_shrinker.c  |  3 +--
 drivers/gpu/drm/i915/i915_gem_stolen.c|  4 ---
 drivers/gpu/drm/i915/i915_gpu_error.c | 11 
 drivers/gpu/drm/i915/i915_vma.c   |  7 +
 .../gpu/drm/i915/selftests/i915_gem_evict.c   | 11 +++-
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  4 ---
 10 files changed, 32 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 66445e34c93c..a954e15c0315 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -254,7 +254,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void 
*data,
mutex_lock(&ggtt->vm.mutex);
 
pinned = ggtt->vm.reserved;
-   list_for_each_entry(vma, &ggtt->vm.bound_list, vm_link)
+   list_for_each_entry(vma, &ggtt->vm.vma_list, vm_link)
if (i915_vma_is_pinned(vma))
pinned += vma->node.size;
 
@@ -1692,7 +1692,7 @@ static void i915_gem_object_bump_inactive_ggtt(struct 
drm_i915_gem_object *obj)
if (!drm_mm_node_allocated(&vma->node))
continue;
 
-   list_move_tail(&vma->vm_link, &vma->vm->bound_list);
+   list_move_tail(&vma->vm_link, &i915->ggtt.vm.vma_list);
}
mutex_unlock(&i915->ggtt.vm.mutex);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c 
b/drivers/gpu/drm/i915/i915_gem_evict.c
index b7c2a396a63f..8ccde5761c2c 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -170,7 +170,10 @@ i915_gem_evict_something(struct i915_address_space *vm,
 search_again:
active = NULL;
INIT_LIST_HEAD(&eviction_list);
-   list_for_each_entry_safe(vma, next, &vm->bound_list, vm_link) {
+   list_for_each_entry_safe(vma, next, &vm->vma_list, vm_link) {
+   if (!drm_mm_node_allocated(&vma->node))
+   continue;
+
if (i915_vma_is_active(vma)) {
if (vma == active) {
if (flags & PIN_NONBLOCK)
@@ -183,7 +186,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
if (!active)
active = vma;
 
-   list_move_tail(&vma->vm_link, &vm->bound_list);
+   list_move_tail(&vma->vm_link, &vm->vma_list);
continue;
}
}
@@ -419,7 +422,10 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
 
INIT_LIST_HEAD(&eviction_list);
mutex_lock(&vm->mutex);
-   list_for_each_entry(vma, &vm->bound_list, vm_link) {
+   list_for_each_entry(vma, &vm->vma_list, vm_link) {
+   if (!drm_mm_node_allocated(&vma->node))
+   continue;
+
if (i915_vma_is_pinned(vma))
continue;
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 7ae10fbb2ee0..17b752f9a1e6 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -492,8 +492,7 @@ static void i915_address_space_init(struct 
i915_address_space *vm, int subclass)
 
stash_init(&vm->free_pages);
 
-   INIT_LIST_HEAD(&vm->unbound_list);
-   INIT_LIST_HEAD(&vm->bound_list);
+   INIT_LIST_HEAD(&vm->vma_list);
 }
 
 static void i915_address_space_fini(struct i915_address_space *vm)
@@ -1934,7 +1933,7 @@ static struct i915_vma *pd_vma_create(struct 
gen6_hw_ppgtt *ppgtt, int size)
INIT_LIST_HEAD(&vma->obj_link);
 
mutex_lock(&vma->vm->mutex);
-   list_add(&vma->vm_link, &vma->vm->unbound_list);
+   list_add(&vma->vm_link, &vma->vm->vma_list);
mutex_unlock(&vma->vm->mutex);
 
return vma;
@@ -2113,19 +2112,12 @@ void i915_ppgtt_close(struct i915_address_space *vm)
 
 static void ppgtt_destroy_vma(struct i915_address_space *vm)
 {
-   struct list_head *phases[] = {
-   &vm->bound_list,
-   &vm->unbound_list,
-   NULL,
-   }, **phase;
+   struct i915_vma *vma, *vn;
 
vm->closed = true;
-   for (phase = phases; *phase; phase++) {
-   struct i915_vma *vma, *vn;
-
-   list_for_each_entry_safe(vma, vn, *phase, vm_link)
-   i915_vma_destroy(vma);
-   }
+   list_for_each_entry_safe(vma, vn, &vm->vma_list, vm_link)
+   i915_vma_destroy(vma);
+   GEM_BUG_ON(!list_empty(&vm->vma_list));
 }
 
 void i915_ppgtt_release(struct kref *kref)
@@ -2137,9 +2129,6 @@ void i915_ppgtt_release(

[Intel-gfx] [PATCH 23/39] drm/i915: Issue engine resets onto idle engines

2019-01-02 Thread Chris Wilson
Always perform the requested reset, even if we believe the engine is
idle. Presumably there was a reason the caller wanted the reset, and in
the near future we lose the easy tracking for whether the engine is
idle.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_reset.c |  4 
 .../gpu/drm/i915/selftests/intel_hangcheck.c  | 22 +--
 2 files changed, 6 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reset.c 
b/drivers/gpu/drm/i915/i915_reset.c
index aaddc0363124..3736a1121237 100644
--- a/drivers/gpu/drm/i915/i915_reset.c
+++ b/drivers/gpu/drm/i915/i915_reset.c
@@ -1060,10 +1060,6 @@ int i915_reset_engine(struct intel_engine_cs *engine, 
const char *msg)
GEM_TRACE("%s flags=%lx\n", engine->name, error->flags);
GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags));
 
-   if (i915_seqno_passed(intel_engine_get_seqno(engine),
- intel_engine_last_submit(engine)))
-   return 0;
-
reset_prepare_engine(engine);
 
if (msg)
diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c 
b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
index 67431355cd6e..4809874ab28c 100644
--- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
+++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
@@ -449,8 +449,6 @@ static int __igt_reset_engine(struct drm_i915_private 
*i915, bool active)
 
set_bit(I915_RESET_ENGINE + id, &i915->gpu_error.flags);
do {
-   u32 seqno = intel_engine_get_seqno(engine);
-
if (active) {
struct i915_request *rq;
 
@@ -479,8 +477,6 @@ static int __igt_reset_engine(struct drm_i915_private 
*i915, bool active)
break;
}
 
-   GEM_BUG_ON(!rq->global_seqno);
-   seqno = rq->global_seqno - 1;
i915_request_put(rq);
}
 
@@ -496,11 +492,10 @@ static int __igt_reset_engine(struct drm_i915_private 
*i915, bool active)
break;
}
 
-   reset_engine_count += active;
if (i915_reset_engine_count(&i915->gpu_error, engine) !=
-   reset_engine_count) {
-   pr_err("%s engine reset %srecorded!\n",
-  engine->name, active ? "not " : "");
+   ++reset_engine_count) {
+   pr_err("%s engine reset not recorded!\n",
+  engine->name);
err = -EINVAL;
break;
}
@@ -728,7 +723,6 @@ static int __igt_reset_engines(struct drm_i915_private 
*i915,
 
set_bit(I915_RESET_ENGINE + id, &i915->gpu_error.flags);
do {
-   u32 seqno = intel_engine_get_seqno(engine);
struct i915_request *rq = NULL;
 
if (flags & TEST_ACTIVE) {
@@ -756,9 +750,6 @@ static int __igt_reset_engines(struct drm_i915_private 
*i915,
err = -EIO;
break;
}
-
-   GEM_BUG_ON(!rq->global_seqno);
-   seqno = rq->global_seqno - 1;
}
 
err = i915_reset_engine(engine, NULL);
@@ -795,10 +786,9 @@ static int __igt_reset_engines(struct drm_i915_private 
*i915,
 
reported = i915_reset_engine_count(&i915->gpu_error, engine);
reported -= threads[engine->id].resets;
-   if (reported != (flags & TEST_ACTIVE ? count : 0)) {
-   pr_err("i915_reset_engine(%s:%s): reset %lu times, but 
reported %lu, expected %lu reported\n",
-  engine->name, test_name, count, reported,
-  (flags & TEST_ACTIVE ? count : 0));
+   if (reported != count) {
+   pr_err("i915_reset_engine(%s:%s): reset %lu times, but 
reported %lu\n",
+  engine->name, test_name, count, reported);
if (!err)
err = -EINVAL;
}
-- 
2.20.1

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


[Intel-gfx] [PATCH 16/39] drm/i915: Mark up Ironlake ips with rpm wakerefs

2019-01-02 Thread Chris Wilson
Currently Ironlake operates under the assumption that rpm awake (and its
error checking is disabled). As such, we have missed a few places where we
access registers without taking the rpm wakeref and thus trigger
warnings. intel_ips being one culprit.

As this involved adding a potentially sleeping rpm_get, we have to
rearrange the spinlocks slightly and so switch to acquiring a device-ref
under the spinlock rather than hold the spinlock for the whole
operation. To be consistent, we make the change in pattern common to the
intel_ips interface even though this adds a few more atomic operations
than necessary in a few cases.

v2: Sagar noted the mb around setting mch_dev were overkill as we only
need ordering there, and that i915_emon_status was still using
struct_mutex for no reason, but lacked rpm.

Signed-off-by: Chris Wilson 
Cc: Sagar Arun Kamble 
---
 drivers/gpu/drm/i915/i915_debugfs.c |  32 ++
 drivers/gpu/drm/i915/i915_drv.c |   3 +
 drivers/gpu/drm/i915/intel_pm.c | 172 ++--
 3 files changed, 102 insertions(+), 105 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 58994f12cfa8..99cde93fa9c7 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1741,32 +1741,24 @@ static int i915_sr_status(struct seq_file *m, void 
*unused)
 
 static int i915_emon_status(struct seq_file *m, void *unused)
 {
-   struct drm_i915_private *dev_priv = node_to_i915(m->private);
-   struct drm_device *dev = &dev_priv->drm;
-   unsigned long temp, chipset, gfx;
+   struct drm_i915_private *i915 = node_to_i915(m->private);
intel_wakeref_t wakeref;
-   int ret;
 
-   if (!IS_GEN(dev_priv, 5))
+   if (!IS_GEN(i915, 5))
return -ENODEV;
 
-   ret = mutex_lock_interruptible(&dev->struct_mutex);
-   if (ret)
-   return ret;
+   with_intel_runtime_pm(i915, wakeref) {
+   unsigned long temp, chipset, gfx;
 
-   wakeref = intel_runtime_pm_get(dev_priv);
-
-   temp = i915_mch_val(dev_priv);
-   chipset = i915_chipset_val(dev_priv);
-   gfx = i915_gfx_val(dev_priv);
-   mutex_unlock(&dev->struct_mutex);
+   temp = i915_mch_val(i915);
+   chipset = i915_chipset_val(i915);
+   gfx = i915_gfx_val(i915);
 
-   intel_runtime_pm_put(dev_priv, wakeref);
-
-   seq_printf(m, "GMCH temp: %ld\n", temp);
-   seq_printf(m, "Chipset power: %ld\n", chipset);
-   seq_printf(m, "GFX power: %ld\n", gfx);
-   seq_printf(m, "Total power: %ld\n", chipset + gfx);
+   seq_printf(m, "GMCH temp: %ld\n", temp);
+   seq_printf(m, "Chipset power: %ld\n", chipset);
+   seq_printf(m, "GFX power: %ld\n", gfx);
+   seq_printf(m, "Total power: %ld\n", chipset + gfx);
+   }
 
return 0;
 }
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 1af88534ee0d..aa6e782afbe5 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1775,6 +1775,9 @@ void i915_driver_unload(struct drm_device *dev)
 
i915_driver_unregister(dev_priv);
 
+   /* Flush any external code that still may be under the RCU lock */
+   synchronize_rcu();
+
if (i915_gem_suspend(dev_priv))
DRM_ERROR("failed to idle hardware; continuing to unload!\n");
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ff6b58d4efa6..690a8e20c119 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6203,10 +6203,6 @@ void intel_init_ipc(struct drm_i915_private *dev_priv)
  */
 DEFINE_SPINLOCK(mchdev_lock);
 
-/* Global for IPS driver to get at the current i915 device. Protected by
- * mchdev_lock. */
-static struct drm_i915_private *i915_mch_dev;
-
 bool ironlake_set_drps(struct drm_i915_private *dev_priv, u8 val)
 {
u16 rgvswctl;
@@ -7849,16 +7845,17 @@ static unsigned long __i915_chipset_val(struct 
drm_i915_private *dev_priv)
 
 unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
 {
-   unsigned long val;
+   intel_wakeref_t wakeref;
+   unsigned long val = 0;
 
if (!IS_GEN(dev_priv, 5))
return 0;
 
-   spin_lock_irq(&mchdev_lock);
-
-   val = __i915_chipset_val(dev_priv);
-
-   spin_unlock_irq(&mchdev_lock);
+   with_intel_runtime_pm(dev_priv, wakeref) {
+   spin_lock_irq(&mchdev_lock);
+   val = __i915_chipset_val(dev_priv);
+   spin_unlock_irq(&mchdev_lock);
+   }
 
return val;
 }
@@ -7935,14 +7932,16 @@ static void __i915_update_gfx_val(struct 
drm_i915_private *dev_priv)
 
 void i915_update_gfx_val(struct drm_i915_private *dev_priv)
 {
+   intel_wakeref_t wakeref;
+
if (!IS_GEN(dev_priv, 5))
return;
 
-   spin_lock_irq(&mchdev_lock);
-
-   __i

[Intel-gfx] [PATCH 19/39] drm/i915: Pull all the reset functionality together into i915_reset.c

2019-01-02 Thread Chris Wilson
Currently the code to reset the GPU and our state is spread widely
across a few files. Pull the logic together into a common file.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/Makefile |3 +-
 drivers/gpu/drm/i915/i915_debugfs.c   |2 +
 drivers/gpu/drm/i915/i915_drv.c   |  206 +--
 drivers/gpu/drm/i915/i915_drv.h   |   33 +-
 drivers/gpu/drm/i915/i915_gem.c   |  443 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c   |1 +
 drivers/gpu/drm/i915/i915_irq.c   |  238 ---
 drivers/gpu/drm/i915/i915_request.c   |1 +
 drivers/gpu/drm/i915/i915_reset.c | 1386 +
 drivers/gpu/drm/i915/i915_reset.h |   56 +
 drivers/gpu/drm/i915/intel_display.c  |   15 +-
 drivers/gpu/drm/i915/intel_engine_cs.c|1 +
 drivers/gpu/drm/i915/intel_guc.h  |3 +
 drivers/gpu/drm/i915/intel_hangcheck.c|1 +
 drivers/gpu/drm/i915/intel_uc.c   |1 +
 drivers/gpu/drm/i915/intel_uncore.c   |  556 ---
 drivers/gpu/drm/i915/selftests/intel_lrc.c|2 +
 .../drm/i915/selftests/intel_workarounds.c|1 +
 18 files changed, 1480 insertions(+), 1469 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_reset.c
 create mode 100644 drivers/gpu/drm/i915/i915_reset.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index c34bee16730d..65ed00db 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -40,9 +40,10 @@ i915-y := i915_drv.o \
  i915_mm.o \
  i915_params.o \
  i915_pci.o \
+ i915_reset.o \
  i915_suspend.o \
- i915_syncmap.o \
  i915_sw_fence.o \
+ i915_syncmap.o \
  i915_sysfs.o \
  intel_csr.o \
  intel_device_info.o \
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 99cde93fa9c7..e162ad357b17 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -32,6 +32,8 @@
 #include "intel_drv.h"
 #include "intel_guc_submission.h"
 
+#include "i915_reset.h"
+
 static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node)
 {
return to_i915(node->minor->dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index aa6e782afbe5..2687922ca8f6 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -49,6 +49,7 @@
 #include "i915_drv.h"
 #include "i915_trace.h"
 #include "i915_pmu.h"
+#include "i915_reset.h"
 #include "i915_query.h"
 #include "i915_vgpu.h"
 #include "intel_drv.h"
@@ -2200,211 +2201,6 @@ static int i915_resume_switcheroo(struct drm_device 
*dev)
return i915_drm_resume(dev);
 }
 
-/**
- * i915_reset - reset chip after a hang
- * @i915: #drm_i915_private to reset
- * @stalled_mask: mask of the stalled engines with the guilty requests
- * @reason: user error message for why we are resetting
- *
- * Reset the chip.  Useful if a hang is detected. Marks the device as wedged
- * on failure.
- *
- * Caller must hold the struct_mutex.
- *
- * Procedure is fairly simple:
- *   - reset the chip using the reset reg
- *   - re-init context state
- *   - re-init hardware status page
- *   - re-init ring buffer
- *   - re-init interrupt state
- *   - re-init display
- */
-void i915_reset(struct drm_i915_private *i915,
-   unsigned int stalled_mask,
-   const char *reason)
-{
-   struct i915_gpu_error *error = &i915->gpu_error;
-   int ret;
-   int i;
-
-   GEM_TRACE("flags=%lx\n", error->flags);
-
-   might_sleep();
-   lockdep_assert_held(&i915->drm.struct_mutex);
-   assert_rpm_wakelock_held(i915);
-   GEM_BUG_ON(!test_bit(I915_RESET_BACKOFF, &error->flags));
-
-   if (!test_bit(I915_RESET_HANDOFF, &error->flags))
-   return;
-
-   /* Clear any previous failed attempts at recovery. Time to try again. */
-   if (!i915_gem_unset_wedged(i915))
-   goto wakeup;
-
-   if (reason)
-   dev_notice(i915->drm.dev, "Resetting chip for %s\n", reason);
-   error->reset_count++;
-
-   ret = i915_gem_reset_prepare(i915);
-   if (ret) {
-   dev_err(i915->drm.dev, "GPU recovery failed\n");
-   goto taint;
-   }
-
-   if (!intel_has_gpu_reset(i915)) {
-   if (i915_modparams.reset)
-   dev_err(i915->drm.dev, "GPU reset not supported\n");
-   else
-   DRM_DEBUG_DRIVER("GPU reset disabled\n");
-   goto error;
-   }
-
-   for (i = 0; i < 3; i++) {
-   ret = intel_gpu_reset(i915, ALL_ENGINES);
-   if (ret == 0)
-   break;
-
-   msleep(100);
-   }
-   if (ret) {
-   dev_err(i915->drm.dev, "Failed to reset chip\n");
-   

[Intel-gfx] ✗ Fi.CI.BAT: failure for series starting with [01/39] drm: Reorder set_property_atomic to avoid returning with an active ww_ctx

2019-01-02 Thread Patchwork
== Series Details ==

Series: series starting with [01/39] drm: Reorder set_property_atomic to avoid 
returning with an active ww_ctx
URL   : https://patchwork.freedesktop.org/series/54636/
State : failure

== Summary ==

Applying: drm: Reorder set_property_atomic to avoid returning with an active 
ww_ctx
Applying: drm/i915/selftests: Take a breath during check_partial_mappings()
Applying: drm/i915: Return immediately if trylock fails for direct-reclaim
Applying: drm/i915/userptr: Avoid struct_mutex recursion for 
mmu_invalidate_range_start
Applying: drm/i915/userptr: Probe vma range before gup
Applying: drm/i915: Always try to reset the GPU on takeover
Applying: drm/i915: Report the number of closed vma held by each context in 
debugfs
Applying: drm/i915: Track all held rpm wakerefs
Applying: drm/i915: Markup paired operations on wakerefs
Using index info to reconstruct a base tree...
M   drivers/gpu/drm/i915/i915_debugfs.c
M   drivers/gpu/drm/i915/i915_drv.h
M   drivers/gpu/drm/i915/i915_perf.c
M   drivers/gpu/drm/i915/intel_display.c
M   drivers/gpu/drm/i915/intel_engine_cs.c
M   drivers/gpu/drm/i915/intel_uncore.c
M   drivers/gpu/drm/i915/selftests/i915_gem_context.c
M   drivers/gpu/drm/i915/selftests/intel_lrc.c
Falling back to patching base and 3-way merge...
Auto-merging drivers/gpu/drm/i915/selftests/intel_lrc.c
Auto-merging drivers/gpu/drm/i915/selftests/i915_gem_context.c
Auto-merging drivers/gpu/drm/i915/intel_uncore.c
Auto-merging drivers/gpu/drm/i915/intel_engine_cs.c
Auto-merging drivers/gpu/drm/i915/intel_display.c
Auto-merging drivers/gpu/drm/i915/i915_perf.c
Auto-merging drivers/gpu/drm/i915/i915_drv.h
Auto-merging drivers/gpu/drm/i915/i915_debugfs.c
Applying: drm/i915: Syntatic sugar for using intel_runtime_pm
Using index info to reconstruct a base tree...
M   drivers/gpu/drm/i915/i915_debugfs.c
M   drivers/gpu/drm/i915/intel_uncore.c
M   drivers/gpu/drm/i915/selftests/i915_gem_context.c
Falling back to patching base and 3-way merge...
Auto-merging drivers/gpu/drm/i915/selftests/i915_gem_context.c
Auto-merging drivers/gpu/drm/i915/intel_uncore.c
Auto-merging drivers/gpu/drm/i915/i915_debugfs.c
Applying: drm/i915: Markup paired operations on display power domains
Applying: drm/i915: Track the wakeref used to initialise display power domains
Applying: drm/i915: Combined gt.awake/gt.power wakerefs
Applying: drm/i915/dp: Markup pps lock power well
Applying: drm/i915: Complain if hsw_get_pipe_config acquires the same power 
well twice
Applying: drm/i915: Mark up Ironlake ips with rpm wakerefs
Applying: drm/i915: Serialise concurrent calls to i915_gem_set_wedged()
Applying: drm/i915: Differentiate between ggtt->mutex and ppgtt->mutex
Applying: drm/i915: Pull all the reset functionality together into i915_reset.c
Using index info to reconstruct a base tree...
M   drivers/gpu/drm/i915/i915_debugfs.c
M   drivers/gpu/drm/i915/i915_drv.c
M   drivers/gpu/drm/i915/i915_drv.h
M   drivers/gpu/drm/i915/intel_display.c
M   drivers/gpu/drm/i915/intel_engine_cs.c
M   drivers/gpu/drm/i915/intel_uncore.c
M   drivers/gpu/drm/i915/selftests/intel_lrc.c
Falling back to patching base and 3-way merge...
Auto-merging drivers/gpu/drm/i915/selftests/intel_lrc.c
Auto-merging drivers/gpu/drm/i915/intel_uncore.c
CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/intel_uncore.c
Auto-merging drivers/gpu/drm/i915/intel_engine_cs.c
Auto-merging drivers/gpu/drm/i915/intel_display.c
Auto-merging drivers/gpu/drm/i915/i915_drv.h
Auto-merging drivers/gpu/drm/i915/i915_drv.c
Auto-merging drivers/gpu/drm/i915/i915_debugfs.c
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch' to see the failed patch
Patch failed at 0019 drm/i915: Pull all the reset functionality together into 
i915_reset.c
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

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


[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915/selftests: Take a breath during check_partial_mappings()

2019-01-02 Thread Patchwork
== Series Details ==

Series: drm/i915/selftests: Take a breath during check_partial_mappings()
URL   : https://patchwork.freedesktop.org/series/54639/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5357 -> Patchwork_11174


Summary
---

  **WARNING**

  Minor unknown changes coming with Patchwork_11174 need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_11174, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: 
https://patchwork.freedesktop.org/api/1.0/series/54639/revisions/1/mbox/

Possible new issues
---

  Here are the unknown changes that may have been introduced in Patchwork_11174:

### IGT changes ###

 Warnings 

  * igt@kms_busy@basic-flip-a:
- fi-kbl-7567u:   PASS -> SKIP +2

  * igt@kms_pipe_crc_basic@nonblocking-crc-pipe-c:
- fi-kbl-7567u:   SKIP -> PASS +33

  
Known issues


  Here are the changes found in Patchwork_11174 that come from known issues:

### IGT changes ###

 Issues hit 

  * igt@gem_exec_suspend@basic-s3:
- fi-blb-e6850:   PASS -> INCOMPLETE [fdo#107718]

  * igt@i915_selftest@live_hangcheck:
- fi-bwr-2160:PASS -> DMESG-FAIL [fdo#108735]

  * igt@kms_chamelium@hdmi-hpd-fast:
- fi-kbl-7500u:   PASS -> FAIL [fdo#108767]

  
 Possible fixes 

  * igt@kms_pipe_crc_basic@nonblocking-crc-pipe-a-frame-sequence:
- fi-byt-clapper: FAIL [fdo#103191] / [fdo#107362] -> PASS

  
  [fdo#103191]: https://bugs.freedesktop.org/show_bug.cgi?id=103191
  [fdo#107362]: https://bugs.freedesktop.org/show_bug.cgi?id=107362
  [fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718
  [fdo#108735]: https://bugs.freedesktop.org/show_bug.cgi?id=108735
  [fdo#108767]: https://bugs.freedesktop.org/show_bug.cgi?id=108767


Participating hosts (50 -> 42)
--

  Missing(8): fi-kbl-soraka fi-ilk-m540 fi-bxt-dsi fi-hsw-4200u 
fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-icl-y 


Build changes
-

* Linux: CI_DRM_5357 -> Patchwork_11174

  CI_DRM_5357: 5afa91c58a040c48f09a1884f6a0b039adf51b6c @ 
git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4755: 0ba18cf75cafb51d1e72557528de4a1be640a85c @ 
git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_11174: f19dd8e416463325ff808a10bc80002d39348d41 @ 
git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

f19dd8e41646 drm/i915/selftests: Take a breath during check_partial_mappings()

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_11174/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH i-g-t] i915/gem_busy: Use a non-preemptible hanging batch

2019-01-02 Thread Mika Kuoppala
Chris Wilson  writes:

> Ensure that the hangcheck notices the hanging batch by using a
> non-preemptible spin batch, as some future versions of hangcheck may
> allow a preemptible GPU hog to survive.
>
> Signed-off-by: Chris Wilson 

Reviewed-by: Mika Kuoppala 

> ---
>  tests/i915/gem_busy.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/tests/i915/gem_busy.c b/tests/i915/gem_busy.c
> index 76b44a5d4..eb3d3ef2b 100644
> --- a/tests/i915/gem_busy.c
> +++ b/tests/i915/gem_busy.c
> @@ -427,7 +427,10 @@ static bool has_extended_busy_ioctl(int fd)
>  
>  static void basic(int fd, unsigned ring, unsigned flags)
>  {
> - igt_spin_t *spin = igt_spin_batch_new(fd, .engine = ring);
> + igt_spin_t *spin =
> + igt_spin_batch_new(fd,
> +.engine = ring,
> +.flags = IGT_SPIN_NO_PREEMPTION);
>   struct timespec tv;
>   int timeout;
>   bool busy;
> -- 
> 2.20.1
>
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 24/39] drm/i915: Stop tracking MRU activity on VMA

2019-01-02 Thread Tvrtko Ursulin


On 02/01/2019 09:41, Chris Wilson wrote:

Our goal is to remove struct_mutex and replace it with fine grained
locking. One of the thorny issues is our eviction logic for reclaiming
space for an execbuffer (or GTT mmaping, among a few other examples).
While eviction itself is easy to move under a per-VM mutex, performing
the activity tracking is less agreeable. One solution is not to do any
MRU tracking and do a simple coarse evaluation during eviction of
active/inactive, with a loose temporal ordering of last
insertion/evaluation. That keeps all the locking constrained to when we
are manipulating the VM itself, neatly avoiding the tricky handling of
possible recursive locking during execbuf and elsewhere.

Note that discarding the MRU is unlikely to impact upon our efficiency
to reclaim VM space (where we think a LRU model is best) as our
current strategy is to use random idle replacement first before doing
a search, and over time the use of softpinned 48b per-ppGTT is growing
(thereby eliminating any need to perform any eviction searches, in
theory at least).


Please also say in the commit that not only it is stopping MRU, but also 
tracking active/inactive and consolidating to one list.




Signed-off-by: Chris Wilson 
---
  drivers/gpu/drm/i915/i915_gem.c   | 10 +---
  drivers/gpu/drm/i915/i915_gem_evict.c | 56 ++-
  drivers/gpu/drm/i915/i915_gem_gtt.c   | 15 ++---
  drivers/gpu/drm/i915/i915_gem_gtt.h   | 26 +
  drivers/gpu/drm/i915/i915_gem_shrinker.c  |  8 ++-
  drivers/gpu/drm/i915/i915_gem_stolen.c|  3 +-
  drivers/gpu/drm/i915/i915_gpu_error.c | 37 ++--
  drivers/gpu/drm/i915/i915_vma.c   |  9 +--
  .../gpu/drm/i915/selftests/i915_gem_evict.c   |  4 +-
  drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  2 +-
  10 files changed, 69 insertions(+), 101 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 800b2c770dce..d9e1dcee176c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -254,10 +254,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void 
*data,
  
  	pinned = ggtt->vm.reserved;

mutex_lock(&dev->struct_mutex);
-   list_for_each_entry(vma, &ggtt->vm.active_list, vm_link)
-   if (i915_vma_is_pinned(vma))
-   pinned += vma->node.size;
-   list_for_each_entry(vma, &ggtt->vm.inactive_list, vm_link)
+   list_for_each_entry(vma, &ggtt->vm.bound_list, vm_link)
if (i915_vma_is_pinned(vma))
pinned += vma->node.size;
mutex_unlock(&dev->struct_mutex);
@@ -1690,13 +1687,10 @@ static void i915_gem_object_bump_inactive_ggtt(struct 
drm_i915_gem_object *obj)
GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
  
  	for_each_ggtt_vma(vma, obj) {

-   if (i915_vma_is_active(vma))
-   continue;
-
if (!drm_mm_node_allocated(&vma->node))
continue;
  
-		list_move_tail(&vma->vm_link, &vma->vm->inactive_list);

+   list_move_tail(&vma->vm_link, &vma->vm->bound_list);
}
  
  	i915 = to_i915(obj->base.dev);

diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c 
b/drivers/gpu/drm/i915/i915_gem_evict.c
index 02b83a5ed96c..6a3608398d2a 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -127,14 +127,10 @@ i915_gem_evict_something(struct i915_address_space *vm,
struct drm_i915_private *dev_priv = vm->i915;
struct drm_mm_scan scan;
struct list_head eviction_list;
-   struct list_head *phases[] = {
-   &vm->inactive_list,
-   &vm->active_list,
-   NULL,
-   }, **phase;
struct i915_vma *vma, *next;
struct drm_mm_node *node;
enum drm_mm_insert_mode mode;
+   struct i915_vma *active;
int ret;
  
  	lockdep_assert_held(&vm->i915->drm.struct_mutex);


There is a comment block below here which talks about active and 
inactive lists which needs updating.



@@ -170,17 +166,31 @@ i915_gem_evict_something(struct i915_address_space *vm,
 */
if (!(flags & PIN_NONBLOCK))
i915_retire_requests(dev_priv);
-   else
-   phases[1] = NULL;
  
  search_again:

+   active = NULL;
INIT_LIST_HEAD(&eviction_list);
-   phase = phases;
-   do {
-   list_for_each_entry(vma, *phase, vm_link)
-   if (mark_free(&scan, vma, flags, &eviction_list))
-   goto found;
-   } while (*++phase);
+   list_for_each_entry_safe(vma, next, &vm->bound_list, vm_link) {
+   if (i915_vma_is_active(vma)) {
+   if (vma == active) {


s/active/first_active/ ?


+   if (flags & PIN_NONBLOCK)
+   break;
+
+   

Re: [Intel-gfx] [PATCH 25/39] drm/i915: Pull VM lists under the VM mutex.

2019-01-02 Thread Tvrtko Ursulin


On 02/01/2019 09:41, Chris Wilson wrote:

Give it a bit of commit text please.


Signed-off-by: Chris Wilson 
---
  drivers/gpu/drm/i915/i915_gem.c | 14 --
  drivers/gpu/drm/i915/i915_gem_evict.c   |  2 ++
  drivers/gpu/drm/i915/i915_gem_gtt.c | 15 +--
  drivers/gpu/drm/i915/i915_gem_shrinker.c|  4 
  drivers/gpu/drm/i915/i915_gem_stolen.c  |  2 ++
  drivers/gpu/drm/i915/i915_vma.c | 11 +++
  drivers/gpu/drm/i915/selftests/i915_gem_evict.c |  3 +++
  drivers/gpu/drm/i915/selftests/i915_gem_gtt.c   |  3 +++
  8 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d9e1dcee176c..66445e34c93c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -246,18 +246,19 @@ int
  i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
  {
-   struct drm_i915_private *dev_priv = to_i915(dev);
-   struct i915_ggtt *ggtt = &dev_priv->ggtt;
+   struct i915_ggtt *ggtt = &to_i915(dev)->ggtt;
struct drm_i915_gem_get_aperture *args = data;
struct i915_vma *vma;
u64 pinned;
  
+	mutex_lock(&ggtt->vm.mutex);

+
pinned = ggtt->vm.reserved;
-   mutex_lock(&dev->struct_mutex);
list_for_each_entry(vma, &ggtt->vm.bound_list, vm_link)
if (i915_vma_is_pinned(vma))
pinned += vma->node.size;
-   mutex_unlock(&dev->struct_mutex);
+
+   mutex_unlock(&ggtt->vm.mutex);
  
  	args->aper_size = ggtt->vm.total;

args->aper_available_size = args->aper_size - pinned;
@@ -1680,20 +1681,21 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void 
*data,
  
  static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj)

  {
-   struct drm_i915_private *i915;
+   struct drm_i915_private *i915 = to_i915(obj->base.dev);
struct list_head *list;
struct i915_vma *vma;
  
  	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
  
+	mutex_lock(&i915->ggtt.vm.mutex);

for_each_ggtt_vma(vma, obj) {
if (!drm_mm_node_allocated(&vma->node))
continue;
  
  		list_move_tail(&vma->vm_link, &vma->vm->bound_list);

}
+   mutex_unlock(&i915->ggtt.vm.mutex);
  
-	i915 = to_i915(obj->base.dev);

spin_lock(&i915->mm.obj_lock);
list = obj->bind_count ? &i915->mm.bound_list : &i915->mm.unbound_list;
list_move_tail(&obj->mm.link, list);
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c 
b/drivers/gpu/drm/i915/i915_gem_evict.c
index 6a3608398d2a..b7c2a396a63f 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -418,6 +418,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
}
  
  	INIT_LIST_HEAD(&eviction_list);

+   mutex_lock(&vm->mutex);
list_for_each_entry(vma, &vm->bound_list, vm_link) {
if (i915_vma_is_pinned(vma))
continue;
@@ -425,6 +426,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
__i915_vma_pin(vma);
list_add(&vma->evict_link, &eviction_list);
}
+   mutex_unlock(&vm->mutex);
  
  	ret = 0;

list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index e5e23c4ac769..7ae10fbb2ee0 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1932,7 +1932,10 @@ static struct i915_vma *pd_vma_create(struct 
gen6_hw_ppgtt *ppgtt, int size)
vma->ggtt_view.type = I915_GGTT_VIEW_ROTATED; /* prevent fencing */
  
  	INIT_LIST_HEAD(&vma->obj_link);

+
+   mutex_lock(&vma->vm->mutex);
list_add(&vma->vm_link, &vma->vm->unbound_list);
+   mutex_unlock(&vma->vm->mutex);
  
  	return vma;

  }
@@ -3504,9 +3507,10 @@ void i915_gem_restore_gtt_mappings(struct 
drm_i915_private *dev_priv)
  
  	i915_check_and_clear_faults(dev_priv);
  
+	mutex_lock(&ggtt->vm.mutex);

+
/* First fill our portion of the GTT with scratch pages */
ggtt->vm.clear_range(&ggtt->vm, 0, ggtt->vm.total);
-
ggtt->vm.closed = true; /* skip rewriting PTE on VMA unbind */
  
  	/* clflush objects bound into the GGTT and rebind them. */

@@ -3516,19 +3520,26 @@ void i915_gem_restore_gtt_mappings(struct 
drm_i915_private *dev_priv)
if (!(vma->flags & I915_VMA_GLOBAL_BIND))
continue;
  
+		mutex_unlock(&ggtt->vm.mutex);

+
if (!i915_vma_unbind(vma))


What is the model - traverse under the new lock but then no need to get 
a reference to operate on outside the lock?



-   continue;
+   goto lock;
  
  		WARN_ON(i915_vma_bind(vma,

  o

Re: [Intel-gfx] [PATCH 06/39] drm/i915: Always try to reset the GPU on takeover

2019-01-02 Thread Mika Kuoppala
Chris Wilson  writes:

> When we first introduced the reset to sanitize the GPU on taking over
> from the BIOS and before returning control to third parties (the BIOS!),
> we restricted it to only systems utilizing HW contexts as we were
> uncertain of how stable our reset mechanism truly was. We now have
> reasonable coverage across all machines that expose a GPU reset method,
> and so we should be safe to sanitize the GPU state everywhere.
>
> v2: We _have_ to skip the reset if it would clobber the display.
>
> Signed-off-by: Chris Wilson 
> ---
>  drivers/gpu/drm/i915/i915_drv.c   |  2 +-
>  drivers/gpu/drm/i915/i915_gem.c   | 11 ++-
>  drivers/gpu/drm/i915/i915_pci.c   |  5 +
>  drivers/gpu/drm/i915/intel_device_info.h  |  1 +
>  drivers/gpu/drm/i915/intel_display.c  |  4 ++--
>  drivers/gpu/drm/i915/intel_engine_cs.c| 14 +-
>  drivers/gpu/drm/i915/intel_ringbuffer.h   |  2 +-
>  drivers/gpu/drm/i915/selftests/i915_gem.c |  2 +-
>  8 files changed, 26 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index dcb935338c63..a96169acdb07 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -2174,7 +2174,7 @@ static int i915_drm_resume_early(struct drm_device *dev)
>  
>   intel_power_domains_resume(dev_priv);
>  
> - intel_engines_sanitize(dev_priv);
> + intel_engines_sanitize(dev_priv, true);
>  
>   enable_rpm_wakeref_asserts(dev_priv);
>  
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index e46a25747ab7..0ebde13620cb 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -3432,8 +3432,7 @@ bool i915_gem_unset_wedged(struct drm_i915_private 
> *i915)
>   i915_retire_requests(i915);
>   GEM_BUG_ON(i915->gt.active_requests);
>  
> - if (!intel_gpu_reset(i915, ALL_ENGINES))
> - intel_engines_sanitize(i915);
> + intel_engines_sanitize(i915, false);
>  
>   /*
>* Undo nop_submit_request. We prevent all new i915 requests from
> @@ -5037,8 +5036,6 @@ void __i915_gem_object_release_unless_active(struct 
> drm_i915_gem_object *obj)
>  
>  void i915_gem_sanitize(struct drm_i915_private *i915)
>  {
> - int err;
> -
>   GEM_TRACE("\n");
>  
>   mutex_lock(&i915->drm.struct_mutex);
> @@ -5063,11 +5060,7 @@ void i915_gem_sanitize(struct drm_i915_private *i915)
>* it may impact the display and we are uncertain about the stability
>* of the reset, so this could be applied to even earlier gen.
>*/
> - err = -ENODEV;
> - if (INTEL_GEN(i915) >= 5 && intel_has_gpu_reset(i915))
> - err = WARN_ON(intel_gpu_reset(i915, ALL_ENGINES));
> - if (!err)
> - intel_engines_sanitize(i915);
> + intel_engines_sanitize(i915, false);
>  
>   intel_uncore_forcewake_put(i915, FORCEWAKE_ALL);
>   intel_runtime_pm_put(i915);
> diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
> index 0d342f2b44a5..dd4aff2b256e 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -82,6 +82,7 @@
>   .display.has_overlay = 1, \
>   .display.overlay_needs_physical = 1, \
>   .display.has_gmch_display = 1, \
> + .gpu_reset_clobbers_display = true, \
>   .hws_needs_physical = 1, \
>   .unfenced_needs_alignment = 1, \
>   .ring_mask = RENDER_RING, \
> @@ -122,6 +123,7 @@ static const struct intel_device_info intel_i865g_info = {
>   GEN(3), \
>   .num_pipes = 2, \
>   .display.has_gmch_display = 1, \
> + .gpu_reset_clobbers_display = true, \
>   .ring_mask = RENDER_RING, \
>   .has_snoop = true, \
>   .has_coherent_ggtt = true, \
> @@ -198,6 +200,7 @@ static const struct intel_device_info intel_pineview_info 
> = {
>   .num_pipes = 2, \
>   .display.has_hotplug = 1, \
>   .display.has_gmch_display = 1, \
> + .gpu_reset_clobbers_display = true, \
>   .ring_mask = RENDER_RING, \
>   .has_snoop = true, \
>   .has_coherent_ggtt = true, \
> @@ -228,6 +231,7 @@ static const struct intel_device_info intel_g45_info = {
>   GEN4_FEATURES,
>   PLATFORM(INTEL_G45),
>   .ring_mask = RENDER_RING | BSD_RING,
> + .gpu_reset_clobbers_display = false,
>  };
>  
>  static const struct intel_device_info intel_gm45_info = {
> @@ -237,6 +241,7 @@ static const struct intel_device_info intel_gm45_info = {
>   .display.has_fbc = 1,
>   .display.supports_tv = 1,
>   .ring_mask = RENDER_RING | BSD_RING,
> + .gpu_reset_clobbers_display = false,

Why not explicitly set this on rest of gen >= 5?
-Mika


>  };
>  
>  #define GEN5_FEATURES \
> diff --git a/drivers/gpu/drm/i915/intel_device_info.h 
> b/drivers/gpu/drm/i915/intel_device_info.h
> index dd34f974a857..8fd683497956 100644
> --- a/drivers/gpu/drm/i915/intel_device_info.h
> +++ b/drivers/gpu

Re: [Intel-gfx] [PATCH 25/39] drm/i915: Pull VM lists under the VM mutex.

2019-01-02 Thread Chris Wilson
Quoting Tvrtko Ursulin (2019-01-02 13:21:17)
> 
> On 02/01/2019 09:41, Chris Wilson wrote:
> 
> Give it a bit of commit text please.

A starting point to counter the pervasive struct_mutex. For the goal of
avoiding (or at least blocking under them!) global locks during user
request submission, a simple but important step is being able to manage
each clients GTT separately. For which, we want to replace using the
struct_mutex as the guard for all things GTT/VM and switch instead to a
specific mutex inside i915_address_space.

> 
> > Signed-off-by: Chris Wilson 
> > ---
> >   drivers/gpu/drm/i915/i915_gem.c | 14 --
> >   drivers/gpu/drm/i915/i915_gem_evict.c   |  2 ++
> >   drivers/gpu/drm/i915/i915_gem_gtt.c | 15 +--
> >   drivers/gpu/drm/i915/i915_gem_shrinker.c|  4 
> >   drivers/gpu/drm/i915/i915_gem_stolen.c  |  2 ++
> >   drivers/gpu/drm/i915/i915_vma.c | 11 +++
> >   drivers/gpu/drm/i915/selftests/i915_gem_evict.c |  3 +++
> >   drivers/gpu/drm/i915/selftests/i915_gem_gtt.c   |  3 +++
> >   8 files changed, 46 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_gem.c 
> > b/drivers/gpu/drm/i915/i915_gem.c
> > index d9e1dcee176c..66445e34c93c 100644
> > --- a/drivers/gpu/drm/i915/i915_gem.c
> > +++ b/drivers/gpu/drm/i915/i915_gem.c
> > @@ -246,18 +246,19 @@ int
> >   i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
> >   struct drm_file *file)
> >   {
> > - struct drm_i915_private *dev_priv = to_i915(dev);
> > - struct i915_ggtt *ggtt = &dev_priv->ggtt;
> > + struct i915_ggtt *ggtt = &to_i915(dev)->ggtt;
> >   struct drm_i915_gem_get_aperture *args = data;
> >   struct i915_vma *vma;
> >   u64 pinned;
> >   
> > + mutex_lock(&ggtt->vm.mutex);
> > +
> >   pinned = ggtt->vm.reserved;
> > - mutex_lock(&dev->struct_mutex);
> >   list_for_each_entry(vma, &ggtt->vm.bound_list, vm_link)
> >   if (i915_vma_is_pinned(vma))
> >   pinned += vma->node.size;
> > - mutex_unlock(&dev->struct_mutex);
> > +
> > + mutex_unlock(&ggtt->vm.mutex);
> >   
> >   args->aper_size = ggtt->vm.total;
> >   args->aper_available_size = args->aper_size - pinned;
> > @@ -1680,20 +1681,21 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void 
> > *data,
> >   
> >   static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object 
> > *obj)
> >   {
> > - struct drm_i915_private *i915;
> > + struct drm_i915_private *i915 = to_i915(obj->base.dev);
> >   struct list_head *list;
> >   struct i915_vma *vma;
> >   
> >   GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
> >   
> > + mutex_lock(&i915->ggtt.vm.mutex);
> >   for_each_ggtt_vma(vma, obj) {
> >   if (!drm_mm_node_allocated(&vma->node))
> >   continue;
> >   
> >   list_move_tail(&vma->vm_link, &vma->vm->bound_list);
> >   }
> > + mutex_unlock(&i915->ggtt.vm.mutex);
> >   
> > - i915 = to_i915(obj->base.dev);
> >   spin_lock(&i915->mm.obj_lock);
> >   list = obj->bind_count ? &i915->mm.bound_list : 
> > &i915->mm.unbound_list;
> >   list_move_tail(&obj->mm.link, list);
> > diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c 
> > b/drivers/gpu/drm/i915/i915_gem_evict.c
> > index 6a3608398d2a..b7c2a396a63f 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_evict.c
> > +++ b/drivers/gpu/drm/i915/i915_gem_evict.c
> > @@ -418,6 +418,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
> >   }
> >   
> >   INIT_LIST_HEAD(&eviction_list);
> > + mutex_lock(&vm->mutex);
> >   list_for_each_entry(vma, &vm->bound_list, vm_link) {
> >   if (i915_vma_is_pinned(vma))
> >   continue;
> > @@ -425,6 +426,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
> >   __i915_vma_pin(vma);
> >   list_add(&vma->evict_link, &eviction_list);
> >   }
> > + mutex_unlock(&vm->mutex);
> >   
> >   ret = 0;
> >   list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
> > diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> > b/drivers/gpu/drm/i915/i915_gem_gtt.c
> > index e5e23c4ac769..7ae10fbb2ee0 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> > +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> > @@ -1932,7 +1932,10 @@ static struct i915_vma *pd_vma_create(struct 
> > gen6_hw_ppgtt *ppgtt, int size)
> >   vma->ggtt_view.type = I915_GGTT_VIEW_ROTATED; /* prevent fencing */
> >   
> >   INIT_LIST_HEAD(&vma->obj_link);
> > +
> > + mutex_lock(&vma->vm->mutex);
> >   list_add(&vma->vm_link, &vma->vm->unbound_list);
> > + mutex_unlock(&vma->vm->mutex);
> >   
> >   return vma;
> >   }
> > @@ -3504,9 +3507,10 @@ void i915_gem_restore_gtt_mappings(struct 
> > drm_i915_private *dev_priv)
> >   
> >   i915_che

Re: [Intel-gfx] [PATCH 06/39] drm/i915: Always try to reset the GPU on takeover

2019-01-02 Thread Chris Wilson
Quoting Mika Kuoppala (2019-01-02 13:19:52)
> Chris Wilson  writes:
> 
> > When we first introduced the reset to sanitize the GPU on taking over
> > from the BIOS and before returning control to third parties (the BIOS!),
> > we restricted it to only systems utilizing HW contexts as we were
> > uncertain of how stable our reset mechanism truly was. We now have
> > reasonable coverage across all machines that expose a GPU reset method,
> > and so we should be safe to sanitize the GPU state everywhere.
> >
> > v2: We _have_ to skip the reset if it would clobber the display.
> >
> > Signed-off-by: Chris Wilson 
> > ---
> >  drivers/gpu/drm/i915/i915_drv.c   |  2 +-
> >  drivers/gpu/drm/i915/i915_gem.c   | 11 ++-
> >  drivers/gpu/drm/i915/i915_pci.c   |  5 +
> >  drivers/gpu/drm/i915/intel_device_info.h  |  1 +
> >  drivers/gpu/drm/i915/intel_display.c  |  4 ++--
> >  drivers/gpu/drm/i915/intel_engine_cs.c| 14 +-
> >  drivers/gpu/drm/i915/intel_ringbuffer.h   |  2 +-
> >  drivers/gpu/drm/i915/selftests/i915_gem.c |  2 +-
> >  8 files changed, 26 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.c 
> > b/drivers/gpu/drm/i915/i915_drv.c
> > index dcb935338c63..a96169acdb07 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.c
> > +++ b/drivers/gpu/drm/i915/i915_drv.c
> > @@ -2174,7 +2174,7 @@ static int i915_drm_resume_early(struct drm_device 
> > *dev)
> >  
> >   intel_power_domains_resume(dev_priv);
> >  
> > - intel_engines_sanitize(dev_priv);
> > + intel_engines_sanitize(dev_priv, true);
> >  
> >   enable_rpm_wakeref_asserts(dev_priv);
> >  
> > diff --git a/drivers/gpu/drm/i915/i915_gem.c 
> > b/drivers/gpu/drm/i915/i915_gem.c
> > index e46a25747ab7..0ebde13620cb 100644
> > --- a/drivers/gpu/drm/i915/i915_gem.c
> > +++ b/drivers/gpu/drm/i915/i915_gem.c
> > @@ -3432,8 +3432,7 @@ bool i915_gem_unset_wedged(struct drm_i915_private 
> > *i915)
> >   i915_retire_requests(i915);
> >   GEM_BUG_ON(i915->gt.active_requests);
> >  
> > - if (!intel_gpu_reset(i915, ALL_ENGINES))
> > - intel_engines_sanitize(i915);
> > + intel_engines_sanitize(i915, false);
> >  
> >   /*
> >* Undo nop_submit_request. We prevent all new i915 requests from
> > @@ -5037,8 +5036,6 @@ void __i915_gem_object_release_unless_active(struct 
> > drm_i915_gem_object *obj)
> >  
> >  void i915_gem_sanitize(struct drm_i915_private *i915)
> >  {
> > - int err;
> > -
> >   GEM_TRACE("\n");
> >  
> >   mutex_lock(&i915->drm.struct_mutex);
> > @@ -5063,11 +5060,7 @@ void i915_gem_sanitize(struct drm_i915_private *i915)
> >* it may impact the display and we are uncertain about the stability
> >* of the reset, so this could be applied to even earlier gen.
> >*/
> > - err = -ENODEV;
> > - if (INTEL_GEN(i915) >= 5 && intel_has_gpu_reset(i915))
> > - err = WARN_ON(intel_gpu_reset(i915, ALL_ENGINES));
> > - if (!err)
> > - intel_engines_sanitize(i915);
> > + intel_engines_sanitize(i915, false);
> >  
> >   intel_uncore_forcewake_put(i915, FORCEWAKE_ALL);
> >   intel_runtime_pm_put(i915);
> > diff --git a/drivers/gpu/drm/i915/i915_pci.c 
> > b/drivers/gpu/drm/i915/i915_pci.c
> > index 0d342f2b44a5..dd4aff2b256e 100644
> > --- a/drivers/gpu/drm/i915/i915_pci.c
> > +++ b/drivers/gpu/drm/i915/i915_pci.c
> > @@ -82,6 +82,7 @@
> >   .display.has_overlay = 1, \
> >   .display.overlay_needs_physical = 1, \
> >   .display.has_gmch_display = 1, \
> > + .gpu_reset_clobbers_display = true, \
> >   .hws_needs_physical = 1, \
> >   .unfenced_needs_alignment = 1, \
> >   .ring_mask = RENDER_RING, \
> > @@ -122,6 +123,7 @@ static const struct intel_device_info intel_i865g_info 
> > = {
> >   GEN(3), \
> >   .num_pipes = 2, \
> >   .display.has_gmch_display = 1, \
> > + .gpu_reset_clobbers_display = true, \
> >   .ring_mask = RENDER_RING, \
> >   .has_snoop = true, \
> >   .has_coherent_ggtt = true, \
> > @@ -198,6 +200,7 @@ static const struct intel_device_info 
> > intel_pineview_info = {
> >   .num_pipes = 2, \
> >   .display.has_hotplug = 1, \
> >   .display.has_gmch_display = 1, \
> > + .gpu_reset_clobbers_display = true, \
> >   .ring_mask = RENDER_RING, \
> >   .has_snoop = true, \
> >   .has_coherent_ggtt = true, \
> > @@ -228,6 +231,7 @@ static const struct intel_device_info intel_g45_info = {
> >   GEN4_FEATURES,
> >   PLATFORM(INTEL_G45),
> >   .ring_mask = RENDER_RING | BSD_RING,
> > + .gpu_reset_clobbers_display = false,
> >  };
> >  
> >  static const struct intel_device_info intel_gm45_info = {
> > @@ -237,6 +241,7 @@ static const struct intel_device_info intel_gm45_info = 
> > {
> >   .display.has_fbc = 1,
> >   .display.supports_tv = 1,
> >   .ring_mask = RENDER_RING | BSD_RING,
> > + .gpu_reset_clobbers_display = false,
>

Re: [Intel-gfx] [PATCH 24/39] drm/i915: Stop tracking MRU activity on VMA

2019-01-02 Thread Chris Wilson
Quoting Tvrtko Ursulin (2019-01-02 13:13:23)
> 
> On 02/01/2019 09:41, Chris Wilson wrote:
> > diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
> > b/drivers/gpu/drm/i915/i915_gem_gtt.h
> > index a0039ea97cdc..bd679c8c56dd 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> > +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> > @@ -299,32 +299,12 @@ struct i915_address_space {
> >   struct i915_page_directory_pointer *scratch_pdp; /* GEN8+ & 48b PPGTT 
> > */
> >   
> >   /**
> > -  * List of objects currently involved in rendering.
> > -  *
> > -  * Includes buffers having the contents of their GPU caches
> > -  * flushed, not necessarily primitives. last_read_req
> > -  * represents when the rendering involved will be completed.
> > -  *
> > -  * A reference is held on the buffer while on this list.
> > +  * List of vma currently bound.
> 
> Reference held comment can stay I hope.

No, that's talking about the active reference, which is only implied and
not technically true even today :)
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 06/39] drm/i915: Always try to reset the GPU on takeover

2019-01-02 Thread Mika Kuoppala
Chris Wilson  writes:

> Quoting Mika Kuoppala (2019-01-02 13:19:52)
>> Chris Wilson  writes:
>> 
>> > When we first introduced the reset to sanitize the GPU on taking over
>> > from the BIOS and before returning control to third parties (the BIOS!),
>> > we restricted it to only systems utilizing HW contexts as we were
>> > uncertain of how stable our reset mechanism truly was. We now have
>> > reasonable coverage across all machines that expose a GPU reset method,
>> > and so we should be safe to sanitize the GPU state everywhere.
>> >
>> > v2: We _have_ to skip the reset if it would clobber the display.
>> >
>> > Signed-off-by: Chris Wilson 
>> > ---
>> >  drivers/gpu/drm/i915/i915_drv.c   |  2 +-
>> >  drivers/gpu/drm/i915/i915_gem.c   | 11 ++-
>> >  drivers/gpu/drm/i915/i915_pci.c   |  5 +
>> >  drivers/gpu/drm/i915/intel_device_info.h  |  1 +
>> >  drivers/gpu/drm/i915/intel_display.c  |  4 ++--
>> >  drivers/gpu/drm/i915/intel_engine_cs.c| 14 +-
>> >  drivers/gpu/drm/i915/intel_ringbuffer.h   |  2 +-
>> >  drivers/gpu/drm/i915/selftests/i915_gem.c |  2 +-
>> >  8 files changed, 26 insertions(+), 15 deletions(-)
>> >
>> > diff --git a/drivers/gpu/drm/i915/i915_drv.c 
>> > b/drivers/gpu/drm/i915/i915_drv.c
>> > index dcb935338c63..a96169acdb07 100644
>> > --- a/drivers/gpu/drm/i915/i915_drv.c
>> > +++ b/drivers/gpu/drm/i915/i915_drv.c
>> > @@ -2174,7 +2174,7 @@ static int i915_drm_resume_early(struct drm_device 
>> > *dev)
>> >  
>> >   intel_power_domains_resume(dev_priv);
>> >  
>> > - intel_engines_sanitize(dev_priv);
>> > + intel_engines_sanitize(dev_priv, true);
>> >  
>> >   enable_rpm_wakeref_asserts(dev_priv);
>> >  
>> > diff --git a/drivers/gpu/drm/i915/i915_gem.c 
>> > b/drivers/gpu/drm/i915/i915_gem.c
>> > index e46a25747ab7..0ebde13620cb 100644
>> > --- a/drivers/gpu/drm/i915/i915_gem.c
>> > +++ b/drivers/gpu/drm/i915/i915_gem.c
>> > @@ -3432,8 +3432,7 @@ bool i915_gem_unset_wedged(struct drm_i915_private 
>> > *i915)
>> >   i915_retire_requests(i915);
>> >   GEM_BUG_ON(i915->gt.active_requests);
>> >  
>> > - if (!intel_gpu_reset(i915, ALL_ENGINES))
>> > - intel_engines_sanitize(i915);
>> > + intel_engines_sanitize(i915, false);
>> >  
>> >   /*
>> >* Undo nop_submit_request. We prevent all new i915 requests from
>> > @@ -5037,8 +5036,6 @@ void __i915_gem_object_release_unless_active(struct 
>> > drm_i915_gem_object *obj)
>> >  
>> >  void i915_gem_sanitize(struct drm_i915_private *i915)
>> >  {
>> > - int err;
>> > -
>> >   GEM_TRACE("\n");
>> >  
>> >   mutex_lock(&i915->drm.struct_mutex);
>> > @@ -5063,11 +5060,7 @@ void i915_gem_sanitize(struct drm_i915_private 
>> > *i915)
>> >* it may impact the display and we are uncertain about the stability
>> >* of the reset, so this could be applied to even earlier gen.
>> >*/
>> > - err = -ENODEV;
>> > - if (INTEL_GEN(i915) >= 5 && intel_has_gpu_reset(i915))
>> > - err = WARN_ON(intel_gpu_reset(i915, ALL_ENGINES));
>> > - if (!err)
>> > - intel_engines_sanitize(i915);
>> > + intel_engines_sanitize(i915, false);
>> >  
>> >   intel_uncore_forcewake_put(i915, FORCEWAKE_ALL);
>> >   intel_runtime_pm_put(i915);
>> > diff --git a/drivers/gpu/drm/i915/i915_pci.c 
>> > b/drivers/gpu/drm/i915/i915_pci.c
>> > index 0d342f2b44a5..dd4aff2b256e 100644
>> > --- a/drivers/gpu/drm/i915/i915_pci.c
>> > +++ b/drivers/gpu/drm/i915/i915_pci.c
>> > @@ -82,6 +82,7 @@
>> >   .display.has_overlay = 1, \
>> >   .display.overlay_needs_physical = 1, \
>> >   .display.has_gmch_display = 1, \
>> > + .gpu_reset_clobbers_display = true, \
>> >   .hws_needs_physical = 1, \
>> >   .unfenced_needs_alignment = 1, \
>> >   .ring_mask = RENDER_RING, \
>> > @@ -122,6 +123,7 @@ static const struct intel_device_info intel_i865g_info 
>> > = {
>> >   GEN(3), \
>> >   .num_pipes = 2, \
>> >   .display.has_gmch_display = 1, \
>> > + .gpu_reset_clobbers_display = true, \
>> >   .ring_mask = RENDER_RING, \
>> >   .has_snoop = true, \
>> >   .has_coherent_ggtt = true, \
>> > @@ -198,6 +200,7 @@ static const struct intel_device_info 
>> > intel_pineview_info = {
>> >   .num_pipes = 2, \
>> >   .display.has_hotplug = 1, \
>> >   .display.has_gmch_display = 1, \
>> > + .gpu_reset_clobbers_display = true, \
>> >   .ring_mask = RENDER_RING, \
>> >   .has_snoop = true, \
>> >   .has_coherent_ggtt = true, \
>> > @@ -228,6 +231,7 @@ static const struct intel_device_info intel_g45_info = 
>> > {
>> >   GEN4_FEATURES,
>> >   PLATFORM(INTEL_G45),
>> >   .ring_mask = RENDER_RING | BSD_RING,
>> > + .gpu_reset_clobbers_display = false,
>> >  };
>> >  
>> >  static const struct intel_device_info intel_gm45_info = {
>> > @@ -237,6 +241,7 @@ static const struct intel_device_info intel_gm45_info 
>> > = {
>> >

[Intel-gfx] ✓ Fi.CI.IGT: success for drm/i915/selftests: Take a breath during check_partial_mappings()

2019-01-02 Thread Patchwork
== Series Details ==

Series: drm/i915/selftests: Take a breath during check_partial_mappings()
URL   : https://patchwork.freedesktop.org/series/54639/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5357_full -> Patchwork_11174_full


Summary
---

  **SUCCESS**

  No regressions found.

  

Known issues


  Here are the changes found in Patchwork_11174_full that come from known 
issues:

### IGT changes ###

 Issues hit 

  * igt@gem_exec_schedule@pi-ringfull-blt:
- shard-skl:  NOTRUN -> FAIL [fdo#103158]
- shard-apl:  NOTRUN -> FAIL [fdo#103158]

  * igt@kms_available_modes_crc@available_mode_test_crc:
- shard-apl:  PASS -> FAIL [fdo#106641]

  * igt@kms_busy@extended-pageflip-hang-newfb-render-a:
- shard-glk:  PASS -> DMESG-WARN [fdo#107956]

  * igt@kms_ccs@pipe-b-crc-primary-basic:
- shard-iclb: NOTRUN -> FAIL [fdo#107725]

  * igt@kms_cursor_crc@cursor-256x256-random:
- shard-apl:  PASS -> FAIL [fdo#103232] +2

  * igt@kms_cursor_crc@cursor-64x64-random:
- shard-glk:  PASS -> FAIL [fdo#103232]

  * igt@kms_fbcon_fbt@psr-suspend:
- shard-skl:  NOTRUN -> FAIL [fdo#107882]

  * igt@kms_flip@flip-vs-expired-vblank:
- shard-skl:  NOTRUN -> FAIL [fdo#105363]

  * igt@kms_flip@modeset-vs-vblank-race:
- shard-glk:  PASS -> FAIL [fdo#103060]

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-mmap-cpu:
- shard-skl:  PASS -> FAIL [fdo#105682]

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-onoff:
- shard-glk:  PASS -> FAIL [fdo#103167]
- shard-apl:  PASS -> FAIL [fdo#103167] +2

  * igt@kms_frontbuffer_tracking@fbc-stridechange:
- shard-iclb: PASS -> FAIL [fdo#105683] / [fdo#108040]

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-pwrite:
- shard-iclb: PASS -> FAIL [fdo#103167] +6

  * igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-mmap-gtt:
- shard-skl:  PASS -> FAIL [fdo#103167]

  * igt@kms_plane@pixel-format-pipe-c-planes:
- shard-iclb: NOTRUN -> FAIL [fdo#103166]
- shard-skl:  NOTRUN -> DMESG-WARN [fdo#106885]

  * igt@kms_plane@plane-position-covered-pipe-b-planes:
- shard-iclb: PASS -> FAIL [fdo#103166] +2

  * igt@kms_plane_alpha_blend@pipe-a-constant-alpha-max:
- shard-skl:  NOTRUN -> FAIL [fdo#108145]

  * igt@kms_plane_alpha_blend@pipe-a-coverage-7efc:
- shard-skl:  PASS -> FAIL [fdo#107815] / [fdo#108145]

  * igt@kms_plane_alpha_blend@pipe-b-alpha-7efc:
- shard-skl:  NOTRUN -> FAIL [fdo#107815] / [fdo#108145]

  * igt@kms_plane_alpha_blend@pipe-c-constant-alpha-max:
- shard-glk:  PASS -> FAIL [fdo#108145]

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
- shard-skl:  PASS -> FAIL [fdo#107815]

  * igt@kms_plane_multiple@atomic-pipe-a-tiling-yf:
- shard-glk:  PASS -> FAIL [fdo#103166]

  * igt@kms_rotation_crc@multiplane-rotation-cropping-top:
- shard-kbl:  PASS -> DMESG-FAIL [fdo#108950]

  * igt@kms_universal_plane@universal-plane-pipe-b-functional:
- shard-apl:  PASS -> FAIL [fdo#103166]

  * igt@pm_backlight@fade_with_suspend:
- shard-skl:  NOTRUN -> FAIL [fdo#107847]
- shard-iclb: NOTRUN -> FAIL [fdo#107847]

  * igt@pm_rpm@modeset-non-lpsp-stress-no-wait:
- shard-skl:  SKIP -> INCOMPLETE [fdo#107807]

  * igt@pm_rpm@modeset-stress-extra-wait:
- shard-iclb: PASS -> DMESG-WARN [fdo#107724]

  * igt@pm_rpm@universal-planes-dpms:
- shard-skl:  PASS -> INCOMPLETE [fdo#107807]

  
 Possible fixes 

  * igt@i915_selftest@live_workarounds:
- shard-iclb: DMESG-FAIL [fdo#108954] -> PASS

  * igt@kms_color@pipe-b-legacy-gamma:
- shard-apl:  FAIL [fdo#104782] -> PASS

  * igt@kms_cursor_crc@cursor-128x128-onscreen:
- shard-apl:  FAIL [fdo#103232] -> PASS +2

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-mmap-gtt:
- shard-apl:  FAIL [fdo#103167] -> PASS +1

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-move:
- shard-glk:  FAIL [fdo#103167] -> PASS +2

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-mmap-wc:
- shard-iclb: FAIL [fdo#103167] -> PASS

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes:
- shard-skl:  FAIL [fdo#103166] -> PASS

  * igt@kms_plane@plane-position-covered-pipe-b-planes:
- shard-glk:  FAIL [fdo#103166] -> PASS +1

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
- shard-skl:  FAIL [fdo#107815] -> PASS

  * igt@kms_plane_alpha_blend@pipe-c-alpha-opaque-fb:
- shard-glk:  FAIL [fdo#108145] -> PASS

  * igt@kms_rmfb@rmfb-ioctl:
- shard-iclb: DMESG-WARN [fdo#107724] 

Re: [Intel-gfx] [PATCH 26/39] drm/i915: Consolidate the bound/unbound vma lists into one

2019-01-02 Thread Tvrtko Ursulin


On 02/01/2019 09:41, Chris Wilson wrote:

Commit text to explain why please.


Signed-off-by: Chris Wilson 
---
  drivers/gpu/drm/i915/i915_gem.c   |  4 +--
  drivers/gpu/drm/i915/i915_gem_evict.c | 12 ++---
  drivers/gpu/drm/i915/i915_gem_gtt.c   | 27 ++-
  drivers/gpu/drm/i915/i915_gem_gtt.h   | 10 +--
  drivers/gpu/drm/i915/i915_gem_shrinker.c  |  3 +--
  drivers/gpu/drm/i915/i915_gem_stolen.c|  4 ---
  drivers/gpu/drm/i915/i915_gpu_error.c | 11 
  drivers/gpu/drm/i915/i915_vma.c   |  7 +
  .../gpu/drm/i915/selftests/i915_gem_evict.c   | 11 +++-
  drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  4 ---
  10 files changed, 32 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 66445e34c93c..a954e15c0315 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -254,7 +254,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void 
*data,
mutex_lock(&ggtt->vm.mutex);
  
  	pinned = ggtt->vm.reserved;

-   list_for_each_entry(vma, &ggtt->vm.bound_list, vm_link)
+   list_for_each_entry(vma, &ggtt->vm.vma_list, vm_link)
if (i915_vma_is_pinned(vma))
pinned += vma->node.size;
  
@@ -1692,7 +1692,7 @@ static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj)

if (!drm_mm_node_allocated(&vma->node))
continue;
  
-		list_move_tail(&vma->vm_link, &vma->vm->bound_list);

+   list_move_tail(&vma->vm_link, &i915->ggtt.vm.vma_list);
}
mutex_unlock(&i915->ggtt.vm.mutex);
  
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c

index b7c2a396a63f..8ccde5761c2c 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -170,7 +170,10 @@ i915_gem_evict_something(struct i915_address_space *vm,
  search_again:
active = NULL;
INIT_LIST_HEAD(&eviction_list);
-   list_for_each_entry_safe(vma, next, &vm->bound_list, vm_link) {
+   list_for_each_entry_safe(vma, next, &vm->vma_list, vm_link) {
+   if (!drm_mm_node_allocated(&vma->node))
+   continue;


Kick them to the end (even after active)? Would need a temporary list 
head I think, but that shouldn't be too bad. Maybe another temporary 
list head would simplify the active vma logic below as well. It would 
basically mean a sorting step from vm->vma_list to 
active/inactive/unbound local lists, then a tri-phase loop as before, 
and then join all lists together replacing vma->vma_list. Downside is 
wasted sorting effort if few first found inactives satisfy the eviction 
pass.. so maybe it is not worth it. Or we could check as we build. No 
idea if more order after the eviction pass would be beneficial though.. 
this all only affects ggtt in practice right?



+
if (i915_vma_is_active(vma)) {
if (vma == active) {
if (flags & PIN_NONBLOCK)
@@ -183,7 +186,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
if (!active)
active = vma;
  
-list_move_tail(&vma->vm_link, &vm->bound_list);

+   list_move_tail(&vma->vm_link, &vm->vma_list);
continue;
}
}
@@ -419,7 +422,10 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
  
  	INIT_LIST_HEAD(&eviction_list);

mutex_lock(&vm->mutex);
-   list_for_each_entry(vma, &vm->bound_list, vm_link) {
+   list_for_each_entry(vma, &vm->vma_list, vm_link) {
+   if (!drm_mm_node_allocated(&vma->node))
+   continue;
+
if (i915_vma_is_pinned(vma))
continue;
  
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c

index 7ae10fbb2ee0..17b752f9a1e6 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -492,8 +492,7 @@ static void i915_address_space_init(struct 
i915_address_space *vm, int subclass)
  
  	stash_init(&vm->free_pages);
  
-	INIT_LIST_HEAD(&vm->unbound_list);

-   INIT_LIST_HEAD(&vm->bound_list);
+   INIT_LIST_HEAD(&vm->vma_list);
  }
  
  static void i915_address_space_fini(struct i915_address_space *vm)

@@ -1934,7 +1933,7 @@ static struct i915_vma *pd_vma_create(struct 
gen6_hw_ppgtt *ppgtt, int size)
INIT_LIST_HEAD(&vma->obj_link);
  
  	mutex_lock(&vma->vm->mutex);

-   list_add(&vma->vm_link, &vma->vm->unbound_list);
+   list_add(&vma->vm_link, &vma->vm->vma_list);
mutex_unlock(&vma->vm->mutex);
  
  	return vma;

@@ -2113,19 +2112,12 @@ void i915_ppgtt_close(struct i915_address_space *vm)
  
  static void ppgtt_dest

Re: [Intel-gfx] [PATCH 27/39] drm/i915: Move vma lookup to its own lock

2019-01-02 Thread Tvrtko Ursulin


On 02/01/2019 09:41, Chris Wilson wrote:

Remove the struct_mutex requirement for looking up the vma for an
object.

Signed-off-by: Chris Wilson 
---
  drivers/gpu/drm/i915/i915_debugfs.c   |  6 +--
  drivers/gpu/drm/i915/i915_gem.c   | 33 +++--
  drivers/gpu/drm/i915/i915_gem_object.h| 45 ++---
  drivers/gpu/drm/i915/i915_vma.c   | 60 +++
  drivers/gpu/drm/i915/i915_vma.h   |  2 +-
  drivers/gpu/drm/i915/selftests/i915_vma.c |  4 +-
  6 files changed, 92 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 5e2d5c8d7e02..8059f6dd3886 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -159,14 +159,14 @@ describe_obj(struct seq_file *m, struct 
drm_i915_gem_object *obj)
   obj->mm.madv == I915_MADV_DONTNEED ? " purgeable" : "");
if (obj->base.name)
seq_printf(m, " (name: %d)", obj->base.name);
-   list_for_each_entry(vma, &obj->vma_list, obj_link) {
+   list_for_each_entry(vma, &obj->vma.list, obj_link) {
if (i915_vma_is_pinned(vma))
pin_count++;
}
seq_printf(m, " (pinned x %d)", pin_count);
if (obj->pin_global)
seq_printf(m, " (global)");
-   list_for_each_entry(vma, &obj->vma_list, obj_link) {
+   list_for_each_entry(vma, &obj->vma.list, obj_link) {
if (!drm_mm_node_allocated(&vma->node))
continue;
  
@@ -322,7 +322,7 @@ static int per_file_stats(int id, void *ptr, void *data)

if (obj->base.name || obj->base.dma_buf)
stats->shared += obj->base.size;
  
-	list_for_each_entry(vma, &obj->vma_list, obj_link) {

+   list_for_each_entry(vma, &obj->vma.list, obj_link) {
if (!drm_mm_node_allocated(&vma->node))
continue;
  
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c

index a954e15c0315..e42ad20d6328 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -438,15 +438,19 @@ int i915_gem_object_unbind(struct drm_i915_gem_object 
*obj)
if (ret)
return ret;
  
-	while ((vma = list_first_entry_or_null(&obj->vma_list,

-  struct i915_vma,
-  obj_link))) {
+   spin_lock(&obj->vma.lock);
+   while (!ret && (vma = list_first_entry_or_null(&obj->vma.list,
+  struct i915_vma,
+  obj_link))) {
list_move_tail(&vma->obj_link, &still_in_list);
+   spin_unlock(&obj->vma.lock);
+
ret = i915_vma_unbind(vma);
-   if (ret)
-   break;
+
+   spin_lock(&obj->vma.lock);
}
-   list_splice(&still_in_list, &obj->vma_list);
+   list_splice(&still_in_list, &obj->vma.list);
+   spin_unlock(&obj->vma.lock);
  
  	return ret;

  }
@@ -3640,7 +3644,7 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
 * reading an invalid PTE on older architectures.
 */
  restart:
-   list_for_each_entry(vma, &obj->vma_list, obj_link) {
+   list_for_each_entry(vma, &obj->vma.list, obj_link) {
if (!drm_mm_node_allocated(&vma->node))
continue;
  
@@ -3718,7 +3722,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,

 */
}
  
-		list_for_each_entry(vma, &obj->vma_list, obj_link) {

+   list_for_each_entry(vma, &obj->vma.list, obj_link) {
if (!drm_mm_node_allocated(&vma->node))
continue;
  
@@ -3728,7 +3732,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,

}
}
  
-	list_for_each_entry(vma, &obj->vma_list, obj_link)

+   list_for_each_entry(vma, &obj->vma.list, obj_link)
vma->node.color = cache_level;
i915_gem_object_set_cache_coherency(obj, cache_level);
obj->cache_dirty = true; /* Always invalidate stale cachelines */
@@ -4304,7 +4308,9 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
  {
mutex_init(&obj->mm.lock);
  
-	INIT_LIST_HEAD(&obj->vma_list);

+   spin_lock_init(&obj->vma.lock);
+   INIT_LIST_HEAD(&obj->vma.list);
+
INIT_LIST_HEAD(&obj->lut_list);
INIT_LIST_HEAD(&obj->batch_pool_link);
  
@@ -4470,14 +4476,13 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,

mutex_lock(&i915->drm.struct_mutex);
  
  		GEM_BUG_ON(i915_gem_object_is_active(obj));

-   list_for_each_entry_safe(vma, vn,
-&obj->vma_list, obj_link) {
+   

Re: [Intel-gfx] [PATCH 28/39] drm/i915: Move intel_execlists_show_requests() aside

2019-01-02 Thread Tvrtko Ursulin


On 02/01/2019 09:41, Chris Wilson wrote:

Move the debug pretty printer into a standalone routine prior to
extending it in upcoming feature work.

Signed-off-by: Chris Wilson 
---
  drivers/gpu/drm/i915/intel_engine_cs.c | 55 ++--
  drivers/gpu/drm/i915/intel_lrc.c   | 58 ++
  drivers/gpu/drm/i915/intel_lrc.h   | 10 -
  3 files changed, 71 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index 59b9349012e3..36177546f68b 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1421,15 +1421,12 @@ void intel_engine_dump(struct intel_engine_cs *engine,
   struct drm_printer *m,
   const char *header, ...)
  {
-   const int MAX_REQUESTS_TO_SHOW = 8;
struct intel_breadcrumbs * const b = &engine->breadcrumbs;
-   const struct intel_engine_execlists * const execlists = 
&engine->execlists;
struct i915_gpu_error * const error = &engine->i915->gpu_error;
-   struct i915_request *rq, *last;
+   struct i915_request *rq;
intel_wakeref_t wakeref;
unsigned long flags;
struct rb_node *rb;
-   int count;
  
  	if (header) {

va_list ap;
@@ -1493,52 +1490,9 @@ void intel_engine_dump(struct intel_engine_cs *engine,
drm_printf(m, "\tDevice is asleep; skipping register dump\n");
}
  
-	local_irq_save(flags);

-   spin_lock(&engine->timeline.lock);
-
-   last = NULL;
-   count = 0;
-   list_for_each_entry(rq, &engine->timeline.requests, link) {
-   if (count++ < MAX_REQUESTS_TO_SHOW - 1)
-   print_request(m, rq, "\t\tE ");
-   else
-   last = rq;
-   }
-   if (last) {
-   if (count > MAX_REQUESTS_TO_SHOW) {
-   drm_printf(m,
-  "\t\t...skipping %d executing requests...\n",
-  count - MAX_REQUESTS_TO_SHOW);
-   }
-   print_request(m, last, "\t\tE ");
-   }
-
-   last = NULL;
-   count = 0;
-   drm_printf(m, "\t\tQueue priority: %d\n", execlists->queue_priority);
-   for (rb = rb_first_cached(&execlists->queue); rb; rb = rb_next(rb)) {
-   struct i915_priolist *p = rb_entry(rb, typeof(*p), node);
-   int i;
-
-   priolist_for_each_request(rq, p, i) {
-   if (count++ < MAX_REQUESTS_TO_SHOW - 1)
-   print_request(m, rq, "\t\tQ ");
-   else
-   last = rq;
-   }
-   }
-   if (last) {
-   if (count > MAX_REQUESTS_TO_SHOW) {
-   drm_printf(m,
-  "\t\t...skipping %d queued requests...\n",
-  count - MAX_REQUESTS_TO_SHOW);
-   }
-   print_request(m, last, "\t\tQ ");
-   }
-
-   spin_unlock(&engine->timeline.lock);
+   intel_execlists_show_requests(engine, m, print_request, 8);
  
-	spin_lock(&b->rb_lock);

+   spin_lock_irqsave(&b->rb_lock, flags);
for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) {
struct intel_wait *w = rb_entry(rb, typeof(*w), node);
  
@@ -1547,8 +1501,7 @@ void intel_engine_dump(struct intel_engine_cs *engine,

   task_state_to_char(w->tsk),
   w->seqno);
}
-   spin_unlock(&b->rb_lock);
-   local_irq_restore(flags);
+   spin_unlock_irqrestore(&b->rb_lock, flags);
  
  	drm_printf(m, "HWSP:\n");

hexdump(m, engine->status_page.page_addr, PAGE_SIZE);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 9bdd7ec12991..bcc5e0d88130 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -2676,6 +2676,64 @@ void intel_lr_context_resume(struct drm_i915_private 
*i915)
}
  }
  
+void intel_execlists_show_requests(struct intel_engine_cs *engine,

+  struct drm_printer *m,
+  void (*show_request)(struct drm_printer *m,
+   struct i915_request *rq,
+   const char *prefix),
+  unsigned int max)
+{
+   const struct intel_engine_execlists *execlists = &engine->execlists;
+   struct i915_request *rq, *last;
+   unsigned long flags;
+   unsigned int count;
+   struct rb_node *rb;
+
+   spin_lock_irqsave(&engine->timeline.lock, flags);
+
+   last = NULL;
+   count = 0;
+   list_for_each_entry(rq, &engine->timeline.requests, link) {
+   if (count++ < max - 1)
+   show_request

Re: [Intel-gfx] [PATCH 29/39] drm/i915: Use b->irq_enable() as predicate for mock engine

2019-01-02 Thread Tvrtko Ursulin


On 02/01/2019 09:41, Chris Wilson wrote:

Some commit text please.


References: d4ccceb05591 ("drm/i915/icl: Ringbuffer interrupt handling")
Signed-off-by: Chris Wilson 
---
  drivers/gpu/drm/i915/intel_breadcrumbs.c | 39 
  drivers/gpu/drm/i915/intel_engine_cs.c   | 11 ++
  drivers/gpu/drm/i915/intel_ringbuffer.h  |  1 -
  drivers/gpu/drm/i915/selftests/mock_engine.c |  1 -
  4 files changed, 20 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c 
b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 4ed7105d7ff5..7b517bf83507 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -158,6 +158,9 @@ static void intel_breadcrumbs_fake_irq(struct timer_list *t)
  
  static void irq_enable(struct intel_engine_cs *engine)

  {
+   if (!engine->irq_enable)
+   return;
+
/*
 * FIXME: Ideally we want this on the API boundary, but for the
 * sake of testing with mock breadcrumbs (no HW so unable to
@@ -167,21 +170,20 @@ static void irq_enable(struct intel_engine_cs *engine)
GEM_BUG_ON(!intel_irqs_enabled(engine->i915));
  
  	/* Caller disables interrupts */

-   if (engine->irq_enable) {
-   spin_lock(&engine->i915->irq_lock);
-   engine->irq_enable(engine);
-   spin_unlock(&engine->i915->irq_lock);
-   }
+   spin_lock(&engine->i915->irq_lock);
+   engine->irq_enable(engine);
+   spin_unlock(&engine->i915->irq_lock);
  }
  
  static void irq_disable(struct intel_engine_cs *engine)

  {
+   if (!engine->irq_disable)
+   return;
+
/* Caller disables interrupts */
-   if (engine->irq_disable) {
-   spin_lock(&engine->i915->irq_lock);
-   engine->irq_disable(engine);
-   spin_unlock(&engine->i915->irq_lock);
-   }
+   spin_lock(&engine->i915->irq_lock);
+   engine->irq_disable(engine);
+   spin_unlock(&engine->i915->irq_lock);
  }


Noise hunks.

  
  void __intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine)

@@ -293,25 +295,16 @@ static bool __intel_breadcrumbs_enable_irq(struct 
intel_breadcrumbs *b)
if (b->irq_armed)
return false;
  
-	/* The breadcrumb irq will be disarmed on the interrupt after the

+   /*
+* The breadcrumb irq will be disarmed on the interrupt after the
 * waiters are signaled. This gives us a single interrupt window in
 * which we can add a new waiter and avoid the cost of re-enabling
 * the irq.
 */
b->irq_armed = true;
  
-	if (I915_SELFTEST_ONLY(b->mock)) {

-   /* For our mock objects we want to avoid interaction
-* with the real hardware (which is not set up). So
-* we simply pretend we have enabled the powerwell
-* and the irq, and leave it up to the mock
-* implementation to call intel_engine_wakeup()
-* itself when it wants to simulate a user interrupt,
-*/
-   return true;
-   }
-
-   /* Since we are waiting on a request, the GPU should be busy
+   /*
+* Since we are waiting on a request, the GPU should be busy
 * and should have its own rpm reference. This is tracked
 * by i915->gt.awake, we can forgo holding our own wakref
 * for the interrupt as before i915->gt.awake is released (when
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index 36177546f68b..7b80a087cc32 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -917,6 +917,9 @@ static bool ring_is_idle(struct intel_engine_cs *engine)
intel_wakeref_t wakeref;
bool idle = true;
  
+	if (I915_SELFTEST_ONLY(!engine->mmio_base))

+   return true;


Seems to make sense, but shouldn't the patch title be "Use 
engine->mmio_base as predicate for mock engine hw access"?


Regards,

Tvrtko


+
/* If the whole device is asleep, the engine must be idle */
wakeref = intel_runtime_pm_get_if_in_use(dev_priv);
if (!wakeref)
@@ -955,9 +958,6 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
if (!intel_engine_signaled(engine, intel_engine_last_submit(engine)))
return false;
  
-	if (I915_SELFTEST_ONLY(engine->breadcrumbs.mock))

-   return true;
-
/* Waiting to drain ELSP? */
if (READ_ONCE(engine->execlists.active)) {
struct tasklet_struct *t = &engine->execlists.tasklet;
@@ -983,10 +983,7 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
return false;
  
  	/* Ring stopped? */

-   if (!ring_is_idle(engine))
-   return false;
-
-   return true;
+   return ring_is_idle(engine);
  }
  
  bool intel_engines_are_idle(struct drm_i915_pri

[Intel-gfx] [PATCH] drm/i915/gen6: Flush RING_IMR changes before changing the global GT IMR

2019-01-02 Thread Chris Wilson
On Baytail, notably, we can still detect missed interrupt syndrome
(where we never spot a completed request). In this case, it can be
alleviated by always keeping the interrupt unmasked, implying that the
interrupt is being lost in the window after modifying the IMR. (This is
the reason we still have the posting reads on enable_irq, if we remove
them we miss interrupts!) Having narrowed the issue down to the IMR,
rather than keeping it always enabled, applying the usual posting
read/flush of the RING_IMR before unmasking the GT IMR also seems to
prevent the missed interrupt. So be it.

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

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 8967dcb5f58f..3d5d6b908148 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -974,6 +974,10 @@ gen6_irq_enable(struct intel_engine_cs *engine)
I915_WRITE_IMR(engine,
   ~(engine->irq_enable_mask |
 engine->irq_keep_mask));
+
+   /* Flush/delay to ensure the RING_IMR is active before the GT IMR */
+   POSTING_READ_FW(RING_IMR(engine->mmio_base));
+
gen5_enable_gt_irq(dev_priv, engine->irq_enable_mask);
 }
 
-- 
2.20.1

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


[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915/gen6: Flush RING_IMR changes before changing the global GT IMR

2019-01-02 Thread Patchwork
== Series Details ==

Series: drm/i915/gen6: Flush RING_IMR changes before changing the global GT IMR
URL   : https://patchwork.freedesktop.org/series/54655/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5358 -> Patchwork_11176


Summary
---

  **WARNING**

  Minor unknown changes coming with Patchwork_11176 need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_11176, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: 
https://patchwork.freedesktop.org/api/1.0/series/54655/revisions/1/mbox/

Possible new issues
---

  Here are the unknown changes that may have been introduced in Patchwork_11176:

### IGT changes ###

 Warnings 

  * igt@kms_flip@basic-flip-vs-dpms:
- fi-skl-6770hq:  SKIP -> PASS +36

  
Known issues


  Here are the changes found in Patchwork_11176 that come from known issues:

### IGT changes ###

 Issues hit 

  * igt@kms_pipe_crc_basic@read-crc-pipe-a:
- fi-byt-clapper: PASS -> FAIL [fdo#107362]

  
 Possible fixes 

  * igt@i915_selftest@live_evict:
- fi-bsw-kefka:   DMESG-WARN [fdo#107709] -> PASS

  * igt@kms_pipe_crc_basic@nonblocking-crc-pipe-a-frame-sequence:
- fi-byt-clapper: FAIL [fdo#103191] / [fdo#107362] -> PASS

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
- fi-blb-e6850:   INCOMPLETE [fdo#107718] -> PASS

  
  [fdo#103191]: https://bugs.freedesktop.org/show_bug.cgi?id=103191
  [fdo#107362]: https://bugs.freedesktop.org/show_bug.cgi?id=107362
  [fdo#107709]: https://bugs.freedesktop.org/show_bug.cgi?id=107709
  [fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718


Participating hosts (50 -> 44)
--

  Additional (2): fi-gdg-551 fi-snb-2600 
  Missing(8): fi-kbl-soraka fi-hsw-4770r fi-ilk-m540 fi-hsw-4200u 
fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-icl-y 


Build changes
-

* Linux: CI_DRM_5358 -> Patchwork_11176

  CI_DRM_5358: c6a0276a5007c01c64a8a80552b78c115e8a0dae @ 
git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4755: 0ba18cf75cafb51d1e72557528de4a1be640a85c @ 
git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_11176: b6858ef7ab8fda7cd93db420e139507d4ca16a46 @ 
git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

b6858ef7ab8f drm/i915/gen6: Flush RING_IMR changes before changing the global 
GT IMR

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_11176/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/5] drm/i915: Refactor PSR status debugfs

2019-01-02 Thread Souza, Jose
On Tue, 2018-12-11 at 18:54 +, Souza, Jose wrote:
> On Tue, 2018-12-11 at 10:32 -0800, Dhinakaran Pandiyan wrote:
> > On Tue, 2018-12-11 at 04:44 -0800, Souza, Jose wrote:
> > > On Mon, 2018-12-10 at 22:51 -0800, Dhinakaran Pandiyan wrote:
> > > > On Tue, 2018-12-04 at 15:00 -0800, José Roberto de Souza wrote:
> > > > > The old debugfs fields was not following a naming partern and
> > > > > it
> > > > > was
> > > > > a bit confusing.
> > > > > 
> > > > > So it went from:
> > > > > ~$ sudo more /sys/kernel/debug/dri/0/i915_edp_psr_status
> > > > > Sink_Support: yes
> > > > > PSR mode: PSR1
> > > > > Enabled: yes
> > > > > Busy frontbuffer bits: 0x000
> > > > > Main link in standby mode: no
> > > > > HW Enabled & Active bit: yes
> > > > > Source PSR status: 0x24050006 [SRDONACK]
> > > > > 
> > > > > To:
> > > > > ~$ sudo more /sys/kernel/debug/dri/0/i915_edp_psr_status
> > > > > Sink support: yes [0x0003]
> > > > > Status: PSR1 enabled
> > > > > Source PSR ctl: enabled [0x81f00e26]
> > > > > Source PSR status: SRDENT [0x40040006]
> > > > > Busy frontbuffer bits: 0x
> > > > > 
> > > > > The 'Main link in standby mode' was removed as it is not
> > > > > useful
> > > > > but
> > > > > if needed by someone the information is still in the register
> > > > > value
> > > > > of 'Source PSR ctl' inside of the brackets, PSR mode and
> > > > > Enabled
> > > > > was
> > > > > squashed into Status, some renames and reorders and we have
> > > > > this
> > > > > cleaner version. This will also make easy to parse debugfs
> > > > > for
> > > > > IGT
> > > > > tests.
> > > > > 
> > > > > Cc: Rodrigo Vivi 
> > > > > Cc: Dhinakaran Pandiyan 
> > > > > Suggested-by: Dhinakaran Pandiyan <
> > > > > dhinakaran.pandi...@intel.com>
> > > > > Signed-off-by: José Roberto de Souza 
> > > > > ---
> > > > >  drivers/gpu/drm/i915/i915_debugfs.c | 96 +++--
> > > > > 
> > > > > 
> > > > > 
> > > > >  1 file changed, 49 insertions(+), 47 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
> > > > > b/drivers/gpu/drm/i915/i915_debugfs.c
> > > > > index 38dcee1ca062..86303ba02666 100644
> > > > > --- a/drivers/gpu/drm/i915/i915_debugfs.c
> > > > > +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> > > > > @@ -2665,7 +2665,8 @@
> > > > > DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status);
> > > > >  static void
> > > > >  psr_source_status(struct drm_i915_private *dev_priv, struct
> > > > > seq_file
> > > > > *m)
> > > > >  {
> > > > > - u32 val, psr_status;
> > > > > + u32 val, status_val;
> > > > > + const char *status = "unknown";
> > > > >  
> > > > >   if (dev_priv->psr.psr2_enabled) {
> > > > >   static const char * const live_status[] = {
> > > > > @@ -2681,14 +2682,11 @@ psr_source_status(struct
> > > > > drm_i915_private
> > > > > *dev_priv, struct seq_file *m)
> > > > >   "BUF_ON",
> > > > >   "TG_ON"
> > > > >   };
> > > > > - psr_status = I915_READ(EDP_PSR2_STATUS);
> > > > > - val = (psr_status & EDP_PSR2_STATUS_STATE_MASK)
> > > > > - EDP_PSR2_STATUS_STATE_SHIFT;
> > > > > - if (val < ARRAY_SIZE(live_status)) {
> > > > > - seq_printf(m, "Source PSR status: 0x%x
> > > > > [%s]\n",
> > > > > -psr_status,
> > > > > live_status[val]);
> > > > > - return;
> > > > > - }
> > > > > + val = I915_READ(EDP_PSR2_STATUS);
> > > > > + status_val = (val & EDP_PSR2_STATUS_STATE_MASK)
> > > > > +   EDP_PSR2_STATUS_STATE_SHIFT;
> > > > > + if (status_val < ARRAY_SIZE(live_status))
> > > > > + status = live_status[status_val];
> > > > >   } else {
> > > > >   static const char * const live_status[] = {
> > > > >   "IDLE",
> > > > > @@ -2700,74 +2698,78 @@ psr_source_status(struct
> > > > > drm_i915_private
> > > > > *dev_priv, struct seq_file *m)
> > > > >   "SRDOFFACK",
> > > > >   "SRDENT_ON",
> > > > >   };
> > > > > - psr_status = I915_READ(EDP_PSR_STATUS);
> > > > > - val = (psr_status & EDP_PSR_STATUS_STATE_MASK)
> > > > > - EDP_PSR_STATUS_STATE_SHIFT;
> > > > > - if (val < ARRAY_SIZE(live_status)) {
> > > > > - seq_printf(m, "Source PSR status: 0x%x
> > > > > [%s]\n",
> > > > > -psr_status,
> > > > > live_status[val]);
> > > > > - return;
> > > > > - }
> > > > > + val = I915_READ(EDP_PSR_STATUS);
> > > > > + status_val = (val & EDP_PSR_STATUS_STATE_MASK)
> > > > > +   EDP_PSR_STATUS_STATE_SHIFT;
> > > > > + if (status_val < ARRAY_SIZE(live_status))
> > > > > + status = live_status[status_v

[Intel-gfx] [PULL] drm-misc-next-fixes

2019-01-02 Thread Maarten Lankhorst
drm-misc-next-fixes-2019-01-02:
Fixes for v4.21:
- Fix null pointer dereference on null state pointer.
- Fix leaking damage clip when destroying plane state.
The following changes since commit 2e6e902d185027f8e3cb8b7305238f7e35d6a436:

  Linux 4.20-rc4 (2018-11-25 14:19:31 -0800)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-next-fixes-2019-01-02

for you to fetch changes up to c75ff001f4fe21a8c9f15aad799a8949aea109f7:

  drm: Put damage blob when destroy plane state (2018-12-24 11:53:50 +0100)


Fixes for v4.21:
- Fix null pointer dereference on null state pointer.
- Fix leaking damage clip when destroying plane state.


Colin Ian King (1):
  drm: fix null pointer dereference on null state pointer

Deepak Rawat (1):
  drm: Put damage blob when destroy plane state

 drivers/gpu/drm/drm_atomic_state_helper.c | 3 +++
 drivers/gpu/drm/drm_damage_helper.c   | 3 ++-
 2 files changed, 5 insertions(+), 1 deletion(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Fix the HDMI hot plug disconnection failure (v4)

2019-01-02 Thread Guang Bai
On Wed, 2 Jan 2019 17:29:46 +0800
Chris Chiu  wrote:

> Happy New Year.
> Sorry for bothering you guys again, I don't really want to make myself
> a nuisance.
> Is there any better idea for fixing this issue?
I've already back ported this change into the kernel 4.18.17 and sent
it to our customer for integration test - So far so good.
Thanks,
-Guang
> 
> Chris
> 
> On Mon, Dec 3, 2018 at 6:38 PM Chris Chiu  wrote:
> >
> > On Fri, Nov 30, 2018 at 1:15 AM Guang Bai 
> > wrote:  
> > >
> > > On Thu, 29 Nov 2018 10:17:49 +0200
> > > Jani Nikula  wrote:
> > >  
> > > > On Wed, 28 Nov 2018, Guang Bai  wrote:  
> > > > > On some GEN9 platforms, slowly unplugging (wiggling) the HDMI
> > > > > cable makes the kernel to believe the HDMI display is still
> > > > > connected. This is because the HDMI DDC lines are
> > > > > disconnected a little bit later after the hot-plug interrupt
> > > > > triggered thus an immediate edid fetch can be made. This
> > > > > problem has been identified by more than one customer
> > > > > recently. Use digital port live states to authorize the edid
> > > > > read at HDMI detection point will ensure most of the display
> > > > > related software states updated and rest of them will be
> > > > > renewed accordingly when the port is connected.
> > > > >
> > > > > v2: Fix the formatting issue
> > > > > v3: Use digital port states to authorize the edid read
> > > > > v4: Add comments on issue histories and rationale of the fix
> > > > > (Chris W)  
> > > >
> > > > You're not answering Chris Wilson's question.
> > > >
> > > > Why do you think the problems we've historically had with live
> > > > status are no longer a problem? We've tried and reverted live
> > > > status checks at least twice before because of regressions. Why
> > > > do you think this time there won't be regressions? Why do you
> > > > think this patch makes forward progress?  
> > > Jani,
> > > I'm still new to kernel developments compared with all of you
> > > working in this area for many years - Haven't got any feedbacks
> > > on how exactly the HDMI live statue *not* fit for HDMI hot-plug
> > > related port status checking, neither had time to track all
> > > upstream bugzilla, plus not working directly with Intel OTC teams
> > > - What are those failing cases/regressions you mentioned above?
> > > - what were the kernel versions related with those developments?
> > > - Given the fact i915 architecture and implementation are
> > > constantly evolving - Should we re-visit those issues with
> > > current kernel implementation?
> > > - Fundamentally, do you think the edid fetch is still *valid*
> > > when the HDMI is unplugged (status either from PCH or DE)? Or
> > > other platform configurations may present more complexities such
> > > as kvm switches are used along with HDMI?
> > > Again, if you could provide me more historical issue details, I'd
> > > like to have some reviews/re-investigation for those cases with
> > > current 4.20 kernel.
> > > Thanks,
> > > -Guang  
> >
> > Hi Jani,
> > I don't know the history and what kind of painful regression
> > that you had run into. Could you maybe provide a test plan or some
> > test cases for the regression verification? I can follow steps to
> > try to verify whether if the patch can work on all cases.
> >
> > Chris
> >  
> > > >
> > > > I've *repeatedly* said from the beginning that I am very
> > > > sceptical of using live status because we've been burned by it
> > > > so many times before. I don't much care to repeat this anymore.
> > > >
> > > >
> > > > BR,
> > > > Jani.
> > > >
> > > >  
> > > > >
> > > > > Cc: Jani Nikula 
> > > > > Cc: Chris Chiu 
> > > > > Cc: Chris Wilson 
> > > > > Signed-off-by: Guang Bai 
> > > > > ---
> > > > >  drivers/gpu/drm/i915/intel_hdmi.c | 2 +-
> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> > > > > b/drivers/gpu/drm/i915/intel_hdmi.c index e2c6a2b..8cf7c78
> > > > > 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > > > > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > > > > @@ -1929,7 +1929,7 @@ intel_hdmi_detect(struct drm_connector
> > > > > *connector, bool force)
> > > > > intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
> > > > >
> > > > > -   if (IS_ICELAKE(dev_priv) &&
> > > > > +   if ((IS_ICELAKE(dev_priv) || IS_GEN9_BC(dev_priv)) &&
> > > > > !intel_digital_port_connected(encoder))
> > > > > goto out;  
> > > >  
> > >  

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


[Intel-gfx] ✓ Fi.CI.IGT: success for drm/i915/gen6: Flush RING_IMR changes before changing the global GT IMR

2019-01-02 Thread Patchwork
== Series Details ==

Series: drm/i915/gen6: Flush RING_IMR changes before changing the global GT IMR
URL   : https://patchwork.freedesktop.org/series/54655/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5358_full -> Patchwork_11176_full


Summary
---

  **WARNING**

  Minor unknown changes coming with Patchwork_11176_full need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_11176_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

Possible new issues
---

  Here are the unknown changes that may have been introduced in 
Patchwork_11176_full:

### IGT changes ###

 Warnings 

  * igt@pm_rc6_residency@rc6-accuracy:
- shard-kbl:  SKIP -> PASS

  * igt@tools_test@tools_test:
- shard-glk:  SKIP -> PASS

  
Known issues


  Here are the changes found in Patchwork_11176_full that come from known 
issues:

### IGT changes ###

 Issues hit 

  * igt@kms_busy@extended-modeset-hang-newfb-render-c:
- shard-hsw:  PASS -> DMESG-WARN [fdo#107956]

  * igt@kms_cursor_crc@cursor-128x128-onscreen:
- shard-apl:  PASS -> FAIL [fdo#103232] +1

  * igt@kms_cursor_crc@cursor-256x85-offscreen:
- shard-glk:  PASS -> INCOMPLETE [fdo#103359] / [k.org#198133]

  * igt@kms_draw_crc@draw-method-rgb565-render-untiled:
- shard-iclb: PASS -> WARN [fdo#108336] +2

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-render:
- shard-iclb: PASS -> DMESG-FAIL [fdo#107720] / [fdo#107724] +1

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-mmap-gtt:
- shard-iclb: PASS -> DMESG-FAIL [fdo#107724] +14

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-mmap-gtt:
- shard-iclb: PASS -> FAIL [fdo#103167] +2

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-fullscreen:
- shard-iclb: PASS -> DMESG-WARN [fdo#107724] / [fdo#108336] +23

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
- shard-iclb: PASS -> INCOMPLETE [fdo#107713]

  * igt@kms_plane@pixel-format-pipe-a-planes:
- shard-skl:  NOTRUN -> DMESG-WARN [fdo#106885]

  * igt@kms_plane@plane-position-covered-pipe-b-planes:
- shard-iclb: PASS -> FAIL [fdo#103166] +1

  * igt@kms_plane@plane-position-covered-pipe-c-planes:
- shard-apl:  PASS -> FAIL [fdo#103166]
- shard-glk:  PASS -> FAIL [fdo#103166]

  * igt@kms_plane_alpha_blend@pipe-a-alpha-opaque-fb:
- shard-glk:  PASS -> FAIL [fdo#108145]

  * igt@kms_plane_alpha_blend@pipe-a-alpha-transparant-fb:
- shard-skl:  NOTRUN -> FAIL [fdo#108145] +1

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
- shard-skl:  PASS -> FAIL [fdo#107815]

  * igt@kms_sysfs_edid_timing:
- shard-iclb: PASS -> FAIL [fdo#100047]

  * igt@kms_vblank@pipe-a-ts-continuation-idle:
- shard-iclb: PASS -> DMESG-WARN [fdo#107724] +36

  * igt@pm_rpm@basic-rte:
- shard-skl:  PASS -> INCOMPLETE [fdo#107807]

  
 Possible fixes 

  * igt@gem_ctx_isolation@rcs0-s3:
- shard-skl:  INCOMPLETE [fdo#104108] / [fdo#107773] -> PASS

  * igt@gem_ppgtt@blt-vs-render-ctxn:
- shard-skl:  TIMEOUT [fdo#108039] -> PASS

  * igt@kms_busy@extended-modeset-hang-newfb-render-a:
- shard-hsw:  DMESG-WARN [fdo#107956] -> PASS

  * igt@kms_busy@extended-modeset-hang-newfb-with-reset-render-c:
- shard-kbl:  DMESG-WARN [fdo#107956] -> PASS

  * igt@kms_cursor_crc@cursor-256x256-onscreen:
- shard-apl:  FAIL [fdo#103232] -> PASS

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic:
- shard-skl:  FAIL [fdo#102670] -> PASS

  * igt@kms_draw_crc@draw-method-xrgb-render-xtiled:
- shard-skl:  FAIL [fdo#107791] -> PASS

  * igt@kms_draw_crc@draw-method-xrgb-render-ytiled:
- shard-skl:  FAIL [fdo#103232] -> PASS

  * igt@kms_flip_tiling@flip-x-tiled:
- shard-skl:  FAIL [fdo#108145] -> PASS

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-move:
- shard-apl:  FAIL [fdo#103167] -> PASS

  * igt@kms_frontbuffer_tracking@fbcpsr-indfb-scaledprimary:
- shard-skl:  FAIL [fdo#105682] -> PASS

  * igt@kms_frontbuffer_tracking@fbcpsr-stridechange:
- shard-iclb: FAIL [fdo#105683] -> PASS

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-pri-shrfb-draw-mmap-cpu:
- shard-skl:  FAIL [fdo#103167] -> PASS

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-blt:
- shard-iclb: FAIL [fdo#103167] -> PASS +9

  * igt@kms_frontbuffer_tracking@psr-suspend:
- shard-iclb: INCOMPLETE [fdo#106978] / [fdo#107713] -> PASS

  * igt@kms_plane@plane-position-c

Re: [Intel-gfx] [PATCH 2/5] drm/i915: Refactor PSR status debugfs

2019-01-02 Thread Dhinakaran Pandiyan
On Wed, 2019-01-02 at 09:09 -0800, Souza, Jose wrote:
> On Tue, 2018-12-11 at 18:54 +, Souza, Jose wrote:
> > On Tue, 2018-12-11 at 10:32 -0800, Dhinakaran Pandiyan wrote:
> > > On Tue, 2018-12-11 at 04:44 -0800, Souza, Jose wrote:
> > > > On Mon, 2018-12-10 at 22:51 -0800, Dhinakaran Pandiyan wrote:
> > > > > On Tue, 2018-12-04 at 15:00 -0800, José Roberto de Souza
> > > > > wrote:
> > > > > > The old debugfs fields was not following a naming partern
> > > > > > and
> > > > > > it
> > > > > > was
> > > > > > a bit confusing.
> > > > > > 
> > > > > > So it went from:
> > > > > > ~$ sudo more /sys/kernel/debug/dri/0/i915_edp_psr_status
> > > > > > Sink_Support: yes
> > > > > > PSR mode: PSR1
> > > > > > Enabled: yes
> > > > > > Busy frontbuffer bits: 0x000
> > > > > > Main link in standby mode: no
> > > > > > HW Enabled & Active bit: yes
> > > > > > Source PSR status: 0x24050006 [SRDONACK]
> > > > > > 
> > > > > > To:
> > > > > > ~$ sudo more /sys/kernel/debug/dri/0/i915_edp_psr_status
> > > > > > Sink support: yes [0x0003]
> > > > > > Status: PSR1 enabled
> > > > > > Source PSR ctl: enabled [0x81f00e26]
> > > > > > Source PSR status: SRDENT [0x40040006]
> > > > > > Busy frontbuffer bits: 0x
> > > > > > 
> > > > > > The 'Main link in standby mode' was removed as it is not
> > > > > > useful
> > > > > > but
> > > > > > if needed by someone the information is still in the
> > > > > > register
> > > > > > value
> > > > > > of 'Source PSR ctl' inside of the brackets, PSR mode and
> > > > > > Enabled
> > > > > > was
> > > > > > squashed into Status, some renames and reorders and we have
> > > > > > this
> > > > > > cleaner version. This will also make easy to parse debugfs
> > > > > > for
> > > > > > IGT
> > > > > > tests.
> > > > > > 
> > > > > > Cc: Rodrigo Vivi 
> > > > > > Cc: Dhinakaran Pandiyan 
> > > > > > Suggested-by: Dhinakaran Pandiyan <
> > > > > > dhinakaran.pandi...@intel.com>
> > > > > > Signed-off-by: José Roberto de Souza 
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/i915_debugfs.c | 96 +++--
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > >  1 file changed, 49 insertions(+), 47 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
> > > > > > b/drivers/gpu/drm/i915/i915_debugfs.c
> > > > > > index 38dcee1ca062..86303ba02666 100644
> > > > > > --- a/drivers/gpu/drm/i915/i915_debugfs.c
> > > > > > +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> > > > > > @@ -2665,7 +2665,8 @@
> > > > > > DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status);
> > > > > >  static void
> > > > > >  psr_source_status(struct drm_i915_private *dev_priv,
> > > > > > struct
> > > > > > seq_file
> > > > > > *m)
> > > > > >  {
> > > > > > -   u32 val, psr_status;
> > > > > > +   u32 val, status_val;
> > > > > > +   const char *status = "unknown";
> > > > > >  
> > > > > > if (dev_priv->psr.psr2_enabled) {
> > > > > > static const char * const live_status[] = {
> > > > > > @@ -2681,14 +2682,11 @@ psr_source_status(struct
> > > > > > drm_i915_private
> > > > > > *dev_priv, struct seq_file *m)
> > > > > > "BUF_ON",
> > > > > > "TG_ON"
> > > > > > };
> > > > > > -   psr_status = I915_READ(EDP_PSR2_STATUS);
> > > > > > -   val = (psr_status & EDP_PSR2_STATUS_STATE_MASK)
> > > > > > -   EDP_PSR2_STATUS_STATE_SHIFT;
> > > > > > -   if (val < ARRAY_SIZE(live_status)) {
> > > > > > -   seq_printf(m, "Source PSR status: 0x%x
> > > > > > [%s]\n",
> > > > > > -  psr_status,
> > > > > > live_status[val]);
> > > > > > -   return;
> > > > > > -   }
> > > > > > +   val = I915_READ(EDP_PSR2_STATUS);
> > > > > > +   status_val = (val & EDP_PSR2_STATUS_STATE_MASK)
> > > > > > + EDP_PSR2_STATUS_STATE_SHIFT;
> > > > > > +   if (status_val < ARRAY_SIZE(live_status))
> > > > > > +   status = live_status[status_val];
> > > > > > } else {
> > > > > > static const char * const live_status[] = {
> > > > > > "IDLE",
> > > > > > @@ -2700,74 +2698,78 @@ psr_source_status(struct
> > > > > > drm_i915_private
> > > > > > *dev_priv, struct seq_file *m)
> > > > > > "SRDOFFACK",
> > > > > > "SRDENT_ON",
> > > > > > };
> > > > > > -   psr_status = I915_READ(EDP_PSR_STATUS);
> > > > > > -   val = (psr_status & EDP_PSR_STATUS_STATE_MASK)
> > > > > > -   EDP_PSR_STATUS_STATE_SHIFT;
> > > > > > -   if (val < ARRAY_SIZE(live_status)) {
> > > > > > -   seq_printf(m, "Source PSR status: 0x%x
> > > > > > [%s]\n",
> > > > > > -  psr_status,
> > > > > > live_status[val]);
> > > > > > -   return;
> > > > > > -   }
> > > > > > +   val = I915_READ(EDP_PSR_STATUS);
> > > > 

Re: [Intel-gfx] [regression from v4.19] Re: 4.20.0-rc6-next-20181210, v4.20-rc1: list_del corruption on thinkpad x220, graphics related?

2019-01-02 Thread Pavel Machek
Hi!

> > > So if you could please try drm-tip reproducing AND open a bug in Bugzilla.
> > > If you are unwilling to do that, it is very difficult to help you
> > > more.
> > 
> > Website says I have to read and agree to two different pieces of
> > legalesee, and I'd need to keep track of yet another password... so
> > you can "communicate" with me.
> > 
> > But you can already communicate with me, over email.
> 
> I've listed all the reasons why our bug handling process is what it is.
> 
> If registering to the Bugzilla is too much of an effort for you, then I
> won't be able to help you further on this.

Actually I did register at the bugzilla. Only useful help there
was that CONFIG_DRM_I915_DEBUG_GEM might be useful. Unfortunately that
one seems to make it panic() and impossible to get anything useful.

https://bugs.freedesktop.org/show_bug.cgi?id=109175

Best regards,

Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v3 07/16] drm/amdgpu/display: Keep malloc ref to MST port

2019-01-02 Thread Lyude Paul
Just like i915 and nouveau, it's a good idea for us to hold a malloc
reference to the port here so that we never pass a freed pointer to any
of the DP MST helper functions.

Also, we stop unsetting aconnector->port in
dm_dp_destroy_mst_connector(). There's literally no point to that
assignment that I can see anyway.

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c   | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 5e7ca1f3a8d1..24632727e127 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -191,6 +191,7 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
drm_encoder_cleanup(&amdgpu_encoder->base);
kfree(amdgpu_encoder);
drm_connector_cleanup(connector);
+   drm_dp_mst_put_port_malloc(amdgpu_dm_connector->port);
kfree(amdgpu_dm_connector);
 }
 
@@ -363,7 +364,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
amdgpu_dm_connector_funcs_reset(connector);
 
DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
-   aconnector, connector->base.id, aconnector->mst_port);
+aconnector, connector->base.id, aconnector->mst_port);
+
+   drm_dp_mst_get_port_malloc(port);
 
DRM_DEBUG_KMS(":%d\n", connector->base.id);
 
@@ -379,12 +382,12 @@ static void dm_dp_destroy_mst_connector(struct 
drm_dp_mst_topology_mgr *mgr,
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
 
DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n",
-   aconnector, connector->base.id, 
aconnector->mst_port);
+aconnector, connector->base.id, aconnector->mst_port);
 
-   aconnector->port = NULL;
if (aconnector->dc_sink) {
amdgpu_dm_update_freesync_caps(connector, NULL);
-   dc_link_remove_remote_sink(aconnector->dc_link, 
aconnector->dc_sink);
+   dc_link_remove_remote_sink(aconnector->dc_link,
+  aconnector->dc_sink);
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
}
-- 
2.20.1

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


[Intel-gfx] [PATCH v3 04/16] drm/dp_mst: Stop releasing VCPI when removing ports from topology

2019-01-02 Thread Lyude Paul
This has never actually worked, and isn't needed anyway: the driver's
always going to try to deallocate VCPI when it tears down the display
that the VCPI belongs to.

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index b8a47c795fa9..f10a7edb401e 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -1176,8 +1176,6 @@ static void drm_dp_destroy_port(struct kref *kref)
struct drm_dp_mst_topology_mgr *mgr = port->mgr;
 
if (!port->input) {
-   port->vcpi.num_slots = 0;
-
kfree(port->cached_edid);
 
/*
@@ -3493,12 +3491,6 @@ static void drm_dp_destroy_connector_work(struct 
work_struct *work)
drm_dp_port_teardown_pdt(port, port->pdt);
port->pdt = DP_PEER_DEVICE_NONE;
 
-   if (!port->input && port->vcpi.vcpi > 0) {
-   drm_dp_mst_reset_vcpi_slots(mgr, port);
-   drm_dp_update_payload_part1(mgr);
-   drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
-   }
-
drm_dp_mst_put_port_malloc(port);
send_hotplug = true;
}
-- 
2.20.1

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


[Intel-gfx] [PATCH v3 03/16] drm/dp_mst: Restart last_connected_port_and_mstb() if topology ref fails

2019-01-02 Thread Lyude Paul
While this isn't a complete fix, this will improve the reliability of
drm_dp_get_last_connected_port_and_mstb() pretty significantly during
hotplug events, since there's a chance that the in-memory topology tree
may not be fully updated when drm_dp_get_last_connected_port_and_mstb()
is called and thus might end up causing our search to fail on an mstb
whose topology refcount has reached 0, but has not yet been removed from
it's parent.

Ideally, we should further fix this problem by ensuring that we deal
with the potential for racing with a hotplug event, which would look
like this:

* drm_dp_payload_send_msg() retrieves the last living relative of mstb
  with drm_dp_get_last_connected_port_and_mstb()
* drm_dp_payload_send_msg() starts building payload message
  At the same time, mstb gets unplugged from the topology and is no
  longer the actual last living relative of the original mstb
* drm_dp_payload_send_msg() tries sending the payload message, hub times
  out
* Hub timed out, we give up and run away-resulting in the payload being
  leaked

This could be fixed by restarting the
drm_dp_get_last_connected_port_and_mstb() search whenever we get a
timeout, sending the payload to the new mstb, then repeating until
either the entire topology is removed from the system or
drm_dp_get_last_connected_port_and_mstb() fails. But since the above
race condition is not terribly likely, we'll address that in a later
patch series once we've improved the recovery handling for VCPI
allocations in the rest of the DP MST helpers.

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 54 ++-
 1 file changed, 44 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index c0dc20fbd55a..b8a47c795fa9 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2045,24 +2045,50 @@ static struct drm_dp_mst_port 
*drm_dp_get_last_connected_port_to_mstb(struct drm
return 
drm_dp_get_last_connected_port_to_mstb(mstb->port_parent->parent);
 }
 
-static struct drm_dp_mst_branch 
*drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
-struct 
drm_dp_mst_branch *mstb,
-int 
*port_num)
+/**
+ * drm_dp_get_last_connected_port_and_mstb() - Find the last living relatives
+ * in a topology of a given branch device
+ * @mgr: The topology manager to use
+ * @mstb: The disconnected branch device
+ * @port_num: Where to store the number of the last connected port
+ *
+ * Searches upwards in the topology starting from @mstb to try to find the
+ * closest available parent of @mstb that's still connected to the rest of the
+ * topology. This can be used in order to perform operations like releasing
+ * payloads, where the branch device which owned the payload may no longer be
+ * around and thus would require that the payload on the last living relative
+ * be freed instead.
+ *
+ * Returns:
+ * The last connected &drm_dp_mst_branch in the topology that was a parent of
+ * @mstb, if there is one.
+ */
+static struct drm_dp_mst_branch *
+drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
+   struct drm_dp_mst_branch *mstb,
+   int *port_num)
 {
struct drm_dp_mst_branch *rmstb = NULL;
struct drm_dp_mst_port *found_port;
+
mutex_lock(&mgr->lock);
-   if (mgr->mst_primary) {
+   if (!mgr->mst_primary)
+   goto out;
+
+   do {
found_port = drm_dp_get_last_connected_port_to_mstb(mstb);
+   if (!found_port)
+   break;
 
-   if (found_port) {
+   if (drm_dp_mst_topology_try_get_mstb(found_port->parent)) {
rmstb = found_port->parent;
-   if (drm_dp_mst_topology_try_get_mstb(rmstb))
-   *port_num = found_port->port_num;
-   else
-   rmstb = NULL;
+   *port_num = found_port->port_num;
+   } else {
+   /* Search again, starting from this parent */
+   mstb = found_port->parent;
}
-   }
+   } while (!rmstb);
+out:
mutex_unlock(&mgr->lock);
return rmstb;
 }
@@ -2111,6 +2137,14 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
 
drm_dp_queue_down_tx(mgr, txmsg);
 
+   /*
+* FIXME: there is a small chance that between getting the last
+* connected mstb and sending the payload message, the last connected
+* mstb could also be removed from the topology. In th

[Intel-gfx] [PATCH v3 02/16] drm/dp_mst: Introduce new refcounting scheme for mstbs and ports

2019-01-02 Thread Lyude Paul
The current way of handling refcounting in the DP MST helpers is really
confusing and probably just plain wrong because it's been hacked up many
times over the years without anyone actually going over the code and
seeing if things could be simplified.

To the best of my understanding, the current scheme works like this:
drm_dp_mst_port and drm_dp_mst_branch both have a single refcount. When
this refcount hits 0 for either of the two, they're removed from the
topology state, but not immediately freed. Both ports and branch devices
will reinitialize their kref once it's hit 0 before actually destroying
themselves. The intended purpose behind this is so that we can avoid
problems like not being able to free a remote payload that might still
be active, due to us having removed all of the port/branch device
structures in memory, as per:

commit 91a25e463130 ("drm/dp/mst: deallocate payload on port destruction")

Which may have worked, but then it caused use-after-free errors. Being
new to MST at the time, I tried fixing it;

commit 263efde31f97 ("drm/dp/mst: Get validated port ref in 
drm_dp_update_payload_part1()")

But, that was broken: both drm_dp_mst_port and drm_dp_mst_branch structs
are validated in almost every DP MST helper function. Simply put, this
means we go through the topology and try to see if the given
drm_dp_mst_branch or drm_dp_mst_port is still attached to something
before trying to use it in order to avoid dereferencing freed memory
(something that has happened a LOT in the past with this library).
Because of this it doesn't actually matter whether or not we keep keep
the ports and branches around in memory as that's not enough, because
any function that validates the branches and ports passed to it will
still reject them anyway since they're no longer in the topology
structure. So, use-after-free errors were fixed but payload deallocation
was completely broken.

Two years later, AMD informed me about this issue and I attempted to
come up with a temporary fix, pending a long-overdue cleanup of this
library:

commit c54c7374ff44 ("drm/dp_mst: Skip validating ports during destruction, 
just ref")

But then that introduced use-after-free errors, so I quickly reverted
it:

commit 9765635b3075 ("Revert "drm/dp_mst: Skip validating ports during 
destruction, just ref"")

And in the process, learned that there is just no simple fix for this:
the design is just broken. Unfortuntely, the usage of these helpers are
quite broken as well. Some drivers like i915 have been smart enough to
avoid accessing any kind of information from MST port structures, but
others like nouveau have assumed, understandably so, that
drm_dp_mst_port structures are normal and can just be accessed at any
time without worrying about use-after-free errors.

After a lot of discussion, me and Daniel Vetter came up with a better
idea to replace all of this.

To summarize, since this is documented far more indepth in the
documentation this patch introduces, we make it so that drm_dp_mst_port
and drm_dp_mst_branch structures have two different classes of
refcounts: topology_kref, and malloc_kref. topology_kref corresponds to
the lifetime of the given drm_dp_mst_port or drm_dp_mst_branch in it's
given topology. Once it hits zero, any associated connectors are removed
and the branch or port can no longer be validated. malloc_kref
corresponds to the lifetime of the memory allocation for the actual
structure, and will always be non-zero so long as the topology_kref is
non-zero. This gives us a way to allow callers to hold onto port and
branch device structures past their topology lifetime, and dramatically
simplifies the lifetimes of both structures. This also finally fixes the
port deallocation problem, properly.

Additionally: since this now means that we can keep ports and branch
devices allocated in memory for however long we need, we no longer need
a significant amount of the port validation that we currently do.

Additionally, there is one last scenario that this fixes, which couldn't
have been fixed properly beforehand:

- CPU1 unrefs port from topology (refcount 1->0)
- CPU2 refs port in topology(refcount 0->1)

Since we now can guarantee memory safety for ports and branches
as-needed, we also can make our main reference counting functions fix
this problem by using kref_get_unless_zero() internally so that topology
refcounts can only ever reach 0 once.

Changes since v2:
* Fix commit message - checkpatch
Changes since v1:
* Remove forward declarations - danvet
* Move "Branch device and port refcounting" section from documentation
  into kernel-doc comments - danvet
* Export internal topology lifetime functions into their own section in
  the kernel-docs - danvet
* s/@/&/g for struct references in kernel-docs - danvet
* Drop the "when they are no longer being used" bits from the kernel
  docs - danvet
* Modify diagrams to show how the DRM driver interacts with the topology
  and payloads - danvet
* Make suggested documentation cha

[Intel-gfx] [PATCH v3 10/16] drm/nouveau: Keep malloc references to MST ports

2019-01-02 Thread Lyude Paul
Now that we finally have a sane way to keep port allocations around, use
it to fix the potential unchecked ->port accesses that nouveau makes by
making sure we keep the mst port allocated for as long as it's
drm_connector is accessible.

Additionally, now that we've guaranteed that mstc->port is allocated for
as long as we keep mstc around we can remove the connector registration
checks for codepaths which release payloads, allowing us to release
payloads on active topologies properly. These registration checks were
only required before in order to avoid situations where mstc->port could
technically be pointing at freed memory.

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 0f7d72518604..982054bbcc8b 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -964,7 +964,11 @@ static void
 nv50_mstc_destroy(struct drm_connector *connector)
 {
struct nv50_mstc *mstc = nv50_mstc(connector);
+
drm_connector_cleanup(&mstc->connector);
+   if (mstc->port)
+   drm_dp_mst_put_port_malloc(mstc->port);
+
kfree(mstc);
 }
 
@@ -1012,6 +1016,7 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct 
drm_dp_mst_port *port,
drm_object_attach_property(&mstc->connector.base, 
dev->mode_config.path_property, 0);
drm_object_attach_property(&mstc->connector.base, 
dev->mode_config.tile_property, 0);
drm_connector_set_path_property(&mstc->connector, path);
+   drm_dp_mst_get_port_malloc(port);
return 0;
 }
 
@@ -1077,6 +1082,7 @@ nv50_mstm_destroy_connector(struct 
drm_dp_mst_topology_mgr *mgr,
drm_fb_helper_remove_one_connector(&drm->fbcon->helper, 
&mstc->connector);
 
drm_modeset_lock(&drm->dev->mode_config.connection_mutex, NULL);
+   drm_dp_mst_put_port_malloc(mstc->port);
mstc->port = NULL;
drm_modeset_unlock(&drm->dev->mode_config.connection_mutex);
 
-- 
2.20.1

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


[Intel-gfx] [PATCH v3 01/16] drm/dp_mst: Rename drm_dp_mst_get_validated_(port|mstb)_ref and friends

2019-01-02 Thread Lyude Paul
s/drm_dp_get_validated_port_ref/drm_dp_mst_topology_get_port_validated/
s/drm_dp_put_port/drm_dp_mst_topology_put_port/
s/drm_dp_get_validated_mstb_ref/drm_dp_mst_topology_get_mstb_validated/
s/drm_dp_put_mst_branch_device/drm_dp_mst_topology_put_mstb/

This is a much more consistent naming scheme, and will make even more
sense once we redesign how the current refcounting scheme here works.

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 114 ++
 1 file changed, 62 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 2ab16c9e6243..6f9b211069a7 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -46,7 +46,7 @@ static bool dump_dp_payload_table(struct 
drm_dp_mst_topology_mgr *mgr,
  char *buf);
 static int test_calc_pbn_mode(void);
 
-static void drm_dp_put_port(struct drm_dp_mst_port *port);
+static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port);
 
 static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
 int id,
@@ -888,7 +888,7 @@ static void drm_dp_destroy_mst_branch_device(struct kref 
*kref)
 */
list_for_each_entry_safe(port, tmp, &mstb->ports, next) {
list_del(&port->next);
-   drm_dp_put_port(port);
+   drm_dp_mst_topology_put_port(port);
}
 
/* drop any tx slots msg */
@@ -911,7 +911,7 @@ static void drm_dp_destroy_mst_branch_device(struct kref 
*kref)
kref_put(kref, drm_dp_free_mst_branch_device);
 }
 
-static void drm_dp_put_mst_branch_device(struct drm_dp_mst_branch *mstb)
+static void drm_dp_mst_topology_put_mstb(struct drm_dp_mst_branch *mstb)
 {
kref_put(&mstb->kref, drm_dp_destroy_mst_branch_device);
 }
@@ -930,7 +930,7 @@ static void drm_dp_port_teardown_pdt(struct drm_dp_mst_port 
*port, int old_pdt)
case DP_PEER_DEVICE_MST_BRANCHING:
mstb = port->mstb;
port->mstb = NULL;
-   drm_dp_put_mst_branch_device(mstb);
+   drm_dp_mst_topology_put_mstb(mstb);
break;
}
 }
@@ -970,12 +970,14 @@ static void drm_dp_destroy_port(struct kref *kref)
kfree(port);
 }
 
-static void drm_dp_put_port(struct drm_dp_mst_port *port)
+static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port)
 {
kref_put(&port->kref, drm_dp_destroy_port);
 }
 
-static struct drm_dp_mst_branch 
*drm_dp_mst_get_validated_mstb_ref_locked(struct drm_dp_mst_branch *mstb, 
struct drm_dp_mst_branch *to_find)
+static struct drm_dp_mst_branch *
+drm_dp_mst_topology_get_mstb_validated_locked(struct drm_dp_mst_branch *mstb,
+ struct drm_dp_mst_branch *to_find)
 {
struct drm_dp_mst_port *port;
struct drm_dp_mst_branch *rmstb;
@@ -985,7 +987,8 @@ static struct drm_dp_mst_branch 
*drm_dp_mst_get_validated_mstb_ref_locked(struct
}
list_for_each_entry(port, &mstb->ports, next) {
if (port->mstb) {
-   rmstb = 
drm_dp_mst_get_validated_mstb_ref_locked(port->mstb, to_find);
+   rmstb = drm_dp_mst_topology_get_mstb_validated_locked(
+   port->mstb, to_find);
if (rmstb)
return rmstb;
}
@@ -993,12 +996,15 @@ static struct drm_dp_mst_branch 
*drm_dp_mst_get_validated_mstb_ref_locked(struct
return NULL;
 }
 
-static struct drm_dp_mst_branch *drm_dp_get_validated_mstb_ref(struct 
drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_branch *mstb)
+static struct drm_dp_mst_branch *
+drm_dp_mst_topology_get_mstb_validated(struct drm_dp_mst_topology_mgr *mgr,
+  struct drm_dp_mst_branch *mstb)
 {
struct drm_dp_mst_branch *rmstb = NULL;
mutex_lock(&mgr->lock);
if (mgr->mst_primary)
-   rmstb = 
drm_dp_mst_get_validated_mstb_ref_locked(mgr->mst_primary, mstb);
+   rmstb = drm_dp_mst_topology_get_mstb_validated_locked(
+   mgr->mst_primary, mstb);
mutex_unlock(&mgr->lock);
return rmstb;
 }
@@ -1021,7 +1027,9 @@ static struct drm_dp_mst_port 
*drm_dp_mst_get_port_ref_locked(struct drm_dp_mst_
return NULL;
 }
 
-static struct drm_dp_mst_port *drm_dp_get_validated_port_ref(struct 
drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
+static struct drm_dp_mst_port *
+drm_dp_mst_topology_get_port_validated(struct drm_dp_mst_topology_mgr *mgr,
+  struct drm_dp_mst_port *port)
 {
struct drm_dp_mst_port *rport = NULL;
mutex_lock(&mgr->lock);
@@ -1210,7 +1218,7 @@ static void drm_dp_add_port(struct drm

[Intel-gfx] [PATCH v3 05/16] drm/dp_mst: Fix payload deallocation on hotplugs using malloc refs

2019-01-02 Thread Lyude Paul
Up until now, freeing payloads on remote MST hubs that just had ports
removed has almost never worked because we've been relying on port
validation in order to stop us from accessing ports that have already
been freed from memory, but ports which need their payloads released due
to being removed will never be a valid part of the topology after
they've been removed.

Since we've introduced malloc refs, we can replace all of the validation
logic in payload helpers which are used for deallocation with some
well-placed malloc krefs. This ensures that regardless of whether or not
the ports are still valid and in the topology, any port which has an
allocated payload will remain allocated in memory until it's payloads
have been removed - finally allowing us to actually release said
payloads correctly.

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 54 +++
 1 file changed, 30 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index f10a7edb401e..769e2c0419c2 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2102,10 +2102,6 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
u8 sinks[DRM_DP_MAX_SDP_STREAMS];
int i;
 
-   port = drm_dp_mst_topology_get_port_validated(mgr, port);
-   if (!port)
-   return -EINVAL;
-
port_num = port->port_num;
mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);
if (!mstb) {
@@ -2113,10 +2109,8 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
   port->parent,
   &port_num);
 
-   if (!mstb) {
-   drm_dp_mst_topology_put_port(port);
+   if (!mstb)
return -EINVAL;
-   }
}
 
txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
@@ -2153,7 +2147,6 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
kfree(txmsg);
 fail_put:
drm_dp_mst_topology_put_mstb(mstb);
-   drm_dp_mst_topology_put_port(port);
return ret;
 }
 
@@ -2258,15 +2251,16 @@ static int drm_dp_destroy_payload_step2(struct 
drm_dp_mst_topology_mgr *mgr,
  */
 int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
 {
-   int i, j;
-   int cur_slots = 1;
struct drm_dp_payload req_payload;
struct drm_dp_mst_port *port;
+   int i, j;
+   int cur_slots = 1;
 
mutex_lock(&mgr->payload_lock);
for (i = 0; i < mgr->max_payloads; i++) {
struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i];
struct drm_dp_payload *payload = &mgr->payloads[i];
+   bool put_port = false;
 
/* solve the current payloads - compare to the hw ones
   - update the hw view */
@@ -2274,12 +2268,20 @@ int drm_dp_update_payload_part1(struct 
drm_dp_mst_topology_mgr *mgr)
if (vcpi) {
port = container_of(vcpi, struct drm_dp_mst_port,
vcpi);
-   port = drm_dp_mst_topology_get_port_validated(mgr,
- port);
-   if (!port) {
-   mutex_unlock(&mgr->payload_lock);
-   return -EINVAL;
+
+   /* Validated ports don't matter if we're releasing
+* VCPI
+*/
+   if (vcpi->num_slots) {
+   port = drm_dp_mst_topology_get_port_validated(
+   mgr, port);
+   if (!port) {
+   mutex_unlock(&mgr->payload_lock);
+   return -EINVAL;
+   }
+   put_port = true;
}
+
req_payload.num_slots = vcpi->num_slots;
req_payload.vcpi = vcpi->vcpi;
} else {
@@ -2311,7 +2313,7 @@ int drm_dp_update_payload_part1(struct 
drm_dp_mst_topology_mgr *mgr)
}
cur_slots += req_payload.num_slots;
 
-   if (port)
+   if (put_port)
drm_dp_mst_topology_put_port(port);
}
 
@@ -3126,6 +3128,8 @@ bool drm_dp_mst_allocate_vcpi(struct 
drm_dp_mst_topology_mgr *mgr,
DRM_DEBUG_KMS("initing vcpi for pbn=%d slots=%d\n",
  pbn, port->vcpi.num_slots);
 
+   /* Keep port allocated until it's payload has been removed *

[Intel-gfx] [PATCH v3 06/16] drm/i915: Keep malloc references to MST ports

2019-01-02 Thread Lyude Paul
So that the ports stay around until we've destroyed the connectors, in
order to ensure that we don't pass an invalid pointer to any MST helpers
once we introduce the new MST VCPI helpers.

Changes since v1:
* Move drm_dp_mst_get_port_malloc() to where we assign
  intel_connector->port - danvet

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/i915/intel_connector.c | 4 
 drivers/gpu/drm/i915/intel_dp_mst.c| 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_connector.c 
b/drivers/gpu/drm/i915/intel_connector.c
index 18e370f607bc..37d2c644f4b8 100644
--- a/drivers/gpu/drm/i915/intel_connector.c
+++ b/drivers/gpu/drm/i915/intel_connector.c
@@ -95,6 +95,10 @@ void intel_connector_destroy(struct drm_connector *connector)
intel_panel_fini(&intel_connector->panel);
 
drm_connector_cleanup(connector);
+
+   if (intel_connector->port)
+   drm_dp_mst_put_port_malloc(intel_connector->port);
+
kfree(connector);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c 
b/drivers/gpu/drm/i915/intel_dp_mst.c
index f05427b74e34..631fd1537252 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -457,6 +457,7 @@ static struct drm_connector 
*intel_dp_add_mst_connector(struct drm_dp_mst_topolo
intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
intel_connector->mst_port = intel_dp;
intel_connector->port = port;
+   drm_dp_mst_get_port_malloc(port);
 
connector = &intel_connector->base;
ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs,
-- 
2.20.1

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


[Intel-gfx] [PATCH v3 00/16] MST refcounting/atomic helpers cleanup

2019-01-02 Thread Lyude Paul
This is the series I've been working on for a while now to get all of
the atomic DRM drivers in the tree to use the atomic MST helpers, and to
make the atomic MST helpers actually idempotent. Turns out it's a lot
more difficult to do that without also fixing how port and branch device
refcounting works so that it actually makes sense, since the current
upstream implementation requires a ton of magic in the atomic helpers to
work around properly and in many situations just plain doesn't work as
intended.

There's still more cleanup that can be done, but I think this is a good
place to start off for now :).

Lyude Paul (16):
  drm/dp_mst: Rename drm_dp_mst_get_validated_(port|mstb)_ref and
friends
  drm/dp_mst: Introduce new refcounting scheme for mstbs and ports
  drm/dp_mst: Restart last_connected_port_and_mstb() if topology ref
fails
  drm/dp_mst: Stop releasing VCPI when removing ports from topology
  drm/dp_mst: Fix payload deallocation on hotplugs using malloc refs
  drm/i915: Keep malloc references to MST ports
  drm/amdgpu/display: Keep malloc ref to MST port
  drm/nouveau: Remove bogus cleanup in nv50_mstm_add_connector()
  drm/nouveau: Remove unnecessary VCPI checks in nv50_msto_cleanup()
  drm/nouveau: Keep malloc references to MST ports
  drm/nouveau: Stop unsetting mstc->port, use malloc refs
  drm/nouveau: Grab payload lock in nv50_msto_payload()
  drm/dp_mst: Add some atomic state iterator macros
  drm/dp_mst: Start tracking per-port VCPI allocations
  drm/dp_mst: Check payload count in drm_dp_mst_atomic_check()
  drm/nouveau: Use atomic VCPI helpers for MST

 .../gpu/dp-mst/topology-figure-1.dot  |  52 +
 .../gpu/dp-mst/topology-figure-2.dot  |  56 ++
 .../gpu/dp-mst/topology-figure-3.dot  |  59 ++
 Documentation/gpu/drm-kms-helpers.rst |  26 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  11 +-
 drivers/gpu/drm/drm_dp_mst_topology.c | 938 ++
 drivers/gpu/drm/i915/intel_connector.c|   4 +
 drivers/gpu/drm/i915/intel_display.c  |   4 +
 drivers/gpu/drm/i915/intel_dp_mst.c   |  65 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c   |  94 +-
 include/drm/drm_dp_mst_helper.h   | 151 ++-
 11 files changed, 1208 insertions(+), 252 deletions(-)
 create mode 100644 Documentation/gpu/dp-mst/topology-figure-1.dot
 create mode 100644 Documentation/gpu/dp-mst/topology-figure-2.dot
 create mode 100644 Documentation/gpu/dp-mst/topology-figure-3.dot

-- 
2.20.1

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


[Intel-gfx] [PATCH v3 15/16] drm/dp_mst: Check payload count in drm_dp_mst_atomic_check()

2019-01-02 Thread Lyude Paul
It occurred to me that we never actually check this! So let's start
doing that.

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index c33c4a3aec34..fc9bcbb55417 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3647,7 +3647,7 @@ drm_dp_mst_atomic_check_topology_state(struct 
drm_dp_mst_topology_mgr *mgr,
   struct drm_dp_mst_topology_state 
*mst_state)
 {
struct drm_dp_vcpi_allocation *vcpi;
-   int avail_slots = 63;
+   int avail_slots = 63, payload_count = 0;
 
list_for_each_entry(vcpi, &mst_state->vcpis, next) {
/* Releasing VCPI is always OK-even if the port is gone */
@@ -3667,6 +3667,12 @@ drm_dp_mst_atomic_check_topology_state(struct 
drm_dp_mst_topology_mgr *mgr,
 avail_slots + vcpi->vcpi);
return -ENOSPC;
}
+
+   if (++payload_count > mgr->max_payloads) {
+   DRM_DEBUG_ATOMIC("[MST MGR:%p] state %p has too many 
payloads (max=%d)\n",
+mgr, mst_state, mgr->max_payloads);
+   return -EINVAL;
+   }
}
DRM_DEBUG_ATOMIC("[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
 mgr, mst_state, avail_slots,
-- 
2.20.1

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


[Intel-gfx] [PATCH v3 08/16] drm/nouveau: Remove bogus cleanup in nv50_mstm_add_connector()

2019-01-02 Thread Lyude Paul
Trying to destroy the connector using mstc->connector.funcs->destroy()
if connector initialization fails is wrong: there is no possible
codepath in nv50_mstc_new where nv50_mstm_add_connector() would return
<0 and mstc would be non-NULL.

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 26af45785939..641252208e67 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1099,11 +1099,8 @@ nv50_mstm_add_connector(struct drm_dp_mst_topology_mgr 
*mgr,
int ret;
 
ret = nv50_mstc_new(mstm, port, path, &mstc);
-   if (ret) {
-   if (mstc)
-   mstc->connector.funcs->destroy(&mstc->connector);
+   if (ret)
return NULL;
-   }
 
return &mstc->connector;
 }
-- 
2.20.1

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


[Intel-gfx] [PATCH v3 09/16] drm/nouveau: Remove unnecessary VCPI checks in nv50_msto_cleanup()

2019-01-02 Thread Lyude Paul
There is no need to look at the port's VCPI allocation before calling
drm_dp_mst_deallocate_vcpi(), as we already have msto->disabled to let
us avoid cleaning up an msto more then once. The DP MST core will never
call drm_dp_mst_deallocate_vcpi() on it's own, which is presumably what
these checks are meant to protect against.

More importantly though, we're about to stop clearing mstc->port in the
next commit, which means if we could potentially hit a use-after-free
error if we tried to check mstc->port->vcpi here. So to make life easier
for anyone who bisects this code in the future, use msto->disabled
instead to check whether or not we need to deallocate VCPI instead.

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 641252208e67..0f7d72518604 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -704,14 +704,17 @@ nv50_msto_cleanup(struct nv50_msto *msto)
struct nv50_mstc *mstc = msto->mstc;
struct nv50_mstm *mstm = mstc->mstm;
 
+   if (!msto->disabled)
+   return;
+
NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
-   if (mstc->port && mstc->port->vcpi.vcpi > 0 && !nv50_msto_payload(msto))
+
+   if (mstc->port)
drm_dp_mst_deallocate_vcpi(&mstm->mgr, mstc->port);
-   if (msto->disabled) {
-   msto->mstc = NULL;
-   msto->head = NULL;
-   msto->disabled = false;
-   }
+
+   msto->mstc = NULL;
+   msto->head = NULL;
+   msto->disabled = false;
 }
 
 static void
-- 
2.20.1

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


[Intel-gfx] [PATCH v3 12/16] drm/nouveau: Grab payload lock in nv50_msto_payload()

2019-01-02 Thread Lyude Paul
Going through the currently programmed payloads isn't safe without
holding mgr->payload_lock, so actually do that and warn if anyone tries
calling nv50_msto_payload() in the future without grabbing the right
locks.

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 157d208d37b5..67f7bf97e5d9 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -680,6 +680,8 @@ nv50_msto_payload(struct nv50_msto *msto)
struct nv50_mstm *mstm = mstc->mstm;
int vcpi = mstc->port->vcpi.vcpi, i;
 
+   WARN_ON(!mutex_is_locked(&mstm->mgr.payload_lock));
+
NV_ATOMIC(drm, "%s: vcpi %d\n", msto->encoder.name, vcpi);
for (i = 0; i < mstm->mgr.max_payloads; i++) {
struct drm_dp_payload *payload = &mstm->mgr.payloads[i];
@@ -733,6 +735,8 @@ nv50_msto_prepare(struct nv50_msto *msto)
   (0x0100 << msto->head->base.index),
};
 
+   mutex_lock(&mstm->mgr.payload_lock);
+
NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name);
if (mstc->port->vcpi.vcpi > 0) {
struct drm_dp_payload *payload = nv50_msto_payload(msto);
@@ -748,7 +752,9 @@ nv50_msto_prepare(struct nv50_msto *msto)
  msto->encoder.name, msto->head->base.base.name,
  args.vcpi.start_slot, args.vcpi.num_slots,
  args.vcpi.pbn, args.vcpi.aligned_pbn);
+
nvif_mthd(&drm->display->disp.object, 0, &args, sizeof(args));
+   mutex_unlock(&mstm->mgr.payload_lock);
 }
 
 static int
-- 
2.20.1

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


[Intel-gfx] [PATCH v3 16/16] drm/nouveau: Use atomic VCPI helpers for MST

2019-01-02 Thread Lyude Paul
Currently, nouveau uses the yolo method of setting up MST displays: it
uses the old VCPI helpers (drm_dp_find_vcpi_slots()) for computing the
display configuration. These helpers don't take care to make sure they
take a reference to the mstb port that they're checking, and
additionally don't actually check whether or not the topology still has
enough bandwidth to provide the VCPI tokens required.

So, drop usage of the old helpers and move entirely over to the atomic
helpers.

Changes since v5:
 - Update nv50_msto_atomic_check() and nv50_mstc_atomic_check() to the
   new requirements for drm_dp_atomic_find_vcpi_slots() and
   drm_dp_atomic_release_vcpi_slots()

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 52 ++---
 1 file changed, 46 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 67f7bf97e5d9..df696008d205 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -762,16 +762,22 @@ nv50_msto_atomic_check(struct drm_encoder *encoder,
   struct drm_crtc_state *crtc_state,
   struct drm_connector_state *conn_state)
 {
-   struct nv50_mstc *mstc = nv50_mstc(conn_state->connector);
+   struct drm_atomic_state *state = crtc_state->state;
+   struct drm_connector *connector = conn_state->connector;
+   struct nv50_mstc *mstc = nv50_mstc(connector);
struct nv50_mstm *mstm = mstc->mstm;
-   int bpp = conn_state->connector->display_info.bpc * 3;
+   int bpp = connector->display_info.bpc * 3;
int slots;
 
-   mstc->pbn = drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock, bpp);
+   mstc->pbn = drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock,
+bpp);
 
-   slots = drm_dp_find_vcpi_slots(&mstm->mgr, mstc->pbn);
-   if (slots < 0)
-   return slots;
+   if (crtc_state->connectors_changed || crtc_state->mode_changed) {
+   slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr,
+ mstc->port, mstc->pbn);
+   if (slots < 0)
+   return slots;
+   }
 
return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state,
   mstc->native);
@@ -934,12 +940,42 @@ nv50_mstc_get_modes(struct drm_connector *connector)
return ret;
 }
 
+static int
+nv50_mstc_atomic_check(struct drm_connector *connector,
+  struct drm_connector_state *new_conn_state)
+{
+   struct drm_atomic_state *state = new_conn_state->state;
+   struct nv50_mstc *mstc = nv50_mstc(connector);
+   struct drm_dp_mst_topology_mgr *mgr = &mstc->mstm->mgr;
+   struct drm_connector_state *old_conn_state =
+   drm_atomic_get_old_connector_state(state, connector);
+   struct drm_crtc_state *old_crtc_state;
+   struct drm_crtc *new_crtc = new_conn_state->crtc,
+   *old_crtc = old_conn_state->crtc;
+
+   if (!old_crtc)
+   return 0;
+
+   old_crtc_state = drm_atomic_get_old_crtc_state(state, old_crtc);
+   if (!old_crtc_state || !old_crtc_state->enable)
+   return 0;
+
+   if (new_crtc)
+   return 0;
+
+   /* This connector will be left without an enabled CRTC, so its VCPI
+* must be released here
+*/
+   return drm_dp_atomic_release_vcpi_slots(state, mgr, mstc->port);
+}
+
 static const struct drm_connector_helper_funcs
 nv50_mstc_help = {
.get_modes = nv50_mstc_get_modes,
.mode_valid = nv50_mstc_mode_valid,
.best_encoder = nv50_mstc_best_encoder,
.atomic_best_encoder = nv50_mstc_atomic_best_encoder,
+   .atomic_check = nv50_mstc_atomic_check,
 };
 
 static enum drm_connector_status
@@ -2121,6 +2157,10 @@ nv50_disp_atomic_check(struct drm_device *dev, struct 
drm_atomic_state *state)
return ret;
}
 
+   ret = drm_dp_mst_atomic_check(state);
+   if (ret)
+   return ret;
+
return 0;
 }
 
-- 
2.20.1

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


  1   2   >