Re: [Intel-gfx] [PATCH] drm/i915: Release the forgotten connector reference

2017-02-02 Thread Joonas Lahtinen
On ke, 2017-02-01 at 19:58 +, Chris Wilson wrote:
> The reference was gained in
> intel_modeset_update_connector_atomic_state() [called from
> intel_modeset_setup_hw_state()] and is never lost if no client ever
> performs a modeset.
> 
> [  649.836069] WARNING: CPU: 6 PID: 8865 at 
> drivers/gpu/drm/drm_mode_config.c:424 drm_mode_config_cleanup+0x21b/0x290 
> [drm]
> [  649.836078] Modules linked in: i915(-) intel_gtt drm_kms_helper 
> cfbfillrect syscopyarea cfbimgblt sysfillrect sysimgblt fb_sys_fops 
> cfbcopyarea drm
> [  649.836099] CPU: 6 PID: 8865 Comm: drv_selftest Not tainted 4.10.0-rc6+ 
> #908
> [  649.836106] Hardware name: Intel Corporation 2012 Client Platform/Emerald 
> Lake 2, BIOS ACRVMBY1.86C.0078.P00.1201161002 01/16/2012
> [  649.836114] Call Trace:
> [  649.836125]  dump_stack+0x4d/0x6f
> [  649.836136]  __warn+0xc1/0xe0
> [  649.836144]  warn_slowpath_null+0x18/0x20
> [  649.836163]  drm_mode_config_cleanup+0x21b/0x290 [drm]
> [  649.836213]  intel_modeset_cleanup+0x59/0xa0 [i915]
> [  649.836242]  i915_driver_unload+0x84/0x170 [i915]
> [  649.836277]  i915_pci_remove+0x14/0x20 [i915]
> [  649.836287]  pci_device_remove+0x28/0x60
> [  649.836301]  device_release_driver_internal+0x132/0x1d0
> [  649.836313]  driver_detach+0x3a/0x80
> [  649.836324]  bus_remove_driver+0x47/0xa0
> [  649.836335]  driver_unregister+0x27/0x50
> [  649.836344]  pci_unregister_driver+0x34/0xa0
> [  649.836387]  i915_exit+0x1a/0x71 [i915]
> [  649.836401]  SyS_delete_module+0x173/0x1c0
> [  649.836413]  entry_SYSCALL_64_fastpath+0x17/0x98
> [  649.836422] RIP: 0033:0x7f8d5a841ee7
> [  649.836432] RSP: 002b:7fff89161a28 EFLAGS: 0206 ORIG_RAX: 
> 00b0
> [  649.836448] RAX: ffda RBX: 55f6cd1db5c0 RCX: 
> 7f8d5a841ee7
> [  649.836458] RDX:  RSI: 0800 RDI: 
> 55f6cd1da7b8
> [  649.836467] RBP: 7f8d5aaee440 R08:  R09: 
> 7fff89161a58
> [  649.836476] R10: 0062 R11: 0206 R12: 
> 
> [  649.836486] R13: 55f6cd1d9010 R14: 003a R15: 
> 7fff891609f0
> [  649.836514] ---[ end trace 0e529da316e2a3d1 ]---
> [  649.836536] [drm:drm_mode_config_cleanup [drm]] *ERROR* connector VGA-1 
> leaked!
> 
> Signed-off-by: Chris Wilson 

Reviewed-by: Joonas Lahtinen 

Regards, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Release the forgotten connector reference

2017-02-02 Thread Chris Wilson
On Thu, Feb 02, 2017 at 10:08:57AM +0200, Joonas Lahtinen wrote:
> On ke, 2017-02-01 at 19:58 +, Chris Wilson wrote:
> > The reference was gained in
> > intel_modeset_update_connector_atomic_state() [called from
> > intel_modeset_setup_hw_state()] and is never lost if no client ever
> > performs a modeset.
> > 
> > [  649.836069] WARNING: CPU: 6 PID: 8865 at 
> > drivers/gpu/drm/drm_mode_config.c:424 drm_mode_config_cleanup+0x21b/0x290 
> > [drm]
> > [  649.836078] Modules linked in: i915(-) intel_gtt drm_kms_helper 
> > cfbfillrect syscopyarea cfbimgblt sysfillrect sysimgblt fb_sys_fops 
> > cfbcopyarea drm
> > [  649.836099] CPU: 6 PID: 8865 Comm: drv_selftest Not tainted 4.10.0-rc6+ 
> > #908
> > [  649.836106] Hardware name: Intel Corporation 2012 Client 
> > Platform/Emerald Lake 2, BIOS ACRVMBY1.86C.0078.P00.1201161002 01/16/2012
> > [  649.836114] Call Trace:
> > [  649.836125]  dump_stack+0x4d/0x6f
> > [  649.836136]  __warn+0xc1/0xe0
> > [  649.836144]  warn_slowpath_null+0x18/0x20
> > [  649.836163]  drm_mode_config_cleanup+0x21b/0x290 [drm]
> > [  649.836213]  intel_modeset_cleanup+0x59/0xa0 [i915]
> > [  649.836242]  i915_driver_unload+0x84/0x170 [i915]
> > [  649.836277]  i915_pci_remove+0x14/0x20 [i915]
> > [  649.836287]  pci_device_remove+0x28/0x60
> > [  649.836301]  device_release_driver_internal+0x132/0x1d0
> > [  649.836313]  driver_detach+0x3a/0x80
> > [  649.836324]  bus_remove_driver+0x47/0xa0
> > [  649.836335]  driver_unregister+0x27/0x50
> > [  649.836344]  pci_unregister_driver+0x34/0xa0
> > [  649.836387]  i915_exit+0x1a/0x71 [i915]
> > [  649.836401]  SyS_delete_module+0x173/0x1c0
> > [  649.836413]  entry_SYSCALL_64_fastpath+0x17/0x98
> > [  649.836422] RIP: 0033:0x7f8d5a841ee7
> > [  649.836432] RSP: 002b:7fff89161a28 EFLAGS: 0206 ORIG_RAX: 
> > 00b0
> > [  649.836448] RAX: ffda RBX: 55f6cd1db5c0 RCX: 
> > 7f8d5a841ee7
> > [  649.836458] RDX:  RSI: 0800 RDI: 
> > 55f6cd1da7b8
> > [  649.836467] RBP: 7f8d5aaee440 R08:  R09: 
> > 7fff89161a58
> > [  649.836476] R10: 0062 R11: 0206 R12: 
> > 
> > [  649.836486] R13: 55f6cd1d9010 R14: 003a R15: 
> > 7fff891609f0
> > [  649.836514] ---[ end trace 0e529da316e2a3d1 ]---
> > [  649.836536] [drm:drm_mode_config_cleanup [drm]] *ERROR* connector VGA-1 
> > leaked!
> > 
> > Signed-off-by: Chris Wilson 
> 
> Reviewed-by: Joonas Lahtinen 

I'm hoping that this won't be required after Maarten's force disable all
CRTC on unload. We will see.
-Chris

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


Re: [Intel-gfx] [PATCH] drm/i915: Release the forgotten connector reference

2017-02-02 Thread Chris Wilson
On Wed, Feb 01, 2017 at 07:58:31PM +, Chris Wilson wrote:
> The reference was gained in
> intel_modeset_update_connector_atomic_state() [called from
> intel_modeset_setup_hw_state()] and is never lost if no client ever
> performs a modeset.
> 
> [  649.836069] WARNING: CPU: 6 PID: 8865 at 
> drivers/gpu/drm/drm_mode_config.c:424 drm_mode_config_cleanup+0x21b/0x290 
> [drm]
> [  649.836078] Modules linked in: i915(-) intel_gtt drm_kms_helper 
> cfbfillrect syscopyarea cfbimgblt sysfillrect sysimgblt fb_sys_fops 
> cfbcopyarea drm
> [  649.836099] CPU: 6 PID: 8865 Comm: drv_selftest Not tainted 4.10.0-rc6+ 
> #908
> [  649.836106] Hardware name: Intel Corporation 2012 Client Platform/Emerald 
> Lake 2, BIOS ACRVMBY1.86C.0078.P00.1201161002 01/16/2012
> [  649.836114] Call Trace:
> [  649.836125]  dump_stack+0x4d/0x6f
> [  649.836136]  __warn+0xc1/0xe0
> [  649.836144]  warn_slowpath_null+0x18/0x20
> [  649.836163]  drm_mode_config_cleanup+0x21b/0x290 [drm]
> [  649.836213]  intel_modeset_cleanup+0x59/0xa0 [i915]
> [  649.836242]  i915_driver_unload+0x84/0x170 [i915]
> [  649.836277]  i915_pci_remove+0x14/0x20 [i915]
> [  649.836287]  pci_device_remove+0x28/0x60
> [  649.836301]  device_release_driver_internal+0x132/0x1d0
> [  649.836313]  driver_detach+0x3a/0x80
> [  649.836324]  bus_remove_driver+0x47/0xa0
> [  649.836335]  driver_unregister+0x27/0x50
> [  649.836344]  pci_unregister_driver+0x34/0xa0
> [  649.836387]  i915_exit+0x1a/0x71 [i915]
> [  649.836401]  SyS_delete_module+0x173/0x1c0
> [  649.836413]  entry_SYSCALL_64_fastpath+0x17/0x98
> [  649.836422] RIP: 0033:0x7f8d5a841ee7
> [  649.836432] RSP: 002b:7fff89161a28 EFLAGS: 0206 ORIG_RAX: 
> 00b0
> [  649.836448] RAX: ffda RBX: 55f6cd1db5c0 RCX: 
> 7f8d5a841ee7
> [  649.836458] RDX:  RSI: 0800 RDI: 
> 55f6cd1da7b8
> [  649.836467] RBP: 7f8d5aaee440 R08:  R09: 
> 7fff89161a58
> [  649.836476] R10: 0062 R11: 0206 R12: 
> 
> [  649.836486] R13: 55f6cd1d9010 R14: 003a R15: 
> 7fff891609f0
> [  649.836514] ---[ end trace 0e529da316e2a3d1 ]---
> [  649.836536] [drm:drm_mode_config_cleanup [drm]] *ERROR* connector VGA-1 
> leaked!
> 
> Signed-off-by: Chris Wilson 
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=95004
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
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: Enable atomic support by default on supported platforms.

2017-02-02 Thread Patchwork
== Series Details ==

Series: drm/i915: Enable atomic support by default on supported platforms.
URL   : https://patchwork.freedesktop.org/series/18970/
State : success

== Summary ==

Series 18970v1 drm/i915: Enable atomic support by default on supported 
platforms.
https://patchwork.freedesktop.org/api/1.0/series/18970/revisions/1/mbox/

Test kms_cursor_legacy:
Subgroup basic-busy-flip-before-cursor-atomic:
skip   -> PASS   (fi-bxt-j4205)
skip   -> PASS   (fi-skl-6260u)
skip   -> PASS   (fi-skl-6700hq)
skip   -> PASS   (fi-skl-6770hq)
skip   -> PASS   (fi-snb-2520m)
skip   -> PASS   (fi-ivb-3520m)
skip   -> PASS   (fi-ivb-3770)
skip   -> PASS   (fi-snb-2600)
skip   -> PASS   (fi-skl-6700k)
skip   -> PASS   (fi-kbl-7500u)
skip   -> PASS   (fi-bdw-5557u)
skip   -> PASS   (fi-hsw-4770)
skip   -> PASS   (fi-hsw-4770r)
Subgroup basic-flip-after-cursor-atomic:
skip   -> PASS   (fi-bxt-j4205)
skip   -> PASS   (fi-skl-6260u)
skip   -> PASS   (fi-skl-6700hq)
skip   -> PASS   (fi-skl-6770hq)
skip   -> PASS   (fi-snb-2520m)
skip   -> PASS   (fi-ivb-3520m)
skip   -> PASS   (fi-ivb-3770)
skip   -> PASS   (fi-snb-2600)
skip   -> PASS   (fi-skl-6700k)
skip   -> PASS   (fi-kbl-7500u)
skip   -> PASS   (fi-bdw-5557u)
skip   -> PASS   (fi-hsw-4770)
skip   -> PASS   (fi-hsw-4770r)
Subgroup basic-flip-before-cursor-atomic:
skip   -> PASS   (fi-bxt-j4205)
skip   -> PASS   (fi-skl-6260u)
skip   -> PASS   (fi-skl-6700hq)
skip   -> PASS   (fi-skl-6770hq)
skip   -> PASS   (fi-snb-2520m)
skip   -> PASS   (fi-ivb-3520m)
skip   -> PASS   (fi-ivb-3770)
skip   -> PASS   (fi-snb-2600)
skip   -> PASS   (fi-skl-6700k)
skip   -> PASS   (fi-kbl-7500u)
skip   -> PASS   (fi-bdw-5557u)
skip   -> PASS   (fi-hsw-4770)
skip   -> PASS   (fi-hsw-4770r)

fi-bdw-5557u total:247  pass:236  dwarn:0   dfail:0   fail:0   skip:11 
fi-bsw-n3050 total:247  pass:208  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205 total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-bxt-t5700 total:78   pass:65   dwarn:0   dfail:0   fail:0   skip:12 
fi-byt-j1900 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-n2820 total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770  total:247  pass:231  dwarn:0   dfail:0   fail:0   skip:16 
fi-hsw-4770r total:247  pass:231  dwarn:0   dfail:0   fail:0   skip:16 
fi-ivb-3520m total:247  pass:229  dwarn:0   dfail:0   fail:0   skip:18 
fi-ivb-3770  total:247  pass:229  dwarn:0   dfail:0   fail:0   skip:18 
fi-kbl-7500u total:247  pass:227  dwarn:0   dfail:0   fail:2   skip:18 
fi-skl-6260u total:247  pass:237  dwarn:0   dfail:0   fail:0   skip:10 
fi-skl-6700hqtotal:247  pass:230  dwarn:0   dfail:0   fail:0   skip:17 
fi-skl-6700k total:247  pass:225  dwarn:4   dfail:0   fail:0   skip:18 
fi-skl-6770hqtotal:247  pass:237  dwarn:0   dfail:0   fail:0   skip:10 
fi-snb-2520m total:247  pass:219  dwarn:0   dfail:0   fail:0   skip:28 
fi-snb-2600  total:247  pass:218  dwarn:0   dfail:0   fail:0   skip:29 

a0cc425b0034c42eb3830f7dd612ac2a132a874c drm-tip: 2017y-02m-01d-17h-17m-34s UTC 
integration manifest
b519f7f drm/i915: Enable atomic support by default on supported platforms.

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3670/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v1½ 07/13] drm/i915/dp: cache common rates with sink rates

2017-02-02 Thread Jani Nikula
On Thu, 02 Feb 2017, "Pandiyan, Dhinakaran"  
wrote:
> On Thu, 2017-01-26 at 21:44 +0200, Jani Nikula wrote:
>> Now that source rates are static and sink rates are updated whenever
>> DPCD is updated, we can do and cache the intersection of them whenever
>> sink rates are updated. This reduces code complexity, as we don't have
>> to keep calling the functions to intersect. We also get rid of several
>> common rates arrays on stack.
>> 
>> Limiting the common rates by a max link rate can be done by picking the
>> first N elements of the cached common rates.
>> 
>> Cc: Manasi Navare 
>> Cc: Ville Syrjälä 
>> Signed-off-by: Jani Nikula 
>> ---
>>  drivers/gpu/drm/i915/intel_dp.c  | 66 
>> ++--
>>  drivers/gpu/drm/i915/intel_drv.h |  3 ++
>>  2 files changed, 40 insertions(+), 29 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c 
>> b/drivers/gpu/drm/i915/intel_dp.c
>> index f163391e61fa..7d3ff92000c3 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -283,17 +283,29 @@ static int intel_dp_find_rate(const int *rates, int 
>> len, int rate)
>>  return -1;
>>  }
>>  
>> -static int intel_dp_common_rates(struct intel_dp *intel_dp,
>> - int *common_rates)
>> +static void intel_dp_set_common_rates(struct intel_dp *intel_dp)
>>  {
>> -int max_rate = intel_dp->max_sink_link_rate;
>> -int i, common_len;
>> +WARN_ON(!intel_dp->num_source_rates || !intel_dp->num_sink_rates);
>>  
>> -common_len = intersect_rates(intel_dp->source_rates,
>> - intel_dp->num_source_rates,
>> - intel_dp->sink_rates,
>> - intel_dp->num_sink_rates,
>> - common_rates);
>> +intel_dp->num_common_rates = intersect_rates(intel_dp->source_rates,
>> + intel_dp->num_source_rates,
>> + intel_dp->sink_rates,
>> + intel_dp->num_sink_rates,
>> + intel_dp->common_rates);
>
>
> Do we need to pass all these args given that all of them are now
> available in intel_dp and intersect_rates() is not used anywhere else? 

My reasoning is that with this interface intersect_rates remains
generic, independent of intel_dp or anything else, and you can be sure
it's stateless.

BR,
Jani.


>
> -DK
>> +
>> +/* Paranoia, there should always be something in common. */
>> +if (WARN_ON(intel_dp->num_common_rates == 0)) {
>> +intel_dp->common_rates[0] = default_rates[0];
>> +intel_dp->num_common_rates = 1;
>> +}
>> +}
>> +
>> +/* get length of common rates potentially limited by max_rate */
>> +static int intel_dp_common_len_rate_limit(struct intel_dp *intel_dp,
>> +  int max_rate)
>> +{
>> +const int *common_rates = intel_dp->common_rates;
>> +int i, common_len = intel_dp->num_common_rates;
>>  
>>  /* Limit results by potentially reduced max rate */
>>  for (i = 0; i < common_len; i++) {
>> @@ -304,25 +316,23 @@ static int intel_dp_common_rates(struct intel_dp 
>> *intel_dp,
>>  return 0;
>>  }
>>  
>> -static int intel_dp_link_rate_index(struct intel_dp *intel_dp,
>> -int *common_rates, int link_rate)
>> +static int intel_dp_link_rate_index(struct intel_dp *intel_dp, int 
>> link_rate)
>>  {
>>  int common_len;
>>  
>> -common_len = intel_dp_common_rates(intel_dp, common_rates);
>> +common_len = intel_dp_common_len_rate_limit(intel_dp,
>> +
>> intel_dp->max_sink_link_rate);
>>  
>> -return intel_dp_find_rate(common_rates, common_len, link_rate);
>> +return intel_dp_find_rate(intel_dp->common_rates, common_len, 
>> link_rate);
>>  }
>>  
>>  int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
>>  int link_rate, uint8_t lane_count)
>>  {
>> -int common_rates[DP_MAX_SUPPORTED_RATES];
>> +const int *common_rates = intel_dp->common_rates;
>>  int link_rate_index;
>>  
>> -link_rate_index = intel_dp_link_rate_index(intel_dp,
>> -   common_rates,
>> -   link_rate);
>> +link_rate_index = intel_dp_link_rate_index(intel_dp, link_rate);
>>  if (link_rate_index > 0) {
>>  intel_dp->max_sink_link_rate = common_rates[link_rate_index - 
>> 1];
>>  intel_dp->max_sink_lane_count = lane_count;
>> @@ -1509,8 +1519,6 @@ static void snprintf_int_array(char *str, size_t len,
>>  
>>  static void intel_dp_print_rates(struct intel_dp *intel_dp)
>>  {
>> -int common_len;
>> -int common_rates[DP_MAX_SUPPORTED_RATES];
>>  char str[128]; /* FIXME: too

Re: [Intel-gfx] [PATCH v1½ 12/13] drm/i915/dp: localize link rate index variable more

2017-02-02 Thread Jani Nikula
On Thu, 02 Feb 2017, Manasi Navare  wrote:
> On Thu, Jan 26, 2017 at 09:44:26PM +0200, Jani Nikula wrote:
>> Localize link_rate_index to the if block, and rename to just index to
>> reduce indent.
>> 
>> Cc: Manasi Navare 
>> Cc: Ville Syrjälä 
>> Signed-off-by: Jani Nikula 
>> ---
>>  drivers/gpu/drm/i915/intel_dp.c | 13 +++--
>>  1 file changed, 7 insertions(+), 6 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c 
>> b/drivers/gpu/drm/i915/intel_dp.c
>> index 7704d32286a3..429dc70c251a 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -1639,7 +1639,6 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>>  /* Conveniently, the link BW constants become indices with a shift...*/
>>  int min_clock = 0;
>>  int max_clock;
>> -int link_rate_index;
>>  int bpp, mode_rate;
>>  int link_avail, link_clock;
>>  const int *common_rates = intel_dp->common_rates;
>> @@ -1684,11 +1683,13 @@ intel_dp_compute_config(struct intel_encoder 
>> *encoder,
>>  
>>  /* Use values requested by Compliance Test Request */
>>  if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) {
>> -link_rate_index = intel_dp_find_rate(intel_dp->common_rates,
>> - intel_dp->num_common_rates,
>> - 
>> intel_dp->compliance.test_link_rate);
>
> Can we not pass just the common_rates as an argument to this function
> since common_rates is already assigned intel_dp->common_rates.

Do you mean just pass intel_dp to intel_dp_find_rate? If yes, I think
this keeps intel_dp_find_rate generic, independent of intel_dp or
anything else, and you can be sure it's stateless (same as
intersect_rates).

If you don't mean that, I don't know what you mean... please explain.

BR,
Jani.


>
> Regards
> Manasi
>
>
>> -if (link_rate_index >= 0)
>> -min_clock = max_clock = link_rate_index;
>> +int index;
>> +
>> +index = intel_dp_find_rate(intel_dp->common_rates,
>> +   intel_dp->num_common_rates,
>> +   intel_dp->compliance.test_link_rate);
>> +if (index >= 0)
>> +min_clock = max_clock = index;
>>  min_lane_count = max_lane_count = 
>> intel_dp->compliance.test_lane_count;
>>  }
>>  DRM_DEBUG_KMS("DP link computation with max lane count %i "
>> -- 
>> 2.1.4
>> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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


Re: [Intel-gfx] [PATCH v1½ 03/13] drm/i915/dp: rename rate_to_index() to intel_dp_find_rate() and reuse

2017-02-02 Thread Jani Nikula
On Wed, 01 Feb 2017, "Pandiyan, Dhinakaran"  
wrote:
> On Thu, 2017-01-26 at 21:44 +0200, Jani Nikula wrote:
>> Rename the function, move it at the top, and reuse in
>> intel_dp_link_rate_index(). If there was a reason in the past to use
>> reverse search order here, there isn't now.
>> 
>> Cc: Manasi Navare 
>> Cc: Ville Syrjälä 
>> Signed-off-by: Jani Nikula 
>> ---
>>  drivers/gpu/drm/i915/intel_dp.c | 33 ++---
>>  1 file changed, 14 insertions(+), 19 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c 
>> b/drivers/gpu/drm/i915/intel_dp.c
>> index 1d66737a3a0f..f3068ff670a1 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -266,6 +266,17 @@ static int intersect_rates(const int *source_rates, int 
>> source_len,
>>  return k;
>>  }
>>  
>> +static int intel_dp_find_rate(const int *rates, int len, int rate)
>
> I wonder if the function name can be more intuitive. The argument is
> rate and the function name indicates it also returns rate. I can't tell
> what the function does by it's name. Feel free to ignore this comment as
> I might be missing some context.

Naming is hard. intel_dp_rate_index?

BR,
Jani.


>
> -DK
>
>> +{
>> +int i;
>> +
>> +for (i = 0; i < len; i++)
>> +if (rate == rates[i])
>> +return i;
>> +
>> +return -1;
>> +}
>> +
>>  static int intel_dp_common_rates(struct intel_dp *intel_dp,
>>   int *common_rates)
>>  {
>> @@ -284,15 +295,10 @@ static int intel_dp_link_rate_index(struct intel_dp 
>> *intel_dp,
>>  int *common_rates, int link_rate)
>>  {
>>  int common_len;
>> -int index;
>>  
>>  common_len = intel_dp_common_rates(intel_dp, common_rates);
>> -for (index = 0; index < common_len; index++) {
>> -if (link_rate == common_rates[common_len - index - 1])
>> -return common_len - index - 1;
>> -}
>>  
>> -return -1;
>> +return intel_dp_find_rate(common_rates, common_len, link_rate);
>>  }
>>  
>>  int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
>> @@ -1542,17 +1548,6 @@ bool intel_dp_read_desc(struct intel_dp *intel_dp)
>>  return true;
>>  }
>>  
>> -static int rate_to_index(const int *rates, int len, int rate)
>> -{
>> -int i;
>> -
>> -for (i = 0; i < len; i++)
>> -if (rate == rates[i])
>> -return i;
>> -
>> -return -1;
>> -}
>> -
>>  int
>>  intel_dp_max_link_rate(struct intel_dp *intel_dp)
>>  {
>> @@ -1568,8 +1563,8 @@ intel_dp_max_link_rate(struct intel_dp *intel_dp)
>>  
>>  int intel_dp_rate_select(struct intel_dp *intel_dp, int rate)
>>  {
>> -int i = rate_to_index(intel_dp->sink_rates, intel_dp->num_sink_rates,
>> -  rate);
>> +int i = intel_dp_find_rate(intel_dp->sink_rates,
>> +   intel_dp->num_sink_rates, rate);
>>  
>>  if (WARN_ON(i < 0))
>>  i = 0;
>

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


[Intel-gfx] [PATCH v2 4/5] drm/i915: Capture module parameters for the GPU error state

2017-02-02 Thread Chris Wilson
They include useful material such as what mode the VM address space is
running in, what submission mode, extra quirks, etc.

v2: Undef the right macro, use type specific pretty printers

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen  #v1
---
 drivers/gpu/drm/i915/i915_drv.h   |  1 +
 drivers/gpu/drm/i915/i915_gpu_error.c | 48 ++-
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 15b6c75ebade..5bcde9395126 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -904,6 +904,7 @@ struct drm_i915_error_state {
u32 reset_count;
u32 suspend_count;
struct intel_device_info device_info;
+   struct i915_params params;
 
/* Generic register state */
u32 eir;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index 5283fe815a4d..58b6296372bf 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -546,6 +546,35 @@ static void err_print_capabilities(struct 
drm_i915_error_state_buf *m,
 #undef PRINT_FLAG
 }
 
+static void err_param_bool(struct drm_i915_error_state_buf *m,
+  const char *name,
+  param_bool x)
+{
+   err_printf(m, "%s: %s\n", name, yesno(x));
+}
+
+static void err_param_int(struct drm_i915_error_state_buf *m,
+ const char *name,
+ param_int x)
+{
+   err_printf(m, "%s: %d\n", name, x);
+}
+
+static void err_param_uint(struct drm_i915_error_state_buf *m,
+  const char *name,
+  param_uint x)
+{
+   err_printf(m, "%s: %u\n", name, x);
+}
+
+static void err_print_params(struct drm_i915_error_state_buf *m,
+const struct i915_params *p)
+{
+#define PRINT(T, x) err_##T(m, #x, p->x);
+   I915_PARAMS_FOR_EACH(PRINT);
+#undef PRINT
+}
+
 int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
const struct i915_error_state_file_priv *error_priv)
 {
@@ -568,7 +597,6 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf 
*m,
   error->boottime.tv_sec, error->boottime.tv_usec);
err_printf(m, "Uptime: %ld s %ld us\n",
   error->uptime.tv_sec, error->uptime.tv_usec);
-   err_print_capabilities(m, &error->device_info);
 
for (i = 0; i < ARRAY_SIZE(error->engine); i++) {
if (error->engine[i].hangcheck_stalled &&
@@ -588,6 +616,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf 
*m,
err_printf(m, "PCI Subsystem: %04x:%04x\n",
   pdev->subsystem_vendor,
   pdev->subsystem_device);
+
err_printf(m, "IOMMU enabled?: %d\n", error->iommu);
 
if (HAS_CSR(dev_priv)) {
@@ -730,6 +759,9 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf 
*m,
if (error->display)
intel_display_print_error_state(m, dev_priv, error->display);
 
+   err_print_capabilities(m, &error->device_info);
+   err_print_params(m, &error->params);
+
 out:
if (m->bytes == 0 && m->err)
return m->err;
@@ -1587,6 +1619,14 @@ static int capture(void *data)
 {
struct drm_i915_error_state *error = data;
 
+   do_gettimeofday(&error->time);
+   error->boottime = ktime_to_timeval(ktime_get_boottime());
+   error->uptime =
+   ktime_to_timeval(ktime_sub(ktime_get(),
+  error->i915->gt.last_init_time));
+
+   error->params = i915;
+
i915_capture_gen_state(error->i915, error);
i915_capture_reg_state(error->i915, error);
i915_gem_record_fences(error->i915, error);
@@ -1595,12 +1635,6 @@ static int capture(void *data)
i915_capture_pinned_buffers(error->i915, error);
i915_gem_capture_guc_log_buffer(error->i915, error);
 
-   do_gettimeofday(&error->time);
-   error->boottime = ktime_to_timeval(ktime_get_boottime());
-   error->uptime =
-   ktime_to_timeval(ktime_sub(ktime_get(),
-  error->i915->gt.last_init_time));
-
error->overlay = intel_overlay_capture_error_state(error->i915);
error->display = intel_display_capture_error_state(error->i915);
 
-- 
2.11.0

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


[Intel-gfx] [PATCH v2 3/5] drm/i915: Use bool i915_param.alpha_support

2017-02-02 Thread Chris Wilson
The alpha_support module option can only take one of two values, so
assign it to a boolean type. The only advantage is in pretty printing
via /sys/module/i915/parameters/alpha_support and elsewhere.

Signed-off-by: Chris Wilson 
Cc: Jani Nikula 
Cc: Rodrigo Vivi 
Cc: Daniel Vetter 
---
 drivers/gpu/drm/i915/i915_params.c | 2 +-
 drivers/gpu/drm/i915/i915_params.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index 0e280fbd52f1..c2679fa7ed11 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -145,7 +145,7 @@ MODULE_PARM_DESC(enable_psr, "Enable PSR "
 "(0=disabled, 1=enabled - link mode chosen per-platform, 
2=force link-standby mode, 3=force link-off mode) "
 "Default: -1 (use per-chip default)");
 
-module_param_named_unsafe(alpha_support, i915.alpha_support, int, 0400);
+module_param_named_unsafe(alpha_support, i915.alpha_support, bool, 0400);
 MODULE_PARM_DESC(alpha_support,
"Enable alpha quality driver support for latest hardware. "
"See also CONFIG_DRM_I915_ALPHA_SUPPORT.");
diff --git a/drivers/gpu/drm/i915/i915_params.h 
b/drivers/gpu/drm/i915/i915_params.h
index 668f88a79842..87ac6ed995d3 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -44,7 +44,6 @@ typedef unsigned int param_uint;
func(param_int, enable_ppgtt); \
func(param_int, enable_execlists); \
func(param_int, enable_psr); \
-   func(param_uint, alpha_support); \
func(param_int, disable_power_well); \
func(param_int, enable_ips); \
func(param_int, invert_brightness); \
@@ -56,6 +55,7 @@ typedef unsigned int param_uint;
func(param_int, edp_vswing); \
func(param_uint, inject_load_failure); \
/* leave bools at the end to not create holes */ \
+   func(param_bool, alpha_support); \
func(param_bool, enable_cmd_parser); \
func(param_bool, enable_hangcheck); \
func(param_bool, fastboot); \
-- 
2.11.0

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


[Intel-gfx] [PATCH v2 5/5] drm/i915: Show the current i915_params in debugfs/i915_capabilites

2017-02-02 Thread Chris Wilson
Alongside the hw capabilities, it is useful to know which of those have
been overridden by the user setting module parameters.

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

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 3ae06568df7b..1568cc4286c0 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -61,6 +61,21 @@ drm_add_fake_info_node(struct drm_minor *minor,
return 0;
 }
 
+static void seq_param_bool(struct seq_file *m, const char *name, param_bool x)
+{
+   seq_printf(m, "i915.%s=%s\n", name, yesno(x));
+}
+
+static void seq_param_int(struct seq_file *m, const char *name, param_int x)
+{
+   seq_printf(m, "i915.%s=%d\n", name, x);
+}
+
+static void seq_param_uint(struct seq_file *m, const char *name, param_uint x)
+{
+   seq_printf(m, "i915.%s=%u\n", name, x);
+}
+
 static int i915_capabilities(struct seq_file *m, void *data)
 {
struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -69,10 +84,15 @@ static int i915_capabilities(struct seq_file *m, void *data)
seq_printf(m, "gen: %d\n", INTEL_GEN(dev_priv));
seq_printf(m, "platform: %s\n", intel_platform_name(info->platform));
seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev_priv));
+
 #define PRINT_FLAG(x)  seq_printf(m, #x ": %s\n", yesno(info->x))
DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG);
 #undef PRINT_FLAG
 
+#define PRINT(T, x) seq_##T(m, #x, i915.x);
+   I915_PARAMS_FOR_EACH(PRINT);
+#undef PRINT
+
return 0;
 }
 
-- 
2.11.0

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


[Intel-gfx] [PATCH v2 1/5] drm/i915: Generate i915_params {} using a macro

2017-02-02 Thread Chris Wilson
I want to print the struct from the error state and so would like to use
the existing struct definition as the template ala DEV_INFO*

v2: Use MEMBER() rather than p().

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/i915_params.h | 81 --
 1 file changed, 43 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_params.h 
b/drivers/gpu/drm/i915/i915_params.h
index 8e433de04679..9a8c60342a82 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -27,46 +27,51 @@
 
 #include  /* for __read_mostly */
 
+#define I915_PARAMS_FOR_EACH(func) \
+   func(int, modeset); \
+   func(int, panel_ignore_lid); \
+   func(int, semaphores); \
+   func(int, lvds_channel_mode); \
+   func(int, panel_use_ssc); \
+   func(int, vbt_sdvo_panel_type); \
+   func(int, enable_rc6); \
+   func(int, enable_dc); \
+   func(int, enable_fbc); \
+   func(int, enable_ppgtt); \
+   func(int, enable_execlists); \
+   func(int, enable_psr); \
+   func(unsigned int, alpha_support); \
+   func(int, disable_power_well); \
+   func(int, enable_ips); \
+   func(int, invert_brightness); \
+   func(int, enable_guc_loading); \
+   func(int, enable_guc_submission); \
+   func(int, guc_log_level); \
+   func(int, use_mmio_flip); \
+   func(int, mmio_debug); \
+   func(int, edp_vswing); \
+   func(unsigned int, inject_load_failure); \
+   /* leave bools at the end to not create holes */ \
+   func(bool, enable_cmd_parser); \
+   func(bool, enable_hangcheck); \
+   func(bool, fastboot); \
+   func(bool, prefault_disable); \
+   func(bool, load_detect_test); \
+   func(bool, force_reset_modeset_test); \
+   func(bool, reset); \
+   func(bool, error_capture); \
+   func(bool, disable_display); \
+   func(bool, verbose_state_checks); \
+   func(bool, nuclear_pageflip); \
+   func(bool, enable_dp_mst); \
+   func(bool, enable_dpcd_backlight); \
+   func(bool, enable_gvt)
+
+#define MEMBER(T, member) T member
 struct i915_params {
-   int modeset;
-   int panel_ignore_lid;
-   int semaphores;
-   int lvds_channel_mode;
-   int panel_use_ssc;
-   int vbt_sdvo_panel_type;
-   int enable_rc6;
-   int enable_dc;
-   int enable_fbc;
-   int enable_ppgtt;
-   int enable_execlists;
-   int enable_psr;
-   unsigned int alpha_support;
-   int disable_power_well;
-   int enable_ips;
-   int invert_brightness;
-   int enable_guc_loading;
-   int enable_guc_submission;
-   int guc_log_level;
-   int use_mmio_flip;
-   int mmio_debug;
-   int edp_vswing;
-   unsigned int inject_load_failure;
-   /* leave bools at the end to not create holes */
-   bool enable_cmd_parser;
-   bool enable_hangcheck;
-   bool fastboot;
-   bool prefault_disable;
-   bool load_detect_test;
-   bool force_reset_modeset_test;
-   bool reset;
-   bool error_capture;
-   bool disable_display;
-   bool verbose_state_checks;
-   bool nuclear_pageflip;
-   bool enable_dp_mst;
-   bool enable_dpcd_backlight;
-   bool enable_gvt;
+   I915_PARAMS_FOR_EACH(MEMBER);
 };
+#undef MEMBER
 
 extern struct i915_params i915 __read_mostly;
 
-- 
2.11.0

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


[Intel-gfx] [PATCH v2 2/5] drm/i915: Convert i915_params to use shortnames for its types

2017-02-02 Thread Chris Wilson
In order to specialise a pretty printer for different types of module
parameters using macro construction, the type names must be a single
word. Use typedefs to construct the parameters using the modparams type
shortnames.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_params.h | 78 --
 1 file changed, 41 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_params.h 
b/drivers/gpu/drm/i915/i915_params.h
index 9a8c60342a82..668f88a79842 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -27,45 +27,49 @@
 
 #include  /* for __read_mostly */
 
+typedef bool param_bool;
+typedef int param_int;
+typedef unsigned int param_uint;
+
 #define I915_PARAMS_FOR_EACH(func) \
-   func(int, modeset); \
-   func(int, panel_ignore_lid); \
-   func(int, semaphores); \
-   func(int, lvds_channel_mode); \
-   func(int, panel_use_ssc); \
-   func(int, vbt_sdvo_panel_type); \
-   func(int, enable_rc6); \
-   func(int, enable_dc); \
-   func(int, enable_fbc); \
-   func(int, enable_ppgtt); \
-   func(int, enable_execlists); \
-   func(int, enable_psr); \
-   func(unsigned int, alpha_support); \
-   func(int, disable_power_well); \
-   func(int, enable_ips); \
-   func(int, invert_brightness); \
-   func(int, enable_guc_loading); \
-   func(int, enable_guc_submission); \
-   func(int, guc_log_level); \
-   func(int, use_mmio_flip); \
-   func(int, mmio_debug); \
-   func(int, edp_vswing); \
-   func(unsigned int, inject_load_failure); \
+   func(param_int, modeset); \
+   func(param_int, panel_ignore_lid); \
+   func(param_int, semaphores); \
+   func(param_int, lvds_channel_mode); \
+   func(param_int, panel_use_ssc); \
+   func(param_int, vbt_sdvo_panel_type); \
+   func(param_int, enable_rc6); \
+   func(param_int, enable_dc); \
+   func(param_int, enable_fbc); \
+   func(param_int, enable_ppgtt); \
+   func(param_int, enable_execlists); \
+   func(param_int, enable_psr); \
+   func(param_uint, alpha_support); \
+   func(param_int, disable_power_well); \
+   func(param_int, enable_ips); \
+   func(param_int, invert_brightness); \
+   func(param_int, enable_guc_loading); \
+   func(param_int, enable_guc_submission); \
+   func(param_int, guc_log_level); \
+   func(param_int, use_mmio_flip); \
+   func(param_int, mmio_debug); \
+   func(param_int, edp_vswing); \
+   func(param_uint, inject_load_failure); \
/* leave bools at the end to not create holes */ \
-   func(bool, enable_cmd_parser); \
-   func(bool, enable_hangcheck); \
-   func(bool, fastboot); \
-   func(bool, prefault_disable); \
-   func(bool, load_detect_test); \
-   func(bool, force_reset_modeset_test); \
-   func(bool, reset); \
-   func(bool, error_capture); \
-   func(bool, disable_display); \
-   func(bool, verbose_state_checks); \
-   func(bool, nuclear_pageflip); \
-   func(bool, enable_dp_mst); \
-   func(bool, enable_dpcd_backlight); \
-   func(bool, enable_gvt)
+   func(param_bool, enable_cmd_parser); \
+   func(param_bool, enable_hangcheck); \
+   func(param_bool, fastboot); \
+   func(param_bool, prefault_disable); \
+   func(param_bool, load_detect_test); \
+   func(param_bool, force_reset_modeset_test); \
+   func(param_bool, reset); \
+   func(param_bool, error_capture); \
+   func(param_bool, disable_display); \
+   func(param_bool, verbose_state_checks); \
+   func(param_bool, nuclear_pageflip); \
+   func(param_bool, enable_dp_mst); \
+   func(param_bool, enable_dpcd_backlight); \
+   func(param_bool, enable_gvt)
 
 #define MEMBER(T, member) T member
 struct i915_params {
-- 
2.11.0

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


[Intel-gfx] [PATCH 01/46] drm: Provide a driver hook for drm_dev_release()

2017-02-02 Thread Chris Wilson
Some state is coupled into the device lifetime outside of the
load/unload timeframe and requires teardown during final unreference
from drm_dev_release(). For example, dmabufs hold both a device and
module reference and may live longer than expected (i.e. the current
pattern of the driver tearing down its state and then releasing a
reference to the drm device) and yet touch driver private state when
destroyed.

v2: Export drm_dev_fini() and move the responsibility for finalizing the
drm_device and freeing it to the release callback. (If no callback is
provided, the core will call drm_dev_fini() and kfree(dev) as before.)
v3: Remember to add drm_dev_fini() to drm_drv.h
v4: Tidy language for kerneldoc
v5: Cross reference from drm_dev_init() to note that driver->release()
allows for arbitrary embedding.

Signed-off-by: Chris Wilson 
Cc: Laurent Pinchart 
Cc: Daniel Vetter 
---
 drivers/gpu/drm/drm_drv.c | 65 ---
 include/drm/drm_drv.h | 13 ++
 2 files changed, 58 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index a8ce3179c07c..fe611d601916 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -465,7 +465,10 @@ static void drm_fs_inode_free(struct inode *inode)
  * that do embed &struct drm_device it must be placed first in the overall
  * structure, and the overall structure must be allocated using kmalloc(): The
  * drm core's release function unconditionally calls kfree() on the @dev 
pointer
- * when the final reference is released.
+ * when the final reference is released. To override this behaviour, and so
+ * allow embedding of the drm_device inside the driver's device struct at an
+ * arbitrary offset, you must supply a driver->release() callback and control
+ * the finalization explicitly.
  *
  * RETURNS:
  * 0 on success, or error code on failure.
@@ -553,6 +556,41 @@ int drm_dev_init(struct drm_device *dev,
 EXPORT_SYMBOL(drm_dev_init);
 
 /**
+ * drm_dev_fini - Finalize a dead DRM device
+ * @dev: DRM device
+ *
+ * Finalize a dead DRM device. This is the converse to drm_dev_init() and
+ * frees up all state allocated by it. All driver state should be finalized
+ * first. Note that this function does not free the @dev, that is left to the
+ * caller.
+ *
+ * The ref-count of @dev must be zero, and drm_dev_fini() should only be called
+ * from a drm_driver->release() callback.
+ */
+void drm_dev_fini(struct drm_device *dev)
+{
+   drm_vblank_cleanup(dev);
+
+   if (drm_core_check_feature(dev, DRIVER_GEM))
+   drm_gem_destroy(dev);
+
+   drm_legacy_ctxbitmap_cleanup(dev);
+   drm_ht_remove(&dev->map_hash);
+   drm_fs_inode_free(dev->anon_inode);
+
+   drm_minor_free(dev, DRM_MINOR_PRIMARY);
+   drm_minor_free(dev, DRM_MINOR_RENDER);
+   drm_minor_free(dev, DRM_MINOR_CONTROL);
+
+   mutex_destroy(&dev->master_mutex);
+   mutex_destroy(&dev->ctxlist_mutex);
+   mutex_destroy(&dev->filelist_mutex);
+   mutex_destroy(&dev->struct_mutex);
+   kfree(dev->unique);
+}
+EXPORT_SYMBOL(drm_dev_fini);
+
+/**
  * drm_dev_alloc - Allocate new DRM device
  * @driver: DRM driver to allocate device for
  * @parent: Parent device object
@@ -598,25 +636,12 @@ static void drm_dev_release(struct kref *ref)
 {
struct drm_device *dev = container_of(ref, struct drm_device, ref);
 
-   drm_vblank_cleanup(dev);
-
-   if (drm_core_check_feature(dev, DRIVER_GEM))
-   drm_gem_destroy(dev);
-
-   drm_legacy_ctxbitmap_cleanup(dev);
-   drm_ht_remove(&dev->map_hash);
-   drm_fs_inode_free(dev->anon_inode);
-
-   drm_minor_free(dev, DRM_MINOR_PRIMARY);
-   drm_minor_free(dev, DRM_MINOR_RENDER);
-   drm_minor_free(dev, DRM_MINOR_CONTROL);
-
-   mutex_destroy(&dev->master_mutex);
-   mutex_destroy(&dev->ctxlist_mutex);
-   mutex_destroy(&dev->filelist_mutex);
-   mutex_destroy(&dev->struct_mutex);
-   kfree(dev->unique);
-   kfree(dev);
+   if (dev->driver->release) {
+   dev->driver->release(dev);
+   } else {
+   drm_dev_fini(dev);
+   kfree(dev);
+   }
 }
 
 /**
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 732e85652d1e..d0d2fa83d06c 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -102,6 +102,17 @@ struct drm_driver {
 *
 */
void (*unload) (struct drm_device *);
+
+   /**
+* @release:
+*
+* Optional callback for destroying device state after the final
+* reference is released, i.e. the device is being destroyed. Drivers
+* using this callback are responsible for calling drm_dev_fini()
+* to finalize the device and then freeing the struct themselves.
+*/
+   void (*release) (struct drm_device *);
+
int (*set_busid)(struct drm_device *dev, struct drm_master *master);
 
/**
@@ -437,6

[Intel-gfx] [PATCH 04/46] drm/i915: Flush the freed object queue on device release

2017-02-02 Thread Chris Wilson
As dmabufs may live beyond the PCI device removal, we need to flush the
freed object worker on device release, and include a warning in case
there is a leak.

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

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6c7a83bbd068..88065fd55147 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4625,7 +4625,9 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
 
 void i915_gem_load_cleanup(struct drm_i915_private *dev_priv)
 {
+   i915_gem_drain_freed_objects(dev_priv);
WARN_ON(!llist_empty(&dev_priv->mm.free_list));
+   WARN_ON(dev_priv->mm.object_count);
 
mutex_lock(&dev_priv->drm.struct_mutex);
i915_gem_timeline_fini(&dev_priv->gt.global_timeline);
-- 
2.11.0

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


[Intel-gfx] [PATCH 09/46] drm/i915: Add unit tests for the breadcrumb rbtree, wakeups

2017-02-02 Thread Chris Wilson
Third retroactive test, make sure that the seqno waiters are woken.

v2: Smattering of comments, rearrange code

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

diff --git a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c 
b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
index 32a27e56c353..fb368eb37660 100644
--- a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
@@ -259,11 +259,212 @@ static int igt_insert_complete(void *arg)
return err;
 }
 
+struct igt_wakeup {
+   struct task_struct *tsk;
+   atomic_t *ready, *set, *done;
+   struct intel_engine_cs *engine;
+   unsigned long flags;
+#define STOP 0
+#define IDLE 1
+   wait_queue_head_t *wq;
+   u32 seqno;
+};
+
+static int wait_atomic(atomic_t *p)
+{
+   schedule();
+   return 0;
+}
+
+static int wait_atomic_timeout(atomic_t *p)
+{
+   return schedule_timeout(10 * HZ) ? 0 : -ETIMEDOUT;
+}
+
+static bool wait_for_ready(struct igt_wakeup *w)
+{
+   DEFINE_WAIT(ready);
+
+   if (atomic_dec_and_test(w->done))
+   wake_up_atomic_t(w->done);
+
+   if (test_bit(STOP, &w->flags))
+   goto out;
+
+   set_bit(IDLE, &w->flags);
+   for (;;) {
+   prepare_to_wait(w->wq, &ready, TASK_INTERRUPTIBLE);
+   if (atomic_read(w->ready) == 0)
+   break;
+
+   schedule();
+   }
+   finish_wait(w->wq, &ready);
+   clear_bit(IDLE, &w->flags);
+
+out:
+   if (atomic_dec_and_test(w->set))
+   wake_up_atomic_t(w->set);
+
+   return !test_bit(STOP, &w->flags);
+}
+
+static int igt_wakeup_thread(void *arg)
+{
+   struct igt_wakeup *w = arg;
+   struct intel_wait wait;
+
+   while (wait_for_ready(w)) {
+   GEM_BUG_ON(kthread_should_stop());
+
+   intel_wait_init(&wait, w->seqno);
+   intel_engine_add_wait(w->engine, &wait);
+   for (;;) {
+   set_current_state(TASK_UNINTERRUPTIBLE);
+   if (i915_seqno_passed(intel_engine_get_seqno(w->engine),
+ w->seqno))
+   break;
+
+   if (test_bit(STOP, &w->flags)) /* emergency escape */
+   break;
+
+   schedule();
+   }
+   intel_engine_remove_wait(w->engine, &wait);
+   __set_current_state(TASK_RUNNING);
+   }
+
+   return 0;
+}
+
+static void igt_wake_all_sync(atomic_t *ready,
+ atomic_t *set,
+ atomic_t *done,
+ wait_queue_head_t *wq,
+ int count)
+{
+   atomic_set(set, count);
+   atomic_set(ready, 0);
+   wake_up_all(wq);
+
+   wait_on_atomic_t(set, wait_atomic, TASK_UNINTERRUPTIBLE);
+   atomic_set(ready, count);
+   atomic_set(done, count);
+}
+
+static int igt_wakeup(void *arg)
+{
+   I915_RND_STATE(prng);
+   const int state = TASK_UNINTERRUPTIBLE;
+   struct intel_engine_cs *engine = arg;
+   struct igt_wakeup *waiters;
+   DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
+   const int count = 4096;
+   const u32 max_seqno = count / 4;
+   atomic_t ready, set, done;
+   int err = -ENOMEM;
+   int n, step;
+
+   mock_engine_reset(engine);
+
+   waiters = drm_malloc_gfp(count, sizeof(*waiters), GFP_TEMPORARY);
+   if (!waiters)
+   goto out_engines;
+
+   /* Create a large number of threads, each waiting on a random seqno.
+* Multiple waiters will be waiting for the same seqno.
+*/
+   atomic_set(&ready, count);
+   for (n = 0; n < count; n++) {
+   waiters[n].wq = &wq;
+   waiters[n].ready = &ready;
+   waiters[n].set = &set;
+   waiters[n].done = &done;
+   waiters[n].engine = engine;
+   waiters[n].flags = BIT(IDLE);
+
+   waiters[n].tsk = kthread_run(igt_wakeup_thread, &waiters[n],
+"i915/igt:%d", n);
+   if (IS_ERR(waiters[n].tsk))
+   goto out_waiters;
+
+   get_task_struct(waiters[n].tsk);
+   }
+
+   for (step = 1; step <= max_seqno; step <<= 1) {
+   u32 seqno;
+
+   /* The waiter threads start paused as we assign them a random
+* seqno and reset the engine. Once the engine is reset,
+* we signal that the threads may begin their wait upon their
+* seqno.
+*/
+   for (n = 0; n < count; n++) {
+   GEM_BUG_ON(!test_bit(IDLE, &waiters[n].flags));
+   waiters[n].seqno =
+   

[Intel-gfx] [PATCH 06/46] drm/i915: Add some selftests for sg_table manipulation

2017-02-02 Thread Chris Wilson
Start exercising the scattergather lists, especially looking at
iteration after coalescing.

v2: Comment on the peculiarity of table construction (i.e. why this
sg_table might be interesting).
v3: Added one __func__ to identify expect_pfn_sg()

Signed-off-by: Chris Wilson 
Cc: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_gem.c|  11 +-
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |   1 +
 drivers/gpu/drm/i915/selftests/scatterlist.c   | 331 +
 3 files changed, 340 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/selftests/scatterlist.c

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 88065fd55147..fc54a8eb3fe5 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2216,17 +2216,17 @@ void __i915_gem_object_put_pages(struct 
drm_i915_gem_object *obj,
mutex_unlock(&obj->mm.lock);
 }
 
-static void i915_sg_trim(struct sg_table *orig_st)
+static bool i915_sg_trim(struct sg_table *orig_st)
 {
struct sg_table new_st;
struct scatterlist *sg, *new_sg;
unsigned int i;
 
if (orig_st->nents == orig_st->orig_nents)
-   return;
+   return false;
 
if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL | __GFP_NOWARN))
-   return;
+   return false;
 
new_sg = new_st.sgl;
for_each_sg(orig_st->sgl, sg, orig_st->nents, i) {
@@ -2239,6 +2239,7 @@ static void i915_sg_trim(struct sg_table *orig_st)
sg_free_table(orig_st);
 
*orig_st = new_st;
+   return true;
 }
 
 static struct sg_table *
@@ -4967,3 +4968,7 @@ i915_gem_object_get_dma_address(struct 
drm_i915_gem_object *obj,
sg = i915_gem_object_get_sg(obj, n, &offset);
return sg_dma_address(sg) + (offset << PAGE_SHIFT);
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/scatterlist.c"
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h 
b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index 69e97a2ba4a6..5f0bdda42ed8 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -9,3 +9,4 @@
  * Tests are executed in order by igt/drv_selftest
  */
 selftest(sanitycheck, i915_mock_sanitycheck) /* keep first (igt selfcheck) */
+selftest(scatterlist, scatterlist_mock_selftests)
diff --git a/drivers/gpu/drm/i915/selftests/scatterlist.c 
b/drivers/gpu/drm/i915/selftests/scatterlist.c
new file mode 100644
index ..fa5bd09c863f
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/scatterlist.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include 
+#include 
+
+#include "../i915_selftest.h"
+
+#define PFN_BIAS (1 << 10)
+
+struct pfn_table {
+   struct sg_table st;
+   unsigned long start, end;
+};
+
+typedef unsigned int (*npages_fn_t)(unsigned long n,
+   unsigned long count,
+   struct rnd_state *rnd);
+
+static noinline int expect_pfn_sg(struct pfn_table *pt,
+ npages_fn_t npages_fn,
+ struct rnd_state *rnd,
+ const char *who,
+ unsigned long timeout)
+{
+   struct scatterlist *sg;
+   unsigned long pfn, n;
+
+   pfn = pt->start;
+   for_each_sg(pt->st.sgl, sg, pt->st.nents, n) {
+   struct page *page = sg_page(sg);
+   unsigned int npages = npages_fn(n, pt->st.nents, rnd);
+
+   if (page_to_pfn(page) != pfn) {
+   pr_err("%s: %s left pages out of order, expected pfn 
%lu, found pfn %lu (using for_each_sg)\n",
+  __func__, who, pfn, page_to_pfn(page)

[Intel-gfx] [PATCH 10/46] drm/i915: Mock the GEM device for self-testing

2017-02-02 Thread Chris Wilson
A simulacrum of drm_i915_private to let us pretend interactions with the
device.

v2: Tidy init error paths

Signed-off-by: Chris Wilson 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_drv.c  |   4 +
 drivers/gpu/drm/i915/i915_gem.c  |   1 +
 drivers/gpu/drm/i915/selftests/mock_drm.c|  54 
 drivers/gpu/drm/i915/selftests/mock_drm.h|  31 +++
 drivers/gpu/drm/i915/selftests/mock_gem_device.c | 104 +++
 drivers/gpu/drm/i915/selftests/mock_gem_device.h |   8 ++
 drivers/gpu/drm/i915/selftests/mock_gem_object.h |   8 ++
 7 files changed, 210 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_drm.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_drm.h
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_gem_device.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_gem_device.h
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_gem_object.h

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 8bba6c4eb4ed..13307f641e5a 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2639,3 +2639,7 @@ static struct drm_driver driver = {
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
 };
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/mock_drm.c"
+#endif
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index fc54a8eb3fe5..778a659a7836 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4971,4 +4971,5 @@ i915_gem_object_get_dma_address(struct 
drm_i915_gem_object *obj,
 
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/scatterlist.c"
+#include "selftests/mock_gem_device.c"
 #endif
diff --git a/drivers/gpu/drm/i915/selftests/mock_drm.c 
b/drivers/gpu/drm/i915/selftests/mock_drm.c
new file mode 100644
index ..113dec05c7dc
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/mock_drm.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "mock_drm.h"
+
+static inline struct inode fake_inode(struct drm_i915_private *i915)
+{
+   return (struct inode){ .i_rdev = i915->drm.primary->index };
+}
+
+struct drm_file *mock_file(struct drm_i915_private *i915)
+{
+   struct inode inode = fake_inode(i915);
+   struct file filp = {};
+   struct drm_file *file;
+   int err;
+
+   err = drm_open(&inode, &filp);
+   if (unlikely(err))
+   return ERR_PTR(err);
+
+   file = filp.private_data;
+   file->authenticated = true;
+   return file;
+}
+
+void mock_file_free(struct drm_i915_private *i915, struct drm_file *file)
+{
+   struct inode inode = fake_inode(i915);
+   struct file filp = { .private_data = file };
+
+   drm_release(&inode, &filp);
+}
diff --git a/drivers/gpu/drm/i915/selftests/mock_drm.h 
b/drivers/gpu/drm/i915/selftests/mock_drm.h
new file mode 100644
index ..b39beee9f8f6
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/mock_drm.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS O

[Intel-gfx] [PATCH 08/46] drm/i915: Add unit tests for the breadcrumb rbtree, completion

2017-02-02 Thread Chris Wilson
Second retroactive test, make sure that the waiters are removed from the
global wait-tree when their seqno completes.

Signed-off-by: Chris Wilson 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c | 107 +
 drivers/gpu/drm/i915/selftests/mock_engine.h   |   6 ++
 2 files changed, 113 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c 
b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
index 6b5acf9de65b..32a27e56c353 100644
--- a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
@@ -64,6 +64,27 @@ static int check_rbtree(struct intel_engine_cs *engine,
return 0;
 }
 
+static int check_completion(struct intel_engine_cs *engine,
+   const unsigned long *bitmap,
+   const struct intel_wait *waiters,
+   const int count)
+{
+   int n;
+
+   for (n = 0; n < count; n++) {
+   if (intel_wait_complete(&waiters[n]) != !!test_bit(n, bitmap))
+   continue;
+
+   pr_err("waiter[%d, seqno=%d] is %s, but expected %s\n",
+  n, waiters[n].seqno,
+  intel_wait_complete(&waiters[n]) ? "complete" : "active",
+  test_bit(n, bitmap) ? "active" : "complete");
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 static int check_rbtree_empty(struct intel_engine_cs *engine)
 {
struct intel_breadcrumbs *b = &engine->breadcrumbs;
@@ -153,10 +174,96 @@ static int igt_random_insert_remove(void *arg)
return err;
 }
 
+static int igt_insert_complete(void *arg)
+{
+   const u32 seqno_bias = 0x1000;
+   struct intel_engine_cs *engine = arg;
+   struct intel_wait *waiters;
+   const int count = 4096;
+   unsigned long *bitmap;
+   int err = -ENOMEM;
+   int n, m;
+
+   mock_engine_reset(engine);
+
+   waiters = drm_malloc_gfp(count, sizeof(*waiters), GFP_TEMPORARY);
+   if (!waiters)
+   goto out_engines;
+
+   bitmap = kcalloc(DIV_ROUND_UP(count, BITS_PER_LONG), sizeof(*bitmap),
+GFP_TEMPORARY);
+   if (!bitmap)
+   goto out_waiters;
+
+   for (n = 0; n < count; n++) {
+   intel_wait_init(&waiters[n], n + seqno_bias);
+   intel_engine_add_wait(engine, &waiters[n]);
+   __set_bit(n, bitmap);
+   }
+   err = check_rbtree(engine, bitmap, waiters, count);
+   if (err)
+   goto out_bitmap;
+
+   /* On each step, we advance the seqno so that several waiters are then
+* complete (we increase the seqno by increasingly larger values to
+* retire more and more waiters at once). All retired waiters should
+* be woken and removed from the rbtree, and so that we check.
+*/
+   for (n = 0; n < count; n = m) {
+   int seqno = 2 * n;
+
+   GEM_BUG_ON(find_first_bit(bitmap, count) != n);
+
+   if (intel_wait_complete(&waiters[n])) {
+   pr_err("waiter[%d, seqno=%d] completed too early\n",
+  n, waiters[n].seqno);
+   err = -EINVAL;
+   goto out_bitmap;
+   }
+
+   /* complete the following waiters */
+   mock_seqno_advance(engine, seqno + seqno_bias);
+   for (m = n; m <= seqno; m++) {
+   if (m == count)
+   break;
+
+   GEM_BUG_ON(!test_bit(m, bitmap));
+   __clear_bit(m, bitmap);
+   }
+
+   intel_engine_remove_wait(engine, &waiters[n]);
+   RB_CLEAR_NODE(&waiters[n].node);
+
+   err = check_rbtree(engine, bitmap, waiters, count);
+   if (err) {
+   pr_err("rbtree corrupt after seqno advance to %d\n",
+  seqno + seqno_bias);
+   goto out_bitmap;
+   }
+
+   err = check_completion(engine, bitmap, waiters, count);
+   if (err) {
+   pr_err("completions after seqno advance to %d failed\n",
+  seqno + seqno_bias);
+   goto out_bitmap;
+   }
+   }
+
+   err = check_rbtree_empty(engine);
+out_bitmap:
+   kfree(bitmap);
+out_waiters:
+   drm_free_large(waiters);
+out_engines:
+   mock_engine_flush(engine);
+   return err;
+}
+
 int intel_breadcrumbs_mock_selftests(void)
 {
static const struct i915_subtest tests[] = {
SUBTEST(igt_random_insert_remove),
+   SUBTEST(igt_insert_complete),
};
struct intel_engine_cs *engine;
int err;
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.h 
b/drivers/gpu/drm/i915/selftests/mock

[Intel-gfx] [PATCH 03/46] drm/i915: Unbind any residual objects/vma from the Global GTT on shutdown

2017-02-02 Thread Chris Wilson
We may unload the PCI device before all users (such as dma-buf) are
completely shutdown. This may leave VMA in the global GTT which we want
to revoke, whilst keeping the objects themselves around to service the
dma-buf.

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

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index b7bcb1e62ce4..65425e71f3a5 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2812,6 +2812,15 @@ int i915_gem_init_ggtt(struct drm_i915_private *dev_priv)
 void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv)
 {
struct i915_ggtt *ggtt = &dev_priv->ggtt;
+   struct i915_vma *vma, *vn;
+
+   ggtt->base.closed = true;
+
+   mutex_lock(&dev_priv->drm.struct_mutex);
+   WARN_ON(!list_empty(&ggtt->base.active_list));
+   list_for_each_entry_safe(vma, vn, &ggtt->base.inactive_list, vm_link)
+   WARN_ON(i915_vma_unbind(vma));
+   mutex_unlock(&dev_priv->drm.struct_mutex);
 
if (dev_priv->mm.aliasing_ppgtt) {
struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
-- 
2.11.0

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


[Intel-gfx] [PATCH 02/46] drm/i915: Split device release from unload

2017-02-02 Thread Chris Wilson
We may need to keep our memory management alive after we have unloaded
the physical pci device. For example, if we have exported an object via
dmabuf, that will keep the device around but the pci device may be
removed before the dmabuf itself is released, use of the pci hardware
will be revoked, but the memory and object management needs to persist
for the dmabuf.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_drv.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 267d5f8c49e1..8bba6c4eb4ed 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1299,7 +1299,8 @@ int i915_driver_load(struct pci_dev *pdev, const struct 
pci_device_id *ent)
pci_disable_device(pdev);
 out_free_priv:
i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret);
-   drm_dev_unref(&dev_priv->drm);
+   drm_dev_fini(&dev_priv->drm);
+   kfree(dev_priv);
return ret;
 }
 
@@ -1358,8 +1359,16 @@ void i915_driver_unload(struct drm_device *dev)
i915_driver_cleanup_mmio(dev_priv);
 
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
+}
+
+static void i915_driver_release(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = to_i915(dev);
 
i915_driver_cleanup_early(dev_priv);
+   drm_dev_fini(&dev_priv->drm);
+
+   kfree(dev_priv);
 }
 
 static int i915_driver_open(struct drm_device *dev, struct drm_file *file)
@@ -2601,6 +2610,7 @@ static struct drm_driver driver = {
.driver_features =
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME |
DRIVER_RENDER | DRIVER_MODESET,
+   .release = i915_driver_release,
.open = i915_driver_open,
.lastclose = i915_driver_lastclose,
.preclose = i915_driver_preclose,
-- 
2.11.0

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


[Intel-gfx] [PATCH 05/46] drm/i915: Provide a hook for selftests

2017-02-02 Thread Chris Wilson
Some pieces of code are independent of hardware but are very tricky to
exercise through the normal userspace ABI or via debugfs hooks. Being
able to create mock unit tests and execute them through CI is vital.
Start by adding a central point where we can execute unit tests and
a parameter to enable them. This is disabled by default as the
expectation is that these tests will occasionally explode.

To facilitate integration with igt, any parameter beginning with
i915.igt__ is interpreted as a subtest executable independently via
igt/drv_selftest.

Two classes of selftests are recognised: mock unit tests and integration
tests. Mock unit tests are run as soon as the module is loaded, before
the device is probed. At that point there is no driver instantiated and
all hw interactions must be "mocked". This is very useful for writing
universal tests to exercise code not typically run on a broad range of
architectures. Alternatively, you can hook into the live selftests and
run when the device has been instantiated - hw interactions are real.

v2: Add a macro for compiling conditional code for mock objects inside
real objects.
v3: Differentiate between mock unit tests and late integration test.
v4: List the tests in natural order, use igt to sort after modparam.
v5: s/late/live/
v6: s/unsigned long/unsigned int/
v7: Use igt_ prefixes for long helpers.

Signed-off-by: Chris Wilson 
Reviewed-by: Tvrtko Ursulin  #v1
---
 drivers/gpu/drm/i915/Kconfig.debug |  16 ++
 drivers/gpu/drm/i915/Makefile  |   3 +
 drivers/gpu/drm/i915/i915_pci.c|  31 ++-
 drivers/gpu/drm/i915/i915_selftest.h   | 102 +
 .../gpu/drm/i915/selftests/i915_live_selftests.h   |  11 +
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |  11 +
 drivers/gpu/drm/i915/selftests/i915_random.c   |  63 ++
 drivers/gpu/drm/i915/selftests/i915_random.h   |  50 +
 drivers/gpu/drm/i915/selftests/i915_selftest.c | 250 +
 tools/testing/selftests/drivers/gpu/i915.sh|   1 +
 10 files changed, 531 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_selftest.h
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_live_selftests.h
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_random.c
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_random.h
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_selftest.c

diff --git a/drivers/gpu/drm/i915/Kconfig.debug 
b/drivers/gpu/drm/i915/Kconfig.debug
index 598551dbf62c..a4d8cfd77c3c 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -26,6 +26,7 @@ config DRM_I915_DEBUG
 select DRM_DEBUG_MM if DRM=y
select DRM_DEBUG_MM_SELFTEST
select DRM_I915_SW_FENCE_DEBUG_OBJECTS
+   select DRM_I915_SELFTEST
 default n
 help
   Choose this option to turn on extra driver debugging that may affect
@@ -59,3 +60,18 @@ config DRM_I915_SW_FENCE_DEBUG_OBJECTS
   Recommended for driver developers only.
 
   If in doubt, say "N".
+
+config DRM_I915_SELFTEST
+   bool "Enable selftests upon driver load"
+   depends on DRM_I915
+   default n
+   select PRIME_NUMBERS
+   help
+ Choose this option to allow the driver to perform selftests upon
+ loading; also requires the i915.selftest=1 module parameter. To
+ exit the module after running the selftests (i.e. to prevent normal
+ module initialisation afterwards) use i915.selftest=-1.
+
+ Recommended for driver developers only.
+
+ If in doubt, say "N".
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index c62ab45683c0..bac62fd5b438 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -116,6 +116,9 @@ i915-y += dvo_ch7017.o \
 
 # Post-mortem debug and GPU hang state capture
 i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
+i915-$(CONFIG_DRM_I915_SELFTEST) += \
+   selftests/i915_random.o \
+   selftests/i915_selftest.o
 
 # virtual gpu code
 i915-y += i915_vgpu.o
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index df2051b41fa1..732101ed57fb 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -27,6 +27,7 @@
 #include 
 
 #include "i915_drv.h"
+#include "i915_selftest.h"
 
 #define GEN_DEFAULT_PIPEOFFSETS \
.pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \
@@ -473,10 +474,19 @@ static const struct pci_device_id pciidlist[] = {
 };
 MODULE_DEVICE_TABLE(pci, pciidlist);
 
+static void i915_pci_remove(struct pci_dev *pdev)
+{
+   struct drm_device *dev = pci_get_drvdata(pdev);
+
+   i915_driver_unload(dev);
+   drm_dev_unref(dev);
+}
+
 static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id 
*ent)
 {
struct intel_de

[Intel-gfx] [PATCH 12/46] drm/i915: Mock infrastructure for request emission

2017-02-02 Thread Chris Wilson
Create a fake engine that runs requests using a timer to simulate hw.

v2: Prevent leaks of ctx->name along error paths

Signed-off-by: Chris Wilson 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_gem_context.c|   4 +
 drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c |  11 +-
 drivers/gpu/drm/i915/selftests/mock_context.c  |  78 ++
 drivers/gpu/drm/i915/selftests/mock_context.h  |  34 
 drivers/gpu/drm/i915/selftests/mock_engine.c   | 172 +++--
 drivers/gpu/drm/i915/selftests/mock_engine.h   |  18 ++-
 drivers/gpu/drm/i915/selftests/mock_gem_device.c   |  95 +++-
 drivers/gpu/drm/i915/selftests/mock_gem_device.h   |   1 +
 drivers/gpu/drm/i915/selftests/mock_request.c  |  44 ++
 drivers/gpu/drm/i915/selftests/mock_request.h  |  44 ++
 10 files changed, 483 insertions(+), 18 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_context.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_context.h
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_request.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_request.h

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 680105421bb9..e6208e361356 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -1188,3 +1188,7 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device 
*dev,
 
return 0;
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/mock_context.c"
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c 
b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
index fb368eb37660..55795cab483c 100644
--- a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
@@ -25,6 +25,7 @@
 #include "../i915_selftest.h"
 #include "i915_random.h"
 
+#include "mock_gem_device.h"
 #include "mock_engine.h"
 
 static int check_rbtree(struct intel_engine_cs *engine,
@@ -466,15 +467,15 @@ int intel_breadcrumbs_mock_selftests(void)
SUBTEST(igt_insert_complete),
SUBTEST(igt_wakeup),
};
-   struct intel_engine_cs *engine;
+   struct drm_i915_private *i915;
int err;
 
-   engine = mock_engine("mock");
-   if (!engine)
+   i915 = mock_gem_device();
+   if (!i915)
return -ENOMEM;
 
-   err = i915_subtests(tests, engine);
-   kfree(engine);
+   err = i915_subtests(tests, i915->engine[RCS]);
+   drm_dev_unref(&i915->drm);
 
return err;
 }
diff --git a/drivers/gpu/drm/i915/selftests/mock_context.c 
b/drivers/gpu/drm/i915/selftests/mock_context.c
new file mode 100644
index ..8d3a90c3f8ac
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/mock_context.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "mock_context.h"
+#include "mock_gtt.h"
+
+struct i915_gem_context *
+mock_context(struct drm_i915_private *i915,
+const char *name)
+{
+   struct i915_gem_context *ctx;
+   int ret;
+
+   ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+   if (!ctx)
+   return NULL;
+
+   kref_init(&ctx->ref);
+   INIT_LIST_HEAD(&ctx->link);
+   ctx->i915 = i915;
+
+   ret = ida_simple_get(&i915->context_hw_ida,
+0, MAX_CONTEXT_HW_ID, GFP_KERNEL);
+   if (ret < 0)
+   goto err_free;
+   ctx->hw_id = ret;
+
+   if (name) {
+   ctx->name = kstrdup(name, GFP_KERNEL);
+   if (!ctx->name)
+   goto err_put;
+
+   ctx->ppgtt = mock_ppgtt(i915, name);
+   if (!ctx->ppgtt)
+   goto err_put;
+   }
+
+   return ctx;
+
+err_free:
+   kfree(ctx);

[Intel-gfx] [PATCH 07/46] drm/i915: Add unit tests for the breadcrumb rbtree, insert/remove

2017-02-02 Thread Chris Wilson
First retroactive test, make sure that the waiters are in global seqno
order after random inserts and removals.

Signed-off-by: Chris Wilson 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/intel_breadcrumbs.c   |  21 +++
 drivers/gpu/drm/i915/intel_engine_cs.c |   4 +
 drivers/gpu/drm/i915/intel_ringbuffer.h|   2 +
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |   1 +
 drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c | 172 +
 drivers/gpu/drm/i915/selftests/mock_engine.c   |  55 +++
 drivers/gpu/drm/i915/selftests/mock_engine.h   |  32 
 7 files changed, 287 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_engine.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_engine.h

diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c 
b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 9fd002bcebb6..1f36756f8759 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -107,6 +107,18 @@ static void __intel_breadcrumbs_enable_irq(struct 
intel_breadcrumbs *b)
if (b->rpm_wakelock)
return;
 
+   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,
+*/
+   b->rpm_wakelock = true;
+   return;
+   }
+
/* Since we are waiting on a request, the GPU should be busy
 * and should have its own rpm reference. For completeness,
 * record an rpm reference for ourselves to cover the
@@ -142,6 +154,11 @@ static void __intel_breadcrumbs_disable_irq(struct 
intel_breadcrumbs *b)
if (!b->rpm_wakelock)
return;
 
+   if (I915_SELFTEST_ONLY(b->mock)) {
+   b->rpm_wakelock = false;
+   return;
+   }
+
if (b->irq_enabled) {
irq_disable(engine);
b->irq_enabled = false;
@@ -661,3 +678,7 @@ unsigned int intel_breadcrumbs_busy(struct drm_i915_private 
*i915)
 
return mask;
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/intel_breadcrumbs.c"
+#endif
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index 69a6416d1223..538d845d7251 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -524,3 +524,7 @@ void intel_engine_get_instdone(struct intel_engine_cs 
*engine,
break;
}
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/mock_engine.c"
+#endif
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h 
b/drivers/gpu/drm/i915/intel_ringbuffer.h
index b9c15cd40fbf..c2f0ecf612b9 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -5,6 +5,7 @@
 #include "i915_gem_batch_pool.h"
 #include "i915_gem_request.h"
 #include "i915_gem_timeline.h"
+#include "i915_selftest.h"
 
 #define I915_CMD_HASH_ORDER 9
 
@@ -247,6 +248,7 @@ struct intel_engine_cs {
 
bool irq_enabled : 1;
bool rpm_wakelock : 1;
+   I915_SELFTEST_DECLARE(bool mock : 1);
} breadcrumbs;
 
/*
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h 
b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index 5f0bdda42ed8..80458e2a2b04 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -10,3 +10,4 @@
  */
 selftest(sanitycheck, i915_mock_sanitycheck) /* keep first (igt selfcheck) */
 selftest(scatterlist, scatterlist_mock_selftests)
+selftest(breadcrumbs, intel_breadcrumbs_mock_selftests)
diff --git a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c 
b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
new file mode 100644
index ..6b5acf9de65b
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copie

[Intel-gfx] Moah selftests

2017-02-02 Thread Chris Wilson
Fewer wide ranging review comments, lots more r-b, we seem to be settling
on a compromise...
-Chris

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


[Intel-gfx] [PATCH 20/46] drm/i915: Live testing of empty requests

2017-02-02 Thread Chris Wilson
Primarily to emphasize the difference between just advancing the
breadcrumb using a bare request and the overhead of dispatching an
execbuffer.

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

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
index f9c171d1a05b..92fa55bd68c8 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
@@ -301,6 +301,160 @@ static int live_nop_request(void *arg)
return err;
 }
 
+static struct i915_vma *empty_batch(struct drm_i915_private *i915)
+{
+   struct drm_i915_gem_object *obj;
+   struct i915_vma *vma;
+   u32 *cmd;
+   int err;
+
+   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(obj))
+   return ERR_CAST(obj);
+
+   cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);
+   if (IS_ERR(cmd)) {
+   err = PTR_ERR(cmd);
+   goto err;
+   }
+   *cmd = MI_BATCH_BUFFER_END;
+   i915_gem_object_unpin_map(obj);
+
+   err = i915_gem_object_set_to_gtt_domain(obj, false);
+   if (err)
+   goto err;
+
+   vma = i915_vma_instance(obj, &i915->ggtt.base, NULL);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto err;
+   }
+
+   err = i915_vma_pin(vma, 0, 0, PIN_USER | PIN_GLOBAL);
+   if (err)
+   goto err;
+
+   return vma;
+
+err:
+   i915_gem_object_put(obj);
+   return ERR_PTR(err);
+}
+
+static struct drm_i915_gem_request *
+empty_request(struct intel_engine_cs *engine,
+ struct i915_vma *batch)
+{
+   struct drm_i915_gem_request *request;
+   int err;
+
+   request = i915_gem_request_alloc(engine,
+engine->i915->kernel_context);
+   if (IS_ERR(request))
+   return request;
+
+   err = engine->emit_flush(request, EMIT_INVALIDATE);
+   if (err)
+   goto out_request;
+
+   err = i915_switch_context(request);
+   if (err)
+   goto out_request;
+
+   err = engine->emit_bb_start(request,
+   batch->node.start,
+   batch->node.size,
+   I915_DISPATCH_SECURE);
+   if (err)
+   goto out_request;
+
+out_request:
+   __i915_add_request(request, err == 0);
+   return err ? ERR_PTR(err) : request;
+}
+
+static int live_empty_request(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct intel_engine_cs *engine;
+   struct live_test t;
+   struct i915_vma *batch;
+   unsigned int id;
+   int err = 0;
+
+   /* Submit various sized batches of empty requests, to each engine
+* (individually), and wait for the batch to complete. We can check
+* the overhead of submitting requests to the hardware.
+*/
+
+   mutex_lock(&i915->drm.struct_mutex);
+
+   batch = empty_batch(i915);
+   if (IS_ERR(batch)) {
+   err = PTR_ERR(batch);
+   goto out_unlock;
+   }
+
+   for_each_engine(engine, i915, id) {
+   IGT_TIMEOUT(end_time);
+   struct drm_i915_gem_request *request;
+   unsigned long n, prime;
+   ktime_t times[2] = {};
+
+   err = begin_live_test(&t, i915, __func__, engine->name);
+   if (err)
+   goto out_batch;
+
+   /* Warmup / preload */
+   request = empty_request(engine, batch);
+   if (IS_ERR(request)) {
+   err = PTR_ERR(request);
+   goto out_batch;
+   }
+   i915_wait_request(request,
+ I915_WAIT_LOCKED,
+ MAX_SCHEDULE_TIMEOUT);
+
+   for_each_prime_number_from(prime, 1, 8192) {
+   times[1] = ktime_get_raw();
+
+   for (n = 0; n < prime; n++) {
+   request = empty_request(engine, batch);
+   if (IS_ERR(request)) {
+   err = PTR_ERR(request);
+   goto out_batch;
+   }
+   }
+   i915_wait_request(request,
+ I915_WAIT_LOCKED,
+ MAX_SCHEDULE_TIMEOUT);
+
+   times[1] = ktime_sub(ktime_get_raw(), times[1]);
+   if (prime == 1)
+   times[0] = times[1];
+
+   if (__igt_timeout(end_time, NULL))
+   break;
+   }
+
+   err = e

[Intel-gfx] [PATCH 16/46] drm/i915: Add a simple fence selftest to i915_gem_request

2017-02-02 Thread Chris Wilson
Do a quick selftest on in the interoperability of dma_fence_wait on a
i915_gem_request.

Signed-off-by: Chris Wilson 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/selftests/i915_gem_request.c | 49 +++
 1 file changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
index 14584b67c4a0..bc6f5618f22b 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
@@ -94,11 +94,60 @@ static int igt_wait_request(void *arg)
return err;
 }
 
+static int igt_fence_wait(void *arg)
+{
+   const long T = HZ / 4;
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_request *request;
+   int err = -EINVAL;
+
+   /* Submit a request, treat it as a fence and wait upon it */
+
+   mutex_lock(&i915->drm.struct_mutex);
+   request = mock_request(i915->engine[RCS], i915->kernel_context, T);
+   if (!request) {
+   err = -ENOMEM;
+   goto out_locked;
+   }
+
+   i915_add_request(request);
+   mutex_unlock(&i915->drm.struct_mutex);
+
+   if (dma_fence_is_signaled(&request->fence)) {
+   pr_err("fence signaled immediately!\n");
+   goto out_device;
+   }
+
+   if (dma_fence_wait_timeout(&request->fence, false, T / 2) != -ETIME) {
+   pr_err("fence wait success after submit (expected timeout)!\n");
+   goto out_device;
+   }
+
+   if (dma_fence_wait_timeout(&request->fence, false, T) <= 0) {
+   pr_err("fence wait timed out (expected success)!\n");
+   goto out_device;
+   }
+
+   if (!dma_fence_is_signaled(&request->fence)) {
+   pr_err("fence unsignaled after waiting!\n");
+   goto out_device;
+   }
+
+   err = 0;
+out_device:
+   mutex_lock(&i915->drm.struct_mutex);
+out_locked:
+   mock_device_flush(i915);
+   mutex_unlock(&i915->drm.struct_mutex);
+   return err;
+}
+
 int i915_gem_request_mock_selftests(void)
 {
static const struct i915_subtest tests[] = {
SUBTEST(igt_add_request),
SUBTEST(igt_wait_request),
+   SUBTEST(igt_fence_wait),
};
struct drm_i915_private *i915;
int err;
-- 
2.11.0

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


[Intel-gfx] [PATCH 18/46] drm/i915: Test simultaneously submitting requests to all engines

2017-02-02 Thread Chris Wilson
Use a recursive-batch to busy spin on each to ensure that each is being
run simultaneously.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/selftests/i915_gem_request.c | 173 ++
 1 file changed, 173 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
index b5c7cd6633f0..570cfa196ca7 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
@@ -301,10 +301,183 @@ static int live_nop_request(void *arg)
return err;
 }
 
+static struct i915_vma *recursive_batch(struct drm_i915_private *i915)
+{
+   struct i915_gem_context *ctx = i915->kernel_context;
+   struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->base : 
&i915->ggtt.base;
+   struct drm_i915_gem_object *obj;
+   const int gen = INTEL_GEN(i915);
+   struct i915_vma *vma;
+   u32 *cmd;
+   int err;
+
+   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(obj))
+   return ERR_CAST(obj);
+
+   vma = i915_vma_instance(obj, vm, NULL);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto err;
+   }
+
+   err = i915_vma_pin(vma, 0, 0, PIN_USER);
+   if (err)
+   goto err;
+
+   err = i915_gem_object_set_to_gtt_domain(obj, true);
+   if (err)
+   goto err;
+
+   cmd = i915_gem_object_pin_map(obj, I915_MAP_WC);
+   if (IS_ERR(cmd)) {
+   err = PTR_ERR(cmd);
+   goto err;
+   }
+
+   if (gen >= 8) {
+   *cmd++ = MI_BATCH_BUFFER_START | 1 << 8 | 1;
+   *cmd++ = lower_32_bits(vma->node.start);
+   *cmd++ = upper_32_bits(vma->node.start);
+   } else if (gen >= 6) {
+   *cmd++ = MI_BATCH_BUFFER_START | 1 << 8;
+   *cmd++ = lower_32_bits(vma->node.start);
+   } else if (gen >= 4) {
+   *cmd++ = MI_BATCH_BUFFER_START | MI_BATCH_GTT;
+   *cmd++ = lower_32_bits(vma->node.start);
+   } else {
+   *cmd++ = MI_BATCH_BUFFER_START | MI_BATCH_GTT | 1;
+   *cmd++ = lower_32_bits(vma->node.start);
+   }
+   *cmd++ = MI_BATCH_BUFFER_END; /* terminate early in case of error */
+
+   wmb();
+   i915_gem_object_unpin_map(obj);
+
+   return vma;
+
+err:
+   i915_gem_object_put(obj);
+   return ERR_PTR(err);
+}
+
+static int live_all_engines(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct intel_engine_cs *engine;
+   struct drm_i915_gem_request *request[I915_NUM_ENGINES];
+   struct i915_vma *batch;
+   struct live_test t;
+   unsigned int id;
+   u32 *cmd;
+   int err;
+
+   /* Check we can submit requests to all engines simultaneously. We
+* send a recursive batch to each engine - checking that we don't
+* block doing so, and that they don't complete too soon.
+*/
+
+   mutex_lock(&i915->drm.struct_mutex);
+
+   err = begin_live_test(&t, i915, __func__, "");
+   if (err)
+   goto out_unlock;
+
+   batch = recursive_batch(i915);
+   if (IS_ERR(batch)) {
+   err = PTR_ERR(batch);
+   pr_err("%s: Unable to create batch, err=%d\n", __func__, err);
+   goto out_unlock;
+   }
+
+   for_each_engine(engine, i915, id) {
+   request[id] = i915_gem_request_alloc(engine,
+i915->kernel_context);
+   if (IS_ERR(request[id])) {
+   err = PTR_ERR(request[id]);
+   pr_err("%s: Request allocation failed with err=%d\n",
+  __func__, err);
+   goto out_request;
+   }
+
+   err = engine->emit_flush(request[id], EMIT_INVALIDATE);
+   GEM_BUG_ON(err);
+
+   err = i915_switch_context(request[id]);
+   GEM_BUG_ON(err);
+
+   err = engine->emit_bb_start(request[id],
+   batch->node.start,
+   batch->node.size,
+   0);
+   GEM_BUG_ON(err);
+   request[id]->batch = batch;
+
+   if (!i915_gem_object_has_active_reference(batch->obj)) {
+   i915_gem_object_get(batch->obj);
+   i915_gem_object_set_active_reference(batch->obj);
+   }
+
+   i915_vma_move_to_active(batch, request[id], 0);
+   i915_gem_request_get(request[id]);
+   i915_add_request(request[id]);
+   }
+
+   for_each_engine(engine, i915, id) {
+   if (i915_gem_request_completed(request[id])) {
+   pr_err("%s(%s): request completed too early!\n",
+   

[Intel-gfx] [PATCH 22/46] drm/i915: Add a live seftest for GEM objects

2017-02-02 Thread Chris Wilson
Starting with a placeholder test just to reassure that we can create a
test object,

Signed-off-by: Chris Wilson 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/selftests/i915_gem_object.c   | 49 ++
 .../gpu/drm/i915/selftests/i915_live_selftests.h   |  1 +
 2 files changed, 50 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
index db8f631e4993..d7330db70063 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
@@ -100,6 +100,46 @@ static int igt_phys_object(void *arg)
return err;
 }
 
+static int igt_gem_huge(void *arg)
+{
+   const unsigned int nreal = 509; /* just to be awkward */
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_object *obj;
+   unsigned int n;
+   int err;
+
+   /* Basic sanitycheck of our huge fake object allocation */
+
+   obj = huge_gem_object(i915,
+ nreal * PAGE_SIZE,
+ i915->ggtt.base.total + PAGE_SIZE);
+   if (IS_ERR(obj))
+   return PTR_ERR(obj);
+
+   err = i915_gem_object_pin_pages(obj);
+   if (err) {
+   pr_err("Failed to allocate %u pages (%lu total), err=%d\n",
+  nreal, obj->base.size / PAGE_SIZE, err);
+   goto out;
+   }
+
+   for (n = 0; n < obj->base.size / PAGE_SIZE; n++) {
+   if (i915_gem_object_get_page(obj, n) !=
+   i915_gem_object_get_page(obj, n % nreal)) {
+   pr_err("Page lookup mismatch at index %u [%u]\n",
+  n, n % nreal);
+   err = -EINVAL;
+   goto out_unpin;
+   }
+   }
+
+out_unpin:
+   i915_gem_object_unpin_pages(obj);
+out:
+   i915_gem_object_put(obj);
+   return err;
+}
+
 int i915_gem_object_mock_selftests(void)
 {
static const struct i915_subtest tests[] = {
@@ -118,3 +158,12 @@ int i915_gem_object_mock_selftests(void)
drm_dev_unref(&i915->drm);
return err;
 }
+
+int i915_gem_object_live_selftests(struct drm_i915_private *i915)
+{
+   static const struct i915_subtest tests[] = {
+   SUBTEST(igt_gem_huge),
+   };
+
+   return i915_subtests(tests, i915);
+}
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h 
b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index 09bf538826df..1822ac99d577 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -10,3 +10,4 @@
  */
 selftest(sanitycheck, i915_live_sanitycheck) /* keep first (igt selfcheck) */
 selftest(requests, i915_gem_request_live_selftests)
+selftest(object, i915_gem_object_live_selftests)
-- 
2.11.0

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


[Intel-gfx] [PATCH 13/46] drm/i915: Create a fake object for testing huge allocations

2017-02-02 Thread Chris Wilson
We would like to be able to exercise huge allocations even on memory
constrained devices. To do this we create an object that allocates only
a few pages and remaps them across its whole range - each page is reused
multiple times. We can therefore pretend we are rendering into a much
larger object.

Signed-off-by: Chris Wilson 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_gem.c  |   1 +
 drivers/gpu/drm/i915/i915_gem_object.h   |  20 ++--
 drivers/gpu/drm/i915/selftests/huge_gem_object.c | 135 +++
 drivers/gpu/drm/i915/selftests/huge_gem_object.h |  45 
 4 files changed, 193 insertions(+), 8 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/selftests/huge_gem_object.c
 create mode 100644 drivers/gpu/drm/i915/selftests/huge_gem_object.h

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 778a659a7836..f35fda5d0abc 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4972,4 +4972,5 @@ i915_gem_object_get_dma_address(struct 
drm_i915_gem_object *obj,
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/scatterlist.c"
 #include "selftests/mock_gem_device.c"
+#include "selftests/huge_gem_object.c"
 #endif
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h 
b/drivers/gpu/drm/i915/i915_gem_object.h
index 33a7d031e749..0da69546970b 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -167,14 +167,18 @@ struct drm_i915_gem_object {
/** Record of address bit 17 of each page at last unbind. */
unsigned long *bit_17;
 
-   struct i915_gem_userptr {
-   uintptr_t ptr;
-   unsigned read_only :1;
-
-   struct i915_mm_struct *mm;
-   struct i915_mmu_object *mmu_object;
-   struct work_struct *work;
-   } userptr;
+   union {
+   struct i915_gem_userptr {
+   uintptr_t ptr;
+   unsigned read_only :1;
+
+   struct i915_mm_struct *mm;
+   struct i915_mmu_object *mmu_object;
+   struct work_struct *work;
+   } userptr;
+
+   unsigned long scratch;
+   };
 
/** for phys allocated objects */
struct drm_dma_handle *phys_handle;
diff --git a/drivers/gpu/drm/i915/selftests/huge_gem_object.c 
b/drivers/gpu/drm/i915/selftests/huge_gem_object.c
new file mode 100644
index ..4e681fc13be4
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/huge_gem_object.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "huge_gem_object.h"
+
+static void huge_free_pages(struct drm_i915_gem_object *obj,
+   struct sg_table *pages)
+{
+   unsigned long nreal = obj->scratch / PAGE_SIZE;
+   struct scatterlist *sg;
+
+   for (sg = pages->sgl; sg && nreal--; sg = __sg_next(sg))
+   __free_page(sg_page(sg));
+
+   sg_free_table(pages);
+   kfree(pages);
+}
+
+static struct sg_table *
+huge_get_pages(struct drm_i915_gem_object *obj)
+{
+#define GFP (GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY)
+   const unsigned long nreal = obj->scratch / PAGE_SIZE;
+   const unsigned long npages = obj->base.size / PAGE_SIZE;
+   struct scatterlist *sg, *src, *end;
+   struct sg_table *pages;
+   unsigned long n;
+
+   pages = kmalloc(sizeof(*pages), GFP);
+   if (!pages)
+   return ERR_PTR(-ENOMEM);
+
+   if (sg_alloc_table(pages, npages, GFP)) {
+   kfree(pages);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   sg = pages->sgl;
+   for (n = 0; n < nreal; n++) {
+   struct page *page;
+
+   page = alloc_page(GFP | __GFP_HIGHMEM);
+   

[Intel-gfx] [PATCH 11/46] drm/i915: Mock a GGTT for self-testing

2017-02-02 Thread Chris Wilson
A very simple mockery, just a random manager and timeline. Useful for
inserting objects and ordering retirement; and not much else.

v2: mock_fini_ggtt() to complement mock_init_ggtt().

Signed-off-by: Chris Wilson 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c  |   4 +
 drivers/gpu/drm/i915/selftests/mock_gem_device.c |  31 +
 drivers/gpu/drm/i915/selftests/mock_gtt.c| 138 +++
 drivers/gpu/drm/i915/selftests/mock_gtt.h|  35 ++
 4 files changed, 208 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_gtt.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_gtt.h

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 65425e71f3a5..afdb2859be05 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3751,3 +3751,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
   size, alignment, color,
   start, end, DRM_MM_INSERT_EVICT);
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/mock_gtt.c"
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c 
b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 15d0a7ccc9d1..dbd32b125d15 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -26,6 +26,7 @@
 
 #include "mock_gem_device.h"
 #include "mock_gem_object.h"
+#include "mock_gtt.h"
 
 static void mock_device_release(struct drm_device *dev)
 {
@@ -33,6 +34,12 @@ static void mock_device_release(struct drm_device *dev)
 
i915_gem_drain_freed_objects(i915);
 
+   mutex_lock(&i915->drm.struct_mutex);
+   mock_fini_ggtt(i915);
+   i915_gem_timeline_fini(&i915->gt.global_timeline);
+   mutex_unlock(&i915->drm.struct_mutex);
+
+   kmem_cache_destroy(i915->vmas);
kmem_cache_destroy(i915->objects);
 
drm_dev_fini(&i915->drm);
@@ -84,19 +91,43 @@ struct drm_i915_private *mock_gem_device(void)
i915->drm.pdev = pdev;
i915->drm.dev_private = i915;
 
+   /* Using the global GTT may ask questions about KMS users, so prepare */
+   drm_mode_config_init(&i915->drm);
+
mkwrite_device_info(i915)->gen = -1;
 
spin_lock_init(&i915->mm.object_stat_lock);
 
INIT_WORK(&i915->mm.free_work, __i915_gem_free_work);
init_llist_head(&i915->mm.free_list);
+   INIT_LIST_HEAD(&i915->mm.unbound_list);
+   INIT_LIST_HEAD(&i915->mm.bound_list);
 
i915->objects = KMEM_CACHE(mock_object, SLAB_HWCACHE_ALIGN);
if (!i915->objects)
goto put_device;
 
+   i915->vmas = KMEM_CACHE(i915_vma, SLAB_HWCACHE_ALIGN);
+   if (!i915->vmas)
+   goto err_objects;
+
+   mutex_lock(&i915->drm.struct_mutex);
+   INIT_LIST_HEAD(&i915->gt.timelines);
+   err = i915_gem_timeline_init__global(i915);
+   if (err) {
+   mutex_unlock(&i915->drm.struct_mutex);
+   goto err_vmas;
+   }
+
+   mock_init_ggtt(i915);
+   mutex_unlock(&i915->drm.struct_mutex);
+
return i915;
 
+err_vmas:
+   kmem_cache_destroy(i915->vmas);
+err_objects:
+   kmem_cache_destroy(i915->objects);
 put_device:
put_device(&pdev->dev);
 err:
diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c 
b/drivers/gpu/drm/i915/selftests/mock_gtt.c
new file mode 100644
index ..a61309c7cb3e
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "mock_gtt.h"
+
+static void mock_insert_page(struct i915_address_space *vm,
+dma_addr_t addr,
+u64 offset,
+  

[Intel-gfx] [PATCH 24/46] drm/i915: Test exhaustion of the mmap space

2017-02-02 Thread Chris Wilson
An unlikely error condition that we can simulate by stealing most of
the range before trying to insert new objects.

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

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
index 140bae2c8ad2..3cdeb83f8742 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
@@ -25,6 +25,7 @@
 #include "../i915_selftest.h"
 
 #include "mock_gem_device.h"
+#include "huge_gem_object.h"
 
 static int igt_gem_object(void *arg)
 {
@@ -432,6 +433,142 @@ next_tiling: ;
return err;
 }
 
+static int make_obj_busy(struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *i915 = to_i915(obj->base.dev);
+   struct drm_i915_gem_request *rq;
+   struct i915_vma *vma;
+   int err;
+
+   vma = i915_vma_instance(obj, &i915->ggtt.base, NULL);
+   if (IS_ERR(vma))
+   return PTR_ERR(vma);
+
+   err = i915_vma_pin(vma, 0, 0, PIN_USER);
+   if (err)
+   return err;
+
+   rq = i915_gem_request_alloc(i915->engine[RCS], i915->kernel_context);
+   if (IS_ERR(rq)) {
+   i915_vma_unpin(vma);
+   return PTR_ERR(rq);
+   }
+
+   i915_vma_move_to_active(vma, rq, 0);
+   i915_add_request(rq);
+
+   i915_gem_object_set_active_reference(obj);
+   i915_vma_unpin(vma);
+   return 0;
+}
+
+static bool assert_mmap_offset(struct drm_i915_private *i915,
+  unsigned long size,
+  int expected)
+{
+   struct drm_i915_gem_object *obj;
+   int err;
+
+   obj = i915_gem_object_create_internal(i915, size);
+   if (IS_ERR(obj))
+   return PTR_ERR(obj);
+
+   err = i915_gem_object_create_mmap_offset(obj);
+   i915_gem_object_put(obj);
+
+   return err == expected;
+}
+
+static int igt_mmap_offset_exhaustion(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_mm *mm = &i915->drm.vma_offset_manager->vm_addr_space_mm;
+   struct drm_i915_gem_object *obj;
+   struct drm_mm_node resv, *hole;
+   u64 hole_start, hole_end;
+   int loop, err;
+
+   /* Trim the device mmap space to only a page */
+   memset(&resv, 0, sizeof(resv));
+   drm_mm_for_each_hole(hole, mm, hole_start, hole_end) {
+   resv.start = hole_start;
+   resv.size = hole_end - hole_start - 1; /* PAGE_SIZE units */
+   err = drm_mm_reserve_node(mm, &resv);
+   if (err) {
+   pr_err("Failed to trim VMA manager, err=%d\n", err);
+   return err;
+   }
+   break;
+   }
+
+   /* Just fits! */
+   if (!assert_mmap_offset(i915, PAGE_SIZE, 0)) {
+   pr_err("Unable to insert object into single page hole\n");
+   err = -EINVAL;
+   goto out;
+   }
+
+   /* Too large */
+   if (!assert_mmap_offset(i915, 2*PAGE_SIZE, -ENOSPC)) {
+   pr_err("Unexpectedly succeeded in inserting too large object 
into single page hole\n");
+   err = -EINVAL;
+   goto out;
+   }
+
+   /* Fill the hole, further allocation attempts should then fail */
+   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   goto out;
+   }
+
+   err = i915_gem_object_create_mmap_offset(obj);
+   if (err) {
+   pr_err("Unable to insert object into reclaimed hole\n");
+   goto err_obj;
+   }
+
+   if (!assert_mmap_offset(i915, PAGE_SIZE, -ENOSPC)) {
+   pr_err("Unexpectedly succeeded in inserting object into no 
holes!\n");
+   err = -EINVAL;
+   goto err_obj;
+   }
+
+   i915_gem_object_put(obj);
+
+   /* Now fill with busy dead objects that we expect to reap */
+   for (loop = 0; loop < 3; loop++) {
+   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   goto out;
+   }
+
+   mutex_lock(&i915->drm.struct_mutex);
+   err = make_obj_busy(obj);
+   mutex_unlock(&i915->drm.struct_mutex);
+   if (err) {
+   pr_err("[loop %d] Failed to busy the object\n", loop);
+   goto err_obj;
+   }
+
+   GEM_BUG_ON(!i915_gem_object_is_active(obj));
+   err = i915_gem_object_create_mmap_offset(obj);
+   if (err) {
+   pr_err("[loop %d] i915_gem_object_create_mmap_offset 
failed with err=%d\n",
+  loop, err);
+ 

[Intel-gfx] [PATCH 19/46] drm/i915: Test request ordering between engines

2017-02-02 Thread Chris Wilson
A request on one engine with a dependency on a request on another engine
must wait for completion of the first request before starting.

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

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
index 570cfa196ca7..f9c171d1a05b 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
@@ -473,11 +473,148 @@ static int live_all_engines(void *arg)
return err;
 }
 
+static int live_sequential_engines(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_request *request[I915_NUM_ENGINES] = {};
+   struct drm_i915_gem_request *prev = NULL;
+   struct intel_engine_cs *engine;
+   struct live_test t;
+   unsigned int id;
+   int err;
+
+   /* Check we can submit requests to all engines sequentially, such
+* that each successive request waits for the earlier ones. This
+* tests that we don't execute requests out of order, even though
+* they are running on independent engines.
+*/
+
+   mutex_lock(&i915->drm.struct_mutex);
+
+   err = begin_live_test(&t, i915, __func__, "");
+   if (err)
+   goto out_unlock;
+
+   for_each_engine(engine, i915, id) {
+   struct i915_vma *batch;
+
+   batch = recursive_batch(i915);
+   if (IS_ERR(batch)) {
+   err = PTR_ERR(batch);
+   pr_err("%s: Unable to create batch for %s, err=%d\n",
+  __func__, engine->name, err);
+   goto out_unlock;
+   }
+
+   request[id] = i915_gem_request_alloc(engine,
+i915->kernel_context);
+   if (IS_ERR(request[id])) {
+   err = PTR_ERR(request[id]);
+   pr_err("%s: Request allocation failed for %s with 
err=%d\n",
+  __func__, engine->name, err);
+   goto out_request;
+   }
+
+   if (prev) {
+   err = i915_gem_request_await_dma_fence(request[id],
+  &prev->fence);
+   if (err) {
+   i915_add_request(request[id]);
+   pr_err("%s: Request await failed for %s with 
err=%d\n",
+  __func__, engine->name, err);
+   goto out_request;
+   }
+   }
+
+   err = engine->emit_flush(request[id], EMIT_INVALIDATE);
+   GEM_BUG_ON(err);
+
+   err = i915_switch_context(request[id]);
+   GEM_BUG_ON(err);
+
+   err = engine->emit_bb_start(request[id],
+   batch->node.start,
+   batch->node.size,
+   0);
+   GEM_BUG_ON(err);
+   request[id]->batch = batch;
+
+   i915_vma_move_to_active(batch, request[id], 0);
+   i915_gem_object_set_active_reference(batch->obj);
+   i915_vma_get(batch);
+
+   i915_gem_request_get(request[id]);
+   i915_add_request(request[id]);
+
+   prev = request[id];
+   }
+
+   for_each_engine(engine, i915, id) {
+   long timeout;
+   u32 *cmd;
+
+   if (i915_gem_request_completed(request[id])) {
+   pr_err("%s(%s): request completed too early!\n",
+  __func__, engine->name);
+   err = -EINVAL;
+   goto out_request;
+   }
+
+   cmd = i915_gem_object_pin_map(request[id]->batch->obj,
+ I915_MAP_WC);
+   if (IS_ERR(cmd)) {
+   err = PTR_ERR(cmd);
+   pr_err("%s: failed to WC map batch, err=%d\n", 
__func__, err);
+   goto out_request;
+   }
+   *cmd = MI_BATCH_BUFFER_END;
+   wmb();
+   i915_gem_object_unpin_map(request[id]->batch->obj);
+
+   timeout = i915_wait_request(request[id],
+   I915_WAIT_LOCKED,
+   MAX_SCHEDULE_TIMEOUT);
+   if (timeout < 0) {
+   err = timeout;
+   pr_err("%s: error waiting for request on %s, err=%d\n",
+  __func__, engine->name, err);
+   goto out_request;
+   }
+
+   GEM_BUG

[Intel-gfx] [PATCH 14/46] drm/i915: Add selftests for i915_gem_request

2017-02-02 Thread Chris Wilson
Simple starting point for adding seltests for i915_gem_request, first
mock a device (with engines and contexts) that allows us to construct
and execute a request, along with waiting for the request to complete.

Signed-off-by: Chris Wilson 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_gem_request.c|  5 ++
 drivers/gpu/drm/i915/selftests/i915_gem_request.c  | 68 ++
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |  1 +
 3 files changed, 74 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_request.c

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c 
b/drivers/gpu/drm/i915/i915_gem_request.c
index 72b7f7d9461d..bd2aeb290cad 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -1193,3 +1193,8 @@ void i915_gem_retire_requests(struct drm_i915_private 
*dev_priv)
for_each_engine(engine, dev_priv, id)
engine_retire_requests(engine);
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/mock_request.c"
+#include "selftests/i915_gem_request.c"
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
new file mode 100644
index ..9921d1c317c0
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "../i915_selftest.h"
+
+#include "mock_gem_device.h"
+
+static int igt_add_request(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_request *request;
+   int err = -ENOMEM;
+
+   /* Basic preliminary test to create a request and let it loose! */
+
+   mutex_lock(&i915->drm.struct_mutex);
+   request = mock_request(i915->engine[RCS],
+  i915->kernel_context,
+  HZ / 10);
+   if (!request)
+   goto out_unlock;
+
+   i915_add_request(request);
+
+   err = 0;
+out_unlock:
+   mutex_unlock(&i915->drm.struct_mutex);
+   return err;
+}
+
+int i915_gem_request_mock_selftests(void)
+{
+   static const struct i915_subtest tests[] = {
+   SUBTEST(igt_add_request),
+   };
+   struct drm_i915_private *i915;
+   int err;
+
+   i915 = mock_gem_device();
+   if (!i915)
+   return -ENOMEM;
+
+   err = i915_subtests(tests, i915);
+   drm_dev_unref(&i915->drm);
+
+   return err;
+}
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h 
b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index 80458e2a2b04..bda982404ad3 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -11,3 +11,4 @@
 selftest(sanitycheck, i915_mock_sanitycheck) /* keep first (igt selfcheck) */
 selftest(scatterlist, scatterlist_mock_selftests)
 selftest(breadcrumbs, intel_breadcrumbs_mock_selftests)
+selftest(requests, i915_gem_request_mock_selftests)
-- 
2.11.0

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


[Intel-gfx] [PATCH 26/46] drm/i915: Move uncore selfchecks to live selftest infrastructure

2017-02-02 Thread Chris Wilson
Now that the kselftest infrastructure exists, put it to use and add to
it the existing consistency checks on the fw register lookup tables.

v2: s/tabke/table/

Signed-off-by: Chris Wilson 
Cc: Tvrtko Ursulin 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/intel_uncore.c| 52 +---
 .../gpu/drm/i915/selftests/i915_live_selftests.h   |  1 +
 drivers/gpu/drm/i915/selftests/intel_uncore.c  | 99 ++
 3 files changed, 104 insertions(+), 48 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/selftests/intel_uncore.c

diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index 3d243fefe09b..9bc103a00b72 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -642,33 +642,6 @@ find_fw_domain(struct drm_i915_private *dev_priv, u32 
offset)
return entry->domains;
 }
 
-static void
-intel_fw_table_check(struct drm_i915_private *dev_priv)
-{
-   const struct intel_forcewake_range *ranges;
-   unsigned int num_ranges;
-   s32 prev;
-   unsigned int i;
-
-   if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG))
-   return;
-
-   ranges = dev_priv->uncore.fw_domains_table;
-   if (!ranges)
-   return;
-
-   num_ranges = dev_priv->uncore.fw_domains_table_entries;
-
-   for (i = 0, prev = -1; i < num_ranges; i++, ranges++) {
-   WARN_ON_ONCE(IS_GEN9(dev_priv) &&
-(prev + 1) != (s32)ranges->start);
-   WARN_ON_ONCE(prev >= (s32)ranges->start);
-   prev = ranges->start;
-   WARN_ON_ONCE(prev >= (s32)ranges->end);
-   prev = ranges->end;
-   }
-}
-
 #define GEN_FW_RANGE(s, e, d) \
{ .start = (s), .end = (e), .domains = (d) }
 
@@ -707,23 +680,6 @@ static const i915_reg_t gen8_shadowed_regs[] = {
/* TODO: Other registers are not yet used */
 };
 
-static void intel_shadow_table_check(void)
-{
-   const i915_reg_t *reg = gen8_shadowed_regs;
-   s32 prev;
-   u32 offset;
-   unsigned int i;
-
-   if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG))
-   return;
-
-   for (i = 0, prev = -1; i < ARRAY_SIZE(gen8_shadowed_regs); i++, reg++) {
-   offset = i915_mmio_reg_offset(*reg);
-   WARN_ON_ONCE(prev >= (s32)offset);
-   prev = offset;
-   }
-}
-
 static int mmio_reg_cmp(u32 key, const i915_reg_t *reg)
 {
u32 offset = i915_mmio_reg_offset(*reg);
@@ -1404,10 +1360,6 @@ void intel_uncore_init(struct drm_i915_private *dev_priv)
break;
}
 
-   intel_fw_table_check(dev_priv);
-   if (INTEL_GEN(dev_priv) >= 8)
-   intel_shadow_table_check();
-
i915_check_and_clear_faults(dev_priv);
 }
 #undef ASSIGN_WRITE_MMIO_VFUNCS
@@ -1925,3 +1877,7 @@ intel_uncore_forcewake_for_reg(struct drm_i915_private 
*dev_priv,
 
return fw_domains;
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/intel_uncore.c"
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h 
b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index fde9ef22cfe8..c060bf24928e 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -9,6 +9,7 @@
  * Tests are executed in order by igt/drv_selftest
  */
 selftest(sanitycheck, i915_live_sanitycheck) /* keep first (igt selfcheck) */
+selftest(uncore, intel_uncore_live_selftests)
 selftest(requests, i915_gem_request_live_selftests)
 selftest(object, i915_gem_object_live_selftests)
 selftest(coherency, i915_gem_coherency_live_selftests)
diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c 
b/drivers/gpu/drm/i915/selftests/intel_uncore.c
new file mode 100644
index ..6b27dca78f69
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARI

[Intel-gfx] [PATCH 27/46] drm/i915: Test all fw tables during mock selftests

2017-02-02 Thread Chris Wilson
In addition to just testing the fw table we load, during the initial
mock testing we can test that all tables are valid (so the testing is
not limited to just the platforms that load that particular table).

Signed-off-by: Chris Wilson 
Cc: Tvrtko Ursulin 
Reviewed-by: Matthew Auld 
---
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |  1 +
 drivers/gpu/drm/i915/selftests/intel_uncore.c  | 49 --
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h 
b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index 2ed94e3a71b7..c61e08de7913 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -10,6 +10,7 @@
  */
 selftest(sanitycheck, i915_mock_sanitycheck) /* keep first (igt selfcheck) */
 selftest(scatterlist, scatterlist_mock_selftests)
+selftest(uncore, intel_uncore_mock_selftests)
 selftest(breadcrumbs, intel_breadcrumbs_mock_selftests)
 selftest(requests, i915_gem_request_mock_selftests)
 selftest(objects, i915_gem_object_mock_selftests)
diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c 
b/drivers/gpu/drm/i915/selftests/intel_uncore.c
index 6b27dca78f69..c563962eaad7 100644
--- a/drivers/gpu/drm/i915/selftests/intel_uncore.c
+++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
@@ -24,20 +24,16 @@
 
 #include "../i915_selftest.h"
 
-static int intel_fw_table_check(struct drm_i915_private *i915)
+static int intel_fw_table_check(const struct intel_forcewake_range *ranges,
+   unsigned int num_ranges,
+   bool is_watertight)
 {
-   const struct intel_forcewake_range *ranges;
-   unsigned int num_ranges, i;
+   unsigned int i;
s32 prev;
 
-   ranges = i915->uncore.fw_domains_table;
-   if (!ranges)
-   return 0;
-
-   num_ranges = i915->uncore.fw_domains_table_entries;
for (i = 0, prev = -1; i < num_ranges; i++, ranges++) {
/* Check that the table is watertight */
-   if (IS_GEN9(i915) && (prev + 1) != (s32)ranges->start) {
+   if (is_watertight && (prev + 1) != (s32)ranges->start) {
pr_err("%s: entry[%d]:(%x, %x) is not watertight to 
previous (%x)\n",
   __func__, i, ranges->start, ranges->end, prev);
return -EINVAL;
@@ -83,15 +79,42 @@ static int intel_shadow_table_check(void)
return 0;
 }
 
-int intel_uncore_live_selftests(struct drm_i915_private *i915)
+int intel_uncore_mock_selftests(void)
 {
-   int err;
+   struct {
+   const struct intel_forcewake_range *ranges;
+   unsigned int num_ranges;
+   bool is_watertight;
+   } fw[] = {
+   { __vlv_fw_ranges, ARRAY_SIZE(__vlv_fw_ranges), false },
+   { __chv_fw_ranges, ARRAY_SIZE(__chv_fw_ranges), false },
+   { __gen9_fw_ranges, ARRAY_SIZE(__gen9_fw_ranges), true },
+   };
+   int err, i;
+
+   for (i = 0; i < ARRAY_SIZE(fw); i++) {
+   err = intel_fw_table_check(fw[i].ranges,
+  fw[i].num_ranges,
+  fw[i].is_watertight);
+   if (err)
+   return err;
+   }
 
-   err = intel_fw_table_check(i915);
+   err = intel_shadow_table_check();
if (err)
return err;
 
-   err = intel_shadow_table_check();
+   return 0;
+}
+
+int intel_uncore_live_selftests(struct drm_i915_private *i915)
+{
+   int err;
+
+   /* Confirm the table we load is still valid */
+   err = intel_fw_table_check(i915->uncore.fw_domains_table,
+  i915->uncore.fw_domains_table_entries,
+  INTEL_GEN(i915) >= 9);
if (err)
return err;
 
-- 
2.11.0

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


[Intel-gfx] [PATCH 21/46] drm/i915: Add selftests for object allocation, phys

2017-02-02 Thread Chris Wilson
The phys object is a rarely used device (only very old machines require
a chunk of physically contiguous pages for a few hardware interactions).
As such, it is not exercised by CI and to combat that we want to add a
test that exercises the phys object on all platforms.

Signed-off-by: Chris Wilson 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_gem.c|   1 +
 drivers/gpu/drm/i915/selftests/i915_gem_object.c   | 120 +
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |   1 +
 3 files changed, 122 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_object.c

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f35fda5d0abc..429c5e4350f7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4973,4 +4973,5 @@ i915_gem_object_get_dma_address(struct 
drm_i915_gem_object *obj,
 #include "selftests/scatterlist.c"
 #include "selftests/mock_gem_device.c"
 #include "selftests/huge_gem_object.c"
+#include "selftests/i915_gem_object.c"
 #endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
new file mode 100644
index ..db8f631e4993
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "../i915_selftest.h"
+
+#include "mock_gem_device.h"
+
+static int igt_gem_object(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_object *obj;
+   int err = -ENOMEM;
+
+   /* Basic test to ensure we can create an object */
+
+   obj = i915_gem_object_create(i915, PAGE_SIZE);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   pr_err("i915_gem_object_create failed, err=%d\n", err);
+   goto out;
+   }
+
+   err = 0;
+   i915_gem_object_put(obj);
+out:
+   return err;
+}
+
+static int igt_phys_object(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_object *obj;
+   int err = -ENOMEM;
+
+   /* Create an object and bind it to a contiguous set of physical pages,
+* i.e. exercise the i915_gem_object_phys API.
+*/
+
+   obj = i915_gem_object_create(i915, PAGE_SIZE);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   pr_err("i915_gem_object_create failed, err=%d\n", err);
+   goto out;
+   }
+
+   err = -EINVAL;
+   mutex_lock(&i915->drm.struct_mutex);
+   err = i915_gem_object_attach_phys(obj, PAGE_SIZE);
+   mutex_unlock(&i915->drm.struct_mutex);
+   if (err) {
+   pr_err("i915_gem_object_attach_phys failed, err=%d\n", err);
+   goto out_obj;
+   }
+
+   if (obj->ops != &i915_gem_phys_ops) {
+   pr_err("i915_gem_object_attach_phys did not create a phys 
object\n");
+   goto out_obj;
+   }
+
+   if (!atomic_read(&obj->mm.pages_pin_count)) {
+   pr_err("i915_gem_object_attach_phys did not pin its phys 
pages\n");
+   goto out_obj;
+   }
+
+   /* Make the object dirty so that put_pages must do copy back the data */
+   mutex_lock(&i915->drm.struct_mutex);
+   err = i915_gem_object_set_to_gtt_domain(obj, true);
+   mutex_unlock(&i915->drm.struct_mutex);
+   if (err) {
+   pr_err("i915_gem_object_set_to_gtt_domain failed with err=%d\n",
+  err);
+   goto out_obj;
+   }
+
+   err = 0;
+out_obj:
+   i915_gem_object_put(obj);
+out:
+   return err;
+}
+
+int i915_gem_object_mock_selftests(void)
+{
+   static const struct i915_subtest tests[] = {
+   SUBTEST(igt_gem_object),
+   SUBTEST(igt_phys_object),
+

[Intel-gfx] [PATCH 15/46] drm/i915: Add a simple request selftest for waiting

2017-02-02 Thread Chris Wilson
A trivial kselftest to submit a request and wait upon it.

Signed-off-by: Chris Wilson 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/selftests/i915_gem_request.c | 46 +++
 1 file changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
index 9921d1c317c0..14584b67c4a0 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
@@ -49,10 +49,56 @@ static int igt_add_request(void *arg)
return err;
 }
 
+static int igt_wait_request(void *arg)
+{
+   const long T = HZ / 4;
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_request *request;
+   int err = -EINVAL;
+
+   /* Submit a request, then wait upon it */
+
+   mutex_lock(&i915->drm.struct_mutex);
+   request = mock_request(i915->engine[RCS], i915->kernel_context, T);
+   if (!request) {
+   err = -ENOMEM;
+   goto out_unlock;
+   }
+
+   i915_add_request(request);
+
+   if (i915_gem_request_completed(request)) {
+   pr_err("request completed immediately!\n");
+   goto out_unlock;
+   }
+
+   if (i915_wait_request(request, I915_WAIT_LOCKED, T / 2) != -ETIME) {
+   pr_err("request wait succeeded (expected tiemout!)\n");
+   goto out_unlock;
+   }
+
+   if (i915_wait_request(request, I915_WAIT_LOCKED, T) == -ETIME) {
+   pr_err("request wait timed out!\n");
+   goto out_unlock;
+   }
+
+   if (!i915_gem_request_completed(request)) {
+   pr_err("request not complete after waiting!\n");
+   goto out_unlock;
+   }
+
+   err = 0;
+out_unlock:
+   mock_device_flush(i915);
+   mutex_unlock(&i915->drm.struct_mutex);
+   return err;
+}
+
 int i915_gem_request_mock_selftests(void)
 {
static const struct i915_subtest tests[] = {
SUBTEST(igt_add_request),
+   SUBTEST(igt_wait_request),
};
struct drm_i915_private *i915;
int err;
-- 
2.11.0

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


[Intel-gfx] [PATCH 17/46] drm/i915: Simple selftest to exercise live requests

2017-02-02 Thread Chris Wilson
Just create several batches of requests and expect it to not fall over!

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/selftests/i915_gem_request.c  | 147 +
 .../gpu/drm/i915/selftests/i915_live_selftests.h   |   1 +
 2 files changed, 148 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
index bc6f5618f22b..b5c7cd6633f0 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
@@ -22,6 +22,8 @@
  *
  */
 
+#include 
+
 #include "../i915_selftest.h"
 
 #include "mock_gem_device.h"
@@ -161,3 +163,148 @@ int i915_gem_request_mock_selftests(void)
 
return err;
 }
+
+struct live_test {
+   struct drm_i915_private *i915;
+   const char *func;
+   const char *name;
+
+   unsigned int reset_count;
+};
+
+static int begin_live_test(struct live_test *t,
+  struct drm_i915_private *i915,
+  const char *func,
+  const char *name)
+{
+   int err;
+
+   t->i915 = i915;
+   t->func = func;
+   t->name = name;
+
+   err = i915_gem_wait_for_idle(i915, I915_WAIT_LOCKED);
+   if (err) {
+   pr_err("%s(%s): failed to idle before, with err=%d!",
+  func, name, err);
+   return err;
+   }
+
+   i915_gem_retire_requests(i915);
+
+   i915->gpu_error.missed_irq_rings = 0;
+   t->reset_count = i915_reset_count(&i915->gpu_error);
+
+   return 0;
+}
+
+static int end_live_test(struct live_test *t)
+{
+   struct drm_i915_private *i915 = t->i915;
+
+   if (wait_for(intel_execlists_idle(i915), 1)) {
+   pr_err("%s(%s): GPU not idle\n", t->func, t->name);
+   return -EIO;
+   }
+
+   if (t->reset_count != i915_reset_count(&i915->gpu_error)) {
+   pr_err("%s(%s): GPU was reset %d times!\n",
+  t->func, t->name,
+  i915_reset_count(&i915->gpu_error) - t->reset_count);
+   return -EIO;
+   }
+
+   if (i915->gpu_error.missed_irq_rings) {
+   pr_err("%s(%s): Missed interrupts on engines %lx\n",
+  t->func, t->name, i915->gpu_error.missed_irq_rings);
+   return -EIO;
+   }
+
+   return 0;
+}
+
+static int live_nop_request(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct intel_engine_cs *engine;
+   struct live_test t;
+   unsigned int id;
+   int err;
+
+   /* Submit various sized batches of empty requests, to each engine
+* (individually), and wait for the batch to complete. We can check
+* the overhead of submitting requests to the hardware.
+*/
+
+   mutex_lock(&i915->drm.struct_mutex);
+
+   for_each_engine(engine, i915, id) {
+   IGT_TIMEOUT(end_time);
+   struct drm_i915_gem_request *request;
+   unsigned long n, prime;
+   ktime_t times[2] = {};
+
+   err = begin_live_test(&t, i915, __func__, engine->name);
+   if (err)
+   goto out_unlock;
+
+   for_each_prime_number_from(prime, 1, 8192) {
+   times[1] = ktime_get_raw();
+
+   for (n = 0; n < prime; n++) {
+   request = i915_gem_request_alloc(engine,
+
i915->kernel_context);
+   if (IS_ERR(request)) {
+   err = PTR_ERR(request);
+   goto out_unlock;
+   }
+
+   /* This space is left intentionally blank.
+*
+* We do not actually want to perform any
+* action with this request, we just want
+* to measure the latency in allocation
+* and submission of our breadcrumbs -
+* ensuring that the bare request is sufficient
+* for the system to work (i.e. proper HEAD
+* tracking of the rings, interrupt handling,
+* etc). It also gives us the lowest bounds
+* for latency.
+*/
+
+   i915_add_request(request);
+   }
+   i915_wait_request(request,
+ I915_WAIT_LOCKED,
+ MAX_SCHEDULE_TIMEOUT);
+
+   times[1] = ktime_sub(ktime_get_raw(), times[1]);
+   if (prime == 1)
+  

[Intel-gfx] [PATCH 32/46] drm/i915: Exercise filling the top/bottom portions of the ppgtt

2017-02-02 Thread Chris Wilson
Allocate objects with varying number of pages (which should hopefully
consist of a mixture of contiguous page chunks and so coalesced sg
lists) and check that the sg walkers in insert_pages cope.

v2: Check both small <-> large

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

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 5c09dc920cb8..4cd55fc0820a 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -22,8 +22,101 @@
  *
  */
 
+#include 
+
 #include "../i915_selftest.h"
 
+#include "mock_drm.h"
+
+static void fake_free_pages(struct drm_i915_gem_object *obj,
+   struct sg_table *pages)
+{
+   sg_free_table(pages);
+   kfree(pages);
+}
+
+static struct sg_table *
+fake_get_pages(struct drm_i915_gem_object *obj)
+{
+#define GFP (GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY)
+#define PFN_BIAS 0x1000
+   struct sg_table *pages;
+   struct scatterlist *sg;
+   typeof(obj->base.size) rem;
+
+   pages = kmalloc(sizeof(*pages), GFP);
+   if (!pages)
+   return ERR_PTR(-ENOMEM);
+
+   rem = round_up(obj->base.size, BIT(31)) >> 31;
+   if (sg_alloc_table(pages, rem, GFP)) {
+   kfree(pages);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   rem = obj->base.size;
+   for (sg = pages->sgl; sg; sg = sg_next(sg)) {
+   unsigned long len = min_t(typeof(rem), rem, BIT(31));
+
+   sg_set_page(sg, pfn_to_page(PFN_BIAS), len, 0);
+   sg_dma_address(sg) = page_to_phys(sg_page(sg));
+   sg_dma_len(sg) = len;
+
+   rem -= len;
+   }
+
+   return pages;
+#undef GFP
+}
+
+static void fake_put_pages(struct drm_i915_gem_object *obj,
+  struct sg_table *pages)
+{
+   fake_free_pages(obj, pages);
+   obj->mm.dirty = false;
+}
+
+static void fake_release(struct drm_i915_gem_object *obj)
+{
+   __i915_gem_object_unpin_pages(obj);
+}
+
+static const struct drm_i915_gem_object_ops fake_ops = {
+   .get_pages = fake_get_pages,
+   .put_pages = fake_put_pages,
+   .release = fake_release
+};
+
+static struct drm_i915_gem_object *
+fake_dma_object(struct drm_i915_private *i915, u64 size)
+{
+   struct drm_i915_gem_object *obj;
+
+   GEM_BUG_ON(!size);
+   GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_PAGE_SIZE));
+
+   if (overflows_type(size, obj->base.size))
+   return ERR_PTR(-E2BIG);
+
+   obj = i915_gem_object_alloc(i915);
+   if (!obj)
+   return ERR_PTR(-ENOMEM);
+
+   drm_gem_private_object_init(&i915->drm, &obj->base, size);
+   i915_gem_object_init(obj, &fake_ops);
+
+   obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+   obj->base.read_domains = I915_GEM_DOMAIN_CPU;
+   obj->cache_level = I915_CACHE_NONE;
+
+   if (i915_gem_object_pin_pages(obj)) {
+   i915_gem_object_free(obj);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   return obj;
+}
+
 static int igt_ppgtt_alloc(void *arg)
 {
struct drm_i915_private *dev_priv = arg;
@@ -87,10 +180,279 @@ static int igt_ppgtt_alloc(void *arg)
return err;
 }
 
+static void close_object_list(struct list_head *objects,
+ struct i915_address_space *vm)
+{
+   struct drm_i915_gem_object *obj, *on;
+
+   list_for_each_entry_safe(obj, on, objects, batch_pool_link) {
+   struct i915_vma *vma;
+
+   vma = i915_vma_instance(obj, vm, NULL);
+   if (!IS_ERR(vma))
+   i915_vma_close(vma);
+
+   list_del(&obj->batch_pool_link);
+   i915_gem_object_put(obj);
+   }
+}
+
+static int fill_hole(struct drm_i915_private *i915,
+struct i915_address_space *vm,
+u64 hole_start, u64 hole_end,
+unsigned long end_time)
+{
+#define FLAGS (PIN_USER | PIN_OFFSET_FIXED)
+   const u64 hole_size = hole_end - hole_start;
+   struct drm_i915_gem_object *obj;
+   const unsigned long max_pages =
+   min_t(u64, ULONG_MAX - 1, hole_size/2 >> PAGE_SHIFT);
+   const unsigned long max_step = max(int_sqrt(max_pages), 2UL);
+   unsigned long npages, prime;
+   struct i915_vma *vma;
+   LIST_HEAD(objects);
+   int err;
+
+   /* Try binding many VMA working inwards from either edge */
+
+   for_each_prime_number_from(prime, 2, max_step) {
+   for (npages = 1; npages <= max_pages; npages *= prime) {
+   const u64 full_size = npages << PAGE_SHIFT;
+   const struct {
+   const char *name;
+   u64 offset;
+   int step;
+   }

[Intel-gfx] [PATCH 25/46] drm/i915: Test coherency of and barriers between cache domains

2017-02-02 Thread Chris Wilson
Write into an object using WB, WC, GTT, and GPU paths and make sure that
our internal API is sufficient to ensure coherent reads and writes.

v2: Avoid invalid free upon allocation error

Signed-off-by: Chris Wilson 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_gem.c|   1 +
 .../gpu/drm/i915/selftests/i915_gem_coherency.c| 364 +
 .../gpu/drm/i915/selftests/i915_live_selftests.h   |   1 +
 3 files changed, 366 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_coherency.c

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 429c5e4350f7..2749c64a35a3 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4974,4 +4974,5 @@ i915_gem_object_get_dma_address(struct 
drm_i915_gem_object *obj,
 #include "selftests/mock_gem_device.c"
 #include "selftests/huge_gem_object.c"
 #include "selftests/i915_gem_object.c"
+#include "selftests/i915_gem_coherency.c"
 #endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c
new file mode 100644
index ..b5de1828221d
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include 
+
+#include "../i915_selftest.h"
+#include "i915_random.h"
+
+static int cpu_set(struct drm_i915_gem_object *obj,
+  unsigned long offset,
+  u32 v)
+{
+   unsigned int needs_clflush;
+   struct page *page;
+   typeof(v) *map;
+   int err;
+
+   err = i915_gem_obj_prepare_shmem_write(obj, &needs_clflush);
+   if (err)
+   return err;
+
+   page = i915_gem_object_get_page(obj, offset >> PAGE_SHIFT);
+   map = kmap_atomic(page);
+   if (needs_clflush & CLFLUSH_BEFORE)
+   clflush(map+offset_in_page(offset) / sizeof(*map));
+   map[offset_in_page(offset) / sizeof(*map)] = v;
+   if (needs_clflush & CLFLUSH_AFTER)
+   clflush(map+offset_in_page(offset) / sizeof(*map));
+   kunmap_atomic(map);
+
+   i915_gem_obj_finish_shmem_access(obj);
+   return 0;
+}
+
+static int cpu_get(struct drm_i915_gem_object *obj,
+  unsigned long offset,
+  u32 *v)
+{
+   unsigned int needs_clflush;
+   struct page *page;
+   typeof(v) map;
+   int err;
+
+   err = i915_gem_obj_prepare_shmem_read(obj, &needs_clflush);
+   if (err)
+   return err;
+
+   page = i915_gem_object_get_page(obj, offset >> PAGE_SHIFT);
+   map = kmap_atomic(page);
+   if (needs_clflush & CLFLUSH_BEFORE)
+   clflush(map+offset_in_page(offset) / sizeof(*map));
+   *v = map[offset_in_page(offset) / sizeof(*map)];
+   kunmap_atomic(map);
+
+   i915_gem_obj_finish_shmem_access(obj);
+   return 0;
+}
+
+static int gtt_set(struct drm_i915_gem_object *obj,
+  unsigned long offset,
+  u32 v)
+{
+   struct i915_vma *vma;
+   typeof(v) *map;
+   int err;
+
+   err = i915_gem_object_set_to_gtt_domain(obj, true);
+   if (err)
+   return err;
+
+   vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
+   if (IS_ERR(vma))
+   return PTR_ERR(vma);
+
+   map = i915_vma_pin_iomap(vma);
+   i915_vma_unpin(vma);
+   if (IS_ERR(map))
+   return PTR_ERR(map);
+
+   map[offset / sizeof(*map)] = v;
+   i915_vma_unpin_iomap(vma);
+
+   return 0;
+}
+
+static int gtt_get(struct drm_i915_gem_object *obj,
+  unsigned long offset,
+  u32 *v)
+{
+   struct i915_vma *vma;
+   typeof(v) map;
+   int err;
+
+   err = i915_gem_object_set_to_gtt_domain(obj, false);
+  

[Intel-gfx] [PATCH 28/46] drm/i915: Sanity check all registers for matching fw domains

2017-02-02 Thread Chris Wilson
Add a late selftest that walks over all forcewake registers (those below
0x4) and uses the mmio debug register to check to see if any are
unclaimed. This is possible if we fail to wake the appropriate
powerwells for the register.

Signed-off-by: Chris Wilson 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/selftests/intel_uncore.c | 53 +++
 1 file changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c 
b/drivers/gpu/drm/i915/selftests/intel_uncore.c
index c563962eaad7..2fb8122944b2 100644
--- a/drivers/gpu/drm/i915/selftests/intel_uncore.c
+++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
@@ -107,6 +107,55 @@ int intel_uncore_mock_selftests(void)
return 0;
 }
 
+static int intel_uncore_check_forcewake_domains(struct drm_i915_private 
*dev_priv)
+{
+#define FW_RANGE 0x4
+   unsigned long *valid;
+   u32 offset;
+   int err;
+
+   if (!HAS_FPGA_DBG_UNCLAIMED(dev_priv) &&
+   !IS_VALLEYVIEW(dev_priv) &&
+   !IS_CHERRYVIEW(dev_priv))
+   return 0;
+
+   valid = kzalloc(BITS_TO_LONGS(FW_RANGE) * sizeof(*valid),
+   GFP_TEMPORARY);
+   if (!valid)
+   return -ENOMEM;
+
+   intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+   check_for_unclaimed_mmio(dev_priv);
+   for (offset = 0; offset < FW_RANGE; offset += 4) {
+   i915_reg_t reg = { offset };
+
+   (void)I915_READ_FW(reg);
+   if (!check_for_unclaimed_mmio(dev_priv))
+   set_bit(offset, valid);
+   }
+
+   intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+
+   err = 0;
+   for_each_set_bit(offset, valid, FW_RANGE) {
+   i915_reg_t reg = { offset };
+
+   intel_uncore_forcewake_reset(dev_priv, false);
+   check_for_unclaimed_mmio(dev_priv);
+
+   (void)I915_READ(reg);
+   if (check_for_unclaimed_mmio(dev_priv)) {
+   pr_err("Unclaimed mmio read to register 0x%04x\n",
+  offset);
+   err = -EINVAL;
+   }
+   }
+
+   kfree(valid);
+   return err;
+}
+
 int intel_uncore_live_selftests(struct drm_i915_private *i915)
 {
int err;
@@ -118,5 +167,9 @@ int intel_uncore_live_selftests(struct drm_i915_private 
*i915)
if (err)
return err;
 
+   err = intel_uncore_check_forcewake_domains(i915);
+   if (err)
+   return err;
+
return 0;
 }
-- 
2.11.0

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


[Intel-gfx] [PATCH 33/46] drm/i915: Exercise filling the top/bottom portions of the global GTT

2017-02-02 Thread Chris Wilson
Same test as previously for the per-process GTT instead applied to the
global GTT.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 61 ++-
 1 file changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 4cd55fc0820a..e1121d157d76 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -22,6 +22,7 @@
  *
  */
 
+#include 
 #include 
 
 #include "../i915_selftest.h"
@@ -189,7 +190,8 @@ static void close_object_list(struct list_head *objects,
struct i915_vma *vma;
 
vma = i915_vma_instance(obj, vm, NULL);
-   if (!IS_ERR(vma))
+   /* Only ppgtt vma may be closed before the object is freed */
+   if (!IS_ERR(vma) && !i915_vma_is_ggtt(vma))
i915_vma_close(vma);
 
list_del(&obj->batch_pool_link);
@@ -448,12 +450,69 @@ static int igt_ppgtt_fill(void *arg)
return exercise_ppgtt(arg, fill_hole);
 }
 
+static int sort_holes(void *priv, struct list_head *A, struct list_head *B)
+{
+   struct drm_mm_node *a = list_entry(A, typeof(*a), hole_stack);
+   struct drm_mm_node *b = list_entry(B, typeof(*b), hole_stack);
+
+   if (a->start < b->start)
+   return -1;
+   else
+   return 1;
+}
+
+static int exercise_ggtt(struct drm_i915_private *i915,
+int (*func)(struct drm_i915_private *i915,
+struct i915_address_space *vm,
+u64 hole_start, u64 hole_end,
+unsigned long end_time))
+{
+   struct i915_ggtt *ggtt = &i915->ggtt;
+   u64 hole_start, hole_end, last = 0;
+   struct drm_mm_node *node;
+   IGT_TIMEOUT(end_time);
+   int err;
+
+   mutex_lock(&i915->drm.struct_mutex);
+restart:
+   list_sort(NULL, &ggtt->base.mm.hole_stack, sort_holes);
+   drm_mm_for_each_hole(node, &ggtt->base.mm, hole_start, hole_end) {
+   if (hole_start < last)
+   continue;
+
+   if (ggtt->base.mm.color_adjust)
+   ggtt->base.mm.color_adjust(node, 0,
+  &hole_start, &hole_end);
+   if (hole_start >= hole_end)
+   continue;
+
+   err = func(i915, &ggtt->base, hole_start, hole_end, end_time);
+   if (err)
+   break;
+
+   /* As we have manipulated the drm_mm, the list may be corrupt */
+   last = hole_end;
+   goto restart;
+   }
+   mutex_unlock(&i915->drm.struct_mutex);
+
+   return err;
+}
+
+static int igt_ggtt_fill(void *arg)
+{
+   return exercise_ggtt(arg, fill_hole);
+}
+
 int i915_gem_gtt_live_selftests(struct drm_i915_private *i915)
 {
static const struct i915_subtest tests[] = {
SUBTEST(igt_ppgtt_alloc),
SUBTEST(igt_ppgtt_fill),
+   SUBTEST(igt_ggtt_fill),
};
 
+   GEM_BUG_ON(offset_in_page(i915->ggtt.base.total));
+
return i915_subtests(tests, i915);
 }
-- 
2.11.0

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


[Intel-gfx] [PATCH 31/46] drm/i915: Add initial selftests for i915_gem_gtt

2017-02-02 Thread Chris Wilson
Simple starting point for adding selftests for i915_gem_gtt, first
try creating a ppGTT and filling it.

Signed-off-by: Chris Wilson 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c|  1 +
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c  | 97 ++
 .../gpu/drm/i915/selftests/i915_live_selftests.h   |  1 +
 3 files changed, 99 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index afdb2859be05..ec360ab939b8 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3754,4 +3754,5 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
 
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/mock_gtt.c"
+#include "selftests/i915_gem_gtt.c"
 #endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
new file mode 100644
index ..5c09dc920cb8
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "../i915_selftest.h"
+
+static int igt_ppgtt_alloc(void *arg)
+{
+   struct drm_i915_private *dev_priv = arg;
+   struct i915_hw_ppgtt *ppgtt;
+   u64 size, last;
+   int err;
+
+   /* Allocate a ppggt and try to fill the entire range */
+
+   if (!USES_PPGTT(dev_priv))
+   return 0;
+
+   ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL);
+   if (!ppgtt)
+   return -ENOMEM;
+
+   err = __hw_ppgtt_init(ppgtt, dev_priv);
+   if (err)
+   goto err_ppgtt;
+
+   if (!ppgtt->base.allocate_va_range)
+   goto err_ppgtt_cleanup;
+
+   /* Check we can allocate the entire range */
+   for (size = 4096;
+size <= ppgtt->base.total;
+size <<= 2) {
+   err = ppgtt->base.allocate_va_range(&ppgtt->base, 0, size);
+   if (err) {
+   if (err == -ENOMEM) {
+   pr_info("[1] Ran out of memory for va_range [0 
+ %llx] [bit %d]\n",
+   size, ilog2(size));
+   err = 0; /* virtual space too large! */
+   }
+   goto err_ppgtt_cleanup;
+   }
+
+   ppgtt->base.clear_range(&ppgtt->base, 0, size);
+   }
+
+   /* Check we can incrementally allocate the entire range */
+   for (last = 0, size = 4096;
+size <= ppgtt->base.total;
+last = size, size <<= 2) {
+   err = ppgtt->base.allocate_va_range(&ppgtt->base,
+   last, size - last);
+   if (err) {
+   if (err == -ENOMEM) {
+   pr_info("[2] Ran out of memory for va_range 
[%llx + %llx] [bit %d]\n",
+   last, size - last, ilog2(size));
+   err = 0; /* virtual space too large! */
+   }
+   goto err_ppgtt_cleanup;
+   }
+   }
+
+err_ppgtt_cleanup:
+   ppgtt->base.cleanup(&ppgtt->base);
+err_ppgtt:
+   kfree(ppgtt);
+   return err;
+}
+
+int i915_gem_gtt_live_selftests(struct drm_i915_private *i915)
+{
+   static const struct i915_subtest tests[] = {
+   SUBTEST(igt_ppgtt_alloc),
+   };
+
+   return i915_subtests(tests, i915);
+}
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h 
b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index 1d26ca1f8bc8..16d6dde29fca 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@

[Intel-gfx] [PATCH 36/46] drm/i915: Test creation of VMA

2017-02-02 Thread Chris Wilson
Simple test to exercise creation and lookup of VMA within an object.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/i915_vma.c|   3 +
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |   1 +
 drivers/gpu/drm/i915/selftests/i915_vma.c  | 224 +
 3 files changed, 228 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_vma.c

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 155906e84812..5c32d12b2d8d 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -687,3 +687,6 @@ int i915_vma_unbind(struct i915_vma *vma)
return 0;
 }
 
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/i915_vma.c"
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h 
b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index 955a4d6ccdaf..b450eab7e6e1 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -15,3 +15,4 @@ selftest(breadcrumbs, intel_breadcrumbs_mock_selftests)
 selftest(requests, i915_gem_request_mock_selftests)
 selftest(objects, i915_gem_object_mock_selftests)
 selftest(dmabuf, i915_gem_dmabuf_mock_selftests)
+selftest(vma, i915_vma_mock_selftests)
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c 
b/drivers/gpu/drm/i915/selftests/i915_vma.c
new file mode 100644
index ..e60f3a962f56
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include 
+
+#include "../i915_selftest.h"
+
+#include "mock_gem_device.h"
+#include "mock_context.h"
+
+static bool assert_vma(struct i915_vma *vma,
+  struct drm_i915_gem_object *obj,
+  struct i915_gem_context *ctx)
+{
+   bool ok = true;
+
+   if (vma->vm != &ctx->ppgtt->base) {
+   pr_err("VMA created with wrong VM\n");
+   ok = false;
+   }
+
+   if (vma->size != obj->base.size) {
+   pr_err("VMA created with wrong size, found %llu, expected 
%zu\n",
+  vma->size, obj->base.size);
+   ok = false;
+   }
+
+   if (vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL) {
+   pr_err("VMA created with wrong type [%d]\n",
+  vma->ggtt_view.type);
+   ok = false;
+   }
+
+   return ok;
+}
+
+static struct i915_vma *
+checked_vma_instance(struct drm_i915_gem_object *obj,
+struct i915_address_space *vm,
+struct i915_ggtt_view *view)
+{
+   struct i915_vma *vma;
+   bool ok = true;
+
+   vma = i915_vma_instance(obj, vm, view);
+   if (IS_ERR(vma))
+   return vma;
+
+   /* Manual checks, will be reinforced by i915_vma_compare! */
+   if (vma->vm != vm) {
+   pr_err("VMA's vm [%p] does not match request [%p]\n",
+  vma->vm, vm);
+   ok = false;
+   }
+
+   if (i915_is_ggtt(vm) != i915_vma_is_ggtt(vma)) {
+   pr_err("VMA ggtt status [%d] does not match parent [%d]\n",
+  i915_vma_is_ggtt(vma), i915_is_ggtt(vm));
+   ok = false;
+   }
+
+   if (i915_vma_compare(vma, vm, view)) {
+   pr_err("i915_vma_compare failed with create parmaters!\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   if (i915_vma_compare(vma, vma->vm,
+i915_vma_is_ggtt(vma) ? &vma->ggtt_view : NULL)) {
+   pr_err("i915_vma_compare failed with itself\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   if (!ok) {
+   pr_err("i915_vma_compare failed to detect the difference!\n");
+   retur

[Intel-gfx] [PATCH 39/46] drm/i915: Test creation of partial VMA

2017-02-02 Thread Chris Wilson
Mock testing to ensure we can create and lookup partial VMA.

v2: Named phases

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/selftests/i915_vma.c | 192 ++
 1 file changed, 192 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c 
b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 4a737a670199..bb42b6191c7a 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -530,12 +530,204 @@ static int igt_vma_rotate(void *arg)
return err;
 }
 
+static bool assert_partial(struct drm_i915_gem_object *obj,
+  struct i915_vma *vma,
+  unsigned long offset,
+  unsigned long size)
+{
+   struct sgt_iter sgt;
+   dma_addr_t dma;
+
+   for_each_sgt_dma(dma, sgt, vma->pages) {
+   dma_addr_t src;
+
+   if (!size) {
+   pr_err("Partial scattergather list too long\n");
+   return false;
+   }
+
+   src = i915_gem_object_get_dma_address(obj, offset);
+   if (src != dma) {
+   pr_err("DMA mismatch for partial page offset %lu\n",
+  offset);
+   return false;
+   }
+
+   offset++;
+   size--;
+   }
+
+   return true;
+}
+
+static bool assert_pin(struct i915_vma *vma,
+  struct i915_ggtt_view *view,
+  u64 size,
+  const char *name)
+{
+   bool ok = true;
+
+   if (vma->size != size) {
+   pr_err("(%s) VMA is wrong size, expected %llu, found %llu\n",
+  name, size, vma->size);
+   ok = false;
+   }
+
+   if (vma->node.size < vma->size) {
+   pr_err("(%s) VMA binding too small, expected %llu, found 
%llu\n",
+  name, vma->size, vma->node.size);
+   ok = false;
+   }
+
+   if (view && view->type != I915_GGTT_VIEW_NORMAL) {
+   if (memcmp(&vma->ggtt_view, view, sizeof(*view))) {
+   pr_err("(%s) VMA mismatch upon creation!\n",
+  name);
+   ok = false;
+   }
+
+   if (vma->pages == vma->obj->mm.pages) {
+   pr_err("(%s) VMA using original object pages!\n",
+  name);
+   ok = false;
+   }
+   } else {
+   if (vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL) {
+   pr_err("Not the normal ggtt view! Found %d\n",
+  vma->ggtt_view.type);
+   ok = false;
+   }
+
+   if (vma->pages != vma->obj->mm.pages) {
+   pr_err("VMA not using object pages!\n");
+   ok = false;
+   }
+   }
+
+   return ok;
+}
+
+static int igt_vma_partial(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct i915_address_space *vm = &i915->ggtt.base;
+   const unsigned int npages = 1021; /* prime! */
+   struct drm_i915_gem_object *obj;
+   const struct phase {
+   const char *name;
+   } phases[] = {
+   { "create" },
+   { "lookup" },
+   { },
+   }, *p;
+   unsigned int sz, offset;
+   struct i915_vma *vma;
+   int err = -ENOMEM;
+
+   /* Create lots of different VMA for the object and check that
+* we are returned the same VMA when we later request the same range.
+*/
+
+   obj = i915_gem_object_create_internal(i915, npages*PAGE_SIZE);
+   if (IS_ERR(obj))
+   goto out;
+
+   for (p = phases; p->name; p++) { /* exercise both create/lookup */
+   unsigned int count, nvma;
+
+   nvma = 0;
+   for_each_prime_number_from(sz, 1, npages) {
+   for_each_prime_number_from(offset, 0, npages - sz) {
+   struct i915_ggtt_view view;
+
+   view.type = I915_GGTT_VIEW_PARTIAL;
+   view.partial.offset = offset;
+   view.partial.size = sz;
+
+   if (sz == npages)
+   view.type = I915_GGTT_VIEW_NORMAL;
+
+   vma = checked_vma_instance(obj, vm, &view);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto out_object;
+   }
+
+   err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL);
+   if (err)
+   goto out_object;
+
+  

[Intel-gfx] [PATCH 34/46] drm/i915: Fill different pages of the GTT

2017-02-02 Thread Chris Wilson
Exercise filling different pages of the GTT

v2: Walk all holes until we timeout

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 89 +++
 1 file changed, 89 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index e1121d157d76..7d695cdcd20a 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -408,6 +408,83 @@ static int fill_hole(struct drm_i915_private *i915,
 #undef FLAGS
 }
 
+static int walk_hole(struct drm_i915_private *i915,
+struct i915_address_space *vm,
+u64 hole_start, u64 hole_end,
+unsigned long end_time)
+{
+   const u64 hole_size = hole_end - hole_start;
+   const unsigned long max_pages =
+   min_t(u64, ULONG_MAX - 1, hole_size >> PAGE_SHIFT);
+   u64 size;
+
+   /* Try binding a single VMA in different positions within the hole */
+
+   for_each_prime_number_from(size, 1, max_pages) {
+   struct drm_i915_gem_object *obj;
+   struct i915_vma *vma;
+   u64 addr;
+   int err = 0;
+
+   obj = fake_dma_object(i915, size << PAGE_SHIFT);
+   if (IS_ERR(obj))
+   break;
+
+   vma = i915_vma_instance(obj, vm, NULL);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto err;
+   }
+
+   for (addr = hole_start;
+addr + obj->base.size < hole_end;
+addr += obj->base.size) {
+   err = i915_vma_pin(vma, 0, 0,
+  addr | PIN_OFFSET_FIXED | PIN_USER);
+   if (err) {
+   pr_err("%s bind failed at %llx + %llx [hole 
%llx- %llx] with err=%d\n",
+  __func__, addr, vma->size,
+  hole_start, hole_end, err);
+   goto err;
+   }
+   i915_vma_unpin(vma);
+
+   if (!drm_mm_node_allocated(&vma->node) ||
+   i915_vma_misplaced(vma, 0, 0, addr | 
PIN_OFFSET_FIXED)) {
+   pr_err("%s incorrect at %llx + %llx\n",
+  __func__, addr, vma->size);
+   err = -EINVAL;
+   goto err;
+   }
+
+   err = i915_vma_unbind(vma);
+   if (err) {
+   pr_err("%s unbind failed at %llx + %llx  with 
err=%d\n",
+  __func__, addr, vma->size, err);
+   goto err;
+   }
+
+   GEM_BUG_ON(drm_mm_node_allocated(&vma->node));
+
+   if (igt_timeout(end_time,
+   "%s timed out at %llx\n",
+   __func__, addr)) {
+   err = -EINTR;
+   goto err;
+   }
+   }
+
+err:
+   if (!i915_vma_is_ggtt(vma))
+   i915_vma_close(vma);
+   i915_gem_object_put(obj);
+   if (err)
+   return err;
+   }
+
+   return 0;
+}
+
 static int exercise_ppgtt(struct drm_i915_private *dev_priv,
  int (*func)(struct drm_i915_private *i915,
  struct i915_address_space *vm,
@@ -450,6 +527,11 @@ static int igt_ppgtt_fill(void *arg)
return exercise_ppgtt(arg, fill_hole);
 }
 
+static int igt_ppgtt_walk(void *arg)
+{
+   return exercise_ppgtt(arg, walk_hole);
+}
+
 static int sort_holes(void *priv, struct list_head *A, struct list_head *B)
 {
struct drm_mm_node *a = list_entry(A, typeof(*a), hole_stack);
@@ -504,11 +586,18 @@ static int igt_ggtt_fill(void *arg)
return exercise_ggtt(arg, fill_hole);
 }
 
+static int igt_ggtt_walk(void *arg)
+{
+   return exercise_ggtt(arg, walk_hole);
+}
+
 int i915_gem_gtt_live_selftests(struct drm_i915_private *i915)
 {
static const struct i915_subtest tests[] = {
SUBTEST(igt_ppgtt_alloc),
+   SUBTEST(igt_ppgtt_walk),
SUBTEST(igt_ppgtt_fill),
+   SUBTEST(igt_ggtt_walk),
SUBTEST(igt_ggtt_fill),
};
 
-- 
2.11.0

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


[Intel-gfx] [PATCH 40/46] drm/i915: Live testing for context execution

2017-02-02 Thread Chris Wilson
Check we can create and execution within a context.

v2: Write one set of dwords through each context/engine to exercise more
contexts within the same time period.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_gem_context.c|   1 +
 drivers/gpu/drm/i915/selftests/i915_gem_context.c  | 400 +
 .../gpu/drm/i915/selftests/i915_live_selftests.h   |   1 +
 3 files changed, 402 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_context.c

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index e6208e361356..baec4bbdffa6 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -1191,4 +1191,5 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device 
*dev,
 
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/mock_context.c"
+#include "selftests/i915_gem_context.c"
 #endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
new file mode 100644
index ..0e6ad1b3d3aa
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "../i915_selftest.h"
+
+#include "mock_drm.h"
+#include "huge_gem_object.h"
+
+#define DW_PER_PAGE (PAGE_SIZE / sizeof(u32))
+
+static struct i915_vma *
+gpu_fill_dw(struct i915_vma *vma, u64 offset, unsigned long count, u32 value)
+{
+   struct drm_i915_gem_object *obj;
+   const int gen = INTEL_GEN(vma->vm->i915);
+   unsigned long n;
+   u32 *cmd;
+   int err;
+
+   n = (4*count + 1)*sizeof(u32);
+   obj = i915_gem_object_create_internal(vma->vm->i915,
+ round_up(n, PAGE_SIZE));
+   if (IS_ERR(obj))
+   return ERR_CAST(obj);
+
+   cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);
+   if (IS_ERR(cmd)) {
+   err = PTR_ERR(cmd);
+   goto err;
+   }
+
+   GEM_BUG_ON(offset + (count - 1) * PAGE_SIZE > vma->node.size);
+   offset += vma->node.start;
+
+   for (n = 0; n < count; n++) {
+   if (gen >= 8) {
+   *cmd++ = MI_STORE_DWORD_IMM_GEN4;
+   *cmd++ = lower_32_bits(offset);
+   *cmd++ = upper_32_bits(offset);
+   *cmd++ = value;
+   } else if (gen >= 4) {
+   *cmd++ = MI_STORE_DWORD_IMM_GEN4 |
+   (gen < 6 ? 1 << 22 : 0);
+   *cmd++ = 0;
+   *cmd++ = offset;
+   *cmd++ = value;
+   } else {
+   *cmd++ = MI_STORE_DWORD_IMM | 1 << 22;
+   *cmd++ = offset;
+   *cmd++ = value;
+   }
+   offset += PAGE_SIZE;
+   }
+   *cmd = MI_BATCH_BUFFER_END;
+   wmb();
+   i915_gem_object_unpin_map(obj);
+
+   err = i915_gem_object_set_to_gtt_domain(obj, false);
+   if (err)
+   goto err;
+
+   vma = i915_vma_instance(obj, vma->vm, NULL);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto err;
+   }
+
+   err = i915_vma_pin(vma, 0, 0, PIN_USER);
+   if (err)
+   goto err;
+
+   return vma;
+
+err:
+   i915_gem_object_put(obj);
+   return ERR_PTR(err);
+}
+
+static unsigned long real_page_count(struct drm_i915_gem_object *obj)
+{
+   return huge_gem_object_phys_size(obj) >> PAGE_SHIFT;
+}
+
+static unsigned long fake_page_count(struct drm_i915_gem_object *obj)
+{
+   return huge_gem_object_dma_size(obj) >> PAGE_SHIFT;
+}
+
+static int gpu_fill(struct drm_i915_gem_object *obj,
+   struct i915_gem_context *ct

[Intel-gfx] [PATCH 29/46] drm/i915: Add some mock tests for dmabuf interop

2017-02-02 Thread Chris Wilson
Check that we can create both dmabuf and objects from dmabuf.

v2: Cleanups, correct include, fix unpin on dead path and prevent
explosion on dmabuf init failure

Signed-off-by: Chris Wilson 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |   5 +
 drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c   | 294 +
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |   1 +
 drivers/gpu/drm/i915/selftests/mock_dmabuf.c   | 176 
 drivers/gpu/drm/i915/selftests/mock_dmabuf.h   |  41 +++
 5 files changed, 517 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_dmabuf.h

diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index d037adcda6f2..3e276eee0450 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -307,3 +307,8 @@ struct drm_gem_object *i915_gem_prime_import(struct 
drm_device *dev,
 
return ERR_PTR(ret);
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/mock_dmabuf.c"
+#include "selftests/i915_gem_dmabuf.c"
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c
new file mode 100644
index ..a2393fcf9fa8
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "../i915_selftest.h"
+
+#include "mock_gem_device.h"
+#include "mock_dmabuf.h"
+
+static int igt_dmabuf_export(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_object *obj;
+   struct dma_buf *dmabuf;
+
+   obj = i915_gem_object_create(i915, PAGE_SIZE);
+   if (IS_ERR(obj))
+   return PTR_ERR(obj);
+
+   dmabuf = i915_gem_prime_export(&i915->drm, &obj->base, 0);
+   i915_gem_object_put(obj);
+   if (IS_ERR(dmabuf)) {
+   pr_err("i915_gem_prime_export failed with err=%d\n",
+  (int)PTR_ERR(dmabuf));
+   return PTR_ERR(dmabuf);
+   }
+
+   dma_buf_put(dmabuf);
+   return 0;
+}
+
+static int igt_dmabuf_import_self(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_object *obj;
+   struct drm_gem_object *import;
+   struct dma_buf *dmabuf;
+   int err;
+
+   obj = i915_gem_object_create(i915, PAGE_SIZE);
+   if (IS_ERR(obj))
+   return PTR_ERR(obj);
+
+   dmabuf = i915_gem_prime_export(&i915->drm, &obj->base, 0);
+   if (IS_ERR(dmabuf)) {
+   pr_err("i915_gem_prime_export failed with err=%d\n",
+  (int)PTR_ERR(dmabuf));
+   err = PTR_ERR(dmabuf);
+   goto out;
+   }
+
+   import = i915_gem_prime_import(&i915->drm, dmabuf);
+   if (IS_ERR(import)) {
+   pr_err("i915_gem_prime_import failed with err=%d\n",
+  (int)PTR_ERR(import));
+   err = PTR_ERR(import);
+   goto out_dmabuf;
+   }
+
+   if (import != &obj->base) {
+   pr_err("i915_gem_prime_import created a new object!\n");
+   err = -EINVAL;
+   goto out_import;
+   }
+
+   err = 0;
+out_import:
+   i915_gem_object_put(to_intel_bo(import));
+out_dmabuf:
+   dma_buf_put(dmabuf);
+out:
+   i915_gem_object_put(obj);
+   return err;
+}
+
+static int igt_dmabuf_import(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_object *obj;
+   struct dma_buf *dmabuf;
+   void *obj_map, *dma_map;
+   u32 pattern[] = { 0, 0xaa, 0xcc, 0x55, 0xff };
+   int err, i;
+
+  

[Intel-gfx] [PATCH 30/46] drm/i915: Add a live dmabuf selftest

2017-02-02 Thread Chris Wilson
Though we have good coverage of our dmabuf interface through the mock
tests, we also want to check the heavy module unload paths of the live
i915 driver.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c | 9 +
 drivers/gpu/drm/i915/selftests/i915_live_selftests.h | 1 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c
index a2393fcf9fa8..817bef74bbcb 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c
@@ -292,3 +292,12 @@ int i915_gem_dmabuf_mock_selftests(void)
drm_dev_unref(&i915->drm);
return err;
 }
+
+int i915_gem_dmabuf_live_selftests(struct drm_i915_private *i915)
+{
+   static const struct i915_subtest tests[] = {
+   SUBTEST(igt_dmabuf_export),
+   };
+
+   return i915_subtests(tests, i915);
+}
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h 
b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index c060bf24928e..1d26ca1f8bc8 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -12,4 +12,5 @@ selftest(sanitycheck, i915_live_sanitycheck) /* keep first 
(igt selfcheck) */
 selftest(uncore, intel_uncore_live_selftests)
 selftest(requests, i915_gem_request_live_selftests)
 selftest(object, i915_gem_object_live_selftests)
+selftest(dmabuf, i915_gem_dmabuf_live_selftests)
 selftest(coherency, i915_gem_coherency_live_selftests)
-- 
2.11.0

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


[Intel-gfx] [PATCH 23/46] drm/i915: Test partial mappings

2017-02-02 Thread Chris Wilson
Create partial mappings to cover a large object, investigating tiling
(fenced regions) and VMA reuse.

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

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
index d7330db70063..140bae2c8ad2 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
@@ -140,6 +140,298 @@ static int igt_gem_huge(void *arg)
return err;
 }
 
+struct tile {
+   unsigned int width;
+   unsigned int height;
+   unsigned int stride;
+   unsigned int size;
+   unsigned int tiling;
+   unsigned int swizzle;
+};
+
+static u64 swizzle_bit(unsigned int bit, u64 offset)
+{
+   return (offset & BIT_ULL(bit)) >> (bit - 6);
+}
+
+static u64 tiled_offset(const struct tile *tile, u64 v)
+{
+   u64 x, y;
+
+   if (tile->tiling == I915_TILING_NONE)
+   return v;
+
+   y = div64_u64_rem(v, tile->stride, &x);
+   v = div64_u64_rem(y, tile->height, &y) * tile->stride * tile->height;
+
+   if (tile->tiling == I915_TILING_X) {
+   v += y * tile->width;
+   v += div64_u64_rem(x, tile->width, &x) << tile->size;
+   v += x;
+   } else {
+   const unsigned int ytile_span = 16;
+   const unsigned int ytile_height = 32 * ytile_span;
+
+   v += y * ytile_span;
+   v += div64_u64_rem(x, ytile_span, &x) * ytile_height;
+   v += x;
+   }
+
+   switch (tile->swizzle) {
+   case I915_BIT_6_SWIZZLE_9:
+   v ^= swizzle_bit(9, v);
+   break;
+   case I915_BIT_6_SWIZZLE_9_10:
+   v ^= swizzle_bit(9, v) ^ swizzle_bit(10, v);
+   break;
+   case I915_BIT_6_SWIZZLE_9_11:
+   v ^= swizzle_bit(9, v) ^ swizzle_bit(11, v);
+   break;
+   case I915_BIT_6_SWIZZLE_9_10_11:
+   v ^= swizzle_bit(9, v) ^ swizzle_bit(10, v) ^ swizzle_bit(11, 
v);
+   break;
+   }
+
+   return v;
+}
+
+static int check_partial_mapping(struct drm_i915_gem_object *obj,
+const struct tile *tile,
+unsigned long end_time)
+{
+   const unsigned int nreal = obj->scratch / PAGE_SIZE;
+   const unsigned long npages = obj->base.size / PAGE_SIZE;
+   struct i915_vma *vma;
+   unsigned long page;
+   int err;
+
+   if (igt_timeout(end_time,
+   "%s: timed out before tiling=%d stride=%d\n",
+   __func__, tile->tiling, tile->stride))
+   return -EINTR;
+
+   err = i915_gem_object_set_tiling(obj, tile->tiling, tile->stride);
+   if (err)
+   return err;
+
+   GEM_BUG_ON(i915_gem_object_get_tiling(obj) != tile->tiling);
+   GEM_BUG_ON(i915_gem_object_get_stride(obj) != tile->stride);
+
+   for_each_prime_number_from(page, 1, npages) {
+   struct i915_ggtt_view view =
+   compute_partial_view(obj, page, MIN_CHUNK_PAGES);
+   u32 __iomem *io;
+   struct page *p;
+   unsigned int n;
+   u64 offset;
+   u32 *cpu;
+
+   GEM_BUG_ON(view.partial.size > nreal);
+
+   err = i915_gem_object_set_to_gtt_domain(obj, true);
+   if (err)
+   return err;
+
+   vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE);
+   if (IS_ERR(vma)) {
+   pr_err("Failed to pin partial view: offset=%lu\n",
+  page);
+   return PTR_ERR(vma);
+   }
+
+   n = page - view.partial.offset;
+   GEM_BUG_ON(n >= view.partial.size);
+
+   io = i915_vma_pin_iomap(vma);
+   i915_vma_unpin(vma);
+   if (IS_ERR(io)) {
+   pr_err("Failed to iomap partial view: offset=%lu\n",
+  page);
+   return PTR_ERR(io);
+   }
+
+   err = i915_vma_get_fence(vma);
+   if (err) {
+   pr_err("Failed to get fence for partial view: 
offset=%lu\n",
+  page);
+   i915_vma_unpin_iomap(vma);
+   return err;
+   }
+
+   iowrite32(page, io + n * PAGE_SIZE/sizeof(*io));
+   i915_vma_unpin_iomap(vma);
+
+   offset = tiled_offset(tile, page << PAGE_SHIFT);
+   if (offset >= obj->base.size)
+   continue;
+
+   i915_gem_object_flush_gtt_write_domain(obj);
+
+   p = i915_gem_object_get_page(obj, offset >> PAGE_SHIFT);
+   

[Intel-gfx] [PATCH 35/46] drm/i915: Exercise filling and removing random ranges from the live GTT

2017-02-02 Thread Chris Wilson
Test the low-level i915_address_space interfaces to sanity check the
live insertion/removal of address ranges.

Signed-off-by: Chris Wilson 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 93 +++
 1 file changed, 93 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 7d695cdcd20a..abde71d857e0 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -26,6 +26,7 @@
 #include 
 
 #include "../i915_selftest.h"
+#include "i915_random.h"
 
 #include "mock_drm.h"
 
@@ -485,6 +486,86 @@ static int walk_hole(struct drm_i915_private *i915,
return 0;
 }
 
+static int drunk_hole(struct drm_i915_private *i915,
+ struct i915_address_space *vm,
+ u64 hole_start, u64 hole_end,
+ unsigned long end_time)
+{
+   I915_RND_STATE(seed_prng);
+   unsigned int size;
+
+   /* Keep creating larger objects until one cannot fit into the hole */
+   for (size = 12; (hole_end - hole_start) >> size; size++) {
+   I915_RND_SUBSTATE(prng, seed_prng);
+   struct drm_i915_gem_object *obj;
+   unsigned int *order, count, n;
+   u64 hole_size;
+
+   hole_size = (hole_end - hole_start) >> size;
+   if (hole_size > KMALLOC_MAX_SIZE / sizeof(u32))
+   hole_size = KMALLOC_MAX_SIZE / sizeof(u32);
+   count = hole_size;
+   do {
+   count >>= 1;
+   order = i915_random_order(count, &prng);
+   } while (!order && count);
+   if (!order)
+   break;
+
+   /* Ignore allocation failures (i.e. don't report them as
+* a test failure) as we are purposefully allocating very
+* large objects without checking that we have sufficient
+* memory. We expect to hit -ENOMEM.
+*/
+
+   obj = fake_dma_object(i915, BIT_ULL(size));
+   if (IS_ERR(obj)) {
+   kfree(order);
+   break;
+   }
+
+   GEM_BUG_ON(obj->base.size != BIT_ULL(size));
+
+   if (i915_gem_object_pin_pages(obj)) {
+   i915_gem_object_put(obj);
+   kfree(order);
+   break;
+   }
+
+   for (n = 0; n < count; n++) {
+   if (vm->allocate_va_range &&
+   vm->allocate_va_range(vm,
+ order[n] * BIT_ULL(size),
+ BIT_ULL(size)))
+   break;
+
+   vm->insert_entries(vm, obj->mm.pages,
+  order[n] * BIT_ULL(size),
+  I915_CACHE_NONE, 0);
+   if (igt_timeout(end_time,
+   "%s timed out after %d/%d\n",
+   __func__, n, count)) {
+   hole_start = hole_end; /* quit */
+   break;
+   }
+   }
+   count = n;
+
+   i915_random_reorder(order, count, &prng);
+   for (n = 0; n < count; n++)
+   vm->clear_range(vm,
+   order[n] * BIT_ULL(size),
+   BIT_ULL(size));
+
+   i915_gem_object_unpin_pages(obj);
+   i915_gem_object_put(obj);
+
+   kfree(order);
+   }
+
+   return 0;
+}
+
 static int exercise_ppgtt(struct drm_i915_private *dev_priv,
  int (*func)(struct drm_i915_private *i915,
  struct i915_address_space *vm,
@@ -532,6 +613,11 @@ static int igt_ppgtt_walk(void *arg)
return exercise_ppgtt(arg, walk_hole);
 }
 
+static int igt_ppgtt_drunk(void *arg)
+{
+   return exercise_ppgtt(arg, drunk_hole);
+}
+
 static int sort_holes(void *priv, struct list_head *A, struct list_head *B)
 {
struct drm_mm_node *a = list_entry(A, typeof(*a), hole_stack);
@@ -591,12 +677,19 @@ static int igt_ggtt_walk(void *arg)
return exercise_ggtt(arg, walk_hole);
 }
 
+static int igt_ggtt_drunk(void *arg)
+{
+   return exercise_ggtt(arg, drunk_hole);
+}
+
 int i915_gem_gtt_live_selftests(struct drm_i915_private *i915)
 {
static const struct i915_subtest tests[] = {
SUBTEST(igt_ppgtt_alloc),
+   SUBTEST(igt_ppgtt_drunk),
SUBTEST(igt_ppgtt_walk),
SUBTEST(igt_ppgtt_fill),
+   SUBTEST(igt_ggtt_drunk),
SUBTEST(igt_ggtt_walk),
  

[Intel-gfx] [PATCH 38/46] drm/i915: Verify page layout for rotated VMA

2017-02-02 Thread Chris Wilson
Exercise creating rotated VMA and checking the page order within.

v2: Be more creative in rotated params

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

diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c 
b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 095d8348f5f0..4a737a670199 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -352,11 +352,190 @@ static int igt_vma_pin1(void *arg)
return err;
 }
 
+static unsigned long rotated_index(const struct intel_rotation_info *r,
+  unsigned int n,
+  unsigned int x,
+  unsigned int y)
+{
+   return (r->plane[n].stride * (r->plane[n].height - y - 1) +
+   r->plane[n].offset + x);
+}
+
+static struct scatterlist *
+assert_rotated(struct drm_i915_gem_object *obj,
+  const struct intel_rotation_info *r, unsigned int n,
+  struct scatterlist *sg)
+{
+   unsigned int x, y;
+
+   for (x = 0; x < r->plane[n].width; x++) {
+   for (y = 0; y < r->plane[n].height; y++) {
+   unsigned long src_idx;
+   dma_addr_t src;
+
+   if (!sg) {
+   pr_err("Invalid sg table: too short at plane 
%d, (%d, %d)!\n",
+  n, x, y);
+   return ERR_PTR(-EINVAL);
+   }
+
+   src_idx = rotated_index(r, n, x, y);
+   src = i915_gem_object_get_dma_address(obj, src_idx);
+
+   if (sg_dma_len(sg) != PAGE_SIZE) {
+   pr_err("Invalid sg.length, found %d, expected 
%lu for rotated page (%d, %d) [src index %lu]\n",
+  sg_dma_len(sg), PAGE_SIZE,
+  x, y, src_idx);
+   return ERR_PTR(-EINVAL);
+   }
+
+   if (sg_dma_address(sg) != src) {
+   pr_err("Invalid address for rotated page (%d, 
%d) [src index %lu]\n",
+  x, y, src_idx);
+   return ERR_PTR(-EINVAL);
+   }
+
+   sg = sg_next(sg);
+   }
+   }
+
+   return sg;
+}
+
+static unsigned int rotated_size(const struct intel_rotation_plane_info *a,
+const struct intel_rotation_plane_info *b)
+{
+   return a->width * a->height + b->width * b->height;
+}
+
+static int igt_vma_rotate(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct i915_address_space *vm = &i915->ggtt.base;
+   struct drm_i915_gem_object *obj;
+   const struct intel_rotation_plane_info planes[] = {
+   { .width = 1, .height = 1, .stride = 1 },
+   { .width = 2, .height = 2, .stride = 2 },
+   { .width = 4, .height = 4, .stride = 4 },
+   { .width = 8, .height = 8, .stride = 8 },
+
+   { .width = 3, .height = 5, .stride = 3 },
+   { .width = 3, .height = 5, .stride = 4 },
+   { .width = 3, .height = 5, .stride = 5 },
+
+   { .width = 5, .height = 3, .stride = 5 },
+   { .width = 5, .height = 3, .stride = 7 },
+   { .width = 5, .height = 3, .stride = 9 },
+
+   { .width = 4, .height = 6, .stride = 6 },
+   { .width = 6, .height = 4, .stride = 6 },
+   { }
+   }, *a, *b;
+   const unsigned int max_pages = 64;
+   int err = -ENOMEM;
+
+   /* Create VMA for many different combinations of planes and check
+* that the page layout within the rotated VMA match our expectations.
+*/
+
+   obj = i915_gem_object_create_internal(i915, max_pages * PAGE_SIZE);
+   if (IS_ERR(obj))
+   goto out;
+
+   for (a = planes; a->width; a++) {
+   for (b = planes + ARRAY_SIZE(planes); b-- != planes; ) {
+   struct i915_ggtt_view view;
+   unsigned int n, max_offset;
+
+   max_offset = max(a->stride * a->height,
+b->stride * b->height);
+   GEM_BUG_ON(max_offset > max_pages);
+   max_offset = max_pages - max_offset;
+
+   view.type = I915_GGTT_VIEW_ROTATED;
+   view.rotated.plane[0] = *a;
+   view.rotated.plane[1] = *b;
+
+   
for_each_prime_number_from(view.rotated.plane[0].offset, 0, max_offset) {
+   
for_each_prime_number_from(view.rotated.plane[1].offset, 0, max_offset) {
+   struct scat

[Intel-gfx] [PATCH 37/46] drm/i915: Exercise i915_vma_pin/i915_vma_insert

2017-02-02 Thread Chris Wilson
High-level testing of the struct drm_mm by verifying our handling of
weird requests to i915_vma_pin.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/i915_vma.c   |   4 +-
 drivers/gpu/drm/i915/i915_vma.h   |   4 +-
 drivers/gpu/drm/i915/selftests/i915_vma.c | 151 ++
 3 files changed, 155 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 5c32d12b2d8d..341c3f82ec1f 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -324,8 +324,8 @@ void i915_vma_unpin_and_release(struct i915_vma **p_vma)
__i915_gem_object_release_unless_active(obj);
 }
 
-bool
-i915_vma_misplaced(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
+bool i915_vma_misplaced(const struct i915_vma *vma,
+   u64 size, u64 alignment, u64 flags)
 {
if (!drm_mm_node_allocated(&vma->node))
return false;
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index e39d922cfb6f..2e03f81dddbe 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -228,8 +228,8 @@ i915_vma_compare(struct i915_vma *vma,
 int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
  u32 flags);
 bool i915_gem_valid_gtt_space(struct i915_vma *vma, unsigned long cache_level);
-bool
-i915_vma_misplaced(struct i915_vma *vma, u64 size, u64 alignment, u64 flags);
+bool i915_vma_misplaced(const struct i915_vma *vma,
+   u64 size, u64 alignment, u64 flags);
 void __i915_vma_set_map_and_fenceable(struct i915_vma *vma);
 int __must_check i915_vma_unbind(struct i915_vma *vma);
 void i915_vma_close(struct i915_vma *vma);
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c 
b/drivers/gpu/drm/i915/selftests/i915_vma.c
index e60f3a962f56..095d8348f5f0 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -202,10 +202,161 @@ static int igt_vma_create(void *arg)
return err;
 }
 
+struct pin_mode {
+   u64 size;
+   u64 flags;
+   bool (*assert)(const struct i915_vma *,
+  const struct pin_mode *mode,
+  int result);
+   const char *string;
+};
+
+static bool assert_pin_valid(const struct i915_vma *vma,
+const struct pin_mode *mode,
+int result)
+{
+   if (result)
+   return false;
+
+   if (i915_vma_misplaced(vma, mode->size, 0, mode->flags))
+   return false;
+
+   return true;
+}
+
+__maybe_unused
+static bool assert_pin_e2big(const struct i915_vma *vma,
+const struct pin_mode *mode,
+int result)
+{
+   return result == -E2BIG;
+}
+
+__maybe_unused
+static bool assert_pin_enospc(const struct i915_vma *vma,
+ const struct pin_mode *mode,
+ int result)
+{
+   return result == -ENOSPC;
+}
+
+__maybe_unused
+static bool assert_pin_einval(const struct i915_vma *vma,
+ const struct pin_mode *mode,
+ int result)
+{
+   return result == -EINVAL;
+}
+
+static int igt_vma_pin1(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   const struct pin_mode modes[] = {
+#define VALID(sz, fl) { .size = (sz), .flags = (fl), .assert = 
assert_pin_valid, .string = #sz ", " #fl ", (valid) " }
+#define __INVALID(sz, fl, check, eval) { .size = (sz), .flags = (fl), .assert 
= (check), .string = #sz ", " #fl ", (invalid " #eval ")" }
+#define INVALID(sz, fl) __INVALID(sz, fl, assert_pin_einval, EINVAL)
+#define TOOBIG(sz, fl) __INVALID(sz, fl, assert_pin_e2big, E2BIG)
+#define NOSPACE(sz, fl) __INVALID(sz, fl, assert_pin_enospc, ENOSPC)
+   VALID(0, PIN_GLOBAL),
+   VALID(0, PIN_GLOBAL | PIN_MAPPABLE),
+
+   VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | 4096),
+   VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | 8192),
+   VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | 
(i915->ggtt.mappable_end - 4096)),
+   VALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | 
(i915->ggtt.mappable_end - 4096)),
+   VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | (i915->ggtt.base.total 
- 4096)),
+
+   VALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | 
(i915->ggtt.mappable_end - 4096)),
+   INVALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | 
i915->ggtt.mappable_end),
+   VALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | (i915->ggtt.base.total 
- 4096)),
+   INVALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | 
i915->ggtt.base.total),
+   INVALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | round_down(U64_MAX, 
PAGE_SIZE)),
+
+   VALID(4096, PIN_GLOBAL),
+   VALID(8192, P

[Intel-gfx] [PATCH 43/46] drm/i915: Add mock exercise for i915_gem_gtt_insert

2017-02-02 Thread Chris Wilson
i915_gem_gtt_insert should allocate from the available free space in the
GTT, evicting as necessary to create space.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 208 ++
 1 file changed, 208 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index f4b627eb63f6..c1c7a8837ffd 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -857,10 +857,218 @@ static int igt_gtt_reserve(void *arg)
return err;
 }
 
+static int igt_gtt_insert(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_object *obj, *on;
+   struct drm_mm_node tmp = {};
+   const struct invalid_insert {
+   u64 size;
+   u64 alignment;
+   u64 start, end;
+   } invalid_insert[] = {
+   {
+   i915->ggtt.base.total + I915_GTT_PAGE_SIZE, 0,
+   0, i915->ggtt.base.total,
+   },
+   {
+   2*I915_GTT_PAGE_SIZE, 0,
+   0, I915_GTT_PAGE_SIZE,
+   },
+   {
+   -(u64)I915_GTT_PAGE_SIZE, 0,
+   0, 4*I915_GTT_PAGE_SIZE,
+   },
+   {
+   -(u64)2*I915_GTT_PAGE_SIZE, 2*I915_GTT_PAGE_SIZE,
+   0, 4*I915_GTT_PAGE_SIZE,
+   },
+   {
+   I915_GTT_PAGE_SIZE, I915_GTT_MIN_ALIGNMENT << 1,
+   I915_GTT_MIN_ALIGNMENT, I915_GTT_MIN_ALIGNMENT << 1,
+   },
+   {}
+   }, *ii;
+   LIST_HEAD(objects);
+   u64 total;
+   int err;
+
+   /* i915_gem_gtt_insert() tries to allocate some free space in the GTT
+* to the node, evicting if required.
+*/
+
+   /* Check a couple of obviously invalid requests */
+   for (ii = invalid_insert; ii->size; ii++) {
+   err = i915_gem_gtt_insert(&i915->ggtt.base, &tmp,
+ ii->size, ii->alignment,
+ I915_COLOR_UNEVICTABLE,
+ ii->start, ii->end,
+ 0);
+   if (err != -ENOSPC) {
+   pr_err("Invalid i915_gem_gtt_insert(.size=%llx, 
.alignment=%llx, .start=%llx, .end=%llx) succeeded (err=%d)\n",
+  ii->size, ii->alignment, ii->start, ii->end,
+  err);
+   return -EINVAL;
+   }
+   }
+
+   /* Start by filling the GGTT */
+   for (total = 0;
+total + I915_GTT_PAGE_SIZE <= i915->ggtt.base.total;
+total += I915_GTT_PAGE_SIZE) {
+   struct i915_vma *vma;
+
+   obj = i915_gem_object_create_internal(i915, I915_GTT_PAGE_SIZE);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   goto out;
+   }
+
+   err = i915_gem_object_pin_pages(obj);
+   if (err) {
+   i915_gem_object_put(obj);
+   goto out;
+   }
+
+   list_add(&obj->batch_pool_link, &objects);
+
+   vma = i915_vma_instance(obj, &i915->ggtt.base, NULL);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto out;
+   }
+
+   err = i915_gem_gtt_insert(&i915->ggtt.base, &vma->node,
+ obj->base.size, 0, obj->cache_level,
+ 0, i915->ggtt.base.total,
+ 0);
+   if (err == -ENOSPC) {
+   /* maxed out the GGTT space */
+   i915_gem_object_put(obj);
+   break;
+   }
+   if (err) {
+   pr_err("i915_gem_gtt_insert (pass 1) failed at 
%llu/%llu with err=%d\n",
+  total, i915->ggtt.base.total, err);
+   goto out;
+   }
+   track_vma_bind(vma);
+   __i915_vma_pin(vma);
+
+   GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
+   }
+
+   list_for_each_entry(obj, &objects, batch_pool_link) {
+   struct i915_vma *vma;
+
+   vma = i915_vma_instance(obj, &i915->ggtt.base, NULL);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto out;
+   }
+
+   if (!drm_mm_node_allocated(&vma->node)) {
+   pr_err("VMA was unexpectedly evicted!\n");
+   err = -EINVAL;
+   goto out;
+   

[Intel-gfx] [PATCH 41/46] drm/i915: Initial selftests for exercising eviction

2017-02-02 Thread Chris Wilson
Very simple tests to just ask eviction to find some free space in a full
GTT and one with some available space.

Signed-off-by: Chris Wilson 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_gem_evict.c  |   4 +
 drivers/gpu/drm/i915/selftests/i915_gem_evict.c| 260 +
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |   1 +
 3 files changed, 265 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_evict.c

diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c 
b/drivers/gpu/drm/i915/i915_gem_evict.c
index c181b1bb3d2c..609a8fcb48ca 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -387,3 +387,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool 
do_idle)
 
return 0;
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/i915_gem_evict.c"
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
new file mode 100644
index ..97af353db218
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "../i915_selftest.h"
+
+#include "mock_gem_device.h"
+
+static int populate_ggtt(struct drm_i915_private *i915)
+{
+   struct drm_i915_gem_object *obj;
+   u64 size;
+
+   for (size = 0;
+size + I915_GTT_PAGE_SIZE <= i915->ggtt.base.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);
+
+   vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);
+   if (IS_ERR(vma))
+   return PTR_ERR(vma);
+   }
+
+   if (!list_empty(&i915->mm.unbound_list)) {
+   size = 0;
+   list_for_each_entry(obj, &i915->mm.unbound_list, global_link)
+   size++;
+
+   pr_err("Found %lld objects unbound!\n", size);
+   return -EINVAL;
+   }
+
+   if (list_empty(&i915->ggtt.base.inactive_list)) {
+   pr_err("No objects on the GGTT inactive list!\n");
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static void unpin_ggtt(struct drm_i915_private *i915)
+{
+   struct i915_vma *vma;
+
+   list_for_each_entry(vma, &i915->ggtt.base.inactive_list, vm_link)
+   i915_vma_unpin(vma);
+}
+
+static void cleanup_objects(struct drm_i915_private *i915)
+{
+   struct drm_i915_gem_object *obj, *on;
+
+   list_for_each_entry_safe(obj, on, &i915->mm.unbound_list, global_link)
+   i915_gem_object_put(obj);
+
+   list_for_each_entry_safe(obj, on, &i915->mm.bound_list, global_link)
+   i915_gem_object_put(obj);
+
+   mutex_unlock(&i915->drm.struct_mutex);
+
+   i915_gem_drain_freed_objects(i915);
+
+   mutex_lock(&i915->drm.struct_mutex);
+}
+
+static int igt_evict_something(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct i915_ggtt *ggtt = &i915->ggtt;
+   int err;
+
+   /* Fill the GGTT with pinned objects and try to evict one. */
+
+   err = populate_ggtt(i915);
+   if (err)
+   goto cleanup;
+
+   /* Everything is pinned, nothing should happen */
+   err = i915_gem_evict_something(&ggtt->base,
+  I915_GTT_PAGE_SIZE, 0, 0,
+  0, U64_MAX,
+  0);
+   if (err != -ENOSPC) {
+   pr_err("i915_gem_evict_something failed on a full GGTT with 
err=%d\n",
+  err);
+   goto cleanup;
+   }
+
+   unpin_ggtt(i915)

Re: [Intel-gfx] [PATCH 05/46] drm/i915: Provide a hook for selftests

2017-02-02 Thread Chris Wilson
On Thu, Feb 02, 2017 at 09:08:24AM +, Chris Wilson wrote:
> Some pieces of code are independent of hardware but are very tricky to
> exercise through the normal userspace ABI or via debugfs hooks. Being
> able to create mock unit tests and execute them through CI is vital.
> Start by adding a central point where we can execute unit tests and
> a parameter to enable them. This is disabled by default as the
> expectation is that these tests will occasionally explode.
> 
> To facilitate integration with igt, any parameter beginning with
> i915.igt__ is interpreted as a subtest executable independently via
> igt/drv_selftest.
> 
> Two classes of selftests are recognised: mock unit tests and integration
> tests. Mock unit tests are run as soon as the module is loaded, before
> the device is probed. At that point there is no driver instantiated and
> all hw interactions must be "mocked". This is very useful for writing
> universal tests to exercise code not typically run on a broad range of
> architectures. Alternatively, you can hook into the live selftests and
> run when the device has been instantiated - hw interactions are real.
> 
> v2: Add a macro for compiling conditional code for mock objects inside
> real objects.
> v3: Differentiate between mock unit tests and late integration test.
> v4: List the tests in natural order, use igt to sort after modparam.
> v5: s/late/live/
> v6: s/unsigned long/unsigned int/
> v7: Use igt_ prefixes for long helpers.
v8: Deobfuscate macros overriding functions, stop using -I$(src)

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


[Intel-gfx] [PATCH 46/46] drm/i915: Add initial selftests for hang detection and resets

2017-02-02 Thread Chris Wilson
Check that we can reset the GPU and continue executing from the next
request.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_drv.h|   4 +-
 drivers/gpu/drm/i915/intel_hangcheck.c |   4 +
 .../gpu/drm/i915/selftests/i915_live_selftests.h   |   1 +
 drivers/gpu/drm/i915/selftests/intel_hangcheck.c   | 531 +
 4 files changed, 538 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/selftests/intel_hangcheck.c

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4a7e4b10c0a9..f82c59768f65 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3356,8 +3356,8 @@ int __must_check i915_gem_init(struct drm_i915_private 
*dev_priv);
 int __must_check i915_gem_init_hw(struct drm_i915_private *dev_priv);
 void i915_gem_init_swizzling(struct drm_i915_private *dev_priv);
 void i915_gem_cleanup_engines(struct drm_i915_private *dev_priv);
-int __must_check i915_gem_wait_for_idle(struct drm_i915_private *dev_priv,
-   unsigned int flags);
+int i915_gem_wait_for_idle(struct drm_i915_private *dev_priv,
+  unsigned int flags);
 int __must_check i915_gem_suspend(struct drm_i915_private *dev_priv);
 void i915_gem_resume(struct drm_i915_private *dev_priv);
 int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
diff --git a/drivers/gpu/drm/i915/intel_hangcheck.c 
b/drivers/gpu/drm/i915/intel_hangcheck.c
index f05971f5586f..dce742243ba6 100644
--- a/drivers/gpu/drm/i915/intel_hangcheck.c
+++ b/drivers/gpu/drm/i915/intel_hangcheck.c
@@ -480,3 +480,7 @@ void intel_hangcheck_init(struct drm_i915_private *i915)
INIT_DELAYED_WORK(&i915->gpu_error.hangcheck_work,
  i915_hangcheck_elapsed);
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/intel_hangcheck.c"
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h 
b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index 15fb4e0dd503..d0d4f4bcd837 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -16,3 +16,4 @@ selftest(dmabuf, i915_gem_dmabuf_live_selftests)
 selftest(coherency, i915_gem_coherency_live_selftests)
 selftest(gtt, i915_gem_gtt_live_selftests)
 selftest(context, i915_gem_context_live_selftests)
+selftest(hangcheck, intel_hangcheck_live_selftests)
diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c 
b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
new file mode 100644
index ..2131d8707dfd
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "../i915_selftest.h"
+
+struct hang {
+   struct drm_i915_private *i915;
+   struct drm_i915_gem_object *hws;
+   struct drm_i915_gem_object *obj;
+   u32 *seqno;
+   u32 *batch;
+};
+
+static int hang_init(struct hang *h, struct drm_i915_private *i915)
+{
+   void *vaddr;
+   int err;
+
+   memset(h, 0, sizeof(*h));
+   h->i915 = i915;
+
+   h->hws = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(h->hws))
+   return PTR_ERR(h->hws);
+
+   h->obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(h->obj)) {
+   err = PTR_ERR(h->obj);
+   goto err_hws;
+   }
+
+   i915_gem_object_set_cache_level(h->hws, I915_CACHE_LLC);
+   vaddr = i915_gem_object_pin_map(h->hws, I915_MAP_WB);
+   if (IS_ERR(vaddr)) {
+   err = PTR_ERR(vaddr);
+   goto err_obj;
+   }
+   h->seqno = memset(vaddr, 0xff, PAGE_SIZE);
+
+   vaddr = i915_gem_object_pin_map(h->obj,
+ 

[Intel-gfx] [PATCH 45/46] drm/i915: Exercise manipulate of single pages in the GGTT

2017-02-02 Thread Chris Wilson
Move a single page of an object around within the GGTT and check
coherency of writes and reads.

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

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 7ec6fb2208a6..27e380a3bae5 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -684,6 +684,96 @@ static int igt_ggtt_drunk(void *arg)
return exercise_ggtt(arg, drunk_hole);
 }
 
+static int igt_ggtt_page(void *arg)
+{
+   const unsigned int count = PAGE_SIZE/sizeof(u32);
+   I915_RND_STATE(prng);
+   struct drm_i915_private *i915 = arg;
+   struct i915_ggtt *ggtt = &i915->ggtt;
+   struct drm_i915_gem_object *obj;
+   struct drm_mm_node tmp;
+   unsigned int *order, n;
+   int err;
+
+   mutex_lock(&i915->drm.struct_mutex);
+
+   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   goto out_unlock;
+   }
+
+   err = i915_gem_object_pin_pages(obj);
+   if (err)
+   goto out_free;
+
+   memset(&tmp, 0, sizeof(tmp));
+   err = drm_mm_insert_node_in_range(&ggtt->base.mm, &tmp,
+ 1024 * PAGE_SIZE, 0,
+ I915_COLOR_UNEVICTABLE,
+ 0, ggtt->mappable_end,
+ DRM_MM_INSERT_LOW);
+   if (err)
+   goto out_unpin;
+
+   order = i915_random_order(count, &prng);
+   if (!order) {
+   err = -ENOMEM;
+   goto out_remove;
+   }
+
+   for (n = 0; n < count; n++) {
+   u64 offset = tmp.start + order[n] * PAGE_SIZE;
+   u32 __iomem *vaddr;
+
+   ggtt->base.insert_page(&ggtt->base,
+  i915_gem_object_get_dma_address(obj, 0),
+  offset, I915_CACHE_NONE, 0);
+
+   vaddr = io_mapping_map_atomic_wc(&ggtt->mappable, offset);
+   iowrite32(n, vaddr + n);
+   io_mapping_unmap_atomic(vaddr);
+
+   wmb();
+   ggtt->base.clear_range(&ggtt->base, offset, PAGE_SIZE);
+   }
+
+   i915_random_reorder(order, count, &prng);
+   for (n = 0; n < count; n++) {
+   u64 offset = tmp.start + order[n] * PAGE_SIZE;
+   u32 __iomem *vaddr;
+   u32 val;
+
+   ggtt->base.insert_page(&ggtt->base,
+  i915_gem_object_get_dma_address(obj, 0),
+  offset, I915_CACHE_NONE, 0);
+
+   vaddr = io_mapping_map_atomic_wc(&ggtt->mappable, offset);
+   val = ioread32(vaddr + n);
+   io_mapping_unmap_atomic(vaddr);
+
+   ggtt->base.clear_range(&ggtt->base, offset, PAGE_SIZE);
+
+   if (val != n) {
+   pr_err("insert page failed: found %d, expected %d\n",
+  val, n);
+   err = -EINVAL;
+   break;
+   }
+   }
+
+   kfree(order);
+out_remove:
+   drm_mm_remove_node(&tmp);
+out_unpin:
+   i915_gem_object_unpin_pages(obj);
+out_free:
+   i915_gem_object_put(obj);
+out_unlock:
+   mutex_unlock(&i915->drm.struct_mutex);
+   return err;
+}
+
 static void track_vma_bind(struct i915_vma *vma)
 {
struct drm_i915_gem_object *obj = vma->obj;
@@ -1138,6 +1228,7 @@ int i915_gem_gtt_live_selftests(struct drm_i915_private 
*i915)
SUBTEST(igt_ggtt_drunk),
SUBTEST(igt_ggtt_walk),
SUBTEST(igt_ggtt_fill),
+   SUBTEST(igt_ggtt_page),
};
 
GEM_BUG_ON(offset_in_page(i915->ggtt.base.total));
-- 
2.11.0

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


[Intel-gfx] [PATCH 42/46] drm/i915: Add mock exercise for i915_gem_gtt_reserve

2017-02-02 Thread Chris Wilson
i915_gem_gtt_reserve should put the node exactly as requested in the
GTT, evicting as required.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c  | 195 +
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |   1 +
 2 files changed, 196 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index abde71d857e0..f4b627eb63f6 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -29,6 +29,7 @@
 #include "i915_random.h"
 
 #include "mock_drm.h"
+#include "mock_gem_device.h"
 
 static void fake_free_pages(struct drm_i915_gem_object *obj,
struct sg_table *pages)
@@ -682,6 +683,200 @@ static int igt_ggtt_drunk(void *arg)
return exercise_ggtt(arg, drunk_hole);
 }
 
+static void track_vma_bind(struct i915_vma *vma)
+{
+   struct drm_i915_gem_object *obj = vma->obj;
+
+   obj->bind_count++; /* track for eviction later */
+   __i915_gem_object_pin_pages(obj);
+
+   vma->pages = obj->mm.pages;
+   list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
+}
+
+static int igt_gtt_reserve(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_object *obj, *on;
+   LIST_HEAD(objects);
+   u64 total;
+   int err;
+
+   /* i915_gem_gtt_reserve() tries to reserve the precise range
+* for the node, and evicts if it has to. So our test checks that
+* it can give us the requsted space and prevent overlaps.
+*/
+
+   /* Start by filling the GGTT */
+   for (total = 0;
+total + 2*I915_GTT_PAGE_SIZE <= i915->ggtt.base.total;
+total += 2*I915_GTT_PAGE_SIZE) {
+   struct i915_vma *vma;
+
+   obj = i915_gem_object_create_internal(i915, 2*PAGE_SIZE);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   goto out;
+   }
+
+   err = i915_gem_object_pin_pages(obj);
+   if (err) {
+   i915_gem_object_put(obj);
+   goto out;
+   }
+
+   list_add(&obj->batch_pool_link, &objects);
+
+   vma = i915_vma_instance(obj, &i915->ggtt.base, NULL);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto out;
+   }
+
+   err = i915_gem_gtt_reserve(&i915->ggtt.base, &vma->node,
+  obj->base.size,
+  total,
+  obj->cache_level,
+  0);
+   if (err) {
+   pr_err("i915_gem_gtt_reserve (pass 1) failed at 
%llu/%llu with err=%d\n",
+  total, i915->ggtt.base.total, err);
+   goto out;
+   }
+   track_vma_bind(vma);
+
+   GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
+   if (vma->node.start != total ||
+   vma->node.size != 2*I915_GTT_PAGE_SIZE) {
+   pr_err("i915_gem_gtt_reserve (pass 1) placement failed, 
found (%llx + %llx), expected (%llx + %lx)\n",
+  vma->node.start, vma->node.size,
+  total, 2*I915_GTT_PAGE_SIZE);
+   err = -EINVAL;
+   goto out;
+   }
+   }
+
+   /* Now we start forcing evictions */
+   for (total = I915_GTT_PAGE_SIZE;
+total + 2*I915_GTT_PAGE_SIZE <= i915->ggtt.base.total;
+total += 2*I915_GTT_PAGE_SIZE) {
+   struct i915_vma *vma;
+
+   obj = i915_gem_object_create_internal(i915, 2*PAGE_SIZE);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   goto out;
+   }
+
+   err = i915_gem_object_pin_pages(obj);
+   if (err) {
+   i915_gem_object_put(obj);
+   goto out;
+   }
+
+   list_add(&obj->batch_pool_link, &objects);
+
+   vma = i915_vma_instance(obj, &i915->ggtt.base, NULL);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto out;
+   }
+
+   err = i915_gem_gtt_reserve(&i915->ggtt.base, &vma->node,
+  obj->base.size,
+  total,
+  obj->cache_level,
+  0);
+   if (err) {
+   pr_err("i915_gem_gtt_reserve (pass 2) failed at 
%llu/%llu with err=%d\n",
+  total, i915->ggtt.base.tot

[Intel-gfx] [PATCH 44/46] drm/i915: Add mock tests for GTT/VMA handling

2017-02-02 Thread Chris Wilson
Use the live tests against the mock ppgtt for quick testing on all
platforms of the VMA layer.

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

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index c1c7a8837ffd..7ec6fb2208a6 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -28,6 +28,7 @@
 #include "../i915_selftest.h"
 #include "i915_random.h"
 
+#include "mock_context.h"
 #include "mock_drm.h"
 #include "mock_gem_device.h"
 
@@ -694,6 +695,45 @@ static void track_vma_bind(struct i915_vma *vma)
list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
 }
 
+static int exercise_mock(struct drm_i915_private *i915,
+int (*func)(struct drm_i915_private *i915,
+struct i915_address_space *vm,
+u64 hole_start, u64 hole_end,
+unsigned long end_time))
+{
+   struct i915_gem_context *ctx;
+   struct i915_hw_ppgtt *ppgtt;
+   IGT_TIMEOUT(end_time);
+   int err;
+
+   ctx = mock_context(i915, "mock");
+   if (!ctx)
+   return -ENOMEM;
+
+   ppgtt = ctx->ppgtt;
+   GEM_BUG_ON(!ppgtt);
+
+   err = func(i915, &ppgtt->base, 0, ppgtt->base.total, end_time);
+
+   mock_context_close(ctx);
+   return err;
+}
+
+static int igt_mock_fill(void *arg)
+{
+   return exercise_mock(arg, fill_hole);
+}
+
+static int igt_mock_walk(void *arg)
+{
+   return exercise_mock(arg, walk_hole);
+}
+
+static int igt_mock_drunk(void *arg)
+{
+   return exercise_mock(arg, drunk_hole);
+}
+
 static int igt_gtt_reserve(void *arg)
 {
struct drm_i915_private *i915 = arg;
@@ -1067,6 +1107,9 @@ static int igt_gtt_insert(void *arg)
 int i915_gem_gtt_mock_selftests(void)
 {
static const struct i915_subtest tests[] = {
+   SUBTEST(igt_mock_drunk),
+   SUBTEST(igt_mock_walk),
+   SUBTEST(igt_mock_fill),
SUBTEST(igt_gtt_reserve),
SUBTEST(igt_gtt_insert),
};
-- 
2.11.0

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


[Intel-gfx] [PATCH igt] intel-ci: Add all driver selftests to BAT

2017-02-02 Thread Chris Wilson
These are meant to be fast and sensitive to new (and old) bugs...

Signed-off-by: Chris Wilson 
Cc: Petri Latvala 
---
 tests/intel-ci/fast-feedback.testlist | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/tests/intel-ci/fast-feedback.testlist 
b/tests/intel-ci/fast-feedback.testlist
index 828bd3ff..a0c3f848 100644
--- a/tests/intel-ci/fast-feedback.testlist
+++ b/tests/intel-ci/fast-feedback.testlist
@@ -249,4 +249,23 @@ igt@drv_module_reload@basic-reload
 igt@drv_module_reload@basic-no-display
 igt@drv_module_reload@basic-reload-inject
 igt@drv_module_reload@basic-reload-final
+igt@drv_selftest@mock_sanitycheck
+igt@drv_selftest@mock_scatterlist
+igt@drv_selftest@mock_uncore
+igt@drv_selftest@mock_breadcrumbs
+igt@drv_selftest@mock_requests
+igt@drv_selftest@mock_objects
+igt@drv_selftest@mock_dmabuf
+igt@drv_selftest@mock_vma
+igt@drv_selftest@mock_evict
+igt@drv_selftest@mock_gtt
+igt@drv_selftest@live_sanitycheck
+igt@drv_selftest@live_uncore
+igt@drv_selftest@live_requests
+igt@drv_selftest@live_object
+igt@drv_selftest@live_dmabuf
+igt@drv_selftest@live_coherency
+igt@drv_selftest@live_gtt
+igt@drv_selftest@live_context
+igt@drv_selftest@live_hangcheck
 igt@gvt_basic@invalid-placeholder-test
-- 
2.11.0

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


Re: [Intel-gfx] [PATCH 01/46] drm: Provide a driver hook for drm_dev_release()

2017-02-02 Thread Laurent Pinchart
Hi Chris,

Thank you for the patch.

On Thursday 02 Feb 2017 09:08:20 Chris Wilson wrote:
> Some state is coupled into the device lifetime outside of the
> load/unload timeframe and requires teardown during final unreference
> from drm_dev_release(). For example, dmabufs hold both a device and
> module reference and may live longer than expected (i.e. the current
> pattern of the driver tearing down its state and then releasing a
> reference to the drm device) and yet touch driver private state when
> destroyed.
> 
> v2: Export drm_dev_fini() and move the responsibility for finalizing the
> drm_device and freeing it to the release callback. (If no callback is
> provided, the core will call drm_dev_fini() and kfree(dev) as before.)
> v3: Remember to add drm_dev_fini() to drm_drv.h
> v4: Tidy language for kerneldoc
> v5: Cross reference from drm_dev_init() to note that driver->release()
> allows for arbitrary embedding.
> 
> Signed-off-by: Chris Wilson 
> Cc: Laurent Pinchart 
> Cc: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_drv.c | 65 ++--
>  include/drm/drm_drv.h | 13 ++
>  2 files changed, 58 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index a8ce3179c07c..fe611d601916 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -465,7 +465,10 @@ static void drm_fs_inode_free(struct inode *inode)
>   * that do embed &struct drm_device it must be placed first in the overall
>   * structure, and the overall structure must be allocated using kmalloc():
> The * drm core's release function unconditionally calls kfree() on the @dev
> pointer - * when the final reference is released.
> + * when the final reference is released. To override this behaviour, and so
> + * allow embedding of the drm_device inside the driver's device struct at
> an + * arbitrary offset, you must supply a driver->release() callback and
> control + * the finalization explicitly.
>   *
>   * RETURNS:
>   * 0 on success, or error code on failure.
> @@ -553,6 +556,41 @@ int drm_dev_init(struct drm_device *dev,
>  EXPORT_SYMBOL(drm_dev_init);
> 
>  /**
> + * drm_dev_fini - Finalize a dead DRM device
> + * @dev: DRM device
> + *
> + * Finalize a dead DRM device. This is the converse to drm_dev_init() and
> + * frees up all state allocated by it. All driver state should be finalized
> + * first. Note that this function does not free the @dev, that is left to
> the + * caller.
> + *
> + * The ref-count of @dev must be zero, and drm_dev_fini() should only be
> called + * from a drm_driver->release() callback.
> + */
> +void drm_dev_fini(struct drm_device *dev)
> +{
> + drm_vblank_cleanup(dev);
> +
> + if (drm_core_check_feature(dev, DRIVER_GEM))
> + drm_gem_destroy(dev);
> +
> + drm_legacy_ctxbitmap_cleanup(dev);
> + drm_ht_remove(&dev->map_hash);
> + drm_fs_inode_free(dev->anon_inode);
> +
> + drm_minor_free(dev, DRM_MINOR_PRIMARY);
> + drm_minor_free(dev, DRM_MINOR_RENDER);
> + drm_minor_free(dev, DRM_MINOR_CONTROL);
> +
> + mutex_destroy(&dev->master_mutex);
> + mutex_destroy(&dev->ctxlist_mutex);
> + mutex_destroy(&dev->filelist_mutex);
> + mutex_destroy(&dev->struct_mutex);
> + kfree(dev->unique);
> +}
> +EXPORT_SYMBOL(drm_dev_fini);
> +
> +/**
>   * drm_dev_alloc - Allocate new DRM device
>   * @driver: DRM driver to allocate device for
>   * @parent: Parent device object
> @@ -598,25 +636,12 @@ static void drm_dev_release(struct kref *ref)
>  {
>   struct drm_device *dev = container_of(ref, struct drm_device, ref);
> 
> - drm_vblank_cleanup(dev);
> -
> - if (drm_core_check_feature(dev, DRIVER_GEM))
> - drm_gem_destroy(dev);
> -
> - drm_legacy_ctxbitmap_cleanup(dev);
> - drm_ht_remove(&dev->map_hash);
> - drm_fs_inode_free(dev->anon_inode);
> -
> - drm_minor_free(dev, DRM_MINOR_PRIMARY);
> - drm_minor_free(dev, DRM_MINOR_RENDER);
> - drm_minor_free(dev, DRM_MINOR_CONTROL);
> -
> - mutex_destroy(&dev->master_mutex);
> - mutex_destroy(&dev->ctxlist_mutex);
> - mutex_destroy(&dev->filelist_mutex);
> - mutex_destroy(&dev->struct_mutex);
> - kfree(dev->unique);
> - kfree(dev);
> + if (dev->driver->release) {
> + dev->driver->release(dev);
> + } else {
> + drm_dev_fini(dev);
> + kfree(dev);
> + }
>  }
> 
>  /**
> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> index 732e85652d1e..d0d2fa83d06c 100644
> --- a/include/drm/drm_drv.h
> +++ b/include/drm/drm_drv.h
> @@ -102,6 +102,17 @@ struct drm_driver {
>*
>*/
>   void (*unload) (struct drm_device *);
> +
> + /**
> +  * @release:
> +  *
> +  * Optional callback for destroying device state after the final

Nitpicking, I'd talk about "device data" or "device memory" instead of "device 
state", as the latter could be confused with the device a

[Intel-gfx] ✓ Fi.CI.BAT: success for series starting with [v2,1/5] drm/i915: Generate i915_params {} using a macro

2017-02-02 Thread Patchwork
== Series Details ==

Series: series starting with [v2,1/5] drm/i915: Generate i915_params {} using a 
macro
URL   : https://patchwork.freedesktop.org/series/18973/
State : success

== Summary ==

Series 18973v1 Series without cover letter
https://patchwork.freedesktop.org/api/1.0/series/18973/revisions/1/mbox/


fi-bdw-5557u total:247  pass:233  dwarn:0   dfail:0   fail:0   skip:14 
fi-bsw-n3050 total:247  pass:208  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205 total:247  pass:225  dwarn:0   dfail:0   fail:0   skip:22 
fi-bxt-t5700 total:78   pass:65   dwarn:0   dfail:0   fail:0   skip:12 
fi-byt-j1900 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-n2820 total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770  total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-hsw-4770r total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-ivb-3520m total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-ivb-3770  total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-kbl-7500u total:247  pass:224  dwarn:0   dfail:0   fail:2   skip:21 
fi-skl-6260u total:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-skl-6700hqtotal:247  pass:227  dwarn:0   dfail:0   fail:0   skip:20 
fi-skl-6700k total:247  pass:222  dwarn:4   dfail:0   fail:0   skip:21 
fi-skl-6770hqtotal:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-snb-2520m total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-snb-2600  total:247  pass:215  dwarn:0   dfail:0   fail:0   skip:32 

a0cc425b0034c42eb3830f7dd612ac2a132a874c drm-tip: 2017y-02m-01d-17h-17m-34s UTC 
integration manifest
4f19807 drm/i915: Show the current i915_params in debugfs/i915_capabilites
8819d2b drm/i915: Capture module parameters for the GPU error state
9afd98b drm/i915: Use bool i915_param.alpha_support
9e99506 drm/i915: Convert i915_params to use shortnames for its types
e80e338 drm/i915: Generate i915_params {} using a macro

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3671/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v6] drm: Provide a driver hook for drm_dev_release()

2017-02-02 Thread Chris Wilson
Some state is coupled into the device lifetime outside of the
load/unload timeframe and requires teardown during final unreference
from drm_dev_release(). For example, dmabufs hold both a device and
module reference and may live longer than expected (i.e. the current
pattern of the driver tearing down its state and then releasing a
reference to the drm device) and yet touch driver private state when
destroyed.

v2: Export drm_dev_fini() and move the responsibility for finalizing the
drm_device and freeing it to the release callback. (If no callback is
provided, the core will call drm_dev_fini() and kfree(dev) as before.)
v3: Remember to add drm_dev_fini() to drm_drv.h
v4: Tidy language for kerneldoc
v5: Cross reference from drm_dev_init() to note that driver->release()
allows for arbitrary embedding.
v6: Refer to driver data rather than driver state, as state is now
becoming associated with the struct drm_atomic_state and friends.

Signed-off-by: Chris Wilson 
Cc: Laurent Pinchart 
Cc: Daniel Vetter 
Reviewed-by: Laurent Pinchart 
---
 drivers/gpu/drm/drm_drv.c | 65 ---
 include/drm/drm_drv.h | 13 ++
 2 files changed, 58 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index a8ce3179c07c..e122e4d022f8 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -465,7 +465,10 @@ static void drm_fs_inode_free(struct inode *inode)
  * that do embed &struct drm_device it must be placed first in the overall
  * structure, and the overall structure must be allocated using kmalloc(): The
  * drm core's release function unconditionally calls kfree() on the @dev 
pointer
- * when the final reference is released.
+ * when the final reference is released. To override this behaviour, and so
+ * allow embedding of the drm_device inside the driver's device struct at an
+ * arbitrary offset, you must supply a driver->release() callback and control
+ * the finalization explicitly.
  *
  * RETURNS:
  * 0 on success, or error code on failure.
@@ -553,6 +556,41 @@ int drm_dev_init(struct drm_device *dev,
 EXPORT_SYMBOL(drm_dev_init);
 
 /**
+ * drm_dev_fini - Finalize a dead DRM device
+ * @dev: DRM device
+ *
+ * Finalize a dead DRM device. This is the converse to drm_dev_init() and
+ * frees up all data allocated by it. All driver private data should be
+ * finalized first. Note that this function does not free the @dev, that is
+ * left to the caller.
+ *
+ * The ref-count of @dev must be zero, and drm_dev_fini() should only be called
+ * from a drm_driver->release() callback.
+ */
+void drm_dev_fini(struct drm_device *dev)
+{
+   drm_vblank_cleanup(dev);
+
+   if (drm_core_check_feature(dev, DRIVER_GEM))
+   drm_gem_destroy(dev);
+
+   drm_legacy_ctxbitmap_cleanup(dev);
+   drm_ht_remove(&dev->map_hash);
+   drm_fs_inode_free(dev->anon_inode);
+
+   drm_minor_free(dev, DRM_MINOR_PRIMARY);
+   drm_minor_free(dev, DRM_MINOR_RENDER);
+   drm_minor_free(dev, DRM_MINOR_CONTROL);
+
+   mutex_destroy(&dev->master_mutex);
+   mutex_destroy(&dev->ctxlist_mutex);
+   mutex_destroy(&dev->filelist_mutex);
+   mutex_destroy(&dev->struct_mutex);
+   kfree(dev->unique);
+}
+EXPORT_SYMBOL(drm_dev_fini);
+
+/**
  * drm_dev_alloc - Allocate new DRM device
  * @driver: DRM driver to allocate device for
  * @parent: Parent device object
@@ -598,25 +636,12 @@ static void drm_dev_release(struct kref *ref)
 {
struct drm_device *dev = container_of(ref, struct drm_device, ref);
 
-   drm_vblank_cleanup(dev);
-
-   if (drm_core_check_feature(dev, DRIVER_GEM))
-   drm_gem_destroy(dev);
-
-   drm_legacy_ctxbitmap_cleanup(dev);
-   drm_ht_remove(&dev->map_hash);
-   drm_fs_inode_free(dev->anon_inode);
-
-   drm_minor_free(dev, DRM_MINOR_PRIMARY);
-   drm_minor_free(dev, DRM_MINOR_RENDER);
-   drm_minor_free(dev, DRM_MINOR_CONTROL);
-
-   mutex_destroy(&dev->master_mutex);
-   mutex_destroy(&dev->ctxlist_mutex);
-   mutex_destroy(&dev->filelist_mutex);
-   mutex_destroy(&dev->struct_mutex);
-   kfree(dev->unique);
-   kfree(dev);
+   if (dev->driver->release) {
+   dev->driver->release(dev);
+   } else {
+   drm_dev_fini(dev);
+   kfree(dev);
+   }
 }
 
 /**
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 732e85652d1e..5699f42195fe 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -102,6 +102,17 @@ struct drm_driver {
 *
 */
void (*unload) (struct drm_device *);
+
+   /**
+* @release:
+*
+* Optional callback for destroying device data after the final
+* reference is released, i.e. the device is being destroyed. Drivers
+* using this callback are responsible for calling drm_dev_fini()
+* to finalize the device and then freeing the struct them

Re: [Intel-gfx] [PATCH v2 1/5] drm/i915: Generate i915_params {} using a macro

2017-02-02 Thread Jani Nikula
On Thu, 02 Feb 2017, Chris Wilson  wrote:
> I want to print the struct from the error state and so would like to use
> the existing struct definition as the template ala DEV_INFO*
>
> v2: Use MEMBER() rather than p().
>
> Signed-off-by: Chris Wilson 
> Reviewed-by: Joonas Lahtinen 

I've been telling everyone who complains about testing specific firmware
blob versions to add a module parameter to specify and override the
default filename. AFAICT this series does not make string parameters any
harder, but please do double check. I think they expect a static
allocation for the string buffer too, so the struct assignment should be
fine as well.

On the series,

Acked-by: Jani Nikula 

> ---
>  drivers/gpu/drm/i915/i915_params.h | 81 
> --
>  1 file changed, 43 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_params.h 
> b/drivers/gpu/drm/i915/i915_params.h
> index 8e433de04679..9a8c60342a82 100644
> --- a/drivers/gpu/drm/i915/i915_params.h
> +++ b/drivers/gpu/drm/i915/i915_params.h
> @@ -27,46 +27,51 @@
>  
>  #include  /* for __read_mostly */
>  
> +#define I915_PARAMS_FOR_EACH(func) \
> + func(int, modeset); \
> + func(int, panel_ignore_lid); \
> + func(int, semaphores); \
> + func(int, lvds_channel_mode); \
> + func(int, panel_use_ssc); \
> + func(int, vbt_sdvo_panel_type); \
> + func(int, enable_rc6); \
> + func(int, enable_dc); \
> + func(int, enable_fbc); \
> + func(int, enable_ppgtt); \
> + func(int, enable_execlists); \
> + func(int, enable_psr); \
> + func(unsigned int, alpha_support); \
> + func(int, disable_power_well); \
> + func(int, enable_ips); \
> + func(int, invert_brightness); \
> + func(int, enable_guc_loading); \
> + func(int, enable_guc_submission); \
> + func(int, guc_log_level); \
> + func(int, use_mmio_flip); \
> + func(int, mmio_debug); \
> + func(int, edp_vswing); \
> + func(unsigned int, inject_load_failure); \
> + /* leave bools at the end to not create holes */ \
> + func(bool, enable_cmd_parser); \
> + func(bool, enable_hangcheck); \
> + func(bool, fastboot); \
> + func(bool, prefault_disable); \
> + func(bool, load_detect_test); \
> + func(bool, force_reset_modeset_test); \
> + func(bool, reset); \
> + func(bool, error_capture); \
> + func(bool, disable_display); \
> + func(bool, verbose_state_checks); \
> + func(bool, nuclear_pageflip); \
> + func(bool, enable_dp_mst); \
> + func(bool, enable_dpcd_backlight); \
> + func(bool, enable_gvt)
> +
> +#define MEMBER(T, member) T member
>  struct i915_params {
> - int modeset;
> - int panel_ignore_lid;
> - int semaphores;
> - int lvds_channel_mode;
> - int panel_use_ssc;
> - int vbt_sdvo_panel_type;
> - int enable_rc6;
> - int enable_dc;
> - int enable_fbc;
> - int enable_ppgtt;
> - int enable_execlists;
> - int enable_psr;
> - unsigned int alpha_support;
> - int disable_power_well;
> - int enable_ips;
> - int invert_brightness;
> - int enable_guc_loading;
> - int enable_guc_submission;
> - int guc_log_level;
> - int use_mmio_flip;
> - int mmio_debug;
> - int edp_vswing;
> - unsigned int inject_load_failure;
> - /* leave bools at the end to not create holes */
> - bool enable_cmd_parser;
> - bool enable_hangcheck;
> - bool fastboot;
> - bool prefault_disable;
> - bool load_detect_test;
> - bool force_reset_modeset_test;
> - bool reset;
> - bool error_capture;
> - bool disable_display;
> - bool verbose_state_checks;
> - bool nuclear_pageflip;
> - bool enable_dp_mst;
> - bool enable_dpcd_backlight;
> - bool enable_gvt;
> + I915_PARAMS_FOR_EACH(MEMBER);
>  };
> +#undef MEMBER
>  
>  extern struct i915_params i915 __read_mostly;

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


Re: [Intel-gfx] [PATCH v6] drm: Provide a driver hook for drm_dev_release()

2017-02-02 Thread Daniel Vetter
On Thu, Feb 02, 2017 at 09:36:32AM +, Chris Wilson wrote:
> Some state is coupled into the device lifetime outside of the
> load/unload timeframe and requires teardown during final unreference
> from drm_dev_release(). For example, dmabufs hold both a device and
> module reference and may live longer than expected (i.e. the current
> pattern of the driver tearing down its state and then releasing a
> reference to the drm device) and yet touch driver private state when
> destroyed.
> 
> v2: Export drm_dev_fini() and move the responsibility for finalizing the
> drm_device and freeing it to the release callback. (If no callback is
> provided, the core will call drm_dev_fini() and kfree(dev) as before.)
> v3: Remember to add drm_dev_fini() to drm_drv.h
> v4: Tidy language for kerneldoc
> v5: Cross reference from drm_dev_init() to note that driver->release()
> allows for arbitrary embedding.
> v6: Refer to driver data rather than driver state, as state is now
> becoming associated with the struct drm_atomic_state and friends.
> 
> Signed-off-by: Chris Wilson 
> Cc: Laurent Pinchart 
> Cc: Daniel Vetter 
> Reviewed-by: Laurent Pinchart 
> ---
>  drivers/gpu/drm/drm_drv.c | 65 
> ---
>  include/drm/drm_drv.h | 13 ++
>  2 files changed, 58 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index a8ce3179c07c..e122e4d022f8 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -465,7 +465,10 @@ static void drm_fs_inode_free(struct inode *inode)
>   * that do embed &struct drm_device it must be placed first in the overall
>   * structure, and the overall structure must be allocated using kmalloc(): 
> The
>   * drm core's release function unconditionally calls kfree() on the @dev 
> pointer
> - * when the final reference is released.
> + * when the final reference is released. To override this behaviour, and so
> + * allow embedding of the drm_device inside the driver's device struct at an
> + * arbitrary offset, you must supply a driver->release() callback and control

The new official way to reference a struct member is &foo.bar. I've
applied this polish to both places and applied your patch, thanks a lot.
-Daniel

> + * the finalization explicitly.
>   *
>   * RETURNS:
>   * 0 on success, or error code on failure.
> @@ -553,6 +556,41 @@ int drm_dev_init(struct drm_device *dev,
>  EXPORT_SYMBOL(drm_dev_init);
>  
>  /**
> + * drm_dev_fini - Finalize a dead DRM device
> + * @dev: DRM device
> + *
> + * Finalize a dead DRM device. This is the converse to drm_dev_init() and
> + * frees up all data allocated by it. All driver private data should be
> + * finalized first. Note that this function does not free the @dev, that is
> + * left to the caller.
> + *
> + * The ref-count of @dev must be zero, and drm_dev_fini() should only be 
> called
> + * from a drm_driver->release() callback.
> + */
> +void drm_dev_fini(struct drm_device *dev)
> +{
> + drm_vblank_cleanup(dev);
> +
> + if (drm_core_check_feature(dev, DRIVER_GEM))
> + drm_gem_destroy(dev);
> +
> + drm_legacy_ctxbitmap_cleanup(dev);
> + drm_ht_remove(&dev->map_hash);
> + drm_fs_inode_free(dev->anon_inode);
> +
> + drm_minor_free(dev, DRM_MINOR_PRIMARY);
> + drm_minor_free(dev, DRM_MINOR_RENDER);
> + drm_minor_free(dev, DRM_MINOR_CONTROL);
> +
> + mutex_destroy(&dev->master_mutex);
> + mutex_destroy(&dev->ctxlist_mutex);
> + mutex_destroy(&dev->filelist_mutex);
> + mutex_destroy(&dev->struct_mutex);
> + kfree(dev->unique);
> +}
> +EXPORT_SYMBOL(drm_dev_fini);
> +
> +/**
>   * drm_dev_alloc - Allocate new DRM device
>   * @driver: DRM driver to allocate device for
>   * @parent: Parent device object
> @@ -598,25 +636,12 @@ static void drm_dev_release(struct kref *ref)
>  {
>   struct drm_device *dev = container_of(ref, struct drm_device, ref);
>  
> - drm_vblank_cleanup(dev);
> -
> - if (drm_core_check_feature(dev, DRIVER_GEM))
> - drm_gem_destroy(dev);
> -
> - drm_legacy_ctxbitmap_cleanup(dev);
> - drm_ht_remove(&dev->map_hash);
> - drm_fs_inode_free(dev->anon_inode);
> -
> - drm_minor_free(dev, DRM_MINOR_PRIMARY);
> - drm_minor_free(dev, DRM_MINOR_RENDER);
> - drm_minor_free(dev, DRM_MINOR_CONTROL);
> -
> - mutex_destroy(&dev->master_mutex);
> - mutex_destroy(&dev->ctxlist_mutex);
> - mutex_destroy(&dev->filelist_mutex);
> - mutex_destroy(&dev->struct_mutex);
> - kfree(dev->unique);
> - kfree(dev);
> + if (dev->driver->release) {
> + dev->driver->release(dev);
> + } else {
> + drm_dev_fini(dev);
> + kfree(dev);
> + }
>  }
>  
>  /**
> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> index 732e85652d1e..5699f42195fe 100644
> --- a/include/drm/drm_drv.h
> +++ b/include/drm/drm_drv.h
> @@ -102,6 +102,17 @@ struct drm_driver {
>

[Intel-gfx] [PATCH] drm/i915: fix i915 running as dom0 under Xen

2017-02-02 Thread Juergen Gross
Commit 920cf4194954ec ("drm/i915: Introduce an internal allocator for
disposable private objects") introduced a regression for the kernel
running as Xen dom0: when switching to graphics mode a GPU HANG
occurred.

Reason seems to be a missing adaption similar to that done in
commit 7453c549f5f648 ("swiotlb: Export swiotlb_max_segment to users")
to i915_gem_object_get_pages_internal().

So limit the maximum page order to be used according to the maximum
swiotlb segment size instead to the complete swiotlb size.

Signed-off-by: Juergen Gross 
---
Please consider for 4.10 as otherwise 4.10 will be unusable as Xen dom0
with i915 graphics.
---
 drivers/gpu/drm/i915/i915_gem_internal.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c 
b/drivers/gpu/drm/i915/i915_gem_internal.c
index 4b3ff3e..d09c749 100644
--- a/drivers/gpu/drm/i915/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/i915_gem_internal.c
@@ -66,8 +66,16 @@ i915_gem_object_get_pages_internal(struct 
drm_i915_gem_object *obj)
 
max_order = MAX_ORDER;
 #ifdef CONFIG_SWIOTLB
-   if (swiotlb_nr_tbl()) /* minimum max swiotlb size is IO_TLB_SEGSIZE */
-   max_order = min(max_order, ilog2(IO_TLB_SEGPAGES));
+   if (swiotlb_nr_tbl()) {
+   unsigned int max_segment;
+
+   max_segment = swiotlb_max_segment();
+   if (max_segment) {
+   max_segment = max_t(unsigned int, max_segment,
+   PAGE_SIZE) >> PAGE_SHIFT;
+   max_order = min(max_order, ilog2(max_segment));
+   }
+   }
 #endif
 
gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_RECLAIMABLE;
-- 
2.10.2

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


Re: [Intel-gfx] [PATCH 4/6] drm: scrambling support in drm layer

2017-02-02 Thread Ville Syrjälä
On Thu, Feb 02, 2017 at 11:18:51AM +0530, Sharma, Shashank wrote:
> Regards
> 
> Shashank
> 
> 
> On 2/1/2017 10:02 PM, Ville Syrjälä wrote:
> > On Wed, Feb 01, 2017 at 06:14:39PM +0530, Shashank Sharma wrote:
> >> HDMI 2.0 spec mandates scrambling for modes with pixel clock higher
> >> than 340Mhz. This patch adds few new functions in drm layer for
> >> core drivers to enable/disable scrambling.
> >>
> >> This patch adds:
> >> - A function to detect scrambling support parsing HF-VSDB
> >> - A function to check scrambling status runtime using SCDC read.
> >> - Two functions to enable/disable scrambling using SCDC read/write.
> >> - Few new bools to reflect scrambling support and status.
> >>
> >> Signed-off-by: Shashank Sharma 
> >> ---
> >>   drivers/gpu/drm/drm_edid.c  | 131 
> >> +++-
> >>   include/drm/drm_connector.h |  24 
> >>   include/drm/drm_edid.h  |   6 +-
> >>   3 files changed, 159 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> >> index 37902e5..f0d940a 100644
> >> --- a/drivers/gpu/drm/drm_edid.c
> >> +++ b/drivers/gpu/drm/drm_edid.c
> >> @@ -37,6 +37,7 @@
> >>   #include 
> >>   #include 
> >>   #include 
> >> +#include 
> >>   
> >>   #define version_greater(edid, maj, min) \
> >>(((edid)->version > (maj)) || \
> >> @@ -3814,6 +3815,132 @@ static void drm_detect_hdmi_scdc(struct 
> >> drm_connector *connector,
> >>}
> >>   }
> >>   
> >> +static void drm_detect_hdmi_scrambling(struct drm_connector *connector,
> >> +   const u8 *hf_vsdb)
> > That names seems off. Should probably be drm_parse_hdmi_forum_vsdb() or
> > something.
> Actually, unlike the last patch set, we are not parsing the whole 
> hf_vsdb, but parsing it only for
> scrambling status byte (hf_vsdb[5]). But may be I can make it 
> drm_detect_scrambling_from_hfvsdb
> ot something similar. We will have more hf_vsdb parsing for 3d flags, 
> yuv420_deep_color etc.

Well, so far I'm not seeing much point in splitting it up. So I'd stuff
it all into one place, for now at least.

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


Re: [Intel-gfx] [PATCH 2/7] drm/i915: add DisplayPort amp unmute for LPE audio mode

2017-02-02 Thread Takashi Iwai
On Tue, 31 Jan 2017 22:36:44 +0100,
Takashi Iwai wrote:
> 
> From: Pierre-Louis Bossart 
> 
> Enable unmute/mute amp notification. This doesn't seem to affect
> HDMI support so this is done unconditionally.
> 
> An earlier version of this patch set a chicken bit at address 0x62F38
> prior to the mute/unmute but this register doesn't seem to do anything
> so this phase was removed.

Sorry, this seems like a wrong result.  It worked yesterday, but when
I retested the latest code today, it didn't work any longer.
Then, after setting the chicken bit, it starts working again.

But now I can't make it broken again.  Turn off the monitor, turn off
the machine, DPMS off, suspend/resume...  All still works without
chicken bit set.

Also, the chicken bit of the register 0x62f38 couldn't be read back.
The register always returns zero when read.

So the chicken bit helps definitely something on a device here, but
it's still mystery how it works.

I'll send an additional patch to re-add the audio chicken bit stuff.


thanks,

Takashi

> 
> Signed-off-by: Pierre-Louis Bossart 
> Signed-off-by: Takashi Iwai 
> ---
>  drivers/gpu/drm/i915/i915_reg.h| 10 ++
>  drivers/gpu/drm/i915/intel_lpe_audio.c | 17 +
>  2 files changed, 27 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index a9ffc8df241b..8fcc80cb864b 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -2061,6 +2061,16 @@ enum skl_disp_power_wells {
>  #define I915_HDMI_LPE_AUDIO_BASE (VLV_DISPLAY_BASE + 0x65000)
>  #define I915_HDMI_LPE_AUDIO_SIZE 0x1000
>  
> +/* DisplayPort Audio w/ LPE */
> +#define VLV_AUD_PORT_EN_B_DBG(VLV_DISPLAY_BASE + 0x62F20)
> +#define VLV_AUD_PORT_EN_C_DBG(VLV_DISPLAY_BASE + 0x62F30)
> +#define VLV_AUD_PORT_EN_D_DBG(VLV_DISPLAY_BASE + 0x62F34)
> +#define VLV_AUD_PORT_EN_DBG(port)_MMIO_PORT3((port) - PORT_B,   \
> + VLV_AUD_PORT_EN_B_DBG, \
> + VLV_AUD_PORT_EN_C_DBG, \
> + VLV_AUD_PORT_EN_D_DBG)
> +#define VLV_AMP_MUTE (1 << 1)
> +
>  #define GEN6_BSD_RNCID   _MMIO(0x12198)
>  
>  #define GEN7_FF_THREAD_MODE  _MMIO(0x20a0)
> diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c 
> b/drivers/gpu/drm/i915/intel_lpe_audio.c
> index 245523e14418..f95624a46f27 100644
> --- a/drivers/gpu/drm/i915/intel_lpe_audio.c
> +++ b/drivers/gpu/drm/i915/intel_lpe_audio.c
> @@ -337,15 +337,25 @@ void intel_lpe_audio_notify(struct drm_i915_private 
> *dev_priv,
>  {
>   unsigned long irq_flags;
>   struct intel_hdmi_lpe_audio_pdata *pdata = NULL;
> + u32 audio_enable;
> + i915_reg_t mmio;
>  
>   if (!HAS_LPE_AUDIO(dev_priv))
>   return;
>  
> + if (port == PORT_A) {
> + DRM_ERROR("PORT_A is not valid for HDMI/DP usages\n");
> + return;
> + }
> +
>   pdata = dev_get_platdata(
>   &(dev_priv->lpe_audio.platdev->dev));
>  
>   spin_lock_irqsave(&pdata->lpe_audio_slock, irq_flags);
>  
> + mmio = VLV_AUD_PORT_EN_DBG(port);
> + audio_enable = I915_READ(mmio);
> +
>   if (eld != NULL) {
>   memcpy(pdata->eld.eld_data, eld,
>   HDMI_MAX_ELD_BYTES);
> @@ -357,11 +367,18 @@ void intel_lpe_audio_notify(struct drm_i915_private 
> *dev_priv,
>   pdata->tmds_clock_speed = tmds_clk_speed;
>   if (link_rate)
>   pdata->link_rate = link_rate;
> +
> + /* Unmute the amp for both DP and HDMI */
> + I915_WRITE(mmio, audio_enable & ~VLV_AMP_MUTE);
> +
>   } else {
>   memset(pdata->eld.eld_data, 0,
>   HDMI_MAX_ELD_BYTES);
>   pdata->hdmi_connected = false;
>   pdata->dp_output = false;
> +
> + /* Mute the amp for both DP and HDMI */
> + I915_WRITE(mmio, audio_enable | VLV_AMP_MUTE);
>   }
>  
>   if (pdata->notify_audio_lpe)
> -- 
> 2.11.0
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915/dp: Read link status more times when EQ not done

2017-02-02 Thread Lee, Shawn C
From: "Lee, Shawn C" 

When user space link status, display driver read DPCD register
0x202, 0x203 and 0x204 to identify sink status. When PSR exit
is ongoing before EQ done. Panel will report EQ & symbol lock
not done. Both of them are under progressing at the same time
to cause this issue.

This WA try to read link status more times if EQ not done.
Panel spec request at least 1000us for fast link train when
PSR exit. So driver will wait 1000us~1500us then retrieve
sink link status again.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99639
TEST=Reboot DUT and no flicking on local display at login screen

Cc: Cooper Chiou 
Cc: Wei Shun Chen 
Cc: Gary C Wang 
Cc: Jani Nikula 

Signed-off-by: Lee, Shawn C 
---
 drivers/gpu/drm/i915/intel_dp.c |   33 -
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e80d620846c8..a9a6ce476438 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4136,13 +4136,36 @@ static void intel_dp_handle_test_request(struct 
intel_dp *intel_dp)
return;
 
/* if link training is requested we should perform it always */
-   if ((intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) ||
-   (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) {
-   DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
- intel_encoder->base.name);
+   if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) {
+   DRM_DEBUG_KMS("%s: compliance test mode, retraining\n",
+   intel_encoder->base.name);
+   } else {
+   u8 retry;
+
+   for (retry = 0; retry < 3; retry++) {
+   if (!drm_dp_channel_eq_ok(link_status, 
intel_dp->lane_count)) {
+   /*
+* EQ not ok may caused by fast link train 
while exit PSR active,
+* wait at least 1000 us then read it again.
+*/
+   DRM_DEBUG_KMS("%s: channel EQ not ok, retry = 
%d, DPCD 0x202 = 0x%x, 0x203 = 0x%x, 0x204 = 0x%x\n",
+   intel_encoder->base.name, retry, 
link_status[0], link_status[1], link_status[2]);
+   usleep_range(1000, 1500);
+   if (!intel_dp_get_link_status(intel_dp, 
link_status)) {
+   DRM_ERROR("Failed to get link 
status\n");
+   return;
+   }
+   } else {
+   /* channel EQ is fine */
+   return;
+   }
+   }
 
-   intel_dp_retrain_link(intel_dp);
+   DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
+   intel_encoder->base.name);
}
+
+   intel_dp_retrain_link(intel_dp);
 }
 
 /*
-- 
1.7.9.5

___
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: enable scrambling

2017-02-02 Thread Ville Syrjälä
On Thu, Feb 02, 2017 at 11:23:19AM +0530, Sharma, Shashank wrote:
> Regards
> 
> Shashank
> 
> 
> On 2/1/2017 10:06 PM, Ville Syrjälä wrote:
> > On Wed, Feb 01, 2017 at 06:14:40PM +0530, Shashank Sharma wrote:
> >> Geminilake platform has a native HDMI 2.0 controller, and is
> >> capable of driving pixel-clocks upto 594Mhz. HDMI 2.0 spec
> >> mendates scrambling for these higher clocks, for reduced RF footprint.
> >>
> >> This patch checks if the monitor supports scrambling, and if required,
> >> enables it during the modeset.
> >>
> >> Signed-off-by: Shashank Sharma 
> >> ---
> >>   drivers/gpu/drm/i915/i915_reg.h   |  2 ++
> >>   drivers/gpu/drm/i915/intel_ddi.c  |  5 +
> >>   drivers/gpu/drm/i915/intel_drv.h  |  2 ++
> >>   drivers/gpu/drm/i915/intel_hdmi.c | 42 
> >> +++
> >>   4 files changed, 51 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/i915/i915_reg.h 
> >> b/drivers/gpu/drm/i915/i915_reg.h
> >> index 495b789..cc85892 100644
> >> --- a/drivers/gpu/drm/i915/i915_reg.h
> >> +++ b/drivers/gpu/drm/i915/i915_reg.h
> >> @@ -7807,6 +7807,8 @@ enum {
> >>   #define  TRANS_DDI_EDP_INPUT_C_ONOFF (6<<12)
> >>   #define  TRANS_DDI_DP_VC_PAYLOAD_ALLOC   (1<<8)
> >>   #define  TRANS_DDI_BFI_ENABLE(1<<4)
> >> +#define  TRANS_DDI_HIGH_TMDS_CHAR_RATE(1<<4)
> >> +#define  TRANS_DDI_HDMI_SCRAMBLING(1<<0)
> >>   
> >>   /* DisplayPort Transport Control */
> >>   #define _DP_TP_CTL_A 0x64040
> >> diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
> >> b/drivers/gpu/drm/i915/intel_ddi.c
> >> index 9a9a670..aea81ce 100644
> >> --- a/drivers/gpu/drm/i915/intel_ddi.c
> >> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> >> @@ -1278,6 +1278,11 @@ void intel_ddi_enable_transcoder_func(struct 
> >> drm_crtc *crtc)
> >>temp |= TRANS_DDI_MODE_SELECT_HDMI;
> >>else
> >>temp |= TRANS_DDI_MODE_SELECT_DVI;
> >> +
> >> +  if (IS_GEMINILAKE(dev_priv)) {
> >> +  temp |= intel_hdmi_check_scrambling(intel_encoder,
> >> +  &intel_crtc->config->base.adjusted_mode);
> >> +  }
> >>} else if (type == INTEL_OUTPUT_ANALOG) {
> >>temp |= TRANS_DDI_MODE_SELECT_FDI;
> >>temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
> >> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> >> b/drivers/gpu/drm/i915/intel_drv.h
> >> index 393f243..aafce7f 100644
> >> --- a/drivers/gpu/drm/i915/intel_drv.h
> >> +++ b/drivers/gpu/drm/i915/intel_drv.h
> >> @@ -1588,6 +1588,8 @@ void intel_hdmi_init_connector(struct 
> >> intel_digital_port *intel_dig_port,
> >>   bool intel_hdmi_compute_config(struct intel_encoder *encoder,
> >>   struct intel_crtc_state *pipe_config,
> >>   struct drm_connector_state *conn_state);
> >> +uint32_t intel_hdmi_check_scrambling(struct intel_encoder *intel_encoder,
> >> +  struct drm_display_mode *mode);
> >>   void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool 
> >> enable);
> >>   
> >>   
> >> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
> >> b/drivers/gpu/drm/i915/intel_hdmi.c
> >> index ebae2bd..92dd9bc 100644
> >> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> >> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> >> @@ -1795,6 +1795,48 @@ static void intel_hdmi_destroy(struct drm_connector 
> >> *connector)
> >>intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
> >>   }
> >>   
> >> +static void
> >> +intel_hdmi_enable_scrambling(struct drm_connector *connector)
> >> +{
> >> +  struct drm_i915_private *dev_priv = connector->dev->dev_private;
> >> +  struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> >> +  struct i2c_adapter *adapter =
> >> +  intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
> >> +
> >> +  if (!drm_enable_scrambling(connector, adapter, true))
> >> +  DRM_ERROR("Request to enable scrambling failed\n");
> >> +}
> > I don't like hiding this somewhere deep like this. It should be
> > somewhere much higher up.
> Why ? All we need to do here is enable two bits in transcoder control 
> register, which is already being
> programmed in a calling function, so I dont see the use case, but I 
> might be missing some bigger picture.
> Can you please elaborate on this ?

We're talking to the display here, which is rather surprising to happen
from a function thing that on the first glance doesn't even seem to
touch the hardware.

> >
> > And I'm thinkign we might want to track the scrambler state
> > in the crtc state.
> Yes, that's a pretty good way to track dynamic status of scrambler, do 
> you think we should add this in
> drm_crtc_state itself ?

I'd just start with intel specific state and later we can see what
everyone else wants to do and potentially unify a bit.

> 
> - Shashank
> >> +
> >> +uint32_t intel_hdmi_check_scrambling(struct intel_encoder *intel_encoder,
> >> +  

Re: [Intel-gfx] [PATCH v2 1/5] drm/i915: Generate i915_params {} using a macro

2017-02-02 Thread Chris Wilson
On Thu, Feb 02, 2017 at 11:37:06AM +0200, Jani Nikula wrote:
> On Thu, 02 Feb 2017, Chris Wilson  wrote:
> > I want to print the struct from the error state and so would like to use
> > the existing struct definition as the template ala DEV_INFO*
> >
> > v2: Use MEMBER() rather than p().
> >
> > Signed-off-by: Chris Wilson 
> > Reviewed-by: Joonas Lahtinen 
> 
> I've been telling everyone who complains about testing specific firmware
> blob versions to add a module parameter to specify and override the
> default filename. AFAICT this series does not make string parameters any
> harder, but please do double check. I think they expect a static
> allocation for the string buffer too, so the struct assignment should be
> fine as well.

charp which is the dynamically allocated string might be easier,
certainly for 0400 parameters.

Hmm. Except for copying into the error state, 0600 charp will take a bit
more work (another iterator to kstrdup). 

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 86649610b9eb..2d32dacebeb3 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -76,6 +76,13 @@ static void seq_param_uint(struct seq_file *m, const char 
*name, param_uint x)
seq_printf(m, "i915.%s=%u\n", name, x);
 }
 
+static void seq_param_charp(struct seq_file *m, const char *name, param_charp 
x)
+{
+   kernel_param_lock(THIS_MODULE);
+   seq_printf(m, "i915.%s=%s\n", name, x);
+   kernel_param_unlock(THIS_MODULE);
+}
+
 static int i915_capabilities(struct seq_file *m, void *data)
 {
struct drm_i915_private *dev_priv = node_to_i915(m->private);
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index b8f2b671fc0a..35602935dba8 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -567,6 +567,15 @@ static void err_param_uint(struct drm_i915_error_state_buf 
*m,
err_printf(m, "%s: %u\n", name, x);
 }
 
+static void err_param_charp(struct drm_i915_error_state_buf *m,
+   const char *name,
+   param_charp x)
+{
+   kernel_param_lock(THIS_MODULE);
+   err_printf(m, "%s: %s\n", name, x);
+   kernel_param_unlock(THIS_MODULE);
+}
+
 static void err_print_params(struct drm_i915_error_state_buf *m,
 const struct i915_params *p)
 {
diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index f1fa51190dc6..f9cc170577c2 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -65,6 +65,8 @@ struct i915_params i915 __read_mostly = {
.enable_gvt = false,
 };
 
+module_param_named_unsafe(my_string, i915.my_string, charp, 0400);
+
 module_param_named(modeset, i915.modeset, int, 0400);
 MODULE_PARM_DESC(modeset,
"Use kernel modesetting [KMS] (0=disable, "
diff --git a/drivers/gpu/drm/i915/i915_params.h 
b/drivers/gpu/drm/i915/i915_params.h
index 87ac6ed995d3..bc5aea9e3fb6 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -30,6 +30,7 @@
 typedef bool param_bool;
 typedef int param_int;
 typedef unsigned int param_uint;
+typedef char *param_charp;
 
 #define I915_PARAMS_FOR_EACH(func) \
func(param_int, modeset); \
@@ -54,6 +55,7 @@ typedef unsigned int param_uint;
func(param_int, mmio_debug); \
func(param_int, edp_vswing); \
func(param_uint, inject_load_failure); \
+   func(param_charp, my_string); \
/* leave bools at the end to not create holes */ \
func(param_bool, alpha_support); \
func(param_bool, enable_cmd_parser); \

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


Re: [Intel-gfx] [PATCH 2/7] drm/i915: add DisplayPort amp unmute for LPE audio mode

2017-02-02 Thread Ville Syrjälä
On Thu, Feb 02, 2017 at 10:57:30AM +0100, Takashi Iwai wrote:
> On Tue, 31 Jan 2017 22:36:44 +0100,
> Takashi Iwai wrote:
> > 
> > From: Pierre-Louis Bossart 
> > 
> > Enable unmute/mute amp notification. This doesn't seem to affect
> > HDMI support so this is done unconditionally.
> > 
> > An earlier version of this patch set a chicken bit at address 0x62F38
> > prior to the mute/unmute but this register doesn't seem to do anything
> > so this phase was removed.
> 
> Sorry, this seems like a wrong result.  It worked yesterday, but when
> I retested the latest code today, it didn't work any longer.
> Then, after setting the chicken bit, it starts working again.
> 
> But now I can't make it broken again.  Turn off the monitor, turn off
> the machine, DPMS off, suspend/resume...  All still works without
> chicken bit set.
> 
> Also, the chicken bit of the register 0x62f38 couldn't be read back.
> The register always returns zero when read.

The docs do say it's write-only actually.

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


Re: [Intel-gfx] [PATCH 2/7] drm/i915: add DisplayPort amp unmute for LPE audio mode

2017-02-02 Thread Takashi Iwai
On Thu, 02 Feb 2017 11:06:05 +0100,
Ville Syrjälä wrote:
> 
> On Thu, Feb 02, 2017 at 10:57:30AM +0100, Takashi Iwai wrote:
> > On Tue, 31 Jan 2017 22:36:44 +0100,
> > Takashi Iwai wrote:
> > > 
> > > From: Pierre-Louis Bossart 
> > > 
> > > Enable unmute/mute amp notification. This doesn't seem to affect
> > > HDMI support so this is done unconditionally.
> > > 
> > > An earlier version of this patch set a chicken bit at address 0x62F38
> > > prior to the mute/unmute but this register doesn't seem to do anything
> > > so this phase was removed.
> > 
> > Sorry, this seems like a wrong result.  It worked yesterday, but when
> > I retested the latest code today, it didn't work any longer.
> > Then, after setting the chicken bit, it starts working again.
> > 
> > But now I can't make it broken again.  Turn off the monitor, turn off
> > the machine, DPMS off, suspend/resume...  All still works without
> > chicken bit set.
> > 
> > Also, the chicken bit of the register 0x62f38 couldn't be read back.
> > The register always returns zero when read.
> 
> The docs do say it's write-only actually.

OK, thanks for confirmation!


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


Re: [Intel-gfx] [PATCH 4/6] drm: scrambling support in drm layer

2017-02-02 Thread Sharma, Shashank

Regards

Shashank


On 2/2/2017 3:21 PM, Ville Syrjälä wrote:

On Thu, Feb 02, 2017 at 11:18:51AM +0530, Sharma, Shashank wrote:

Regards

Shashank


On 2/1/2017 10:02 PM, Ville Syrjälä wrote:

On Wed, Feb 01, 2017 at 06:14:39PM +0530, Shashank Sharma wrote:

HDMI 2.0 spec mandates scrambling for modes with pixel clock higher
than 340Mhz. This patch adds few new functions in drm layer for
core drivers to enable/disable scrambling.

This patch adds:
- A function to detect scrambling support parsing HF-VSDB
- A function to check scrambling status runtime using SCDC read.
- Two functions to enable/disable scrambling using SCDC read/write.
- Few new bools to reflect scrambling support and status.

Signed-off-by: Shashank Sharma 
---
   drivers/gpu/drm/drm_edid.c  | 131 
+++-
   include/drm/drm_connector.h |  24 
   include/drm/drm_edid.h  |   6 +-
   3 files changed, 159 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 37902e5..f0d940a 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -37,6 +37,7 @@
   #include 
   #include 
   #include 
+#include 
   
   #define version_greater(edid, maj, min) \

(((edid)->version > (maj)) || \
@@ -3814,6 +3815,132 @@ static void drm_detect_hdmi_scdc(struct drm_connector 
*connector,
}
   }
   
+static void drm_detect_hdmi_scrambling(struct drm_connector *connector,

+const u8 *hf_vsdb)

That names seems off. Should probably be drm_parse_hdmi_forum_vsdb() or
something.

Actually, unlike the last patch set, we are not parsing the whole
hf_vsdb, but parsing it only for
scrambling status byte (hf_vsdb[5]). But may be I can make it
drm_detect_scrambling_from_hfvsdb
ot something similar. We will have more hf_vsdb parsing for 3d flags,
yuv420_deep_color etc.

Well, so far I'm not seeing much point in splitting it up. So I'd stuff
it all into one place, for now at least.
I had published a patch just doing as you suggested which was parsing 
complete hf-vsdb in one shot, and adding info in

hdmi_info structure, to accommodate it.
(Patch https://patchwork.freedesktop.org/patch/128963/ and 
https://patchwork.freedesktop.org/patch/128962/)


But you gave a review comment not to add anything which is not being 
used in the patch series:

https://patchwork.freedesktop.org/patch/128962/

That was the only reason I have split hf-vsdb parsing patch into 3 parts
- parse SCDC and scrambling info (here)
- with YUV420 deep color ( upcoming )
- with 3d handling (upcoming)

So I am confused, split or no split :-) ?

- Shashank

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


Re: [Intel-gfx] [PATCH 4/6] drm: scrambling support in drm layer

2017-02-02 Thread Ville Syrjälä
On Thu, Feb 02, 2017 at 03:46:55PM +0530, Sharma, Shashank wrote:
> Regards
> 
> Shashank
> 
> 
> On 2/2/2017 3:21 PM, Ville Syrjälä wrote:
> > On Thu, Feb 02, 2017 at 11:18:51AM +0530, Sharma, Shashank wrote:
> >> Regards
> >>
> >> Shashank
> >>
> >>
> >> On 2/1/2017 10:02 PM, Ville Syrjälä wrote:
> >>> On Wed, Feb 01, 2017 at 06:14:39PM +0530, Shashank Sharma wrote:
>  HDMI 2.0 spec mandates scrambling for modes with pixel clock higher
>  than 340Mhz. This patch adds few new functions in drm layer for
>  core drivers to enable/disable scrambling.
> 
>  This patch adds:
>  - A function to detect scrambling support parsing HF-VSDB
>  - A function to check scrambling status runtime using SCDC read.
>  - Two functions to enable/disable scrambling using SCDC read/write.
>  - Few new bools to reflect scrambling support and status.
> 
>  Signed-off-by: Shashank Sharma 
>  ---
> drivers/gpu/drm/drm_edid.c  | 131 
>  +++-
> include/drm/drm_connector.h |  24 
> include/drm/drm_edid.h  |   6 +-
> 3 files changed, 159 insertions(+), 2 deletions(-)
> 
>  diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>  index 37902e5..f0d940a 100644
>  --- a/drivers/gpu/drm/drm_edid.c
>  +++ b/drivers/gpu/drm/drm_edid.c
>  @@ -37,6 +37,7 @@
> #include 
> #include 
> #include 
>  +#include 
> 
> #define version_greater(edid, maj, min) \
>   (((edid)->version > (maj)) || \
>  @@ -3814,6 +3815,132 @@ static void drm_detect_hdmi_scdc(struct 
>  drm_connector *connector,
>   }
> }
> 
>  +static void drm_detect_hdmi_scrambling(struct drm_connector *connector,
>  + const u8 *hf_vsdb)
> >>> That names seems off. Should probably be drm_parse_hdmi_forum_vsdb() or
> >>> something.
> >> Actually, unlike the last patch set, we are not parsing the whole
> >> hf_vsdb, but parsing it only for
> >> scrambling status byte (hf_vsdb[5]). But may be I can make it
> >> drm_detect_scrambling_from_hfvsdb
> >> ot something similar. We will have more hf_vsdb parsing for 3d flags,
> >> yuv420_deep_color etc.
> > Well, so far I'm not seeing much point in splitting it up. So I'd stuff
> > it all into one place, for now at least.
> I had published a patch just doing as you suggested which was parsing 
> complete hf-vsdb in one shot, and adding info in
> hdmi_info structure, to accommodate it.
> (Patch https://patchwork.freedesktop.org/patch/128963/ and 
> https://patchwork.freedesktop.org/patch/128962/)
> 
> But you gave a review comment not to add anything which is not being 
> used in the patch series:
> https://patchwork.freedesktop.org/patch/128962/

That's doesn't require the things that are left to be split into
separate functions.

> 
> That was the only reason I have split hf-vsdb parsing patch into 3 parts
> - parse SCDC and scrambling info (here)
> - with YUV420 deep color ( upcoming )
> - with 3d handling (upcoming)
> 
> So I am confused, split or no split :-) ?
> 
> - Shashank

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


[Intel-gfx] [PATCH v8] drm/i915/scheduler: emulate a scheduler for guc

2017-02-02 Thread Chris Wilson
This emulates execlists on top of the GuC in order to defer submission of
requests to the hardware. This deferral allows time for high priority
requests to gazump their way to the head of the queue, however it nerfs
the GuC by converting it back into a simple execlist (where the CPU has
to wake up after every request to feed new commands into the GuC).

v2: Drop hack status - though iirc there is still a lockdep inversion
between fence and engine->timeline->lock (which is impossible as the
nesting only occurs on different fences - hopefully just requires some
judicious lockdep annotation)
v3: Apply lockdep nesting to enabling signaling on the request, using
the pattern we already have in __i915_gem_request_submit();
v4: Replaying requests after a hang also now needs the timeline
spinlock, to disable the interrupts at least
v5: Hold wq lock for completeness, and emit a tracepoint for enabling signal
v6: Reorder interrupt checking for a happier gcc.
v7: Only signal the tasklet after a user-interrupt if using guc scheduling
v8: Restore lost update of rq through the i915_guc_irq_handler (Tvrtko)

Signed-off-by: Chris Wilson 
Cc: Tvrtko Ursulin 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_guc_submission.c | 110 +++--
 drivers/gpu/drm/i915/i915_irq.c|  13 +++-
 drivers/gpu/drm/i915/intel_lrc.c   |   5 +-
 3 files changed, 114 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c 
b/drivers/gpu/drm/i915/i915_guc_submission.c
index 8ced9e26f075..d99185aafe58 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -25,6 +25,8 @@
 #include "i915_drv.h"
 #include "intel_uc.h"
 
+#include 
+
 /**
  * DOC: GuC-based command submission
  *
@@ -348,7 +350,7 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request 
*request)
u32 freespace;
int ret;
 
-   spin_lock(&client->wq_lock);
+   spin_lock_irq(&client->wq_lock);
freespace = CIRC_SPACE(client->wq_tail, desc->head, client->wq_size);
freespace -= client->wq_rsvd;
if (likely(freespace >= wqi_size)) {
@@ -358,7 +360,7 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request 
*request)
client->no_wq_space++;
ret = -EAGAIN;
}
-   spin_unlock(&client->wq_lock);
+   spin_unlock_irq(&client->wq_lock);
 
return ret;
 }
@@ -370,9 +372,9 @@ void i915_guc_wq_unreserve(struct drm_i915_gem_request 
*request)
 
GEM_BUG_ON(READ_ONCE(client->wq_rsvd) < wqi_size);
 
-   spin_lock(&client->wq_lock);
+   spin_lock_irq(&client->wq_lock);
client->wq_rsvd -= wqi_size;
-   spin_unlock(&client->wq_lock);
+   spin_unlock_irq(&client->wq_lock);
 }
 
 /* Construct a Work Item and append it to the GuC's Work Queue */
@@ -532,10 +534,97 @@ static void __i915_guc_submit(struct drm_i915_gem_request 
*rq)
 
 static void i915_guc_submit(struct drm_i915_gem_request *rq)
 {
-   i915_gem_request_submit(rq);
+   __i915_gem_request_submit(rq);
__i915_guc_submit(rq);
 }
 
+static void nested_enable_signaling(struct drm_i915_gem_request *rq)
+{
+   /* If we use dma_fence_enable_sw_signaling() directly, lockdep
+* detects an ordering issue between the fence lockclass and the
+* global_timeline. This circular dependency can only occur via 2
+* different fences (but same fence lockclass), so we use the nesting
+* annotation here to prevent the warn, equivalent to the nesting
+* inside i915_gem_request_submit() for when we also enable the
+* signaler.
+*/
+
+   if (test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
+&rq->fence.flags))
+   return;
+
+   GEM_BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags));
+   trace_dma_fence_enable_signal(&rq->fence);
+
+   spin_lock_nested(&rq->lock, SINGLE_DEPTH_NESTING);
+   intel_engine_enable_signaling(rq);
+   spin_unlock(&rq->lock);
+}
+
+static bool i915_guc_dequeue(struct intel_engine_cs *engine)
+{
+   struct execlist_port *port = engine->execlist_port;
+   struct drm_i915_gem_request *last = port[0].request;
+   unsigned long flags;
+   struct rb_node *rb;
+   bool submit = false;
+
+   spin_lock_irqsave(&engine->timeline->lock, flags);
+   rb = engine->execlist_first;
+   while (rb) {
+   struct drm_i915_gem_request *cursor =
+   rb_entry(rb, typeof(*cursor), priotree.node);
+
+   if (last && cursor->ctx != last->ctx) {
+   if (port != engine->execlist_port)
+   break;
+
+   i915_gem_request_assign(&port->request, last);
+   nested_enable_signaling(last);
+   port++;
+   }
+
+   rb = rb_next(rb);
+   rb_erase(&cursor->priotre

Re: [Intel-gfx] [PATCH 4/6] drm: scrambling support in drm layer

2017-02-02 Thread Sharma, Shashank

Regards

Shashank


On 2/2/2017 3:58 PM, Ville Syrjälä wrote:

On Thu, Feb 02, 2017 at 03:46:55PM +0530, Sharma, Shashank wrote:

Regards

Shashank


On 2/2/2017 3:21 PM, Ville Syrjälä wrote:

On Thu, Feb 02, 2017 at 11:18:51AM +0530, Sharma, Shashank wrote:

Regards

Shashank


On 2/1/2017 10:02 PM, Ville Syrjälä wrote:

On Wed, Feb 01, 2017 at 06:14:39PM +0530, Shashank Sharma wrote:

HDMI 2.0 spec mandates scrambling for modes with pixel clock higher
than 340Mhz. This patch adds few new functions in drm layer for
core drivers to enable/disable scrambling.

This patch adds:
- A function to detect scrambling support parsing HF-VSDB
- A function to check scrambling status runtime using SCDC read.
- Two functions to enable/disable scrambling using SCDC read/write.
- Few new bools to reflect scrambling support and status.

Signed-off-by: Shashank Sharma 
---
drivers/gpu/drm/drm_edid.c  | 131 
+++-
include/drm/drm_connector.h |  24 
include/drm/drm_edid.h  |   6 +-
3 files changed, 159 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 37902e5..f0d940a 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -37,6 +37,7 @@
#include 
#include 
#include 
+#include 

#define version_greater(edid, maj, min) \

(((edid)->version > (maj)) || \
@@ -3814,6 +3815,132 @@ static void drm_detect_hdmi_scdc(struct drm_connector 
*connector,
}
}

+static void drm_detect_hdmi_scrambling(struct drm_connector *connector,

+const u8 *hf_vsdb)

That names seems off. Should probably be drm_parse_hdmi_forum_vsdb() or
something.

Actually, unlike the last patch set, we are not parsing the whole
hf_vsdb, but parsing it only for
scrambling status byte (hf_vsdb[5]). But may be I can make it
drm_detect_scrambling_from_hfvsdb
ot something similar. We will have more hf_vsdb parsing for 3d flags,
yuv420_deep_color etc.

Well, so far I'm not seeing much point in splitting it up. So I'd stuff
it all into one place, for now at least.

I had published a patch just doing as you suggested which was parsing
complete hf-vsdb in one shot, and adding info in
hdmi_info structure, to accommodate it.
(Patch https://patchwork.freedesktop.org/patch/128963/ and
https://patchwork.freedesktop.org/patch/128962/)

But you gave a review comment not to add anything which is not being
used in the patch series:
https://patchwork.freedesktop.org/patch/128962/

That's doesn't require the things that are left to be split into
separate functions.

So please let me know if my understanding is correct.
- Name the function as *_parse_hfvsdb only
- Call it while parsing the EDID extension blocks (the same place)
- Keep on adding parsing of the HF-VSDB blocks, in the same function, in 
an incremental way, as we add patches for them.
In this way the function won't be split into multiple small functions, 
but all the parsing will be done in one function.


- Shashank

That was the only reason I have split hf-vsdb parsing patch into 3 parts
- parse SCDC and scrambling info (here)
- with YUV420 deep color ( upcoming )
- with 3d handling (upcoming)

So I am confused, split or no split :-) ?

- Shashank


___
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: enable scrambling

2017-02-02 Thread Sharma, Shashank

Regards

Shashank


On 2/2/2017 3:32 PM, Ville Syrjälä wrote:

On Thu, Feb 02, 2017 at 11:23:19AM +0530, Sharma, Shashank wrote:

Regards

Shashank


On 2/1/2017 10:06 PM, Ville Syrjälä wrote:

On Wed, Feb 01, 2017 at 06:14:40PM +0530, Shashank Sharma wrote:

Geminilake platform has a native HDMI 2.0 controller, and is
capable of driving pixel-clocks upto 594Mhz. HDMI 2.0 spec
mendates scrambling for these higher clocks, for reduced RF footprint.

This patch checks if the monitor supports scrambling, and if required,
enables it during the modeset.

Signed-off-by: Shashank Sharma 
---
   drivers/gpu/drm/i915/i915_reg.h   |  2 ++
   drivers/gpu/drm/i915/intel_ddi.c  |  5 +
   drivers/gpu/drm/i915/intel_drv.h  |  2 ++
   drivers/gpu/drm/i915/intel_hdmi.c | 42 
+++
   4 files changed, 51 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 495b789..cc85892 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7807,6 +7807,8 @@ enum {
   #define  TRANS_DDI_EDP_INPUT_C_ONOFF (6<<12)
   #define  TRANS_DDI_DP_VC_PAYLOAD_ALLOC   (1<<8)
   #define  TRANS_DDI_BFI_ENABLE(1<<4)
+#define  TRANS_DDI_HIGH_TMDS_CHAR_RATE (1<<4)
+#define  TRANS_DDI_HDMI_SCRAMBLING (1<<0)
   
   /* DisplayPort Transport Control */

   #define _DP_TP_CTL_A 0x64040
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 9a9a670..aea81ce 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1278,6 +1278,11 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc 
*crtc)
temp |= TRANS_DDI_MODE_SELECT_HDMI;
else
temp |= TRANS_DDI_MODE_SELECT_DVI;
+
+   if (IS_GEMINILAKE(dev_priv)) {
+   temp |= intel_hdmi_check_scrambling(intel_encoder,
+   &intel_crtc->config->base.adjusted_mode);
+   }
} else if (type == INTEL_OUTPUT_ANALOG) {
temp |= TRANS_DDI_MODE_SELECT_FDI;
temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 393f243..aafce7f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1588,6 +1588,8 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
   bool intel_hdmi_compute_config(struct intel_encoder *encoder,
   struct intel_crtc_state *pipe_config,
   struct drm_connector_state *conn_state);
+uint32_t intel_hdmi_check_scrambling(struct intel_encoder *intel_encoder,
+   struct drm_display_mode *mode);
   void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool 
enable);
   
   
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c

index ebae2bd..92dd9bc 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1795,6 +1795,48 @@ static void intel_hdmi_destroy(struct drm_connector 
*connector)
intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
   }
   
+static void

+intel_hdmi_enable_scrambling(struct drm_connector *connector)
+{
+   struct drm_i915_private *dev_priv = connector->dev->dev_private;
+   struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+   struct i2c_adapter *adapter =
+   intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
+
+   if (!drm_enable_scrambling(connector, adapter, true))
+   DRM_ERROR("Request to enable scrambling failed\n");
+}

I don't like hiding this somewhere deep like this. It should be
somewhere much higher up.

Why ? All we need to do here is enable two bits in transcoder control
register, which is already being
programmed in a calling function, so I dont see the use case, but I
might be missing some bigger picture.
Can you please elaborate on this ?

We're talking to the display here, which is rather surprising to happen
from a function thing that on the first glance doesn't even seem to
touch the hardware.
I kind of agree with this, and I am also tempted now to shift this call 
upwards, but I want to

keep this close to port enabling as well, as the HDMI 2.0 spec says:
"Max time period between a source enables scrambling on monitor, and 
starts sending scrambled

  video should be 100ms" else the sink might choose to disable scrambling.

Considering this, where do you think would be right place to enabled 
scrambling on monitor ?


- Shashank

And I'm thinkign we might want to track the scrambler state
in the crtc state.

Yes, that's a pretty good way to track dynamic status of scrambler, do
you think we should add this in
drm_crtc_state itself ?

I'd just start with intel specific state and later we can see what
everyone else wants to 

Re: [Intel-gfx] [PATCH] drm/i915: fix i915 running as dom0 under Xen

2017-02-02 Thread Daniel Vetter
On Thu, Feb 02, 2017 at 10:47:11AM +0100, Juergen Gross wrote:
> Commit 920cf4194954ec ("drm/i915: Introduce an internal allocator for
> disposable private objects") introduced a regression for the kernel
> running as Xen dom0: when switching to graphics mode a GPU HANG
> occurred.
> 
> Reason seems to be a missing adaption similar to that done in
> commit 7453c549f5f648 ("swiotlb: Export swiotlb_max_segment to users")
> to i915_gem_object_get_pages_internal().
> 
> So limit the maximum page order to be used according to the maximum
> swiotlb segment size instead to the complete swiotlb size.
> 
> Signed-off-by: Juergen Gross 
Fixes: 920cf4194954 ("drm/i915: Introduce an internal allocator for disposable 
private objects")
Cc: Chris Wilson 
Cc: Tvrtko Ursulin 
Cc: Daniel Vetter 
Cc: Jani Nikula 
Cc: intel-gfx@lists.freedesktop.org
Cc:  # v4.10-rc1+

We have a nice script for these :-)
-Daniel

> ---
> Please consider for 4.10 as otherwise 4.10 will be unusable as Xen dom0
> with i915 graphics.
> ---
>  drivers/gpu/drm/i915/i915_gem_internal.c | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c 
> b/drivers/gpu/drm/i915/i915_gem_internal.c
> index 4b3ff3e..d09c749 100644
> --- a/drivers/gpu/drm/i915/i915_gem_internal.c
> +++ b/drivers/gpu/drm/i915/i915_gem_internal.c
> @@ -66,8 +66,16 @@ i915_gem_object_get_pages_internal(struct 
> drm_i915_gem_object *obj)
>  
>   max_order = MAX_ORDER;
>  #ifdef CONFIG_SWIOTLB
> - if (swiotlb_nr_tbl()) /* minimum max swiotlb size is IO_TLB_SEGSIZE */
> - max_order = min(max_order, ilog2(IO_TLB_SEGPAGES));
> + if (swiotlb_nr_tbl()) {
> + unsigned int max_segment;
> +
> + max_segment = swiotlb_max_segment();
> + if (max_segment) {
> + max_segment = max_t(unsigned int, max_segment,
> + PAGE_SIZE) >> PAGE_SHIFT;
> + max_order = min(max_order, ilog2(max_segment));
> + }
> + }
>  #endif
>  
>   gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_RECLAIMABLE;
> -- 
> 2.10.2
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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


Re: [Intel-gfx] [PATCH 2/4] drm/i915/lspcon: Fix resume time initialization due to unasserted HPD

2017-02-02 Thread Sharma, Shashank

Reviewed-by: Shashank Sharma

Regards
Shashank
On 1/29/2017 9:43 PM, Imre Deak wrote:

On Sun, Jan 29, 2017 at 10:33:07AM +0530, Sharma, Shashank wrote:

Regards

Shashank


On 1/28/2017 1:47 PM, Imre Deak wrote:

On Sat, Jan 28, 2017 at 10:32:03AM +0530, Sharma, Shashank wrote:

Regards

Shashank


On 1/27/2017 3:09 PM, Imre Deak wrote:

During system resume time initialization the HPD level on LSPCON ports
can stay low for an extended amount of time, leading to failed AUX
transfers and LSPCON initialization. Fix this by waiting for HPD to get
asserted.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99178
Cc: Shashank Sharma 
Cc: Jani Nikula 
Cc: Ville Syrjälä 
Cc: Daniel Vetter 
Cc:  # v4.9+
Signed-off-by: Imre Deak 
---
  drivers/gpu/drm/i915/intel_dp.c | 4 ++--
  drivers/gpu/drm/i915/intel_drv.h| 2 ++
  drivers/gpu/drm/i915/intel_lspcon.c | 5 -
  3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e0f9b9e..a7785ce 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4400,8 +4400,8 @@ static bool bxt_digital_port_connected(struct 
drm_i915_private *dev_priv,
   *
   * Return %true if @port is connected, %false otherwise.
   */
-static bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
-struct intel_digital_port *port)
+bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+ struct intel_digital_port *port)
  {
if (HAS_PCH_IBX(dev_priv))
return ibx_digital_port_connected(dev_priv, port);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index b71fece..b9cde11 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1489,6 +1489,8 @@ bool __intel_dp_read_desc(struct intel_dp *intel_dp,
  bool intel_dp_read_desc(struct intel_dp *intel_dp);
  int intel_dp_link_required(int pixel_clock, int bpp);
  int intel_dp_max_data_rate(int max_link_clock, int max_lanes);
+bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+ struct intel_digital_port *port);
  /* intel_dp_aux_backlight.c */
  int intel_dp_aux_init_backlight_funcs(struct intel_connector 
*intel_connector);
diff --git a/drivers/gpu/drm/i915/intel_lspcon.c 
b/drivers/gpu/drm/i915/intel_lspcon.c
index f6d4e69..c300647 100644
--- a/drivers/gpu/drm/i915/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/intel_lspcon.c
@@ -158,6 +158,8 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
  static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon)
  {
struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
+   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+   struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
unsigned long start = jiffies;
if (!lspcon->desc_valid)
@@ -173,7 +175,8 @@ static void lspcon_resume_in_pcon_wa(struct intel_lspcon 
*lspcon)
if (!__intel_dp_read_desc(intel_dp, &desc))
return;
-   if (!memcmp(&intel_dp->desc, &desc, sizeof(desc))) {
+   if (intel_digital_port_connected(dev_priv, dig_port) &&

when in PCON mode, live_status is always up for LSPCON port, so this check
will be always true, isn't it ?

Not at least in case of the MegaChips LSPCON I've seen, there it takes a
while for HPD to get asserted. And while it's not asserted AUX
transactions will either:
- return garbage in case of native AUX transactions
- hang the chip/FW until next cold reboot in case of I2C-over-AUX
   transactions
- simply not get a reply if the chip/FW initialization has reached a
   certain phase

Based on the DP specification the sink/branch device is not required to
respond in case the HPD is not asserted, so the 3rd scenario is
compliant, but the first two are not.

In PCON mode after initialization and HPD getting asserted, HPD will
stay asserted except for the short pulses signaling an output
connect/disconnect.

The reason might be, that LSPCON resumes in LS type2 adapter state, where
the live_status behavior is normal
and reflects the real HPD line, but the moment we move to PCON mode, HPD
gets asserted low.

No, this chip/firmware resumes in PCON mode not in LS mode. Otherwise
native AUX transfers wouldn't return any reply (per LSPCON
specification) and HPD wouldn't get asserted on its own without a
display connected. Notice that we only check the LS/PCON state and
change it to PCON mode if necessary only after HPD gets asserted.

--Imre


I know you would have tested this well, but I also want to test this code
and logic first, before we go ahead with the patch.

Shashank

--Imre


- Shashank

+   !memcmp(&intel_dp->desc, &desc, sizeof(desc))) {
DRM_DEBUG_KMS("LSPCON recovering in PCON mode after %u 
ms\n"

Re: [Intel-gfx] [PATCH 3/4] drm/i915/lspcon: Remove DPCD compare based resume time workaround

2017-02-02 Thread Sharma, Shashank

Reviewed-by: Shashank Sharma

Regards
Shashank
On 1/28/2017 1:49 PM, Imre Deak wrote:

On Sat, Jan 28, 2017 at 10:36:16AM +0530, Sharma, Shashank wrote:

Regards

Shashank


On 1/27/2017 3:09 PM, Imre Deak wrote:

This effectively reverts
commit 489375c866c111f16cea93b2467ebe59c9022cc7
Author: Imre Deak 
Date:   Mon Oct 24 19:33:31 2016 +0300

 drm/i915/lspcon: Add workaround for resuming in PCON mode

The workaround was added without considering that HPD is low during
the failed AUX transfers the WA fixed. Since the previous patch we
wait for HPD to get asserted. My tests also show that this happens
_after_ the DPCD reads start to return correct values. This
suggests that we don't need this WA any more, let's try to remove
it to reduce the clutter.

Cc: Shashank Sharma 
Cc: Jani Nikula 
Cc: Ville Syrjälä 
Cc: Daniel Vetter 
Signed-off-by: Imre Deak 
---
  drivers/gpu/drm/i915/intel_drv.h|  1 -
  drivers/gpu/drm/i915/intel_lspcon.c | 17 ++---
  2 files changed, 2 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index b9cde11..b2882ff 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -989,7 +989,6 @@ struct intel_dp {
  struct intel_lspcon {
bool active;
enum drm_lspcon_mode mode;
-   bool desc_valid;
  };
  struct intel_digital_port {
diff --git a/drivers/gpu/drm/i915/intel_lspcon.c 
b/drivers/gpu/drm/i915/intel_lspcon.c
index c300647..71cbe9c 100644
--- a/drivers/gpu/drm/i915/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/intel_lspcon.c
@@ -162,21 +162,8 @@ static void lspcon_resume_in_pcon_wa(struct intel_lspcon 
*lspcon)
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
unsigned long start = jiffies;
-   if (!lspcon->desc_valid)
-   return;
-
while (1) {
-   struct intel_dp_desc desc;
-
-   /*
-* The w/a only applies in PCON mode and we don't expect any
-* AUX errors.
-*/
-   if (!__intel_dp_read_desc(intel_dp, &desc))
-   return;
-
-   if (intel_digital_port_connected(dev_priv, dig_port) &&
-   !memcmp(&intel_dp->desc, &desc, sizeof(desc))) {
+   if (intel_digital_port_connected(dev_priv, dig_port)) {

Again, does it matter, as in PCON mode live_status will be always true ?

See my answer for the previous patch.


- Shashank

DRM_DEBUG_KMS("LSPCON recovering in PCON mode after %u 
ms\n",
  jiffies_to_msecs(jiffies - start));
return;
@@ -253,7 +240,7 @@ bool lspcon_init(struct intel_digital_port *intel_dig_port)
return false;
}
-   lspcon->desc_valid = intel_dp_read_desc(dp);
+   intel_dp_read_desc(dp);
DRM_DEBUG_KMS("Success: LSPCON init\n");
return true;


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


Re: [Intel-gfx] [PATCH] drm/i915: fix i915 running as dom0 under Xen

2017-02-02 Thread Chris Wilson
On Thu, Feb 02, 2017 at 11:48:21AM +0100, Daniel Vetter wrote:
> On Thu, Feb 02, 2017 at 10:47:11AM +0100, Juergen Gross wrote:
> > Commit 920cf4194954ec ("drm/i915: Introduce an internal allocator for
> > disposable private objects") introduced a regression for the kernel
> > running as Xen dom0: when switching to graphics mode a GPU HANG
> > occurred.
> > 
> > Reason seems to be a missing adaption similar to that done in
> > commit 7453c549f5f648 ("swiotlb: Export swiotlb_max_segment to users")
> > to i915_gem_object_get_pages_internal().
> > 
> > So limit the maximum page order to be used according to the maximum
> > swiotlb segment size instead to the complete swiotlb size.
> > 
> > Signed-off-by: Juergen Gross 
> Fixes: 920cf4194954 ("drm/i915: Introduce an internal allocator for 
> disposable private objects")
> Cc: Chris Wilson 
> Cc: Tvrtko Ursulin 
> Cc: Daniel Vetter 
> Cc: Jani Nikula 
> Cc: intel-gfx@lists.freedesktop.org
> Cc:  # v4.10-rc1+
> 
> We have a nice script for these :-)

Pffifle. 7453c549f5f648 allowed Xen to change it and silently conflicted
with those that already used the previous limits, which didn't land in
our tree until v4.10-rc3.
-Chris

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


Re: [Intel-gfx] [PATCH] drm/i915/dp: Read link status more times when EQ not done

2017-02-02 Thread Jani Nikula
On Thu, 02 Feb 2017, "Lee, Shawn C"  wrote:
> From: "Lee, Shawn C" 
>
> When user space link status, display driver read DPCD register
> 0x202, 0x203 and 0x204 to identify sink status. When PSR exit
> is ongoing before EQ done. Panel will report EQ & symbol lock
> not done. Both of them are under progressing at the same time
> to cause this issue.
>
> This WA try to read link status more times if EQ not done.
> Panel spec request at least 1000us for fast link train when
> PSR exit. So driver will wait 1000us~1500us then retrieve
> sink link status again.

I'm not sure about the patch, but no matter what it needs to be rebased
on top of current drm-tip to even be considered.

If you're working around a specific eDP PSR issue, why do this on *all*
DP?

BR,
Jani.


>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99639
> TEST=Reboot DUT and no flicking on local display at login screen
>
> Cc: Cooper Chiou 
> Cc: Wei Shun Chen 
> Cc: Gary C Wang 
> Cc: Jani Nikula 
>
> Signed-off-by: Lee, Shawn C 
> ---
>  drivers/gpu/drm/i915/intel_dp.c |   33 -
>  1 file changed, 28 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index e80d620846c8..a9a6ce476438 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4136,13 +4136,36 @@ static void intel_dp_handle_test_request(struct 
> intel_dp *intel_dp)
>   return;
>  
>   /* if link training is requested we should perform it always */
> - if ((intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) ||
> - (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) {
> - DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
> -   intel_encoder->base.name);
> + if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) {
> + DRM_DEBUG_KMS("%s: compliance test mode, retraining\n",
> + intel_encoder->base.name);
> + } else {
> + u8 retry;
> +
> + for (retry = 0; retry < 3; retry++) {
> + if (!drm_dp_channel_eq_ok(link_status, 
> intel_dp->lane_count)) {
> + /*
> +  * EQ not ok may caused by fast link train 
> while exit PSR active,
> +  * wait at least 1000 us then read it again.
> +  */
> + DRM_DEBUG_KMS("%s: channel EQ not ok, retry = 
> %d, DPCD 0x202 = 0x%x, 0x203 = 0x%x, 0x204 = 0x%x\n",
> + intel_encoder->base.name, retry, 
> link_status[0], link_status[1], link_status[2]);
> + usleep_range(1000, 1500);
> + if (!intel_dp_get_link_status(intel_dp, 
> link_status)) {
> + DRM_ERROR("Failed to get link 
> status\n");
> + return;
> + }
> + } else {
> + /* channel EQ is fine */
> + return;
> + }
> + }
>  
> - intel_dp_retrain_link(intel_dp);
> + DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
> + intel_encoder->base.name);
>   }
> +
> + intel_dp_retrain_link(intel_dp);
>  }
>  
>  /*

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


[Intel-gfx] [PATCH i-g-t v2] tests/kms_plane_multiple: Test only with maximum number of planes

2017-02-02 Thread Mika Kahola
To be more suitable for BAT testing, let's modify the test such a way
that it only uses the maximum number of available planes. This reduces
the total number of subtests.

v2: Fix broken kms_plane_multiple --list-subtests (Petri)

Cc: Petri Latvala 
Cc: Robert Foss 
Signed-off-by: Mika Kahola 
---
 tests/kms_plane_multiple.c | 141 +
 1 file changed, 65 insertions(+), 76 deletions(-)

diff --git a/tests/kms_plane_multiple.c b/tests/kms_plane_multiple.c
index bb84878..4930286 100644
--- a/tests/kms_plane_multiple.c
+++ b/tests/kms_plane_multiple.c
@@ -171,7 +171,7 @@ create_fb_for_mode_position(data_t *data, igt_output_t 
*output, drmModeModeInfo
mode->hdisplay, mode->vdisplay,
color->red, color->green, color->blue);
 
-   for (int i = 0; i <= max_planes; i++) {
+   for (int i = 0; i < max_planes; i++) {
if (data->plane[i]->type == DRM_PLANE_TYPE_PRIMARY)
continue;
igt_paint_color(cr, rect_x[i], rect_y[i],
@@ -211,7 +211,7 @@ prepare_planes(data_t *data, enum pipe pipe_id, color_t 
*color,
/* planes with random positions */
x[primary->index] = 0;
y[primary->index] = 0;
-   for (i = 1; i <= max_planes; i++) {
+   for (i = 0; i < max_planes; i++) {
igt_plane_t *plane = igt_output_get_plane(output, i);
 
if (plane->type == DRM_PLANE_TYPE_PRIMARY)
@@ -247,7 +247,7 @@ prepare_planes(data_t *data, enum pipe pipe_id, color_t 
*color,
 static void
 test_atomic_plane_position_with_output(data_t *data, enum pipe pipe,
   igt_output_t *output, int n_planes,
-  int max_planes, uint64_t tiling)
+  uint64_t tiling)
 {
char buf[256];
struct drm_event *e = (void *)buf;
@@ -270,7 +270,7 @@ test_atomic_plane_position_with_output(data_t *data, enum 
pipe pipe,
}
 
igt_info("Testing connector %s using pipe %s with %d planes %s with 
seed %d\n",
-igt_output_name(output), kmstest_pipe_name(pipe), max_planes,
+igt_output_name(output), kmstest_pipe_name(pipe), n_planes,
 info, opt.seed);
 
test_init(data, pipe, n_planes);
@@ -280,7 +280,7 @@ test_atomic_plane_position_with_output(data_t *data, enum 
pipe pipe,
 
i = 0;
while (i < iterations || loop_forever) {
-   prepare_planes(data, pipe, &blue, tiling, max_planes, output);
+   prepare_planes(data, pipe, &blue, tiling, n_planes, output);
 
vblank_start = kmstest_get_vblank(data->display.drm_fd, pipe,
  DRM_VBLANK_NEXTONMISS);
@@ -316,7 +316,7 @@ test_atomic_plane_position_with_output(data_t *data, enum 
pipe pipe,
 static void
 test_legacy_plane_position_with_output(data_t *data, enum pipe pipe,
   igt_output_t *output, int n_planes,
-  int max_planes, uint64_t tiling)
+  uint64_t tiling)
 {
test_position_t test = { .data = data };
color_t blue  = { 0.0f, 0.0f, 1.0f };
@@ -336,7 +336,7 @@ test_legacy_plane_position_with_output(data_t *data, enum 
pipe pipe,
}
 
igt_info("Testing connector %s using pipe %s with %d planes %s with 
seed %d\n",
-igt_output_name(output), kmstest_pipe_name(pipe), max_planes,
+igt_output_name(output), kmstest_pipe_name(pipe), n_planes,
 info, opt.seed);
 
test_init(data, pipe, n_planes);
@@ -346,7 +346,7 @@ test_legacy_plane_position_with_output(data_t *data, enum 
pipe pipe,
 
i = 0;
while (i < iterations || loop_forever) {
-   prepare_planes(data, pipe, &blue, tiling, max_planes, output);
+   prepare_planes(data, pipe, &blue, tiling, n_planes, output);
 
igt_display_commit2(&data->display, COMMIT_LEGACY);
 
@@ -365,19 +365,16 @@ test_legacy_plane_position_with_output(data_t *data, enum 
pipe pipe,
 }
 
 static void
-test_plane_position(data_t *data, enum pipe pipe, bool atomic, int n_planes,
-   int max_planes, uint64_t tiling)
+test_plane_position(data_t *data, enum pipe pipe, bool atomic, uint64_t tiling)
 {
igt_output_t *output;
int connected_outs;
int devid = intel_get_drm_devid(data->drm_fd);
+   int n_planes = data->display.pipes[pipe].n_planes;
 
if (atomic)
igt_require(data->display.is_atomic);
 
-   igt_skip_on(pipe >= data->display.n_pipes);
-   igt_skip_on(max_planes >= data->display.pipes[pipe].n_planes);
-
if ((tiling == LOCAL_I915_FORMAT_MOD_Y_TILED ||
 tiling == LOCAL_I915_FORMAT_MOD_Yf_TILED))
igt_require(AT_LEAST_GEN(devid, 9));
@@ -392,14 +389,12 @@ test_plane

Re: [Intel-gfx] [PATCH 1/6] drm: Add SCDC helpers

2017-02-02 Thread Jani Nikula
On Wed, 01 Feb 2017, Shashank Sharma  wrote:
> From: Thierry Reding 
>
> SCDC is a mechanism defined in the HDMI 2.0 specification that allows
> the source and sink devices to communicate.
>
> This commit introduces helpers to access the SCDC and provides the
> symbolic names for the various registers defined in the specification.
>
> Signed-off-by: Thierry Reding 

One process note, you need to add your own Signed-off-by under the
original author's sign-off, even when you're posting them unchanged.

Signed-off-by means https://developercertificate.org/

BR,
Jani.


> ---
>  Documentation/gpu/drm-kms-helpers.rst |  12 
>  drivers/gpu/drm/Makefile  |   3 +-
>  drivers/gpu/drm/drm_scdc_helper.c | 111 
>  include/drm/drm_scdc_helper.h | 132 
> ++
>  4 files changed, 257 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/drm_scdc_helper.c
>  create mode 100644 include/drm/drm_scdc_helper.h
>
> diff --git a/Documentation/gpu/drm-kms-helpers.rst 
> b/Documentation/gpu/drm-kms-helpers.rst
> index 03040aa..7592756 100644
> --- a/Documentation/gpu/drm-kms-helpers.rst
> +++ b/Documentation/gpu/drm-kms-helpers.rst
> @@ -217,6 +217,18 @@ EDID Helper Functions Reference
>  .. kernel-doc:: drivers/gpu/drm/drm_edid.c
> :export:
>  
> +SCDC Helper Functions Reference
> +===
> +
> +.. kernel-doc:: drivers/gpu/drm/drm_scdc_helper.c
> +   :doc: scdc helpers
> +
> +.. kernel-doc:: include/drm/drm_scdc_helper.h
> +   :internal:
> +
> +.. kernel-doc:: drivers/gpu/drm/drm_scdc_helper.c
> +   :export:
> +
>  Rectangle Utilities Reference
>  =
>  
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 92de399..ad91cd9 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -31,7 +31,8 @@ drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
>  drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
>   drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
>   drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
> - drm_simple_kms_helper.o drm_modeset_helper.o
> + drm_simple_kms_helper.o drm_modeset_helper.o \
> + drm_scdc_helper.o
>  
>  drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
>  drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
> diff --git a/drivers/gpu/drm/drm_scdc_helper.c 
> b/drivers/gpu/drm/drm_scdc_helper.c
> new file mode 100644
> index 000..fe0e121
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_scdc_helper.c
> @@ -0,0 +1,111 @@
> +/*
> + * Copyright (c) 2015 NVIDIA Corporation. All rights reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sub license,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include 
> +
> +#include 
> +
> +/**
> + * DOC: scdc helpers
> + *
> + * Status and Control Data Channel (SCDC) is a mechanism introduced by the
> + * HDMI 2.0 specification. It is a point-to-point protocol that allows the
> + * HDMI source and HDMI sink to exchange data. The same I2C interface that
> + * is used to access EDID serves as the transport mechanism for SCDC.
> + */
> +
> +#define SCDC_I2C_SLAVE_ADDRESS 0x54
> +
> +/**
> + * drm_scdc_read - read a block of data from SCDC
> + * @adapter: I2C controller
> + * @offset: start offset of block to read
> + * @buffer: return location for the block to read
> + * @size: size of the block to read
> + *
> + * Reads a block of data from SCDC, starting at a given offset.
> + *
> + * Returns:
> + * The number of bytes read from SCDC or a negative error code on failure.
> + */
> +ssize_t drm_scdc_read(struct i2c_adapter *adapter, u8 offset, void *buffer,
> +   size_t size)
> +{
> + struct i2c_msg msgs[2] = {
> + {
> + .addr = SCDC_I2C_SL

[Intel-gfx] ✗ Fi.CI.BAT: failure for series starting with [v6] drm: Provide a driver hook for drm_dev_release() (rev2)

2017-02-02 Thread Patchwork
== Series Details ==

Series: series starting with [v6] drm: Provide a driver hook for 
drm_dev_release() (rev2)
URL   : https://patchwork.freedesktop.org/series/18974/
State : failure

== Summary ==

  CC [M]  drivers/gpu/drm/i915/gvt/firmware.o
  CC [M]  drivers/gpu/drm/i915/gvt/trace_points.o
  CC [M]  drivers/gpu/drm/i915/gvt/vgpu.o
  CC [M]  drivers/gpu/drm/i915/gvt/interrupt.o
  CC [M]  drivers/gpu/drm/i915/gvt/display.o
  CC [M]  drivers/gpu/drm/i915/gvt/mmio.o
  CC [M]  drivers/gpu/drm/i915/gvt/cfg_space.o
  CC [M]  drivers/gpu/drm/i915/gvt/edid.o
  CC [M]  drivers/gpu/drm/i915/gvt/opregion.o
  CC [M]  drivers/gpu/drm/i915/gvt/scheduler.o
  CC [M]  drivers/gpu/drm/i915/gvt/execlist.o
  CC [M]  drivers/gpu/drm/i915/gvt/gtt.o
  CC [M]  drivers/gpu/drm/i915/gvt/sched_policy.o
  CC [M]  drivers/gpu/drm/i915/gvt/render.o
  CC [M]  drivers/gpu/drm/i915/intel_lpe_audio.o
  CC [M]  drivers/gpu/drm/i915/gvt/cmd_parser.o
  LD  drivers/tty/serial/8250/8250.o
  LD [M]  drivers/mmc/core/mmc_block.o
  LD  drivers/usb/storage/usb-storage.o
  LD  drivers/mmc/built-in.o
  LD  drivers/usb/storage/built-in.o
  LD  lib/raid6/raid6_pq.o
  LD [M]  drivers/gpu/drm/vgem/vgem.o
  LD  lib/raid6/built-in.o
  LD  drivers/scsi/scsi_mod.o
  LD  drivers/acpi/acpica/acpi.o
  LD  drivers/video/console/built-in.o
  LD  drivers/video/built-in.o
  LD  drivers/spi/built-in.o
  LD  drivers/acpi/acpica/built-in.o
  LD [M]  drivers/net/ethernet/intel/e1000/e1000.o
  LD  drivers/usb/gadget/libcomposite.o
  LD  net/ipv6/ipv6.o
  LD  drivers/acpi/built-in.o
  LD  net/ipv6/built-in.o
  LD  drivers/usb/gadget/udc/udc-core.o
  LD  drivers/usb/gadget/udc/built-in.o
  LD  drivers/usb/gadget/built-in.o
In file included from drivers/gpu/drm/i915/i915_gem_gtt.c:3764:0:
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c: In function ‘igt_ggtt_page’:
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c:715:8: error: ‘DRM_MM_INSERT_LOW’ 
undeclared (first use in this function)
DRM_MM_INSERT_LOW);
^
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c:715:8: note: each undeclared 
identifier is reported only once for each function it appears in
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c:711:8: error: too many arguments 
to function ‘drm_mm_insert_node_in_range’
  err = drm_mm_insert_node_in_range(&ggtt->base.mm, &tmp,
^
In file included from ./include/drm/drmP.h:75:0,
 from drivers/gpu/drm/i915/i915_gem_gtt.c:31:
./include/drm/drm_mm.h:356:19: note: declared here
 static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
   ^
  LD  drivers/gpu/drm/drm.o
scripts/Makefile.build:293: recipe for target 
'drivers/gpu/drm/i915/i915_gem_gtt.o' failed
make[4]: *** [drivers/gpu/drm/i915/i915_gem_gtt.o] Error 1
make[4]: *** Waiting for unfinished jobs
  LD  drivers/scsi/sd_mod.o
  LD [M]  sound/pci/hda/snd-hda-codec-generic.o
  LD  drivers/scsi/built-in.o
  LD  sound/pci/built-in.o
  LD  sound/built-in.o
  LD  drivers/tty/serial/8250/8250_base.o
  LD  drivers/tty/serial/8250/built-in.o
  LD  drivers/tty/serial/built-in.o
  LD  net/ipv4/built-in.o
  LD [M]  drivers/net/ethernet/intel/igb/igb.o
  LD  drivers/md/md-mod.o
  LD  drivers/md/built-in.o
  AR  lib/lib.a
  LD  drivers/usb/core/usbcore.o
  EXPORTS lib/lib-ksyms.o
  LD  drivers/usb/core/built-in.o
  CC  arch/x86/kernel/cpu/capflags.o
  LD  arch/x86/kernel/cpu/built-in.o
  LD  arch/x86/kernel/built-in.o
  LD  drivers/tty/vt/built-in.o
  LD  drivers/tty/built-in.o
  LD  lib/built-in.o
  LD  fs/btrfs/btrfs.o
  LD  arch/x86/built-in.o
  LD  fs/btrfs/built-in.o
  LD  drivers/usb/host/xhci-hcd.o
  LD  fs/ext4/ext4.o
  LD  fs/ext4/built-in.o
  LD  fs/built-in.o
  LD  drivers/usb/host/built-in.o
  LD  drivers/usb/built-in.o
  LD [M]  drivers/net/ethernet/intel/e1000e/e1000e.o
  LD  net/core/built-in.o
  LD  net/built-in.o
  LD  drivers/net/ethernet/built-in.o
  LD  drivers/net/built-in.o
scripts/Makefile.build:551: recipe for target 'drivers/gpu/drm/i915' failed
make[3]: *** [drivers/gpu/drm/i915] Error 2
scripts/Makefile.build:551: recipe for target 'drivers/gpu/drm' failed
make[2]: *** [drivers/gpu/drm] Error 2
scripts/Makefile.build:551: recipe for target 'drivers/gpu' failed
make[1]: *** [drivers/gpu] Error 2
Makefile:988: recipe for target 'drivers' failed
make: *** [drivers] Error 2

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


Re: [Intel-gfx] [PATCH] drm/i915: Release the forgotten connector reference

2017-02-02 Thread Daniel Vetter
On Thu, Feb 02, 2017 at 08:16:23AM +, Chris Wilson wrote:
> On Thu, Feb 02, 2017 at 10:08:57AM +0200, Joonas Lahtinen wrote:
> > On ke, 2017-02-01 at 19:58 +, Chris Wilson wrote:
> > > The reference was gained in
> > > intel_modeset_update_connector_atomic_state() [called from
> > > intel_modeset_setup_hw_state()] and is never lost if no client ever
> > > performs a modeset.
> > > 
> > > [  649.836069] WARNING: CPU: 6 PID: 8865 at 
> > > drivers/gpu/drm/drm_mode_config.c:424 drm_mode_config_cleanup+0x21b/0x290 
> > > [drm]
> > > [  649.836078] Modules linked in: i915(-) intel_gtt drm_kms_helper 
> > > cfbfillrect syscopyarea cfbimgblt sysfillrect sysimgblt fb_sys_fops 
> > > cfbcopyarea drm
> > > [  649.836099] CPU: 6 PID: 8865 Comm: drv_selftest Not tainted 
> > > 4.10.0-rc6+ #908
> > > [  649.836106] Hardware name: Intel Corporation 2012 Client 
> > > Platform/Emerald Lake 2, BIOS ACRVMBY1.86C.0078.P00.1201161002 01/16/2012
> > > [  649.836114] Call Trace:
> > > [  649.836125]  dump_stack+0x4d/0x6f
> > > [  649.836136]  __warn+0xc1/0xe0
> > > [  649.836144]  warn_slowpath_null+0x18/0x20
> > > [  649.836163]  drm_mode_config_cleanup+0x21b/0x290 [drm]
> > > [  649.836213]  intel_modeset_cleanup+0x59/0xa0 [i915]
> > > [  649.836242]  i915_driver_unload+0x84/0x170 [i915]
> > > [  649.836277]  i915_pci_remove+0x14/0x20 [i915]
> > > [  649.836287]  pci_device_remove+0x28/0x60
> > > [  649.836301]  device_release_driver_internal+0x132/0x1d0
> > > [  649.836313]  driver_detach+0x3a/0x80
> > > [  649.836324]  bus_remove_driver+0x47/0xa0
> > > [  649.836335]  driver_unregister+0x27/0x50
> > > [  649.836344]  pci_unregister_driver+0x34/0xa0
> > > [  649.836387]  i915_exit+0x1a/0x71 [i915]
> > > [  649.836401]  SyS_delete_module+0x173/0x1c0
> > > [  649.836413]  entry_SYSCALL_64_fastpath+0x17/0x98
> > > [  649.836422] RIP: 0033:0x7f8d5a841ee7
> > > [  649.836432] RSP: 002b:7fff89161a28 EFLAGS: 0206 ORIG_RAX: 
> > > 00b0
> > > [  649.836448] RAX: ffda RBX: 55f6cd1db5c0 RCX: 
> > > 7f8d5a841ee7
> > > [  649.836458] RDX:  RSI: 0800 RDI: 
> > > 55f6cd1da7b8
> > > [  649.836467] RBP: 7f8d5aaee440 R08:  R09: 
> > > 7fff89161a58
> > > [  649.836476] R10: 0062 R11: 0206 R12: 
> > > 
> > > [  649.836486] R13: 55f6cd1d9010 R14: 003a R15: 
> > > 7fff891609f0
> > > [  649.836514] ---[ end trace 0e529da316e2a3d1 ]---
> > > [  649.836536] [drm:drm_mode_config_cleanup [drm]] *ERROR* connector 
> > > VGA-1 leaked!
> > > 
> > > Signed-off-by: Chris Wilson 
> > 
> > Reviewed-by: Joonas Lahtinen 
> 
> I'm hoping that this won't be required after Maarten's force disable all
> CRTC on unload. We will see.

Yeah, I think landing that would be better, but if this is annoying CI or
something like that, I'm ok with merging already with a FIXME comment
added.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v4 2/2] drm: kselftest for drm_mm and bottom-up allocation

2017-02-02 Thread Chris Wilson
Check that if we request bottom-up allocation from drm_mm_insert_node()
we receive the next available hole from the bottom.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 100 +++
 2 files changed, 101 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 6a4575fdc1c0..37bbdac52896 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -17,6 +17,7 @@ selftest(align32, igt_align32)
 selftest(align64, igt_align64)
 selftest(evict, igt_evict)
 selftest(evict_range, igt_evict_range)
+selftest(bottomup, igt_bottomup)
 selftest(topdown, igt_topdown)
 selftest(color, igt_color)
 selftest(color_evict, igt_color_evict)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index bb5b7480e0b4..1e71bc182ca9 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1697,6 +1697,106 @@ static int igt_topdown(void *ignored)
return ret;
 }
 
+static int igt_bottomup(void *ignored)
+{
+   const struct insert_mode *bottomup = &insert_modes[BOTTOMUP];
+   DRM_RND_STATE(prng, random_seed);
+   const unsigned int count = 8192;
+   unsigned int size;
+   unsigned long *bitmap;
+   struct drm_mm mm;
+   struct drm_mm_node *nodes, *node, *next;
+   unsigned int *order, n, m, o = 0;
+   int ret;
+
+   /* Like igt_topdown, but instead of searching for the last hole,
+* we search for the first.
+*/
+
+   ret = -ENOMEM;
+   nodes = vzalloc(count * sizeof(*nodes));
+   if (!nodes)
+   goto err;
+
+   bitmap = kzalloc(count / BITS_PER_LONG * sizeof(unsigned long),
+GFP_TEMPORARY);
+   if (!bitmap)
+   goto err_nodes;
+
+   order = drm_random_order(count, &prng);
+   if (!order)
+   goto err_bitmap;
+
+   ret = -EINVAL;
+   for (size = 1; size <= 64; size <<= 1) {
+   drm_mm_init(&mm, 0, size*count);
+   for (n = 0; n < count; n++) {
+   if (!expect_insert(&mm, &nodes[n],
+  size, 0, n,
+  bottomup)) {
+   pr_err("bottomup insert failed, size %u step 
%d\n", size, n);
+   goto out;
+   }
+
+   if (!assert_one_hole(&mm, size*(n + 1), size*count))
+   goto out;
+   }
+
+   if (!assert_continuous(&mm, size))
+   goto out;
+
+   drm_random_reorder(order, count, &prng);
+   for_each_prime_number_from(n, 1, min(count, max_prime)) {
+   for (m = 0; m < n; m++) {
+   node = &nodes[order[(o + m) % count]];
+   drm_mm_remove_node(node);
+   __set_bit(node_index(node), bitmap);
+   }
+
+   for (m = 0; m < n; m++) {
+   unsigned int first;
+
+   node = &nodes[order[(o + m) % count]];
+   if (!expect_insert(&mm, node,
+  size, 0, 0,
+  bottomup)) {
+   pr_err("insert failed, step %d/%d\n", 
m, n);
+   goto out;
+   }
+
+   first = find_first_bit(bitmap, count);
+   if (node_index(node) != first) {
+   pr_err("node %d/%d not inserted into 
bottom hole, expected %d, found %d\n",
+  m, n, first, node_index(node));
+   goto out;
+   }
+   __clear_bit(first, bitmap);
+   }
+
+   DRM_MM_BUG_ON(find_first_bit(bitmap, count) != count);
+
+   o += n;
+   }
+
+   drm_mm_for_each_node_safe(node, next, &mm)
+   drm_mm_remove_node(node);
+   DRM_MM_BUG_ON(!drm_mm_clean(&mm));
+   }
+
+   ret = 0;
+out:
+   drm_mm_for_each_node_safe(node, next, &mm)
+   drm_mm_remove_node(node);
+   drm_mm_takedown(&mm);
+   kfree(order);
+err_bitmap:
+   kfree(bitmap);
+err_nodes:
+   vfree(nodes);
+err:
+   return ret;
+}
+
 static void separate_adjacent_colors(const struct drm_mm_node *node,
 unsigned long color,
 

[Intel-gfx] [PATCH v4 1/2] drm: Improve drm_mm search (and fix topdown allocation) with rbtrees

2017-02-02 Thread Chris Wilson
The drm_mm range manager claimed to support top-down insertion, but it
was neither searching for the top-most hole that could fit the
allocation request nor fitting the request to the hole correctly.

In order to search the range efficiently, we create a secondary index
for the holes using either their size or their address. This index
allows us to find the smallest hole or the hole at the bottom or top of
the range efficiently, whilst keeping the hole stack to rapidly service
evictions.

v2: Search for holes both high and low. Rename flags to mode.
v3: Discover rb_entry_safe() and use it!
v4: Kerneldoc for enum drm_mm_insert_mode.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
Cc: Alex Deucher 
Cc: "Christian König" 
Cc: David Airlie 
Cc: Russell King 
Cc: Daniel Vetter 
Cc: Jani Nikula 
Cc: Sean Paul 
Cc: Lucas Stach 
Cc: Christian Gmeiner 
Cc: Rob Clark 
Cc: Thierry Reding 
Cc: Stephen Warren 
Cc: Alexandre Courbot 
Cc: Eric Anholt 
Cc: Sinclair Yeh 
Cc: Thomas Hellstrom 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c  |  16 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c |  20 +-
 drivers/gpu/drm/armada/armada_gem.c  |   4 +-
 drivers/gpu/drm/drm_mm.c | 488 +++
 drivers/gpu/drm/drm_vma_manager.c|   3 +-
 drivers/gpu/drm/etnaviv/etnaviv_mmu.c|  16 +-
 drivers/gpu/drm/i915/i915_gem.c  |  10 +-
 drivers/gpu/drm/i915/i915_gem_evict.c|   9 +-
 drivers/gpu/drm/i915/i915_gem_execbuffer.c   |   5 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c  |  39 +--
 drivers/gpu/drm/i915/i915_gem_stolen.c   |   6 +-
 drivers/gpu/drm/msm/msm_gem.c|   3 +-
 drivers/gpu/drm/msm/msm_gem_vma.c|   3 +-
 drivers/gpu/drm/selftests/test-drm_mm.c  |  58 ++--
 drivers/gpu/drm/sis/sis_mm.c |   6 +-
 drivers/gpu/drm/tegra/gem.c  |   4 +-
 drivers/gpu/drm/ttm/ttm_bo_manager.c |  18 +-
 drivers/gpu/drm/vc4/vc4_crtc.c   |   2 +-
 drivers/gpu/drm/vc4/vc4_hvs.c|   3 +-
 drivers/gpu/drm/vc4/vc4_plane.c  |   6 +-
 drivers/gpu/drm/via/via_mm.c |   4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c   |  10 +-
 include/drm/drm_mm.h | 184 +-
 23 files changed, 470 insertions(+), 447 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
index e4eb6dd3798a..0335c2f331e9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
@@ -97,8 +97,7 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
 {
struct amdgpu_gtt_mgr *mgr = man->priv;
struct drm_mm_node *node = mem->mm_node;
-   enum drm_mm_search_flags sflags = DRM_MM_SEARCH_BEST;
-   enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT;
+   enum drm_mm_insert_mode mode;
unsigned long fpfn, lpfn;
int r;
 
@@ -115,15 +114,14 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
else
lpfn = man->size;
 
-   if (place && place->flags & TTM_PL_FLAG_TOPDOWN) {
-   sflags = DRM_MM_SEARCH_BELOW;
-   aflags = DRM_MM_CREATE_TOP;
-   }
+   mode = DRM_MM_INSERT_BEST;
+   if (place && place->flags & TTM_PL_FLAG_TOPDOWN)
+   mode = DRM_MM_INSERT_HIGH;
 
spin_lock(&mgr->lock);
-   r = drm_mm_insert_node_in_range_generic(&mgr->mm, node, mem->num_pages,
-   mem->page_alignment, 0,
-   fpfn, lpfn, sflags, aflags);
+   r = drm_mm_insert_node_in_range(&mgr->mm, node,
+   mem->num_pages, mem->page_alignment, 0,
+   fpfn, lpfn, mode);
spin_unlock(&mgr->lock);
 
if (!r) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index ac9007986c11..9e577e3d3147 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -97,8 +97,7 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager 
*man,
struct amdgpu_vram_mgr *mgr = man->priv;
struct drm_mm *mm = &mgr->mm;
struct drm_mm_node *nodes;
-   enum drm_mm_search_flags sflags = DRM_MM_SEARCH_DEFAULT;
-   enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT;
+   enum drm_mm_insert_mode mode;
unsigned long lpfn, num_nodes, pages_per_node, pages_left;
unsigned i;
int r;
@@ -121,10 +120,9 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager 
*man,
if (!nodes)
return -ENOMEM;
 
-   if (place->flags & TTM_PL_FLAG_TOPDOWN) {
-   sflags = DRM_MM_SEARCH_BELOW;
-   aflags = DRM_MM_CREATE_TOP;
-   }
+   mode = DRM_MM_INSERT_BEST;
+   

Re: [Intel-gfx] [PATCH 1/6] drm: Add SCDC helpers

2017-02-02 Thread Sharma, Shashank
Sure, Thanks for the information, will add that in V2.   

Regards
Shashank
-Original Message-
From: Jani Nikula [mailto:jani.nik...@linux.intel.com] 
Sent: Thursday, February 2, 2017 4:55 PM
To: Sharma, Shashank ; 
dri-de...@lists.freedesktop.org; intel-gfx@lists.freedesktop.org; 
ville.syrj...@linux.intel.com
Cc: jose.ab...@synopsys.com; =daniel.vet...@intel.com; Thierry Reding 
; thierry.red...@gmail.com
Subject: Re: [Intel-gfx] [PATCH 1/6] drm: Add SCDC helpers

On Wed, 01 Feb 2017, Shashank Sharma  wrote:
> From: Thierry Reding 
>
> SCDC is a mechanism defined in the HDMI 2.0 specification that allows 
> the source and sink devices to communicate.
>
> This commit introduces helpers to access the SCDC and provides the 
> symbolic names for the various registers defined in the specification.
>
> Signed-off-by: Thierry Reding 

One process note, you need to add your own Signed-off-by under the original 
author's sign-off, even when you're posting them unchanged.

Signed-off-by means https://developercertificate.org/

BR,
Jani.


> ---
>  Documentation/gpu/drm-kms-helpers.rst |  12 
>  drivers/gpu/drm/Makefile  |   3 +-
>  drivers/gpu/drm/drm_scdc_helper.c | 111 
>  include/drm/drm_scdc_helper.h | 132 
> ++
>  4 files changed, 257 insertions(+), 1 deletion(-)  create mode 100644 
> drivers/gpu/drm/drm_scdc_helper.c  create mode 100644 
> include/drm/drm_scdc_helper.h
>
> diff --git a/Documentation/gpu/drm-kms-helpers.rst 
> b/Documentation/gpu/drm-kms-helpers.rst
> index 03040aa..7592756 100644
> --- a/Documentation/gpu/drm-kms-helpers.rst
> +++ b/Documentation/gpu/drm-kms-helpers.rst
> @@ -217,6 +217,18 @@ EDID Helper Functions Reference  .. kernel-doc:: 
> drivers/gpu/drm/drm_edid.c
> :export:
>  
> +SCDC Helper Functions Reference
> +===
> +
> +.. kernel-doc:: drivers/gpu/drm/drm_scdc_helper.c
> +   :doc: scdc helpers
> +
> +.. kernel-doc:: include/drm/drm_scdc_helper.h
> +   :internal:
> +
> +.. kernel-doc:: drivers/gpu/drm/drm_scdc_helper.c
> +   :export:
> +
>  Rectangle Utilities Reference
>  =
>  
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 
> 92de399..ad91cd9 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -31,7 +31,8 @@ drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o 
> drm_debugfs_crc.o  drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o 
> drm_probe_helper.o \
>   drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
>   drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
> - drm_simple_kms_helper.o drm_modeset_helper.o
> + drm_simple_kms_helper.o drm_modeset_helper.o \
> + drm_scdc_helper.o
>  
>  drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
>  drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o diff 
> --git a/drivers/gpu/drm/drm_scdc_helper.c 
> b/drivers/gpu/drm/drm_scdc_helper.c
> new file mode 100644
> index 000..fe0e121
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_scdc_helper.c
> @@ -0,0 +1,111 @@
> +/*
> + * Copyright (c) 2015 NVIDIA Corporation. All rights reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person 
> +obtaining a
> + * copy of this software and associated documentation files (the 
> +"Software"),
> + * to deal in the Software without restriction, including without 
> +limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sub 
> +license,
> + * and/or sell copies of the Software, and to permit persons to whom 
> +the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including 
> +the
> + * next paragraph) shall be included in all copies or substantial 
> +portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
> +EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
> +MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT 
> +SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 
> +OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
> +ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
> +OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include 
> +
> +#include 
> +
> +/**
> + * DOC: scdc helpers
> + *
> + * Status and Control Data Channel (SCDC) is a mechanism introduced 
> +by the
> + * HDMI 2.0 specification. It is a point-to-point protocol that 
> +allows the
> + * HDMI source and HDMI sink to exchange data. The same I2C interface 
> +that
> + * is used to access EDID serves as the transport mechanism for SCDC.
> + */
> +
> +#define SCDC_I2C_SLAVE_ADDRESS 0x54
> +
> +/**
> + * drm_scdc_read - read a block of data from SCDC
> + * @

Re: [Intel-gfx] [PATCH] drm/i915: fix i915 running as dom0 under Xen

2017-02-02 Thread Tvrtko Ursulin


On 02/02/2017 09:47, Juergen Gross wrote:

Commit 920cf4194954ec ("drm/i915: Introduce an internal allocator for
disposable private objects") introduced a regression for the kernel
running as Xen dom0: when switching to graphics mode a GPU HANG
occurred.

Reason seems to be a missing adaption similar to that done in
commit 7453c549f5f648 ("swiotlb: Export swiotlb_max_segment to users")
to i915_gem_object_get_pages_internal().

So limit the maximum page order to be used according to the maximum
swiotlb segment size instead to the complete swiotlb size.

Signed-off-by: Juergen Gross 
---
Please consider for 4.10 as otherwise 4.10 will be unusable as Xen dom0
with i915 graphics.
---
 drivers/gpu/drm/i915/i915_gem_internal.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c 
b/drivers/gpu/drm/i915/i915_gem_internal.c
index 4b3ff3e..d09c749 100644
--- a/drivers/gpu/drm/i915/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/i915_gem_internal.c
@@ -66,8 +66,16 @@ i915_gem_object_get_pages_internal(struct 
drm_i915_gem_object *obj)

max_order = MAX_ORDER;
 #ifdef CONFIG_SWIOTLB
-   if (swiotlb_nr_tbl()) /* minimum max swiotlb size is IO_TLB_SEGSIZE */
-   max_order = min(max_order, ilog2(IO_TLB_SEGPAGES));
+   if (swiotlb_nr_tbl()) {
+   unsigned int max_segment;
+
+   max_segment = swiotlb_max_segment();
+   if (max_segment) {
+   max_segment = max_t(unsigned int, max_segment,
+   PAGE_SIZE) >> PAGE_SHIFT;
+   max_order = min(max_order, ilog2(max_segment));
+   }
+   }
 #endif

gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_RECLAIMABLE;



Looks OK to me. We could bikeshed it to only use swiotlb_max_segment() 
which I think was the intention when that API was added but can leave 
that for the future.


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] ✗ Fi.CI.BAT: failure for drm/i915: fix i915 running as dom0 under Xen

2017-02-02 Thread Patchwork
== Series Details ==

Series: drm/i915: fix i915 running as dom0 under Xen
URL   : https://patchwork.freedesktop.org/series/18979/
State : failure

== Summary ==

Series 18979v1 drm/i915: fix i915 running as dom0 under Xen
https://patchwork.freedesktop.org/api/1.0/series/18979/revisions/1/mbox/

Test gem_exec_flush:
Subgroup basic-wb-ro-default:
pass   -> INCOMPLETE (fi-byt-j1900)
Test kms_pipe_crc_basic:
Subgroup nonblocking-crc-pipe-c-frame-sequence:
fail   -> PASS   (fi-skl-6770hq)

fi-bdw-5557u total:247  pass:233  dwarn:0   dfail:0   fail:0   skip:14 
fi-bsw-n3050 total:247  pass:208  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205 total:247  pass:225  dwarn:0   dfail:0   fail:0   skip:22 
fi-bxt-t5700 total:78   pass:65   dwarn:0   dfail:0   fail:0   skip:12 
fi-byt-j1900 total:56   pass:46   dwarn:0   dfail:0   fail:0   skip:9  
fi-byt-n2820 total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770  total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-hsw-4770r total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-ivb-3520m total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-ivb-3770  total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-kbl-7500u total:247  pass:224  dwarn:0   dfail:0   fail:2   skip:21 
fi-skl-6260u total:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-skl-6700hqtotal:247  pass:227  dwarn:0   dfail:0   fail:0   skip:20 
fi-skl-6700k total:247  pass:222  dwarn:4   dfail:0   fail:0   skip:21 
fi-skl-6770hqtotal:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-snb-2520m total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-snb-2600  total:247  pass:215  dwarn:0   dfail:0   fail:0   skip:32 

ce4c6eb9b0d270df56813af310cd918298ac7ba2 drm-tip: 2017y-02m-02d-10h-12m-30s UTC 
integration manifest
a372572 drm/i915: fix i915 running as dom0 under Xen

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3673/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: fix i915 running as dom0 under Xen

2017-02-02 Thread Chris Wilson
On Thu, Feb 02, 2017 at 12:11:29PM +, Tvrtko Ursulin wrote:
> 
> On 02/02/2017 09:47, Juergen Gross wrote:
> >Commit 920cf4194954ec ("drm/i915: Introduce an internal allocator for
> >disposable private objects") introduced a regression for the kernel
> >running as Xen dom0: when switching to graphics mode a GPU HANG
> >occurred.
> >
> >Reason seems to be a missing adaption similar to that done in
> >commit 7453c549f5f648 ("swiotlb: Export swiotlb_max_segment to users")
> >to i915_gem_object_get_pages_internal().
> >
> >So limit the maximum page order to be used according to the maximum
> >swiotlb segment size instead to the complete swiotlb size.
> >
> >Signed-off-by: Juergen Gross 
> >---
> >Please consider for 4.10 as otherwise 4.10 will be unusable as Xen dom0
> >with i915 graphics.
> >---
> > drivers/gpu/drm/i915/i915_gem_internal.c | 12 ++--
> > 1 file changed, 10 insertions(+), 2 deletions(-)
> >
> >diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c 
> >b/drivers/gpu/drm/i915/i915_gem_internal.c
> >index 4b3ff3e..d09c749 100644
> >--- a/drivers/gpu/drm/i915/i915_gem_internal.c
> >+++ b/drivers/gpu/drm/i915/i915_gem_internal.c
> >@@ -66,8 +66,16 @@ i915_gem_object_get_pages_internal(struct 
> >drm_i915_gem_object *obj)
> >
> > max_order = MAX_ORDER;
> > #ifdef CONFIG_SWIOTLB
> >-if (swiotlb_nr_tbl()) /* minimum max swiotlb size is IO_TLB_SEGSIZE */
> >-max_order = min(max_order, ilog2(IO_TLB_SEGPAGES));
> >+if (swiotlb_nr_tbl()) {
> >+unsigned int max_segment;
> >+
> >+max_segment = swiotlb_max_segment();
> >+if (max_segment) {
> >+max_segment = max_t(unsigned int, max_segment,
> >+PAGE_SIZE) >> PAGE_SHIFT;
> >+max_order = min(max_order, ilog2(max_segment));
> >+}
> >+}
> > #endif
> >
> > gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_RECLAIMABLE;
> >
> 
> Looks OK to me. We could bikeshed it to only use
> swiotlb_max_segment() which I think was the intention when that API
> was added but can leave that for the future.
> 
> Reviewed-by: Tvrtko Ursulin 

Pushed, I imagine this has been added to the list of sg cleanups you
have :)
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
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: enable scrambling

2017-02-02 Thread Ville Syrjälä
On Thu, Feb 02, 2017 at 04:15:21PM +0530, Sharma, Shashank wrote:
> Regards
> 
> Shashank
> 
> 
> On 2/2/2017 3:32 PM, Ville Syrjälä wrote:
> > On Thu, Feb 02, 2017 at 11:23:19AM +0530, Sharma, Shashank wrote:
> >> Regards
> >>
> >> Shashank
> >>
> >>
> >> On 2/1/2017 10:06 PM, Ville Syrjälä wrote:
> >>> On Wed, Feb 01, 2017 at 06:14:40PM +0530, Shashank Sharma wrote:
>  Geminilake platform has a native HDMI 2.0 controller, and is
>  capable of driving pixel-clocks upto 594Mhz. HDMI 2.0 spec
>  mendates scrambling for these higher clocks, for reduced RF footprint.
> 
>  This patch checks if the monitor supports scrambling, and if required,
>  enables it during the modeset.
> 
>  Signed-off-by: Shashank Sharma 
>  ---
> drivers/gpu/drm/i915/i915_reg.h   |  2 ++
> drivers/gpu/drm/i915/intel_ddi.c  |  5 +
> drivers/gpu/drm/i915/intel_drv.h  |  2 ++
> drivers/gpu/drm/i915/intel_hdmi.c | 42 
>  +++
> 4 files changed, 51 insertions(+)
> 
>  diff --git a/drivers/gpu/drm/i915/i915_reg.h 
>  b/drivers/gpu/drm/i915/i915_reg.h
>  index 495b789..cc85892 100644
>  --- a/drivers/gpu/drm/i915/i915_reg.h
>  +++ b/drivers/gpu/drm/i915/i915_reg.h
>  @@ -7807,6 +7807,8 @@ enum {
> #define  TRANS_DDI_EDP_INPUT_C_ONOFF  (6<<12)
> #define  TRANS_DDI_DP_VC_PAYLOAD_ALLOC(1<<8)
> #define  TRANS_DDI_BFI_ENABLE (1<<4)
>  +#define  TRANS_DDI_HIGH_TMDS_CHAR_RATE  (1<<4)
>  +#define  TRANS_DDI_HDMI_SCRAMBLING  (1<<0)
> 
> /* DisplayPort Transport Control */
> #define _DP_TP_CTL_A  0x64040
>  diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
>  b/drivers/gpu/drm/i915/intel_ddi.c
>  index 9a9a670..aea81ce 100644
>  --- a/drivers/gpu/drm/i915/intel_ddi.c
>  +++ b/drivers/gpu/drm/i915/intel_ddi.c
>  @@ -1278,6 +1278,11 @@ void intel_ddi_enable_transcoder_func(struct 
>  drm_crtc *crtc)
>   temp |= TRANS_DDI_MODE_SELECT_HDMI;
>   else
>   temp |= TRANS_DDI_MODE_SELECT_DVI;
>  +
>  +if (IS_GEMINILAKE(dev_priv)) {
>  +temp |= 
>  intel_hdmi_check_scrambling(intel_encoder,
>  +
>  &intel_crtc->config->base.adjusted_mode);
>  +}
>   } else if (type == INTEL_OUTPUT_ANALOG) {
>   temp |= TRANS_DDI_MODE_SELECT_FDI;
>   temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
>  diff --git a/drivers/gpu/drm/i915/intel_drv.h 
>  b/drivers/gpu/drm/i915/intel_drv.h
>  index 393f243..aafce7f 100644
>  --- a/drivers/gpu/drm/i915/intel_drv.h
>  +++ b/drivers/gpu/drm/i915/intel_drv.h
>  @@ -1588,6 +1588,8 @@ void intel_hdmi_init_connector(struct 
>  intel_digital_port *intel_dig_port,
> bool intel_hdmi_compute_config(struct intel_encoder *encoder,
>  struct intel_crtc_state *pipe_config,
>  struct drm_connector_state *conn_state);
>  +uint32_t intel_hdmi_check_scrambling(struct intel_encoder 
>  *intel_encoder,
>  +struct drm_display_mode *mode);
> void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool 
>  enable);
> 
> 
>  diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
>  b/drivers/gpu/drm/i915/intel_hdmi.c
>  index ebae2bd..92dd9bc 100644
>  --- a/drivers/gpu/drm/i915/intel_hdmi.c
>  +++ b/drivers/gpu/drm/i915/intel_hdmi.c
>  @@ -1795,6 +1795,48 @@ static void intel_hdmi_destroy(struct 
>  drm_connector *connector)
>   intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
> }
> 
>  +static void
>  +intel_hdmi_enable_scrambling(struct drm_connector *connector)
>  +{
>  +struct drm_i915_private *dev_priv = connector->dev->dev_private;
>  +struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>  +struct i2c_adapter *adapter =
>  +intel_gmbus_get_adapter(dev_priv, 
>  intel_hdmi->ddc_bus);
>  +
>  +if (!drm_enable_scrambling(connector, adapter, true))
>  +DRM_ERROR("Request to enable scrambling failed\n");
>  +}
> >>> I don't like hiding this somewhere deep like this. It should be
> >>> somewhere much higher up.
> >> Why ? All we need to do here is enable two bits in transcoder control
> >> register, which is already being
> >> programmed in a calling function, so I dont see the use case, but I
> >> might be missing some bigger picture.
> >> Can you please elaborate on this ?
> > We're talking to the display here, which is rather surprising to happen
> > from a function thing that on the fir

Re: [Intel-gfx] [PATCH] drm/i915: Release the forgotten connector reference

2017-02-02 Thread Chris Wilson
On Thu, Feb 02, 2017 at 12:35:26PM +0100, Daniel Vetter wrote:
> On Thu, Feb 02, 2017 at 08:16:23AM +, Chris Wilson wrote:
> > On Thu, Feb 02, 2017 at 10:08:57AM +0200, Joonas Lahtinen wrote:
> > > On ke, 2017-02-01 at 19:58 +, Chris Wilson wrote:
> > > > The reference was gained in
> > > > intel_modeset_update_connector_atomic_state() [called from
> > > > intel_modeset_setup_hw_state()] and is never lost if no client ever
> > > > performs a modeset.
> > > > 
> > > > [  649.836069] WARNING: CPU: 6 PID: 8865 at 
> > > > drivers/gpu/drm/drm_mode_config.c:424 
> > > > drm_mode_config_cleanup+0x21b/0x290 [drm]
> > > > [  649.836078] Modules linked in: i915(-) intel_gtt drm_kms_helper 
> > > > cfbfillrect syscopyarea cfbimgblt sysfillrect sysimgblt fb_sys_fops 
> > > > cfbcopyarea drm
> > > > [  649.836099] CPU: 6 PID: 8865 Comm: drv_selftest Not tainted 
> > > > 4.10.0-rc6+ #908
> > > > [  649.836106] Hardware name: Intel Corporation 2012 Client 
> > > > Platform/Emerald Lake 2, BIOS ACRVMBY1.86C.0078.P00.1201161002 
> > > > 01/16/2012
> > > > [  649.836114] Call Trace:
> > > > [  649.836125]  dump_stack+0x4d/0x6f
> > > > [  649.836136]  __warn+0xc1/0xe0
> > > > [  649.836144]  warn_slowpath_null+0x18/0x20
> > > > [  649.836163]  drm_mode_config_cleanup+0x21b/0x290 [drm]
> > > > [  649.836213]  intel_modeset_cleanup+0x59/0xa0 [i915]
> > > > [  649.836242]  i915_driver_unload+0x84/0x170 [i915]
> > > > [  649.836277]  i915_pci_remove+0x14/0x20 [i915]
> > > > [  649.836287]  pci_device_remove+0x28/0x60
> > > > [  649.836301]  device_release_driver_internal+0x132/0x1d0
> > > > [  649.836313]  driver_detach+0x3a/0x80
> > > > [  649.836324]  bus_remove_driver+0x47/0xa0
> > > > [  649.836335]  driver_unregister+0x27/0x50
> > > > [  649.836344]  pci_unregister_driver+0x34/0xa0
> > > > [  649.836387]  i915_exit+0x1a/0x71 [i915]
> > > > [  649.836401]  SyS_delete_module+0x173/0x1c0
> > > > [  649.836413]  entry_SYSCALL_64_fastpath+0x17/0x98
> > > > [  649.836422] RIP: 0033:0x7f8d5a841ee7
> > > > [  649.836432] RSP: 002b:7fff89161a28 EFLAGS: 0206 ORIG_RAX: 
> > > > 00b0
> > > > [  649.836448] RAX: ffda RBX: 55f6cd1db5c0 RCX: 
> > > > 7f8d5a841ee7
> > > > [  649.836458] RDX:  RSI: 0800 RDI: 
> > > > 55f6cd1da7b8
> > > > [  649.836467] RBP: 7f8d5aaee440 R08:  R09: 
> > > > 7fff89161a58
> > > > [  649.836476] R10: 0062 R11: 0206 R12: 
> > > > 
> > > > [  649.836486] R13: 55f6cd1d9010 R14: 003a R15: 
> > > > 7fff891609f0
> > > > [  649.836514] ---[ end trace 0e529da316e2a3d1 ]---
> > > > [  649.836536] [drm:drm_mode_config_cleanup [drm]] *ERROR* connector 
> > > > VGA-1 leaked!
> > > > 
> > > > Signed-off-by: Chris Wilson 
> > > 
> > > Reviewed-by: Joonas Lahtinen 
> > 
> > I'm hoping that this won't be required after Maarten's force disable all
> > CRTC on unload. We will see.
> 
> Yeah, I think landing that would be better, but if this is annoying CI or
> something like that, I'm ok with merging already with a FIXME comment
> added.

By itself the first force disable CRTCs on unload wasn't enough, but
Maarten has a second patch to apply more force that does. This patch is
not required.
-Chris

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


Re: [Intel-gfx] [PATCH v2 03/38] drm/i915: Add some selftests for sg_table manipulation

2017-02-02 Thread Tvrtko Ursulin


On 01/02/2017 11:34, Chris Wilson wrote:

On Wed, Feb 01, 2017 at 11:17:39AM +, Tvrtko Ursulin wrote:



+
+   for (npages = npages_funcs; *npages; npages++) {
+   prandom_seed_state(&prng,
+  i915_selftest.random_seed);
+   if (!alloc_table(&pt, sz, sz, *npages, &prng))
+   return 0; /* out of memory, give up */


You don't have skip status? Sounds not ideal to silently abort.


It runs until we use all physical memory, if left to its own devices. It's
not a skip if we have already completed some tests. ENOMEM of the test
setup itself is not what I'm testing for here, the test is for the
iterators.


But suppose you mess up the test so the starting condition asks for 
impossible amount of memory but the test claims it passed. I don't think 
that is a good behaviour.



+static int igt_sg_trim(void *ignored)
+{
+   IGT_TIMEOUT(end_time);
+   const unsigned long max = PAGE_SIZE; /* not prime! */
+   struct pfn_table pt;
+   unsigned long prime;
+
+   for_each_prime_number(prime, max) {
+   const npages_fn_t *npages;
+   int err;
+
+   for (npages = npages_funcs; *npages; npages++) {
+   struct rnd_state prng;
+
+   prandom_seed_state(&prng, i915_selftest.random_seed);
+   if (!alloc_table(&pt, prime, max, *npages, &prng))
+   return 0; /* out of memory, give up */
+
+   err = 0;
+   if (i915_sg_trim(&pt.st)) {
+   if (pt.st.orig_nents != prime ||
+   pt.st.nents != prime) {
+   pr_err("i915_sg_trim failed (nents %u, 
orig_nents %u), expected %lu\n",
+  pt.st.nents, pt.st.orig_nents, 
prime);
+   err = -EINVAL;
+   } else {
+   prandom_seed_state(&prng,
+  
i915_selftest.random_seed);
+   err = expect_pfn_sgtable(&pt,
+*npages, &prng,
+"i915_sg_trim",
+end_time);
+   }
+   }


Similar to alloc_table failures above - no log or action when
i915_sg_trim fails due out of memory?


No, simply because that's an expected and acceptable result. The
question should be whether we always want to check after sg_trim.


Same as above really, I think that creates a big doubt in the test output.

Regards,

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


Re: [Intel-gfx] [PATCH 09/46] drm/i915: Add unit tests for the breadcrumb rbtree, wakeups

2017-02-02 Thread Tvrtko Ursulin


On 02/02/2017 09:08, Chris Wilson wrote:

Third retroactive test, make sure that the seqno waiters are woken.

v2: Smattering of comments, rearrange code


v3: Fix assert.


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

diff --git a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c 
b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
index 32a27e56c353..fb368eb37660 100644
--- a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
@@ -259,11 +259,212 @@ static int igt_insert_complete(void *arg)
return err;
 }

+struct igt_wakeup {
+   struct task_struct *tsk;
+   atomic_t *ready, *set, *done;
+   struct intel_engine_cs *engine;
+   unsigned long flags;
+#define STOP 0
+#define IDLE 1
+   wait_queue_head_t *wq;
+   u32 seqno;
+};
+
+static int wait_atomic(atomic_t *p)
+{
+   schedule();
+   return 0;
+}
+
+static int wait_atomic_timeout(atomic_t *p)
+{
+   return schedule_timeout(10 * HZ) ? 0 : -ETIMEDOUT;
+}
+
+static bool wait_for_ready(struct igt_wakeup *w)
+{
+   DEFINE_WAIT(ready);
+
+   if (atomic_dec_and_test(w->done))
+   wake_up_atomic_t(w->done);
+
+   if (test_bit(STOP, &w->flags))
+   goto out;
+
+   set_bit(IDLE, &w->flags);


I think this needs to be before atomic_dec_and_test(w->done), to avoid 
that same assert racing with the threads. Because immediately after the 
wake_up_atomic above the main loop starts asserting the IDLE bit which 
is not guaranteed to be set yet.


Regards,

Tvrtko


+   for (;;) {
+   prepare_to_wait(w->wq, &ready, TASK_INTERRUPTIBLE);
+   if (atomic_read(w->ready) == 0)
+   break;
+
+   schedule();
+   }
+   finish_wait(w->wq, &ready);
+   clear_bit(IDLE, &w->flags);
+
+out:
+   if (atomic_dec_and_test(w->set))
+   wake_up_atomic_t(w->set);
+
+   return !test_bit(STOP, &w->flags);
+}
+
+static int igt_wakeup_thread(void *arg)
+{
+   struct igt_wakeup *w = arg;
+   struct intel_wait wait;
+
+   while (wait_for_ready(w)) {
+   GEM_BUG_ON(kthread_should_stop());
+
+   intel_wait_init(&wait, w->seqno);
+   intel_engine_add_wait(w->engine, &wait);
+   for (;;) {
+   set_current_state(TASK_UNINTERRUPTIBLE);
+   if (i915_seqno_passed(intel_engine_get_seqno(w->engine),
+ w->seqno))
+   break;
+
+   if (test_bit(STOP, &w->flags)) /* emergency escape */
+   break;
+
+   schedule();
+   }
+   intel_engine_remove_wait(w->engine, &wait);
+   __set_current_state(TASK_RUNNING);
+   }
+
+   return 0;
+}
+
+static void igt_wake_all_sync(atomic_t *ready,
+ atomic_t *set,
+ atomic_t *done,
+ wait_queue_head_t *wq,
+ int count)
+{
+   atomic_set(set, count);
+   atomic_set(ready, 0);
+   wake_up_all(wq);
+
+   wait_on_atomic_t(set, wait_atomic, TASK_UNINTERRUPTIBLE);
+   atomic_set(ready, count);
+   atomic_set(done, count);
+}
+
+static int igt_wakeup(void *arg)
+{
+   I915_RND_STATE(prng);
+   const int state = TASK_UNINTERRUPTIBLE;
+   struct intel_engine_cs *engine = arg;
+   struct igt_wakeup *waiters;
+   DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
+   const int count = 4096;
+   const u32 max_seqno = count / 4;
+   atomic_t ready, set, done;
+   int err = -ENOMEM;
+   int n, step;
+
+   mock_engine_reset(engine);
+
+   waiters = drm_malloc_gfp(count, sizeof(*waiters), GFP_TEMPORARY);
+   if (!waiters)
+   goto out_engines;
+
+   /* Create a large number of threads, each waiting on a random seqno.
+* Multiple waiters will be waiting for the same seqno.
+*/
+   atomic_set(&ready, count);
+   for (n = 0; n < count; n++) {
+   waiters[n].wq = &wq;
+   waiters[n].ready = &ready;
+   waiters[n].set = &set;
+   waiters[n].done = &done;
+   waiters[n].engine = engine;
+   waiters[n].flags = BIT(IDLE);
+
+   waiters[n].tsk = kthread_run(igt_wakeup_thread, &waiters[n],
+"i915/igt:%d", n);
+   if (IS_ERR(waiters[n].tsk))
+   goto out_waiters;
+
+   get_task_struct(waiters[n].tsk);
+   }
+
+   for (step = 1; step <= max_seqno; step <<= 1) {
+   u32 seqno;
+
+   /* The waiter threads start paused as we assign them a random
+* seqno and reset the engi

Re: [Intel-gfx] [PATCH 38/46] drm/i915: Verify page layout for rotated VMA

2017-02-02 Thread Tvrtko Ursulin


On 02/02/2017 09:08, Chris Wilson wrote:

Exercise creating rotated VMA and checking the page order within.

v2: Be more creative in rotated params


v3: ...


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

diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c 
b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 095d8348f5f0..4a737a670199 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -352,11 +352,190 @@ static int igt_vma_pin1(void *arg)
return err;
 }

+static unsigned long rotated_index(const struct intel_rotation_info *r,
+  unsigned int n,
+  unsigned int x,
+  unsigned int y)
+{
+   return (r->plane[n].stride * (r->plane[n].height - y - 1) +
+   r->plane[n].offset + x);
+}
+
+static struct scatterlist *
+assert_rotated(struct drm_i915_gem_object *obj,
+  const struct intel_rotation_info *r, unsigned int n,
+  struct scatterlist *sg)
+{
+   unsigned int x, y;
+
+   for (x = 0; x < r->plane[n].width; x++) {
+   for (y = 0; y < r->plane[n].height; y++) {
+   unsigned long src_idx;
+   dma_addr_t src;
+
+   if (!sg) {
+   pr_err("Invalid sg table: too short at plane %d, 
(%d, %d)!\n",
+  n, x, y);
+   return ERR_PTR(-EINVAL);
+   }
+
+   src_idx = rotated_index(r, n, x, y);
+   src = i915_gem_object_get_dma_address(obj, src_idx);
+
+   if (sg_dma_len(sg) != PAGE_SIZE) {
+   pr_err("Invalid sg.length, found %d, expected %lu 
for rotated page (%d, %d) [src index %lu]\n",
+  sg_dma_len(sg), PAGE_SIZE,
+  x, y, src_idx);
+   return ERR_PTR(-EINVAL);
+   }
+
+   if (sg_dma_address(sg) != src) {
+   pr_err("Invalid address for rotated page (%d, %d) 
[src index %lu]\n",
+  x, y, src_idx);
+   return ERR_PTR(-EINVAL);
+   }
+
+   sg = sg_next(sg);
+   }
+   }
+
+   return sg;
+}
+
+static unsigned int rotated_size(const struct intel_rotation_plane_info *a,
+const struct intel_rotation_plane_info *b)
+{
+   return a->width * a->height + b->width * b->height;
+}
+
+static int igt_vma_rotate(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct i915_address_space *vm = &i915->ggtt.base;
+   struct drm_i915_gem_object *obj;
+   const struct intel_rotation_plane_info planes[] = {
+   { .width = 1, .height = 1, .stride = 1 },
+   { .width = 2, .height = 2, .stride = 2 },
+   { .width = 4, .height = 4, .stride = 4 },
+   { .width = 8, .height = 8, .stride = 8 },
+
+   { .width = 3, .height = 5, .stride = 3 },
+   { .width = 3, .height = 5, .stride = 4 },
+   { .width = 3, .height = 5, .stride = 5 },
+
+   { .width = 5, .height = 3, .stride = 5 },
+   { .width = 5, .height = 3, .stride = 7 },
+   { .width = 5, .height = 3, .stride = 9 },
+
+   { .width = 4, .height = 6, .stride = 6 },
+   { .width = 6, .height = 4, .stride = 6 },
+   { }
+   }, *a, *b;
+   const unsigned int max_pages = 64;
+   int err = -ENOMEM;
+
+   /* Create VMA for many different combinations of planes and check
+* that the page layout within the rotated VMA match our expectations.
+*/
+
+   obj = i915_gem_object_create_internal(i915, max_pages * PAGE_SIZE);
+   if (IS_ERR(obj))
+   goto out;
+
+   for (a = planes; a->width; a++) {
+   for (b = planes + ARRAY_SIZE(planes); b-- != planes; ) {
+   struct i915_ggtt_view view;
+   unsigned int n, max_offset;
+
+   max_offset = max(a->stride * a->height,
+b->stride * b->height);
+   GEM_BUG_ON(max_offset > max_pages);
+   max_offset = max_pages - max_offset;
+
+   view.type = I915_GGTT_VIEW_ROTATED;
+   view.rotated.plane[0] = *a;
+   view.rotated.plane[1] = *b;
+
+   
for_each_prime_number_from(view.rotated.plane[0].offset, 0, max_offset) {
+   
for_each_prime_number_from(view.rotated.plane[1].offset, 0, max_offset)

Re: [Intel-gfx] [PATCH 09/46] drm/i915: Add unit tests for the breadcrumb rbtree, wakeups

2017-02-02 Thread Chris Wilson
On Thu, Feb 02, 2017 at 12:49:58PM +, Tvrtko Ursulin wrote:
> 
> On 02/02/2017 09:08, Chris Wilson wrote:
> >+static bool wait_for_ready(struct igt_wakeup *w)
> >+{
> >+DEFINE_WAIT(ready);
> >+
> >+if (atomic_dec_and_test(w->done))
> >+wake_up_atomic_t(w->done);
> >+
> >+if (test_bit(STOP, &w->flags))
> >+goto out;
> >+
> >+set_bit(IDLE, &w->flags);
> 
> I think this needs to be before atomic_dec_and_test(w->done), to
> avoid that same assert racing with the threads. Because immediately
> after the wake_up_atomic above the main loop starts asserting the
> IDLE bit which is not guaranteed to be set yet.

Before wake_up_atomic_t which is the same thing, yup.
-Chris

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


  1   2   >