Re: [Intel-gfx] [PATCH 0/2] drm: link status property and DP link training failure handling

2016-12-16 Thread Pandiyan, Dhinakaran
On Fri, 2016-12-16 at 16:47 +0200, Jani Nikula wrote:
> On Fri, 16 Dec 2016, Daniel Vetter  wrote:
> > On Fri, Dec 16, 2016 at 12:29:05PM +0200, Jani Nikula wrote:
> >> The two remaining patches from [1], rebased.
> >> 
> >> BR,
> >> Jani.
> >> 
> >> 
> >> [1] 
> >> 1480984058-552-1-git-send-email-manasi.d.navare@intel.com">http://mid.mail-archive.com/1480984058-552-1-git-send-email-manasi.d.navare@intel.com
> >
> > Just for the record, I think the only thing missing here is the Xorg
> > review on the -modesetting patch. As soon as we have that I can vacuum
> > this up (probably best through drm-misc, but not sure).
> 
> Yeah I rebased this (and provided a debug hack privately) so Martin can
> test the modesetting changes.
> 
> BR,
> Jani.
> 
> 

I tested the -modesetting patch, which Martin had provided to Manasi,
with a compliance testing device (DPR-120) that can simulate link
training failure. The link rate correctly lowered after the link_status
property was set to BAD by the kernel and the userspace responded with a
modeset. 

One thing that was not straight forward to figure out was I had to boot
with i915.nuclear_pageflip=1. Is it documented somewhere that the
property needs DRIVER_ATOMIC to be set, or is it implicit?

The other thing I had trouble with -modesetting was, there was no
modeset following a long pulse from the sink at the begging of the test.
I had to force a modeset by changing the resolution so that the link
training path is executed. However, the link training failure induced a
modeset without any intervention.

-DK


> > -Daniel
> >
> >> 
> >> 
> >> Manasi Navare (2):
> >>   drm: Add a new connector atomic property for link status
> >>   drm/i915: Implement Link Rate fallback on Link training failure
> >> 
> >>  drivers/gpu/drm/drm_atomic.c  | 16 +
> >>  drivers/gpu/drm/drm_atomic_helper.c   | 15 
> >>  drivers/gpu/drm/drm_connector.c   | 52 
> >> +++
> >>  drivers/gpu/drm/i915/intel_dp.c   | 27 ++
> >>  drivers/gpu/drm/i915/intel_dp_link_training.c | 22 ++--
> >>  drivers/gpu/drm/i915/intel_drv.h  |  3 ++
> >>  include/drm/drm_connector.h   | 19 ++
> >>  include/drm/drm_mode_config.h |  5 +++
> >>  include/uapi/drm/drm_mode.h   |  4 +++
> >>  9 files changed, 161 insertions(+), 2 deletions(-)
> >> 
> >> -- 
> >> 2.1.4
> >> 
> >> ___
> >> dri-devel mailing list
> >> dri-de...@lists.freedesktop.org
> >> https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 

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


Re: [Intel-gfx] [PATCH v2 i-g-t] tools: Add intel_dp_compliance for DisplayPort 1.2 compliance automation

2016-12-16 Thread Jim Bride
On Wed, Dec 07, 2016 at 02:04:52PM -0800, Manasi Navare wrote:
> This is the userspace component of the Displayport Compliance
> testing software required for compliance testing of the I915
> Display Port driver. This must be running in order to successfully
> complete Display Port compliance testing. This app and the kernel
> code that accompanies it has been written to satify the requirements
> of the Displayport Link CTS 1.2 rev1.1 specification from VESA.
> Note that this application does not support eDP compliance testing.
> This utility has an automation support for the Link training tests
> (4.3.1.1. - 4.3.2.3), EDID tests (4.2.2.3
> - 4.2.2.6) and Video Pattern generation tests (4.3.3.1) from CTS
> specification 1.2 Rev 1.1.
> 
> This tool has the support for responding to the hotplug uevents
> sent by compliance testting unit after each test.
> 
> The Linux DUT running this utility must be in text (console) mode
> and cannot have any other display manager running. Since this uses
> sysfs nodes for kernel interaction, this utility should be run as
> Root. Once this user application is up and running, waiting for
> test requests, the test appliance software on the windows host
> can now be used to execute the compliance tests.
> 
> This app is based on some prior work done in April 2015 (by
> Todd Previte )
> 
> v2:
> * Add mode unset on hotplug uevent on disconnect (Manasi Navare)
> 
> Cc: Petri Latvala 
> Cc: Marius Vlad 
> Cc: Daniel Vetter 
> Signed-off-by: Manasi Navare 

Some general suggestions (more inline as well):

* Please audit all output messages for proper spelling, grammar, caps, etc.
* Many of the lines are quite long.  It would be nice to keep the line
  lengths short (under 100 chars for sure, but IMHO under 78 is even better.)
* Many of the functions only return '0'; consider changing them to void.  
* Perhaps this is excess paranoia, but I would check the validity of any
  pointer passed into a function before dereferencing it.  This isn't done
  in several cases.
* Make sure and check out Petri's feedback, all of which I agree with.

Jim

> ---
>  tools/Makefile.am   |3 +-
>  tools/Makefile.sources  |7 +
>  tools/intel_dp_compliance.c | 1060 
> +++
>  tools/intel_dp_compliance.h |   35 ++
>  tools/intel_dp_compliance_hotplug.c |  123 
>  5 files changed, 1227 insertions(+), 1 deletion(-)
>  create mode 100644 tools/intel_dp_compliance.c
>  create mode 100644 tools/intel_dp_compliance.h
>  create mode 100644 tools/intel_dp_compliance_hotplug.c
> 
> diff --git a/tools/Makefile.am b/tools/Makefile.am
> index 18f86f6..eac6d64 100644
> --- a/tools/Makefile.am
> +++ b/tools/Makefile.am
> @@ -13,7 +13,7 @@ AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib
>  AM_CFLAGS = $(DEBUG_CFLAGS) $(DRM_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNFLAGS) \
>   $(CAIRO_CFLAGS) $(LIBUNWIND_CFLAGS) -DPKGDATADIR=\"$(pkgdatadir)\" \
>   $(WERROR_CFLAGS)
> -LDADD = $(top_builddir)/lib/libintel_tools.la
> +LDADD = $(top_builddir)/lib/libintel_tools.la $(GLIB_LIBS)
>  AM_LDFLAGS = -Wl,--as-needed
>  
>  
> @@ -24,6 +24,7 @@ moduledir = $(libdir)
>  intel_aubdump_la_LDFLAGS = -module -avoid-version -no-undefined
>  intel_aubdump_la_SOURCES = aubdump.c
>  intel_aubdump_la_LIBADD = $(top_builddir)/lib/libintel_tools.la -ldl
> +intel_dp_compliance_la_LIBADD = $(LDADD)
>  
>  bin_SCRIPTS = intel_aubdump
>  CLEANFILES = $(bin_SCRIPTS)
> diff --git a/tools/Makefile.sources b/tools/Makefile.sources
> index be58871..09c0667 100644
> --- a/tools/Makefile.sources
> +++ b/tools/Makefile.sources
> @@ -13,6 +13,7 @@ tools_prog_lists =  \
>   intel_bios_reader   \
>   intel_display_crc   \
>   intel_display_poller\
> + intel_dp_compliance \
>   intel_forcewaked\
>   intel_gpu_frequency \
>   intel_firmware_decode   \
> @@ -55,3 +56,9 @@ intel_l3_parity_SOURCES =   \
>   intel_l3_parity.h   \
>   intel_l3_udev_listener.c
>  
> +intel_dp_compliance_SOURCES = \
> +intel_dp_compliance.c \
> +intel_dp_compliance.h \
> +intel_dp_compliance_hotplug.c \
> +$(NULL)
> +
> diff --git a/tools/intel_dp_compliance.c b/tools/intel_dp_compliance.c
> new file mode 100644
> index 000..807d3f4
> --- /dev/null
> +++ b/tools/intel_dp_compliance.c
> @@ -0,0 +1,1060 @@
> +/*
> + * Copyright ? 2014-2015 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
> + * 

Re: [Intel-gfx] [PATCH 1/9] drm/i915: Keep i915_handle_error kerneldoc parameters together

2016-12-16 Thread Chris Wilson
On Fri, Dec 16, 2016 at 12:20:02PM -0800, Michel Thierry wrote:
> And before the function description.
> Tidy up from commit 14bb2c11796d70b ("drm/i915: Fix a buch of kerneldoc
> warnings"), all others kerneldoc blocks look ok.
> 
> Cc: Tvrtko Ursulin 
> Signed-off-by: Michel Thierry 
Reviewed-by: Chris Wilson 
-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] ✓ Fi.CI.BAT: success for series starting with [1/4] drm/i915: introduce GEM_WARN_ON

2016-12-16 Thread Chris Wilson
On Tue, Dec 13, 2016 at 09:15:35PM -, Patchwork wrote:
> == Series Details ==
> 
> Series: series starting with [1/4] drm/i915: introduce GEM_WARN_ON
> URL   : https://patchwork.freedesktop.org/series/16758/
> State : success
> 
> == Summary ==
> 
> Series 16758v1 Series without cover letter
> https://patchwork.freedesktop.org/api/1.0/series/16758/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-t5700 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
> 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-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
> 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:226  dwarn:0   dfail:0   fail:0   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:224  dwarn:3   dfail:0   fail:0   skip:20 
> 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 
> 
> 57b72b4a6d7b787aedeb7b776ab35c3b2d7f58e9 drm-tip: 2016y-12m-13d-17h-59m-26s 
> UTC integration manifest
> ec9dba0 drm/i915: convert to using range_overflows
> 2e82cdf drm/i915: introduce range_overflows utility macros
> b2b8e00 drm/i915: move vma sanity checking into i915_vma_bind
> 16aef35 drm/i915: introduce GEM_WARN_ON

And pushed. Thanks,
-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 6/9] drm/i915/tdr: Add engine reset count to error state

2016-12-16 Thread Michel Thierry


On 16/12/16 12:37, Chris Wilson wrote:

On Fri, Dec 16, 2016 at 12:20:07PM -0800, Michel Thierry wrote:

From: Arun Siluvery 

Driver maintains count of how many times a given engine is reset, useful to
capture this in error state also. It gives an idea of how engine is coping
up with the workloads it is executing before this error state.


Also i915_engine_info().


I'll add it there too.


Cc: Chris Wilson 
Cc: Mika Kuoppala 
Signed-off-by: Arun Siluvery 
Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_drv.c   | 1 +
 drivers/gpu/drm/i915/i915_drv.h   | 9 +
 drivers/gpu/drm/i915/i915_gpu_error.c | 3 +++
 3 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a034793bc246..1c706a082d60 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1877,6 +1877,7 @@ int i915_reset_engine(struct intel_engine_cs *engine)
intel_engine_reset_cancel(engine);
intel_execlists_restart_submission(engine);

+   dev_priv->gpu_error.engine_reset_count[engine->id]++;
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
return 0;

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a97cc8f50ade..25183762ed94 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -937,6 +937,7 @@ struct drm_i915_error_state {
enum intel_engine_hangcheck_action hangcheck_action;
struct i915_address_space *vm;
int num_requests;
+   u32 reset_count;

/* position of active request inside the ring */
u32 rq_head, rq_post, rq_tail;
@@ -1629,6 +1630,8 @@ struct i915_gpu_error {
 #define I915_RESET_IN_PROGRESS 0
 #define I915_WEDGED(BITS_PER_LONG - 1)

+   unsigned long engine_reset_count[I915_NUM_ENGINES];
+
/**
 * Waitqueue to signal when a hang is detected. Used to for waiters
 * to release the struct_mutex for the reset to procede.
@@ -3397,6 +3400,12 @@ static inline u32 i915_reset_count(struct i915_gpu_error 
*error)
return READ_ONCE(error->reset_count);
 }

+static inline u32 i915_engine_reset_count(struct i915_gpu_error *error,


That's a weird hodgepodge. We first think of intel_engine and are
confused, then we spot the reset. i915_reset_engine_count?



Agreed i915_reset_engine_count is better (plus it's called from 
i915_reset_info).



+ struct intel_engine_cs *engine)
+{
+   return READ_ONCE(error->engine_reset_count[engine->id]);
+}
+


Then the same rename here, reset_engine_count[].

Thanks

 void i915_gem_reset(struct drm_i915_private *dev_priv);
 void i915_gem_set_wedged(struct drm_i915_private *dev_priv);
 void i915_gem_reset_engine(struct intel_engine_cs *engine);
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index e16037d1b0ba..f168ad873521 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -453,6 +453,7 @@ static void error_print_engine(struct 
drm_i915_error_state_buf *m,
err_printf(m, "  hangcheck action timestamp: %lu, %u ms ago\n",
   ee->hangcheck_timestamp,
   jiffies_to_msecs(jiffies - ee->hangcheck_timestamp));
+   err_printf(m, "  engine reset count: %u\n", ee->reset_count);

error_print_request(m, "  ELSP[0]: ", >execlist[0]);
error_print_request(m, "  ELSP[1]: ", >execlist[1]);
@@ -1170,6 +1171,8 @@ static void error_record_engine_registers(struct 
drm_i915_error_state *error,
ee->hangcheck_timestamp = engine->hangcheck.action_timestamp;
ee->hangcheck_action = engine->hangcheck.action;
ee->hangcheck_stalled = engine->hangcheck.stalled;
+   ee->reset_count = i915_engine_reset_count(_priv->gpu_error,
+ engine);

if (USES_PPGTT(dev_priv)) {
int i;
--
2.11.0




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


[Intel-gfx] ✗ Fi.CI.BAT: warning for Execlist based engine-reset

2016-12-16 Thread Patchwork
== Series Details ==

Series: Execlist based engine-reset
URL   : https://patchwork.freedesktop.org/series/16936/
State : warning

== Summary ==

Series 16936v1 Execlist based engine-reset
https://patchwork.freedesktop.org/api/1.0/series/16936/revisions/1/mbox/

Test kms_pipe_crc_basic:
Subgroup suspend-read-crc-pipe-b:
pass   -> SKIP   (fi-bxt-j4205)

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:222  dwarn:0   dfail:0   fail:0   skip:25 
fi-bxt-t5700 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
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-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
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:226  dwarn:0   dfail:0   fail:0   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:224  dwarn:3   dfail:0   fail:0   skip:20 
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 

705f1e8fef81d504f0032df8e21bdc2e74850b3a drm-tip: 2016y-12m-16d-15h-40m-02s UTC 
integration manifest
9a591cb drm/i915: Add engine reset count in get-reset-stats ioctl
709af8f drm/i915/tdr: Enable Engine reset and recovery support
f37aa42 drm/i915/tdr: Export per-engine reset count info to debugfs
4c1e046 drm/i915/tdr: Add engine reset count to error state
41e96eb drm/i915: Skip reset request if there is one already
d3b2dc8f4 drm/i915/tdr: Add support for per engine reset recovery
d654f09 drm/i915/tdr: Modify error handler for per engine hang recovery
db8e495 drm/i915: Update i915.reset to handle engine resets
b94f5b6 drm/i915: Keep i915_handle_error kerneldoc parameters together

== Logs ==

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


Re: [Intel-gfx] [PATCH 4/9] drm/i915/tdr: Add support for per engine reset recovery

2016-12-16 Thread Chris Wilson
On Fri, Dec 16, 2016 at 12:20:05PM -0800, Michel Thierry wrote:
> From: Arun Siluvery 
> 
> This change implements support for per-engine reset as an initial, less
> intrusive hang recovery option to be attempted before falling back to the
> legacy full GPU reset recovery mode if necessary. This is only supported
> from Gen8 onwards.
> 
> Hangchecker determines which engines are hung and invokes error handler to
> recover from it. Error handler schedules recovery for each of those engines
> that are hung. The recovery procedure is as follows,
>  - identifies the request that caused the hang and it is dropped
>  - force engine to idle: this is done by issuing a reset request
>  - reset and re-init engine
>  - restart submissions to the engine
> 
> If engine reset fails then we fall back to heavy weight full gpu reset
> which resets all engines and reinitiazes complete state of HW and SW.
> 
> v2: Rebase.
> 
> Cc: Chris Wilson 
> Cc: Mika Kuoppala 
> Signed-off-by: Tomas Elf 
> Signed-off-by: Arun Siluvery 
> Signed-off-by: Michel Thierry 
> ---
>  drivers/gpu/drm/i915/i915_drv.c | 56 
> +++--
>  drivers/gpu/drm/i915/i915_drv.h |  3 ++
>  drivers/gpu/drm/i915/i915_gem.c |  2 +-
>  drivers/gpu/drm/i915/intel_lrc.c| 12 
>  drivers/gpu/drm/i915/intel_lrc.h|  1 +
>  drivers/gpu/drm/i915/intel_uncore.c | 41 ---
>  6 files changed, 108 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index e5688edd62cd..a034793bc246 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1830,18 +1830,70 @@ void i915_reset(struct drm_i915_private *dev_priv)
>   *
>   * Reset a specific GPU engine. Useful if a hang is detected.
>   * Returns zero on successful reset or otherwise an error code.
> + *
> + * Procedure is fairly simple:
> + *  - identifies the request that caused the hang and it is dropped
> + *  - force engine to idle: this is done by issuing a reset request
> + *  - reset engine
> + *  - restart submissions to the engine
>   */
>  int i915_reset_engine(struct intel_engine_cs *engine)

What's the serialisation between potential callers of
i915_reset_engine()?

>  {
>   int ret;
>   struct drm_i915_private *dev_priv = engine->i915;
>  
> - /* FIXME: replace me with engine reset sequence */
> - ret = -ENODEV;
> + /*
> +  * We need to first idle the engine by issuing a reset request,
> +  * then perform soft reset and re-initialize hw state, for all of
> +  * this GT power need to be awake so ensure it does throughout the
> +  * process
> +  */
> + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
> +
> + /*
> +  * the request that caused the hang is stuck on elsp, identify the
> +  * active request and drop it, adjust head to skip the offending
> +  * request to resume executing remaining requests in the queue.
> +  */
> + i915_gem_reset_engine(engine);

Must freeze the engine and irqs first, before calling
i915_gem_reset_engine() (i.e. something like disable_engines_irq,
cancelling tasklet)

Eeek note that the current i915_gem_reset_engine() is lacking a
spinlock.

> +
> + ret = intel_engine_reset_begin(engine);
> + if (ret) {
> + DRM_ERROR("Failed to disable %s\n", engine->name);
> + goto error;
> + }
> +
> + ret = intel_gpu_reset(dev_priv, intel_engine_flag(engine));
> + if (ret) {
> + DRM_ERROR("Failed to reset %s, ret=%d\n", engine->name, ret);
> + intel_engine_reset_cancel(engine);
> + goto error;
> + }
> +
> + ret = engine->init_hw(engine);
> + if (ret)
> + goto error;
>  
> + intel_engine_reset_cancel(engine);
> + intel_execlists_restart_submission(engine);

engine->init_hw(engine) *is* intel_execlists_restart_submission.

> +
> + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
> + return 0;
> +
> +error:
>   /* use full gpu reset to recover on error */
>   set_bit(I915_RESET_IN_PROGRESS, _priv->gpu_error.flags);
>  
> + /* Engine reset is performed without taking struct_mutex, since it
> +  * failed we now fallback to full gpu reset. Wakeup any waiters
> +  * which should now see the reset_in_progress and release
> +  * struct_mutex for us to continue recovery.
> +  */
> + rcu_read_lock();
> + intel_engine_wakeup(engine);
> + rcu_read_unlock();
> +
> + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   return ret;
>  }

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

Re: [Intel-gfx] [PATCH 6/9] drm/i915/tdr: Add engine reset count to error state

2016-12-16 Thread Chris Wilson
On Fri, Dec 16, 2016 at 12:20:07PM -0800, Michel Thierry wrote:
> From: Arun Siluvery 
> 
> Driver maintains count of how many times a given engine is reset, useful to
> capture this in error state also. It gives an idea of how engine is coping
> up with the workloads it is executing before this error state.

Also i915_engine_info().
 
> Cc: Chris Wilson 
> Cc: Mika Kuoppala 
> Signed-off-by: Arun Siluvery 
> Signed-off-by: Michel Thierry 
> ---
>  drivers/gpu/drm/i915/i915_drv.c   | 1 +
>  drivers/gpu/drm/i915/i915_drv.h   | 9 +
>  drivers/gpu/drm/i915/i915_gpu_error.c | 3 +++
>  3 files changed, 13 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index a034793bc246..1c706a082d60 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1877,6 +1877,7 @@ int i915_reset_engine(struct intel_engine_cs *engine)
>   intel_engine_reset_cancel(engine);
>   intel_execlists_restart_submission(engine);
>  
> + dev_priv->gpu_error.engine_reset_count[engine->id]++;
>   intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   return 0;
>  
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index a97cc8f50ade..25183762ed94 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -937,6 +937,7 @@ struct drm_i915_error_state {
>   enum intel_engine_hangcheck_action hangcheck_action;
>   struct i915_address_space *vm;
>   int num_requests;
> + u32 reset_count;
>  
>   /* position of active request inside the ring */
>   u32 rq_head, rq_post, rq_tail;
> @@ -1629,6 +1630,8 @@ struct i915_gpu_error {
>  #define I915_RESET_IN_PROGRESS   0
>  #define I915_WEDGED  (BITS_PER_LONG - 1)
>  
> + unsigned long engine_reset_count[I915_NUM_ENGINES];
> +
>   /**
>* Waitqueue to signal when a hang is detected. Used to for waiters
>* to release the struct_mutex for the reset to procede.
> @@ -3397,6 +3400,12 @@ static inline u32 i915_reset_count(struct 
> i915_gpu_error *error)
>   return READ_ONCE(error->reset_count);
>  }
>  
> +static inline u32 i915_engine_reset_count(struct i915_gpu_error *error,

That's a weird hodgepodge. We first think of intel_engine and are
confused, then we spot the reset. i915_reset_engine_count?

> +   struct intel_engine_cs *engine)
> +{
> + return READ_ONCE(error->engine_reset_count[engine->id]);
> +}
> +
>  void i915_gem_reset(struct drm_i915_private *dev_priv);
>  void i915_gem_set_wedged(struct drm_i915_private *dev_priv);
>  void i915_gem_reset_engine(struct intel_engine_cs *engine);
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
> b/drivers/gpu/drm/i915/i915_gpu_error.c
> index e16037d1b0ba..f168ad873521 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -453,6 +453,7 @@ static void error_print_engine(struct 
> drm_i915_error_state_buf *m,
>   err_printf(m, "  hangcheck action timestamp: %lu, %u ms ago\n",
>  ee->hangcheck_timestamp,
>  jiffies_to_msecs(jiffies - ee->hangcheck_timestamp));
> + err_printf(m, "  engine reset count: %u\n", ee->reset_count);
>  
>   error_print_request(m, "  ELSP[0]: ", >execlist[0]);
>   error_print_request(m, "  ELSP[1]: ", >execlist[1]);
> @@ -1170,6 +1171,8 @@ static void error_record_engine_registers(struct 
> drm_i915_error_state *error,
>   ee->hangcheck_timestamp = engine->hangcheck.action_timestamp;
>   ee->hangcheck_action = engine->hangcheck.action;
>   ee->hangcheck_stalled = engine->hangcheck.stalled;
> + ee->reset_count = i915_engine_reset_count(_priv->gpu_error,
> +   engine);
>  
>   if (USES_PPGTT(dev_priv)) {
>   int i;
> -- 
> 2.11.0
> 

-- 
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 i-g-t] igt_kms: Use const parameters for igt_assert_crc_equal

2016-12-16 Thread Lyude
Since we're not modifying these anywhere, let's make them const so as to
not break code doing comparisons against compile-time CRCs.

Signed-off-by: Lyude 
---
 lib/igt_debugfs.c | 2 +-
 lib/igt_debugfs.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c
index 3d92c6a..f8c8727 100644
--- a/lib/igt_debugfs.c
+++ b/lib/igt_debugfs.c
@@ -270,7 +270,7 @@ bool igt_debugfs_search(const char *filename, const char 
*substring)
  * be random testcase failures when different screen contents end up with the
  * same CRC by chance.
  */
-void igt_assert_crc_equal(igt_crc_t *a, igt_crc_t *b)
+void igt_assert_crc_equal(const igt_crc_t *a, const igt_crc_t *b)
 {
int i;
 
diff --git a/lib/igt_debugfs.h b/lib/igt_debugfs.h
index 4c6572c..86c25dd 100644
--- a/lib/igt_debugfs.h
+++ b/lib/igt_debugfs.h
@@ -113,7 +113,7 @@ enum intel_pipe_crc_source {
 INTEL_PIPE_CRC_SOURCE_MAX,
 };
 
-void igt_assert_crc_equal(igt_crc_t *a, igt_crc_t *b);
+void igt_assert_crc_equal(const igt_crc_t *a, const igt_crc_t *b);
 char *igt_crc_to_string(igt_crc_t *crc);
 
 void igt_require_pipe_crc(void);
-- 
2.9.3

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


[Intel-gfx] [PATCH 3/9] drm/i915/tdr: Modify error handler for per engine hang recovery

2016-12-16 Thread Michel Thierry
From: Arun Siluvery 

This is a preparatory patch which modifies error handler to do per engine
hang recovery. The actual patch which implements this sequence follows
later in the series. The aim is to prepare existing recovery function to
adapt to this new function where applicable (which fails at this point
because core implementation is lacking) and continue recovery using legacy
full gpu reset.

A helper function is also added to query the availability of engine
reset.

The error events behaviour that are used to notify user of reset are
adapted to engine reset such that it doesn't break users listening to these
events. In legacy we report an error event, a reset event before resetting
the gpu and a reset done event marking the completion of reset. The same
behaviour is adapted but reset event is only dispatched once even when
multiple engines are hung. Finally once reset is complete we send reset
done event as usual.

Note that this implementation of engine reset is for i915 directly
submitting to the ELSP, where the driver manages the hang detection,
recovery and resubmission. With GuC submission these tasks are shared
between driver and firmware; i915 will still responsible for detecting a
hang, and when it does it will have to request GuC to reset that Engine and
remind the firmware about the outstanding submissions.

v2: rebase, advertise engine reset availability in platform definition,
add note about GuC submission.

Cc: Chris Wilson 
Cc: Mika Kuoppala 
Signed-off-by: Ian Lister 
Signed-off-by: Tomas Elf 
Signed-off-by: Arun Siluvery 
Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_drv.c | 21 +
 drivers/gpu/drm/i915/i915_drv.h |  3 ++
 drivers/gpu/drm/i915/i915_irq.c | 88 +++--
 drivers/gpu/drm/i915/i915_pci.c |  5 ++-
 drivers/gpu/drm/i915/intel_uncore.c | 11 +
 5 files changed, 103 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6428588518aa..e5688edd62cd 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1824,6 +1824,27 @@ void i915_reset(struct drm_i915_private *dev_priv)
goto wakeup;
 }
 
+/**
+ * i915_reset_engine - reset GPU engine to recover from a hang
+ * @engine: engine to reset
+ *
+ * Reset a specific GPU engine. Useful if a hang is detected.
+ * Returns zero on successful reset or otherwise an error code.
+ */
+int i915_reset_engine(struct intel_engine_cs *engine)
+{
+   int ret;
+   struct drm_i915_private *dev_priv = engine->i915;
+
+   /* FIXME: replace me with engine reset sequence */
+   ret = -ENODEV;
+
+   /* use full gpu reset to recover on error */
+   set_bit(I915_RESET_IN_PROGRESS, _priv->gpu_error.flags);
+
+   return ret;
+}
+
 static int i915_pm_suspend(struct device *kdev)
 {
struct pci_dev *pdev = to_pci_dev(kdev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fb3c88144aa8..6b4e8ee19905 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -781,6 +781,7 @@ struct intel_csr {
func(has_ddi); \
func(has_decoupled_mmio); \
func(has_dp_mst); \
+   func(has_engine_reset); \
func(has_fbc); \
func(has_fpga_dbg); \
func(has_full_ppgtt); \
@@ -3007,6 +3008,8 @@ extern void i915_driver_unload(struct drm_device *dev);
 extern int intel_gpu_reset(struct drm_i915_private *dev_priv, u32 engine_mask);
 extern bool intel_has_gpu_reset(struct drm_i915_private *dev_priv);
 extern void i915_reset(struct drm_i915_private *dev_priv);
+extern bool intel_has_engine_reset(struct drm_i915_private *dev_priv);
+extern int i915_reset_engine(struct intel_engine_cs *engine);
 extern int intel_guc_reset(struct drm_i915_private *dev_priv);
 extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine);
 extern void intel_hangcheck_init(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 77caeeb5ee55..da619810f59e 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2594,7 +2594,8 @@ static void i915_error_wake_up(struct drm_i915_private 
*dev_priv)
  * Fire an error uevent so userspace can see that a hang or error
  * was detected.
  */
-static void i915_reset_and_wakeup(struct drm_i915_private *dev_priv)
+static void i915_reset_and_wakeup(struct drm_i915_private *dev_priv,
+ u32 engine_mask)
 {
struct kobject *kobj = _priv->drm.primary->kdev->kobj;
char *error_event[] = { I915_ERROR_UEVENT "=1", NULL };
@@ -2603,7 +2604,15 @@ static void i915_reset_and_wakeup(struct 
drm_i915_private *dev_priv)
 

[Intel-gfx] [RFC 9/9] drm/i915: Add engine reset count in get-reset-stats ioctl

2016-12-16 Thread Michel Thierry
Users/tests relying on the total reset count will start seeing a smaller
number since most of the hangs can be handled by engine reset.
Note that if reset engine x, context a running on engine y will be unaware
and unaffected.

To start the discussion, include just a total engine reset count. If it
is deemed useful, it can be extended to report each engine separately.

Cc: Chris Wilson 
Cc: Mika Kuoppala 
Cc: mesa-...@lists.freedesktop.org
Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_gem_context.c | 14 +++---
 include/uapi/drm/i915_drm.h |  3 ++-
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 1822d338c7aa..7f89ff21e2e5 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -1339,9 +1339,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device 
*dev,
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_i915_reset_stats *args = data;
struct i915_gem_context *ctx;
+   struct intel_engine_cs *engine;
+   enum intel_engine_id id;
int ret;
 
-   if (args->flags || args->pad)
+   if (args->flags)
return -EINVAL;
 
if (args->ctx_id == DEFAULT_CONTEXT_HANDLE && !capable(CAP_SYS_ADMIN))
@@ -1357,10 +1359,16 @@ int i915_gem_context_reset_stats_ioctl(struct 
drm_device *dev,
return PTR_ERR(ctx);
}
 
-   if (capable(CAP_SYS_ADMIN))
+   if (capable(CAP_SYS_ADMIN)) {
args->reset_count = i915_reset_count(_priv->gpu_error);
-   else
+   for_each_engine(engine, dev_priv, id)
+   args->engine_reset_count +=
+   i915_engine_reset_count(_priv->gpu_error,
+   engine);
+   } else {
args->reset_count = 0;
+   args->engine_reset_count = 0;
+   }
 
args->batch_active = ctx->guilty_count;
args->batch_pending = ctx->active_count;
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 1110e628c239..172ce188a8cb 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1201,7 +1201,8 @@ struct drm_i915_reset_stats {
/* Number of batches lost pending for execution, for this context */
__u32 batch_pending;
 
-   __u32 pad;
+   /* Number of engine resets since boot/module reload, for all contexts */
+   __u32 engine_reset_count;
 };
 
 struct drm_i915_gem_userptr {
-- 
2.11.0

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


[Intel-gfx] ✗ Fi.CI.BAT: warning for series starting with [v3,01/38] drm/i915: Use the MRU stack search after evicting

2016-12-16 Thread Patchwork
== Series Details ==

Series: series starting with [v3,01/38] drm/i915: Use the MRU stack search 
after evicting
URL   : https://patchwork.freedesktop.org/series/16934/
State : warning

== Summary ==

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

Test kms_pipe_crc_basic:
Subgroup suspend-read-crc-pipe-b:
pass   -> SKIP   (fi-bxt-j4205)

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:222  dwarn:0   dfail:0   fail:0   skip:25 
fi-bxt-t5700 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
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-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
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:226  dwarn:0   dfail:0   fail:0   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:224  dwarn:3   dfail:0   fail:0   skip:20 
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 

705f1e8fef81d504f0032df8e21bdc2e74850b3a drm-tip: 2016y-12m-16d-15h-40m-02s UTC 
integration manifest
7c45ab9 drm: kselftest for drm_mm and bottom-up allocation
f0dc10e drm: Improve drm_mm search (and fix topdown allocation) with rbtrees
9d67b2a drm: Use drm_mm_insert_node_in_range_generic() for everyone
7c31969 drm: Apply range restriction after color adjustment when allocation
a389ffb drm: Wrap drm_mm_node.hole_follows
8f3d65a drm: Apply tight eviction scanning to color_adjust
713e51e drm: Simplify drm_mm scan-list manipulation
3f23d58 drm: Optimise power-of-two alignments in drm_mm_scan_add_block()
4b7fe06 drm: Compute tight evictions for drm_mm_scan
7b43f39 drm: Fix application of color vs range restriction when scanning drm_mm
46ca14a drm: Unconditionally do the range check in drm_mm_scan_add_block()
52d3c07 drm: Rename prev_node to hole in drm_mm_scan_add_block()
843ed0b drm: Extract struct drm_mm_scan from struct drm_mm
bd683ec drm: Add asserts to catch overflow in drm_mm_init() and 
drm_mm_init_scan()
54b09d7 drm: Simplify drm_mm_clean()
5d0b310 drm: Detect overflow in drm_mm_reserve_node()
68a3fad drm: Fix kerneldoc for drm_mm_scan_remove_block()
58b86fb drm: Promote drm_mm alignment to u64
200a726 drm/i915: Build DRM range manager selftests for CI
8b85ea3 drm: kselftest for drm_mm and restricted color eviction
bc18224 drm: kselftest for drm_mm and color eviction
aecad93 drm: kselftest for drm_mm and color adjustment
72de4a2 drm: kselftest for drm_mm and top-down allocation
79acff5 drm: kselftest for drm_mm and range restricted eviction
de7a869 drm: kselftest for drm_mm and eviction
7c2f995 drm: kselftest for drm_mm and alignment
a45196d drm: kselftest for drm_mm_insert_node_in_range()
63e7304 drm: kselftest for drm_mm_replace_node()
f859694 drm: kselftest for drm_mm_insert_node()
2f810a4 drm: kselftest for drm_mm_reserve_node()
203008d drm: kselftest for drm_mm_debug()
fd28f93 drm: kselftest for drm_mm_init()
a23ba8f drm: Add some kselftests for the DRM range manager (struct drm_mm)
d742b04 drm: Add a simple generator of random permutations
95765bd lib: Add a simple prime number generator
80ec238 drm: Compile time enabling for asserts in drm_mm
a451708 drm: Use drm_mm_nodes() as shorthand for the list of nodes under struct 
drm_mm
a4063bcc drm/i915: Use the MRU stack search after evicting

== Logs ==

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


[Intel-gfx] [PATCH 5/9] drm/i915: Skip reset request if there is one already

2016-12-16 Thread Michel Thierry
From: Mika Kuoppala 

To perform engine reset we first disable engine to capture its state. This
is done by issuing a reset request. Because we are reusing existing
infrastructure, again when we actually reset an engine, reset function
checks engine mask and issues reset request again which is unnecessary. To
avoid this we check if the engine is already prepared, if so we just exit
from that point.

Cc: Chris Wilson 
Signed-off-by: Mika Kuoppala 
Signed-off-by: Arun Siluvery 
Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/intel_uncore.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index 9105c166a6d5..cd3102d841a4 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -1761,10 +1761,15 @@ int intel_wait_for_register(struct drm_i915_private 
*dev_priv,
 static int gen8_engine_reset_begin(struct intel_engine_cs *engine)
 {
struct drm_i915_private *dev_priv = engine->i915;
+   const i915_reg_t reset_ctrl = RING_RESET_CTL(engine->mmio_base);
+   const u32 ready = RESET_CTL_REQUEST_RESET | RESET_CTL_READY_TO_RESET;
int ret;
 
-   I915_WRITE_FW(RING_RESET_CTL(engine->mmio_base),
- _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET));
+   /* If engine has been already prepared, we can shortcut here */
+   if ((I915_READ_FW(reset_ctrl) & ready) == ready)
+   return 0;
+
+   I915_WRITE_FW(reset_ctrl, _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET));
 
ret = intel_wait_for_register_fw(dev_priv,
 RING_RESET_CTL(engine->mmio_base),
-- 
2.11.0

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


[Intel-gfx] [PATCH 7/9] drm/i915/tdr: Export per-engine reset count info to debugfs

2016-12-16 Thread Michel Thierry
From: Arun Siluvery 

A new variable is added to export the reset counts to debugfs, this
includes full gpu reset and engine reset count. This is useful for tests
where they are expected to trigger reset; these counts are checked before
and after the test to ensure the same.

Cc: Chris Wilson 
Cc: Mika Kuoppala 
Signed-off-by: Arun Siluvery 
Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_debugfs.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 54e196d9d83e..b2a3c31ba95c 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1370,6 +1370,23 @@ static int i915_hangcheck_info(struct seq_file *m, void 
*unused)
return 0;
 }
 
+static int i915_reset_info(struct seq_file *m, void *unused)
+{
+   struct drm_i915_private *dev_priv = node_to_i915(m->private);
+   struct i915_gpu_error *error = _priv->gpu_error;
+   struct intel_engine_cs *engine;
+   enum intel_engine_id id;
+
+   seq_printf(m, "full gpu reset = %u\n", i915_reset_count(error));
+
+   for_each_engine(engine, dev_priv, id) {
+   seq_printf(m, "%s = %u\n", engine->name,
+  i915_engine_reset_count(error, engine));
+   }
+
+   return 0;
+}
+
 static int ironlake_drpc_info(struct seq_file *m)
 {
struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -5408,6 +5425,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_guc_log_dump", i915_guc_log_dump, 0},
{"i915_frequency_info", i915_frequency_info, 0},
{"i915_hangcheck_info", i915_hangcheck_info, 0},
+   {"i915_reset_info", i915_reset_info, 0},
{"i915_drpc_info", i915_drpc_info, 0},
{"i915_emon_status", i915_emon_status, 0},
{"i915_ring_freq_table", i915_ring_freq_table, 0},
-- 
2.11.0

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


[Intel-gfx] [PATCH 6/9] drm/i915/tdr: Add engine reset count to error state

2016-12-16 Thread Michel Thierry
From: Arun Siluvery 

Driver maintains count of how many times a given engine is reset, useful to
capture this in error state also. It gives an idea of how engine is coping
up with the workloads it is executing before this error state.

Cc: Chris Wilson 
Cc: Mika Kuoppala 
Signed-off-by: Arun Siluvery 
Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_drv.c   | 1 +
 drivers/gpu/drm/i915/i915_drv.h   | 9 +
 drivers/gpu/drm/i915/i915_gpu_error.c | 3 +++
 3 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a034793bc246..1c706a082d60 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1877,6 +1877,7 @@ int i915_reset_engine(struct intel_engine_cs *engine)
intel_engine_reset_cancel(engine);
intel_execlists_restart_submission(engine);
 
+   dev_priv->gpu_error.engine_reset_count[engine->id]++;
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
return 0;
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a97cc8f50ade..25183762ed94 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -937,6 +937,7 @@ struct drm_i915_error_state {
enum intel_engine_hangcheck_action hangcheck_action;
struct i915_address_space *vm;
int num_requests;
+   u32 reset_count;
 
/* position of active request inside the ring */
u32 rq_head, rq_post, rq_tail;
@@ -1629,6 +1630,8 @@ struct i915_gpu_error {
 #define I915_RESET_IN_PROGRESS 0
 #define I915_WEDGED(BITS_PER_LONG - 1)
 
+   unsigned long engine_reset_count[I915_NUM_ENGINES];
+
/**
 * Waitqueue to signal when a hang is detected. Used to for waiters
 * to release the struct_mutex for the reset to procede.
@@ -3397,6 +3400,12 @@ static inline u32 i915_reset_count(struct i915_gpu_error 
*error)
return READ_ONCE(error->reset_count);
 }
 
+static inline u32 i915_engine_reset_count(struct i915_gpu_error *error,
+ struct intel_engine_cs *engine)
+{
+   return READ_ONCE(error->engine_reset_count[engine->id]);
+}
+
 void i915_gem_reset(struct drm_i915_private *dev_priv);
 void i915_gem_set_wedged(struct drm_i915_private *dev_priv);
 void i915_gem_reset_engine(struct intel_engine_cs *engine);
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index e16037d1b0ba..f168ad873521 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -453,6 +453,7 @@ static void error_print_engine(struct 
drm_i915_error_state_buf *m,
err_printf(m, "  hangcheck action timestamp: %lu, %u ms ago\n",
   ee->hangcheck_timestamp,
   jiffies_to_msecs(jiffies - ee->hangcheck_timestamp));
+   err_printf(m, "  engine reset count: %u\n", ee->reset_count);
 
error_print_request(m, "  ELSP[0]: ", >execlist[0]);
error_print_request(m, "  ELSP[1]: ", >execlist[1]);
@@ -1170,6 +1171,8 @@ static void error_record_engine_registers(struct 
drm_i915_error_state *error,
ee->hangcheck_timestamp = engine->hangcheck.action_timestamp;
ee->hangcheck_action = engine->hangcheck.action;
ee->hangcheck_stalled = engine->hangcheck.stalled;
+   ee->reset_count = i915_engine_reset_count(_priv->gpu_error,
+ engine);
 
if (USES_PPGTT(dev_priv)) {
int i;
-- 
2.11.0

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


[Intel-gfx] [PATCH 0/9] Execlist based engine-reset

2016-12-16 Thread Michel Thierry
These patches are to add engine reset feature from Gen8. This is also
referred to as Timeout detection and recovery (TDR). This complements to
the full gpu reset feature available in i915 but it only allows to reset a
particular engine instead of all engines thus providing a light weight
engine reset and recovery mechanism.

This implementation is for execlist based submission only hence limited
from Gen8 onwards. For GuC based submission, additional changes can be
added later on.

Timeout detection relies on the existing hangcheck which remains the same,
main changes are to the recovery mechanism. Once we detect a hang on a
particular engine we identify the request that caused the hang, skip the
request and adjust head pointers to allow the execution to proceed
normally. After some cleanup, submissions are restarted to process
remaining work queued to that engine.

If engine reset fails to recover engine correctly then we fallback to full
gpu reset.

v2: ELSP queue request tracking and reset path changes to handle incomplete
requests during reset. Thanks to Chris Wilson for providing these patches.

v3: Let the waiter keep handling the full gpu reset if it already has the
lock; point out that GuC submission needs a different method to restart
workloads after the engine reset completes.

Arun Siluvery (6):
  drm/i915: Update i915.reset to handle engine resets
  drm/i915/tdr: Modify error handler for per engine hang recovery
  drm/i915/tdr: Add support for per engine reset recovery
  drm/i915/tdr: Add engine reset count to error state
  drm/i915/tdr: Export per-engine reset count info to debugfs
  drm/i915/tdr: Enable Engine reset and recovery support

Michel Thierry (2):
  drm/i915: Keep i915_handle_error kerneldoc parameters together
  drm/i915: Add engine reset count in get-reset-stats ioctl

Mika Kuoppala (1):
  drm/i915: Skip reset request if there is one already

 drivers/gpu/drm/i915/i915_debugfs.c | 18 +++
 drivers/gpu/drm/i915/i915_drv.c | 74 +++
 drivers/gpu/drm/i915/i915_drv.h | 15 ++
 drivers/gpu/drm/i915/i915_gem.c |  2 +-
 drivers/gpu/drm/i915/i915_gem_context.c | 14 +++--
 drivers/gpu/drm/i915/i915_gpu_error.c   |  3 ++
 drivers/gpu/drm/i915/i915_irq.c | 91 -
 drivers/gpu/drm/i915/i915_params.c  |  6 +--
 drivers/gpu/drm/i915/i915_params.h  |  2 +-
 drivers/gpu/drm/i915/i915_pci.c |  5 +-
 drivers/gpu/drm/i915/intel_lrc.c| 12 +
 drivers/gpu/drm/i915/intel_lrc.h|  1 +
 drivers/gpu/drm/i915/intel_uncore.c | 61 +++---
 include/uapi/drm/i915_drm.h |  3 +-
 14 files changed, 266 insertions(+), 41 deletions(-)

Cc: Chris Wilson 
Cc: Mika Kuoppala 
-- 
2.11.0

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


[Intel-gfx] [PATCH 1/9] drm/i915: Keep i915_handle_error kerneldoc parameters together

2016-12-16 Thread Michel Thierry
And before the function description.
Tidy up from commit 14bb2c11796d70b ("drm/i915: Fix a buch of kerneldoc
warnings"), all others kerneldoc blocks look ok.

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

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index a0e70f5b3aad..77caeeb5ee55 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2703,12 +2703,13 @@ static void i915_clear_error_registers(struct 
drm_i915_private *dev_priv)
  * i915_handle_error - handle a gpu error
  * @dev_priv: i915 device private
  * @engine_mask: mask representing engines that are hung
+ * @fmt: Error message format string
+ *
  * Do some basic checking of register state at error time and
  * dump it to the syslog.  Also call i915_capture_error_state() to make
  * sure we get a record and make it available in debugfs.  Fire a uevent
  * so userspace knows something bad happened (should trigger collection
  * of a ring dump etc.).
- * @fmt: Error message format string
  */
 void i915_handle_error(struct drm_i915_private *dev_priv,
   u32 engine_mask,
-- 
2.11.0

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


[Intel-gfx] [PATCH 8/9] drm/i915/tdr: Enable Engine reset and recovery support

2016-12-16 Thread Michel Thierry
From: Arun Siluvery 

This feature is made available only from Gen8, for previous gen devices
driver uses legacy full gpu reset.

Cc: Chris Wilson 
Cc: Mika Kuoppala 
Signed-off-by: Tomas Elf 
Signed-off-by: Arun Siluvery 
Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_params.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index c858c4d50491..fe1cc54e82e3 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -46,7 +46,7 @@ struct i915_params i915 __read_mostly = {
.prefault_disable = 0,
.load_detect_test = 0,
.force_reset_modeset_test = 0,
-   .reset = 1,
+   .reset = 2,
.error_capture = true,
.invert_brightness = 0,
.disable_display = 0,
@@ -114,7 +114,7 @@ MODULE_PARM_DESC(vbt_sdvo_panel_type,
"(-2=ignore, -1=auto [default], index in VBT BIOS table)");
 
 module_param_named_unsafe(reset, i915.reset, int, 0600);
-MODULE_PARM_DESC(reset, "Attempt GPU resets (0=disabled, 1=full gpu reset 
[default], 2=engine reset)");
+MODULE_PARM_DESC(reset, "Attempt GPU resets (0=disabled, 1=full gpu reset, 
2=engine reset [default])");
 
 #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
 module_param_named(error_capture, i915.error_capture, bool, 0600);
-- 
2.11.0

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


[Intel-gfx] [PATCH 2/9] drm/i915: Update i915.reset to handle engine resets

2016-12-16 Thread Michel Thierry
From: Arun Siluvery 

In preparation for engine reset work update this parameter to handle more
than one type of reset. Default at the moment is still full gpu reset.

Cc: Chris Wilson 
Cc: Mika Kuoppala 
Signed-off-by: Arun Siluvery 
Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_params.c | 6 +++---
 drivers/gpu/drm/i915/i915_params.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index 0e280fbd52f1..c858c4d50491 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -46,7 +46,7 @@ struct i915_params i915 __read_mostly = {
.prefault_disable = 0,
.load_detect_test = 0,
.force_reset_modeset_test = 0,
-   .reset = true,
+   .reset = 1,
.error_capture = true,
.invert_brightness = 0,
.disable_display = 0,
@@ -113,8 +113,8 @@ MODULE_PARM_DESC(vbt_sdvo_panel_type,
"Override/Ignore selection of SDVO panel mode in the VBT "
"(-2=ignore, -1=auto [default], index in VBT BIOS table)");
 
-module_param_named_unsafe(reset, i915.reset, bool, 0600);
-MODULE_PARM_DESC(reset, "Attempt GPU resets (default: true)");
+module_param_named_unsafe(reset, i915.reset, int, 0600);
+MODULE_PARM_DESC(reset, "Attempt GPU resets (0=disabled, 1=full gpu reset 
[default], 2=engine reset)");
 
 #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
 module_param_named(error_capture, i915.error_capture, bool, 0600);
diff --git a/drivers/gpu/drm/i915/i915_params.h 
b/drivers/gpu/drm/i915/i915_params.h
index 8e433de04679..da569e20bbec 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -34,6 +34,7 @@ struct i915_params {
int lvds_channel_mode;
int panel_use_ssc;
int vbt_sdvo_panel_type;
+   int reset;
int enable_rc6;
int enable_dc;
int enable_fbc;
@@ -58,7 +59,6 @@ struct i915_params {
bool prefault_disable;
bool load_detect_test;
bool force_reset_modeset_test;
-   bool reset;
bool error_capture;
bool disable_display;
bool verbose_state_checks;
-- 
2.11.0

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


Re: [Intel-gfx] [PATCH v3 04/38] lib: Add a simple prime number generator

2016-12-16 Thread Chris Wilson
On Fri, Dec 16, 2016 at 07:25:16PM +, Chris Wilson wrote:
> +static void __exit primes_exit(void)
> +{
> + const struct primes *p;
> +
> + mutex_lock();
> + p = rcu_dereference_protected(primes, lockdep_is_held());
> + if (p != _primes) {
> + kfree_rcu((struct primes *)p, rcu);
> + rcu_assign_pointer(p, _primes);

Too much sparse appleasing, too little thinking. It's only the module
shutdown path, but we might as well be correct: s/p/primes here.
-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] [PATCH v3 09/38] drm: kselftest for drm_mm_reserve_node()

2016-12-16 Thread Chris Wilson
Exercise drm_mm_reserve_node(), check that we can't reserve an already
occupied range and that the lists are correct after reserving/removing.

v2: Check for invalid node reservation.

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  | 275 +++
 2 files changed, 276 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 0265f09e92fa..693d85677e7f 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -8,3 +8,4 @@
 selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck for igt) */
 selftest(init, igt_init)
 selftest(debug, igt_debug)
+selftest(reserve, igt_reserve)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 434320061d9e..673519cf41e1 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -80,6 +80,57 @@ static bool assert_one_hole(const struct drm_mm *mm, u64 
start, u64 end)
return ok;
 }
 
+static bool assert_continuous(const struct drm_mm *mm, u64 size)
+{
+   struct drm_mm_node *node, *check, *found;
+   unsigned long n;
+   u64 addr;
+
+   if (!assert_no_holes(mm))
+   return false;
+
+   n = 0;
+   addr = 0;
+   drm_mm_for_each_node(node, mm) {
+   if (node->start != addr) {
+   pr_err("node[%ld] list out of order, expected %llx 
found %llx\n",
+  n, addr, node->start);
+   return false;
+   }
+
+   if (node->size != size) {
+   pr_err("node[%ld].size incorrect, expected %llx, found 
%llx\n",
+  n, size, node->size);
+   return false;
+   }
+
+   if (node->hole_follows) {
+   pr_err("node[%ld] is followed by a hole!\n", n);
+   return false;
+   }
+
+   found = NULL;
+   drm_mm_for_each_node_in_range(check, mm, addr, addr + size) {
+   if (node != check) {
+   pr_err("lookup return wrong node, expected 
start %llx, found %llx\n",
+  node->start, check->start);
+   return false;
+   }
+   found = check;
+   }
+   if (!found) {
+   pr_err("lookup failed for node %llx + %llx\n",
+  addr, size);
+   return false;
+   }
+
+   addr += size;
+   n++;
+   }
+
+   return true;
+}
+
 static int igt_init(void *ignored)
 {
const unsigned int size = 4096;
@@ -176,6 +227,230 @@ static int igt_debug(void *ignored)
return 0;
 }
 
+static struct drm_mm_node *set_node(struct drm_mm_node *node,
+   u64 start, u64 size)
+{
+   node->start = start;
+   node->size = size;
+   return node;
+}
+
+static bool expect_reserve_fail(struct drm_mm *mm, struct drm_mm_node *node)
+{
+   int err;
+
+   err = drm_mm_reserve_node(mm, node);
+   if (likely(err == -ENOSPC))
+   return true;
+
+   if (!err) {
+   pr_err("impossible reserve succeeded, node %llu + %llu\n",
+  node->start, node->size);
+   drm_mm_remove_node(node);
+   } else {
+   pr_err("impossible reserve failed with wrong error %d [expected 
%d], node %llu + %llu\n",
+  err, -ENOSPC, node->start, node->size);
+   }
+   return false;
+}
+
+static bool check_reserve_boundaries(struct drm_mm *mm,
+unsigned int count,
+u64 size)
+{
+   const struct boundary {
+   u64 start, size;
+   const char *name;
+   } boundaries[] = {
+#define B(st, sz) { (st), (sz), "{ " #st ", " #sz "}" }
+   B(0, 0),
+   B(-size, 0),
+   B(size, 0),
+   B(size * count, 0),
+   B(-size, size),
+   B(-size, -size),
+   B(-size, 2*size),
+   B(0, -size),
+   B(size, -size),
+   B(count*size, size),
+   B(count*size, -size),
+   B(count*size, count*size),
+   B(count*size, -count*size),
+   B(count*size, -(count+1)*size),
+   B((count+1)*size, size),
+   B((count+1)*size, -size),
+   B((count+1)*size, -2*size),
+#undef B
+   };
+   struct drm_mm_node tmp = {};
+   int n;
+
+   for (n 

[Intel-gfx] [PATCH v3 37/38] drm: Improve drm_mm search (and fix topdown allocation) with rbtrees

2016-12-16 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.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 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 | 511 +++
 drivers/gpu/drm/drm_vma_manager.c|   3 +-
 drivers/gpu/drm/etnaviv/etnaviv_mmu.c|   8 +-
 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 | 135 +++
 23 files changed, 434 insertions(+), 449 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
index 00f46b0e076d..d841fcb2e709 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->mode & TTM_PL_FLAG_TOPDOWN)
+   mode = DRM_MM_INSERT_HIGH;
 
spin_lock(>lock);
-   r = drm_mm_insert_node_in_range_generic(>mm, node, mem->num_pages,
-   mem->page_alignment, 0,
-   fpfn, lpfn, sflags, aflags);
+   r = drm_mm_insert_node_in_range(>mm, node,
+   mem->num_pages, mem->page_alignment, 0,
+   fpfn, lpfn, mode);
spin_unlock(>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 d710226a0fff..5f106ad815ce 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 = >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;
+   if (place->flags & TTM_PL_FLAG_TOPDOWN)
+   mode = DRM_MM_INSERT_HIGH;
 
pages_left = mem->num_pages;
 
@@ -135,13 +133,11 @@ static int amdgpu_vram_mgr_new(struct 
ttm_mem_type_manager *man,
 
if (pages == pages_per_node)
alignment = pages_per_node;
-   else
-   

[Intel-gfx] [PATCH v3 23/38] drm: Detect overflow in drm_mm_reserve_node()

2016-12-16 Thread Chris Wilson
Protect ourselves from a caller passing in node.start + node.size that
will overflow and trick us into reserving that node.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 767cfd05c628..370cb8ee91c9 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -308,10 +308,9 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct 
drm_mm_node *node)
u64 hole_start, hole_end;
u64 adj_start, adj_end;
 
-   if (WARN_ON(node->size == 0))
-   return -EINVAL;
-
end = node->start + node->size;
+   if (unlikely(end <= node->start))
+   return -ENOSPC;
 
/* Find the relevant hole to add our node to */
hole = drm_mm_interval_tree_iter_first(>interval_tree,
-- 
2.11.0

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


[Intel-gfx] [PATCH v3 17/38] drm: kselftest for drm_mm and color adjustment

2016-12-16 Thread Chris Wilson
Check that after applying the driver's color adjustment, fitting of the
node and its alignment are still correct.

v2: s/no_color_touching/separate_adjacent_colors/

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  | 183 +++
 2 files changed, 184 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index cd508e3d6538..ff44f39a1826 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -18,3 +18,4 @@ selftest(align64, igt_align64)
 selftest(evict, igt_evict)
 selftest(evict_range, igt_evict_range)
 selftest(topdown, igt_topdown)
+selftest(color, igt_color)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index a499895a76c4..71520a21de8d 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1666,6 +1666,189 @@ static int igt_topdown(void *ignored)
return ret;
 }
 
+static void separate_adjacent_colors(const struct drm_mm_node *node,
+unsigned long color,
+u64 *start,
+u64 *end)
+{
+   if (node->allocated && node->color != color)
+   ++*start;
+
+   node = list_next_entry(node, node_list);
+   if (node->allocated && node->color != color)
+   --*end;
+}
+
+static bool colors_abutt(const struct drm_mm_node *node)
+{
+   if (!node->hole_follows &&
+   list_next_entry(node, node_list)->allocated) {
+   pr_err("colors abutt; %ld [%llx + %llx] is next to %ld [%llx + 
%llx]!\n",
+  node->color, node->start, node->size,
+  list_next_entry(node, node_list)->color,
+  list_next_entry(node, node_list)->start,
+  list_next_entry(node, node_list)->size);
+   return true;
+   }
+
+   return false;
+}
+
+static int igt_color(void *ignored)
+{
+   const unsigned int count = min(4096u, max_iterations);
+   const struct insert_mode *mode;
+   struct drm_mm mm;
+   struct drm_mm_node *node, *nn;
+   unsigned int n;
+   int ret = -EINVAL, err;
+
+   /* Color adjustment complicates everything. First we just check
+* that when we insert a node we apply any color_adjustment callback.
+* The callback we use should ensure that there is a gap between
+* any two nodes, and so after each insertion we check that those
+* holes are inserted and that they are preserved.
+*/
+
+   drm_mm_init(, 0, U64_MAX);
+
+   for (n = 1; n <= count; n++) {
+   node = kzalloc(sizeof(*node), GFP_KERNEL);
+   if (!node) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   if (!expect_insert(, node,
+  n, 0, n,
+  _modes[0])) {
+   pr_err("insert failed, step %d\n", n);
+   kfree(node);
+   goto out;
+   }
+   }
+
+   drm_mm_for_each_node_safe(node, nn, ) {
+   if (node->color != node->size) {
+   pr_err("invalid color stored: expected %lld, found 
%ld\n",
+  node->size, node->color);
+
+   goto out;
+   }
+
+   drm_mm_remove_node(node);
+   kfree(node);
+   }
+
+   /* Now, let's start experimenting with applying a color callback */
+   mm.color_adjust = separate_adjacent_colors;
+   for (mode = insert_modes; mode->name; mode++) {
+   u64 last;
+
+   node = kzalloc(sizeof(*node), GFP_KERNEL);
+   if (!node) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   node->size = 1 + 2*count;
+   node->color = node->size;
+
+   err = drm_mm_reserve_node(, node);
+   if (err) {
+   pr_err("initial reserve failed!\n");
+   ret = err;
+   goto out;
+   }
+
+   last = node->start + node->size;
+
+   for (n = 1; n <= count; n++) {
+   int rem;
+
+   node = kzalloc(sizeof(*node), GFP_KERNEL);
+   if (!node) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   node->start = last;
+   node->size = n + count;
+   node->color = node->size;
+
+  

[Intel-gfx] [PATCH v3 24/38] drm: Simplify drm_mm_clean()

2016-12-16 Thread Chris Wilson
Since commit ea7b1dd44867 ("drm: mm: track free areas implicitly"),
to test whether there are any nodes allocated within the range manager,
we merely have to ask whether the node_list is empty.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 19 +--
 include/drm/drm_mm.h | 14 +-
 2 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 370cb8ee91c9..e0419cf09bbb 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -873,22 +873,6 @@ bool drm_mm_scan_remove_block(struct drm_mm_node *node)
 EXPORT_SYMBOL(drm_mm_scan_remove_block);
 
 /**
- * drm_mm_clean - checks whether an allocator is clean
- * @mm: drm_mm allocator to check
- *
- * Returns:
- * True if the allocator is completely free, false if there's still a node
- * allocated in it.
- */
-bool drm_mm_clean(const struct drm_mm *mm)
-{
-   const struct list_head *head = drm_mm_nodes(mm);
-
-   return (head->next->next == head);
-}
-EXPORT_SYMBOL(drm_mm_clean);
-
-/**
  * drm_mm_init - initialize a drm-mm allocator
  * @mm: the drm_mm structure to initialize
  * @start: start of the range managed by @mm
@@ -928,10 +912,9 @@ EXPORT_SYMBOL(drm_mm_init);
  */
 void drm_mm_takedown(struct drm_mm *mm)
 {
-   if (WARN(!list_empty(drm_mm_nodes(mm)),
+   if (WARN(!drm_mm_clean(mm),
 "Memory manager not clean during takedown.\n"))
show_leaks(mm);
-
 }
 EXPORT_SYMBOL(drm_mm_takedown);
 
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 7eeb98b5bf70..72e0c0ddf8d0 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -342,7 +342,19 @@ void drm_mm_remove_node(struct drm_mm_node *node);
 void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
 void drm_mm_init(struct drm_mm *mm, u64 start, u64 size);
 void drm_mm_takedown(struct drm_mm *mm);
-bool drm_mm_clean(const struct drm_mm *mm);
+
+/**
+ * drm_mm_clean - checks whether an allocator is clean
+ * @mm: drm_mm allocator to check
+ *
+ * Returns:
+ * True if the allocator is completely free, false if there's still a node
+ * allocated in it.
+ */
+static inline bool drm_mm_clean(const struct drm_mm *mm)
+{
+   return list_empty(drm_mm_nodes(mm));
+}
 
 struct drm_mm_node *
 __drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last);
-- 
2.11.0

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


[Intel-gfx] [PATCH v3 25/38] drm: Add asserts to catch overflow in drm_mm_init() and drm_mm_init_scan()

2016-12-16 Thread Chris Wilson
A simple assert to ensure that we don't overflow start + size when
initialising the drm_mm, or its scanner.

In future, we may want to switch to tracking the value of ranges (rather
than size) so that we can cover the full u64, for example like resource
tracking.

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

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index e0419cf09bbb..b80305484124 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -729,6 +729,8 @@ void drm_mm_init_scan(struct drm_mm *mm,
  u64 alignment,
  unsigned long color)
 {
+   DRM_MM_BUG_ON(!size);
+
mm->scan_color = color;
mm->scan_alignment = alignment;
mm->scan_size = size;
@@ -764,6 +766,9 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm,
 u64 start,
 u64 end)
 {
+   DRM_MM_BUG_ON(start >= end);
+   DRM_MM_BUG_ON(!size || size > end - start);
+
mm->scan_color = color;
mm->scan_alignment = alignment;
mm->scan_size = size;
@@ -882,6 +887,8 @@ EXPORT_SYMBOL(drm_mm_scan_remove_block);
  */
 void drm_mm_init(struct drm_mm *mm, u64 start, u64 size)
 {
+   DRM_MM_BUG_ON(start + size <= start);
+
INIT_LIST_HEAD(>hole_stack);
mm->scanned_blocks = 0;
 
-- 
2.11.0

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


[Intel-gfx] [PATCH v3 28/38] drm: Unconditionally do the range check in drm_mm_scan_add_block()

2016-12-16 Thread Chris Wilson
Doing the check is trivial (low cost in comparison to overall eviction)
and helps simplify the code.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c  | 53 +++
 drivers/gpu/drm/i915/i915_gem_evict.c | 10 ++-
 include/drm/drm_mm.h  | 33 ++
 3 files changed, 34 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 459f10ca5714..c68f79149b9a 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -710,46 +710,6 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  */
 
 /**
- * drm_mm_scan_init - initialize lru scanning
- * @scan: scan state
- * @mm: drm_mm to scan
- * @size: size of the allocation
- * @alignment: alignment of the allocation
- * @color: opaque tag value to use for the allocation
- *
- * This simply sets up the scanning routines with the parameters for the 
desired
- * hole. Note that there's no need to specify allocation flags, since they only
- * change the place a node is allocated from within a suitable hole.
- *
- * Warning:
- * As long as the scan list is non-empty, no other operations than
- * adding/removing nodes to/from the scan list are allowed.
- */
-void drm_mm_scan_init(struct drm_mm_scan *scan,
- struct drm_mm *mm,
- u64 size,
- u64 alignment,
- unsigned long color)
-{
-   DRM_MM_BUG_ON(!size);
-   DRM_MM_BUG_ON(mm->scan_active);
-
-   scan->mm = mm;
-
-   scan->color = color;
-   scan->alignment = alignment;
-   scan->size = size;
-
-   scan->check_range = 0;
-
-   scan->hit_start = U64_MAX;
-   scan->hit_end = 0;
-
-   scan->prev_scanned_node = NULL;
-}
-EXPORT_SYMBOL(drm_mm_scan_init);
-
-/**
  * drm_mm_scan_init_with_range - initialize range-restricted lru scanning
  * @scan: scan state
  * @mm: drm_mm to scan
@@ -788,7 +748,6 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
DRM_MM_BUG_ON(end <= start);
scan->range_start = start;
scan->range_end = end;
-   scan->check_range = 1;
 
scan->hit_start = U64_MAX;
scan->hit_end = 0;
@@ -830,15 +789,11 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
node->node_list.next = >prev_scanned_node->node_list;
scan->prev_scanned_node = node;
 
-   adj_start = hole_start = drm_mm_hole_node_start(hole);
-   adj_end = hole_end = drm_mm_hole_node_end(hole);
+   hole_start = drm_mm_hole_node_start(hole);
+   hole_end = drm_mm_hole_node_end(hole);
 
-   if (scan->check_range) {
-   if (adj_start < scan->range_start)
-   adj_start = scan->range_start;
-   if (adj_end > scan->range_end)
-   adj_end = scan->range_end;
-   }
+   adj_start = max(hole_start, scan->range_start);
+   adj_end = min(hole_end, scan->range_end);
 
if (mm->color_adjust)
mm->color_adjust(hole, scan->color, _start, _end);
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c 
b/drivers/gpu/drm/i915/i915_gem_evict.c
index 6db0d73c0aa7..77ded288534b 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -126,13 +126,9 @@ i915_gem_evict_something(struct i915_address_space *vm,
 * On each list, the oldest objects lie at the HEAD with the freshest
 * object on the TAIL.
 */
-   if (start != 0 || end != vm->total) {
-   drm_mm_scan_init_with_range(, >mm, min_size,
-   alignment, cache_level,
-   start, end);
-   } else
-   drm_mm_scan_init(, >mm, min_size,
-alignment, cache_level);
+   drm_mm_scan_init_with_range(, >mm,
+   min_size, alignment, cache_level,
+   start, end);
 
/* Retire before we search the active list. Although we have
 * reasonable accuracy in our retirement lists, we may have
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index fcad718c5fb4..bae0f10da8e3 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -120,7 +120,6 @@ struct drm_mm_scan {
struct drm_mm_node *prev_scanned_node;
 
unsigned long color;
-   bool check_range : 1;
 };
 
 /**
@@ -387,11 +386,6 @@ __drm_mm_interval_first(const struct drm_mm *mm, u64 
start, u64 last);
 node__ && node__->start < (end__); \
 node__ = list_next_entry(node__, node_list))
 
-void drm_mm_scan_init(struct drm_mm_scan *scan,
- struct drm_mm *mm,
- u64 size,
- u64 alignment,
- unsigned long color);
 void 

[Intel-gfx] [PATCH v3 30/38] drm: Compute tight evictions for drm_mm_scan

2016-12-16 Thread Chris Wilson
Compute the minimal required hole during scan and only evict those nodes
that overlap. This enables us to reduce the number of nodes we need to
evict to the bare minimum.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c| 60 +++--
 drivers/gpu/drm/etnaviv/etnaviv_mmu.c   |  2 +-
 drivers/gpu/drm/i915/i915_gem_evict.c   |  3 +-
 drivers/gpu/drm/selftests/test-drm_mm.c | 10 +++---
 include/drm/drm_mm.h| 22 ++--
 5 files changed, 71 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 1b5613bcb35e..189ab84c5a59 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -718,10 +718,10 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  * @color: opaque tag value to use for the allocation
  * @start: start of the allowed range for the allocation
  * @end: end of the allowed range for the allocation
+ * @flags: flags to specify how the allocation will be performed afterwards
  *
  * This simply sets up the scanning routines with the parameters for the 
desired
- * hole. Note that there's no need to specify allocation flags, since they only
- * change the place a node is allocated from within a suitable hole.
+ * hole.
  *
  * Warning:
  * As long as the scan list is non-empty, no other operations than
@@ -733,7 +733,8 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
 u64 alignment,
 unsigned long color,
 u64 start,
-u64 end)
+u64 end,
+unsigned int flags)
 {
DRM_MM_BUG_ON(start >= end);
DRM_MM_BUG_ON(!size || size > end - start);
@@ -744,6 +745,7 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
scan->color = color;
scan->alignment = alignment;
scan->size = size;
+   scan->flags = flags;
 
DRM_MM_BUG_ON(end <= start);
scan->range_start = start;
@@ -778,7 +780,7 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
DRM_MM_BUG_ON(node->mm != mm);
DRM_MM_BUG_ON(!node->allocated);
DRM_MM_BUG_ON(node->scanned_block);
-   node->scanned_block = 1;
+   node->scanned_block = true;
mm->scan_active++;
 
hole = list_prev_entry(node, node_list);
@@ -800,15 +802,53 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
 
adj_start = max(col_start, scan->range_start);
adj_end = min(col_end, scan->range_end);
+   if (adj_end <= adj_start || adj_end - adj_start < scan->size)
+   return false;
+
+   if (scan->flags == DRM_MM_CREATE_TOP)
+   adj_start = adj_end - scan->size;
+
+   if (scan->alignment) {
+   u64 rem;
+
+   div64_u64_rem(adj_start, scan->alignment, );
+   if (rem) {
+   adj_start -= rem;
+   if (scan->flags != DRM_MM_CREATE_TOP)
+   adj_start += scan->alignment;
+   if (adj_start < max(col_start, scan->range_start) ||
+   min(col_end, scan->range_end) - adj_start < 
scan->size)
+   return false;
+
+   if (adj_end <= adj_start ||
+   adj_end - adj_start < scan->size)
+   return false;
+   }
+   }
 
-   if (check_free_hole(adj_start, adj_end,
-   scan->size, scan->alignment)) {
+   if (mm->color_adjust) {
+   /* If allocations need adjusting due to neighbouring colours,
+* we do not have enough information to decide if we need
+* to evict nodes on either side of [adj_start, adj_end].
+* What almost works is
+* hit_start = adj_start + (hole_start - col_start);
+* hit_end = adj_start + scan->size + (hole_end - col_end);
+* but because the decision is only made on the final hole,
+* we may underestimate the required adjustments for an
+* interior allocation.
+*/
scan->hit_start = hole_start;
scan->hit_end = hole_end;
-   return true;
+   } else {
+   scan->hit_start = adj_start;
+   scan->hit_end = adj_start + scan->size;
}
 
-   return false;
+   DRM_MM_BUG_ON(scan->hit_start >= scan->hit_end);
+   DRM_MM_BUG_ON(scan->hit_start < hole_start);
+   DRM_MM_BUG_ON(scan->hit_end > hole_end);
+
+   return true;
 }
 EXPORT_SYMBOL(drm_mm_scan_add_block);
 
@@ -836,7 +876,7 @@ bool drm_mm_scan_remove_block(struct drm_mm_scan *scan,
 
DRM_MM_BUG_ON(node->mm != scan->mm);

[Intel-gfx] [PATCH v3 26/38] drm: Extract struct drm_mm_scan from struct drm_mm

2016-12-16 Thread Chris Wilson
The scan state occupies a large proportion of the struct drm_mm and is
rarely used and only contains temporary state. That makes it suitable to
moving to its struct and onto the stack of the callers.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c| 124 ++--
 drivers/gpu/drm/etnaviv/etnaviv_mmu.c   |   7 +-
 drivers/gpu/drm/i915/i915_gem_evict.c   |  19 +++--
 drivers/gpu/drm/selftests/test-drm_mm.c |  45 ++--
 include/drm/drm_mm.h|  43 +++
 5 files changed, 138 insertions(+), 100 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index b80305484124..21bd2e13738b 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -574,7 +574,7 @@ static struct drm_mm_node *drm_mm_search_free_generic(const 
struct drm_mm *mm,
u64 adj_end;
u64 best_size;
 
-   DRM_MM_BUG_ON(mm->scanned_blocks);
+   DRM_MM_BUG_ON(mm->scan_active);
 
best = NULL;
best_size = ~0UL;
@@ -618,7 +618,7 @@ static struct drm_mm_node 
*drm_mm_search_free_in_range_generic(const struct drm_
u64 adj_end;
u64 best_size;
 
-   DRM_MM_BUG_ON(mm->scanned_blocks);
+   DRM_MM_BUG_ON(mm->scan_active);
 
best = NULL;
best_size = ~0UL;
@@ -693,7 +693,7 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  *
  * The DRM range allocator supports this use-case through the scanning
  * interfaces. First a scan operation needs to be initialized with
- * drm_mm_init_scan() or drm_mm_init_scan_with_range(). The driver adds
+ * drm_mm_scan_init() or drm_mm_scan_init_with_range(). The driver adds
  * objects to the roaster (probably by walking an LRU list, but this can be
  * freely implemented) until a suitable hole is found or there's no further
  * evictable object.
@@ -710,7 +710,8 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  */
 
 /**
- * drm_mm_init_scan - initialize lru scanning
+ * drm_mm_scan_init - initialize lru scanning
+ * @scan: scan state
  * @mm: drm_mm to scan
  * @size: size of the allocation
  * @alignment: alignment of the allocation
@@ -724,26 +725,33 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  * As long as the scan list is non-empty, no other operations than
  * adding/removing nodes to/from the scan list are allowed.
  */
-void drm_mm_init_scan(struct drm_mm *mm,
+void drm_mm_scan_init(struct drm_mm_scan *scan,
+ struct drm_mm *mm,
  u64 size,
  u64 alignment,
  unsigned long color)
 {
DRM_MM_BUG_ON(!size);
+   DRM_MM_BUG_ON(mm->scan_active);
 
-   mm->scan_color = color;
-   mm->scan_alignment = alignment;
-   mm->scan_size = size;
-   mm->scanned_blocks = 0;
-   mm->scan_hit_start = 0;
-   mm->scan_hit_end = 0;
-   mm->scan_check_range = 0;
-   mm->prev_scanned_node = NULL;
+   scan->mm = mm;
+
+   scan->color = color;
+   scan->alignment = alignment;
+   scan->size = size;
+
+   scan->check_range = 0;
+
+   scan->hit_start = U64_MAX;
+   scan->hit_end = 0;
+
+   scan->prev_scanned_node = NULL;
 }
-EXPORT_SYMBOL(drm_mm_init_scan);
+EXPORT_SYMBOL(drm_mm_scan_init);
 
 /**
- * drm_mm_init_scan - initialize range-restricted lru scanning
+ * drm_mm_scan_init_with_range - initialize range-restricted lru scanning
+ * @scan: scan state
  * @mm: drm_mm to scan
  * @size: size of the allocation
  * @alignment: alignment of the allocation
@@ -759,7 +767,8 @@ EXPORT_SYMBOL(drm_mm_init_scan);
  * As long as the scan list is non-empty, no other operations than
  * adding/removing nodes to/from the scan list are allowed.
  */
-void drm_mm_init_scan_with_range(struct drm_mm *mm,
+void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
+struct drm_mm *mm,
 u64 size,
 u64 alignment,
 unsigned long color,
@@ -768,19 +777,25 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm,
 {
DRM_MM_BUG_ON(start >= end);
DRM_MM_BUG_ON(!size || size > end - start);
+   DRM_MM_BUG_ON(mm->scan_active);
+
+   scan->mm = mm;
+
+   scan->color = color;
+   scan->alignment = alignment;
+   scan->size = size;
+
+   DRM_MM_BUG_ON(end <= start);
+   scan->range_start = start;
+   scan->range_end = end;
+   scan->check_range = 1;
 
-   mm->scan_color = color;
-   mm->scan_alignment = alignment;
-   mm->scan_size = size;
-   mm->scanned_blocks = 0;
-   mm->scan_hit_start = 0;
-   mm->scan_hit_end = 0;
-   mm->scan_start = start;
-   mm->scan_end = end;
-   mm->scan_check_range = 1;
-   mm->prev_scanned_node = NULL;
+   scan->hit_start = U64_MAX;
+   scan->hit_end = 0;
+
+   scan->prev_scanned_node = NULL;
 }

[Intel-gfx] [PATCH v3 32/38] drm: Simplify drm_mm scan-list manipulation

2016-12-16 Thread Chris Wilson
Since we mandate a strict reverse-order of drm_mm_scan_remove_block()
after drm_mm_scan_add_block() we can further simplify the list
manipulations when generating the temporary scan-hole.

v2: Highlight the games being played with the lists to track the scan
holes without allocation.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 35 ++-
 include/drm/drm_mm.h |  7 +--
 2 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 0441d84fba74..ccca8dafb7fc 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -518,9 +518,7 @@ void drm_mm_remove_node(struct drm_mm_node *node)
struct drm_mm_node *prev_node;
 
DRM_MM_BUG_ON(!node->allocated);
-   DRM_MM_BUG_ON(node->scanned_block ||
- node->scanned_prev_free ||
- node->scanned_next_free);
+   DRM_MM_BUG_ON(node->scanned_block);
 
prev_node =
list_entry(node->node_list.prev, struct drm_mm_node, node_list);
@@ -757,8 +755,6 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
 
scan->hit_start = U64_MAX;
scan->hit_end = 0;
-
-   scan->prev_scanned_node = NULL;
 }
 EXPORT_SYMBOL(drm_mm_scan_init_with_range);
 
@@ -787,14 +783,14 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
node->scanned_block = true;
mm->scan_active++;
 
+   /* Remove this block from the node_list so that we enlarge the hole
+* (distance between the end of our previous node and the start of
+* or next), without poisoning the link so that we can restore it
+* later in drm_mm_scan_remove_block().
+*/
hole = list_prev_entry(node, node_list);
-
-   node->scanned_preceeds_hole = hole->hole_follows;
-   hole->hole_follows = 1;
-   list_del(>node_list);
-   node->node_list.prev = >node_list;
-   node->node_list.next = >prev_scanned_node->node_list;
-   scan->prev_scanned_node = node;
+   DRM_MM_BUG_ON(list_next_entry(hole, node_list) != node);
+   __list_del_entry(>node_list);
 
hole_start = __drm_mm_hole_node_start(hole);
hole_end = __drm_mm_hole_node_end(hole);
@@ -888,9 +884,17 @@ bool drm_mm_scan_remove_block(struct drm_mm_scan *scan,
DRM_MM_BUG_ON(!node->mm->scan_active);
node->mm->scan_active--;
 
+   /* During drm_mm_scan_add_block() we decoupled this node leaving
+* its pointers intact. Now that the caller is walking back along
+* the eviction list we can restore this block into its rightful
+* place on the full node_list. To confirm that the caller is walking
+* backwards correctly we check that prev_node->next == node->next,
+* i.e. both believe the same node should be on the other side of the
+* hole.
+*/
prev_node = list_prev_entry(node, node_list);
-
-   prev_node->hole_follows = node->scanned_preceeds_hole;
+   DRM_MM_BUG_ON(list_next_entry(prev_node, node_list) !=
+ list_next_entry(node, node_list));
list_add(>node_list, _node->node_list);
 
return (node->start + node->size > scan->hit_start &&
@@ -917,9 +921,6 @@ void drm_mm_init(struct drm_mm *mm, u64 start, u64 size)
INIT_LIST_HEAD(>head_node.node_list);
mm->head_node.allocated = 0;
mm->head_node.hole_follows = 1;
-   mm->head_node.scanned_block = 0;
-   mm->head_node.scanned_prev_free = 0;
-   mm->head_node.scanned_next_free = 0;
mm->head_node.mm = mm;
mm->head_node.start = start + size;
mm->head_node.size = start - mm->head_node.start;
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index d6701d56ea74..ff120b7d0f85 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -74,11 +74,8 @@ struct drm_mm_node {
struct list_head hole_stack;
struct rb_node rb;
unsigned hole_follows : 1;
-   unsigned scanned_block : 1;
-   unsigned scanned_prev_free : 1;
-   unsigned scanned_next_free : 1;
-   unsigned scanned_preceeds_hole : 1;
unsigned allocated : 1;
+   bool scanned_block : 1;
unsigned long color;
u64 start;
u64 size;
@@ -118,8 +115,6 @@ struct drm_mm_scan {
u64 hit_start;
u64 hit_end;
 
-   struct drm_mm_node *prev_scanned_node;
-
unsigned long color;
unsigned int flags;
 };
-- 
2.11.0

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


[Intel-gfx] [PATCH v3 35/38] drm: Apply range restriction after color adjustment when allocation

2016-12-16 Thread Chris Wilson
mm->color_adjust() compares the hole with its neighbouring nodes. They
only abutt before we restrict the hole, so we have to apply color_adjust
before we apply the range restriction.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index c0024719f32b..e279ac7c7aaf 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -410,14 +410,12 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
 
DRM_MM_BUG_ON(!drm_mm_hole_follows(hole_node) || node->allocated);
 
-   if (adj_start < start)
-   adj_start = start;
-   if (adj_end > end)
-   adj_end = end;
-
if (mm->color_adjust)
mm->color_adjust(hole_node, color, _start, _end);
 
+   adj_start = max(adj_start, start);
+   adj_end = min(adj_end, end);
+
if (flags & DRM_MM_CREATE_TOP)
adj_start = adj_end - size;
 
@@ -625,17 +623,15 @@ static struct drm_mm_node 
*drm_mm_search_free_in_range_generic(const struct drm_
   flags & DRM_MM_SEARCH_BELOW) {
u64 hole_size = adj_end - adj_start;
 
-   if (adj_start < start)
-   adj_start = start;
-   if (adj_end > end)
-   adj_end = end;
-
if (mm->color_adjust) {
mm->color_adjust(entry, color, _start, _end);
if (adj_end <= adj_start)
continue;
}
 
+   adj_start = max(adj_start, start);
+   adj_end = min(adj_end, end);
+
if (!check_free_hole(adj_start, adj_end, size, alignment))
continue;
 
-- 
2.11.0

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


[Intel-gfx] [PATCH v3 12/38] drm: kselftest for drm_mm_insert_node_in_range()

2016-12-16 Thread Chris Wilson
Exercise drm_mm_insert_node_in_range(), check that we only allocate from
the specified range.

v2: Use all allocation flags

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  | 264 +++
 2 files changed, 265 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index dca726baa65d..92b2c1cb10fa 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -11,3 +11,4 @@ selftest(debug, igt_debug)
 selftest(reserve, igt_reserve)
 selftest(insert, igt_insert)
 selftest(replace, igt_replace)
+selftest(insert_range, igt_insert_range)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index fa5b12c57161..cbd4f09e6b2f 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -738,6 +738,270 @@ static int igt_replace(void *ignored)
return 0;
 }
 
+static bool expect_insert_in_range(struct drm_mm *mm, struct drm_mm_node *node,
+  u64 size, u64 alignment, unsigned long color,
+  u64 range_start, u64 range_end,
+  const struct insert_mode *mode)
+{
+   int err;
+
+   err = drm_mm_insert_node_in_range_generic(mm, node,
+ size, alignment, color,
+ range_start, range_end,
+ mode->search_flags,
+ mode->create_flags);
+   if (err) {
+   pr_err("insert (size=%llu, alignment=%llu, color=%lu, mode=%s) 
nto range [%llx, %llx] failed with err=%d\n",
+  size, alignment, color, mode->name,
+  range_start, range_end, err);
+   return false;
+   }
+
+   if (!assert_node(node, mm, size, alignment, color)) {
+   drm_mm_remove_node(node);
+   return false;
+   }
+
+   return true;
+}
+
+static bool expect_insert_in_range_fail(struct drm_mm *mm,
+   u64 size,
+   u64 range_start,
+   u64 range_end)
+{
+   struct drm_mm_node tmp = {};
+   int err;
+
+   err = drm_mm_insert_node_in_range_generic(mm, ,
+ size, 0, 0,
+ range_start, range_end,
+ DRM_MM_SEARCH_DEFAULT,
+ DRM_MM_CREATE_DEFAULT);
+   if (likely(err == -ENOSPC))
+   return true;
+
+   if (!err) {
+   pr_err("impossible insert succeeded, node %llx + %llu, range 
[%llx, %llx]\n",
+  tmp.start, tmp.size, range_start, range_end);
+   drm_mm_remove_node();
+   } else {
+   pr_err("impossible insert failed with wrong error %d [expected 
%d], size %llu, range [%llx, %llx]\n",
+  err, -ENOSPC, size, range_start, range_end);
+   }
+
+   return false;
+}
+
+static bool assert_contiguous_in_range(struct drm_mm *mm,
+  u64 size,
+  u64 start,
+  u64 end)
+{
+   struct drm_mm_node *node;
+   unsigned int n;
+
+   if (!expect_insert_in_range_fail(mm, size, start, end))
+   return false;
+
+   n = div64_u64(start + size - 1, size);
+   drm_mm_for_each_node(node, mm) {
+   if (node->start < start || node->start + node->size > end) {
+   pr_err("node %d out of range, address [%llx + %llu], 
range [%llx, %llx]\n",
+  n, node->start, node->start + node->size, start, 
end);
+   return false;
+   }
+
+   if (node->start != n * size) {
+   pr_err("node %d out of order, expected start %llx, 
found %llx\n",
+  n, n * size, node->start);
+   return false;
+   }
+
+   if (node->size != size) {
+   pr_err("node %d has wrong size, expected size %llx, 
found %llx\n",
+  n, size, node->size);
+   return false;
+   }
+
+   if (node->hole_follows && drm_mm_hole_node_end(node) < end) {
+   pr_err("node %d is followed by a hole!\n", n);
+   return false;
+   }
+
+   n++;
+   }
+
+   

[Intel-gfx] [PATCH v3 16/38] drm: kselftest for drm_mm and top-down allocation

2016-12-16 Thread Chris Wilson
Check that if we request top-down allocation from drm_mm_insert_node()
we receive the next available hole from the top.

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  | 119 +++
 2 files changed, 120 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 965aca65c160..cd508e3d6538 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -17,3 +17,4 @@ selftest(align32, igt_align32)
 selftest(align64, igt_align64)
 selftest(evict, igt_evict)
 selftest(evict_range, igt_evict_range)
+selftest(topdown, igt_topdown)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index f662d98177ee..a499895a76c4 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1547,6 +1547,125 @@ static int igt_evict_range(void *ignored)
return ret;
 }
 
+static unsigned int node_index(const struct drm_mm_node *node)
+{
+   return div64_u64(node->start, node->size);
+}
+
+static int igt_topdown(void *ignored)
+{
+   const struct insert_mode *topdown = _modes[TOPDOWN];
+   DRM_RND_STATE(prng, random_seed);
+   const unsigned int count = 8192;
+   unsigned int size;
+   unsigned long *bitmap = NULL;
+   struct drm_mm mm;
+   struct drm_mm_node *nodes, *node, *next;
+   unsigned int *order, n, m, o = 0;
+   int ret;
+
+   /* When allocating top-down, we expect to be returned a node
+* from a suitable hole at the top of the drm_mm. We check that
+* the returned node does match the highest available slot.
+*/
+
+   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, );
+   if (!order)
+   goto err_bitmap;
+
+   ret = -EINVAL;
+   for (size = 1; size <= 64; size <<= 1) {
+   drm_mm_init(, 0, size*count);
+   for (n = 0; n < count; n++) {
+   if (!expect_insert(, [n],
+  size, 0, n,
+  topdown)) {
+   pr_err("insert failed, size %u step %d\n", 
size, n);
+   goto out;
+   }
+
+   if (nodes[n].hole_follows) {
+   pr_err("hole after topdown insert %d, 
start=%llx\n, size=%u",
+  n, nodes[n].start, size);
+   goto out;
+   }
+
+   if (!assert_one_hole(, 0, size*(count - n - 1)))
+   goto out;
+   }
+
+   if (!assert_continuous(, size))
+   goto out;
+
+   drm_random_reorder(order, count, );
+   for_each_prime_number(n, min(count, max_prime)) {
+   for (m = 0; m < n; m++) {
+   node = [order[(o + m) % count]];
+   drm_mm_remove_node(node);
+   __set_bit(node_index(node), bitmap);
+   }
+
+   for (m = 0; m < n; m++) {
+   unsigned int last;
+
+   node = [order[(o + m) % count]];
+   if (!expect_insert(, node,
+  size, 0, 0,
+  topdown)) {
+   pr_err("insert failed, step %d/%d\n", 
m, n);
+   goto out;
+   }
+
+   if (node->hole_follows) {
+   pr_err("hole after topdown insert 
%d/%d, start=%llx\n",
+  m, n, node->start);
+   goto out;
+   }
+
+   last = find_last_bit(bitmap, count);
+   if (node_index(node) != last) {
+   pr_err("node %d/%d, size %d, not 
inserted into upmost hole, expected %d, found %d\n",
+  m, n, size, last, 
node_index(node));
+   goto out;
+   }
+
+   __clear_bit(last, bitmap);
+   

[Intel-gfx] [PATCH v3 07/38] drm: kselftest for drm_mm_init()

2016-12-16 Thread Chris Wilson
Simple first test to just exercise initialisation of struct drm_mm.

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  | 114 +++
 2 files changed, 115 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 1610e0a63a5b..844dd29db540 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -6,3 +6,4 @@
  * Tests are executed in order by igt/drm_mm
  */
 selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck for igt) */
+selftest(init, igt_init)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 682f5f86f465..87ad147670da 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -27,6 +27,120 @@ static int igt_sanitycheck(void *ignored)
return 0;
 }
 
+static bool assert_no_holes(const struct drm_mm *mm)
+{
+   struct drm_mm_node *hole;
+   u64 hole_start, hole_end;
+   unsigned long count;
+
+   count = 0;
+   drm_mm_for_each_hole(hole, mm, hole_start, hole_end)
+   count++;
+   if (count) {
+   pr_err("Expected to find no holes (after reserve), found %lu 
instead\n", count);
+   return false;
+   }
+
+   drm_mm_for_each_node(hole, mm) {
+   if (hole->hole_follows) {
+   pr_err("Hole follows node, expected none!\n");
+   return false;
+   }
+   }
+
+   return true;
+}
+
+static bool assert_one_hole(const struct drm_mm *mm, u64 start, u64 end)
+{
+   struct drm_mm_node *hole;
+   u64 hole_start, hole_end;
+   unsigned long count;
+   bool ok = true;
+
+   if (end <= start)
+   return true;
+
+   count = 0;
+   drm_mm_for_each_hole(hole, mm, hole_start, hole_end) {
+   if (start != hole_start || end != hole_end) {
+   if (ok)
+   pr_err("empty mm has incorrect hole, found 
(%llx, %llx), expect (%llx, %llx)\n",
+  hole_start, hole_end,
+  start, end);
+   ok = false;
+   }
+   count++;
+   }
+   if (count != 1) {
+   pr_err("Expected to find one hole, found %lu instead\n", count);
+   ok = false;
+   }
+
+   return ok;
+}
+
+static int igt_init(void *ignored)
+{
+   const unsigned int size = 4096;
+   struct drm_mm mm;
+   struct drm_mm_node tmp;
+   int ret = -EINVAL;
+
+   /* Start with some simple checks on initialising the struct drm_mm */
+   memset(, 0, sizeof(mm));
+   if (drm_mm_initialized()) {
+   pr_err("zeroed mm claims to be initialized\n");
+   return ret;
+   }
+
+   memset(, 0xff, sizeof(mm));
+   drm_mm_init(, 0, size);
+   if (!drm_mm_initialized()) {
+   pr_err("mm claims not to be initialized\n");
+   goto out;
+   }
+
+   if (!drm_mm_clean()) {
+   pr_err("mm not empty on creation\n");
+   goto out;
+   }
+
+   /* After creation, it should all be one massive hole */
+   if (!assert_one_hole(, 0, size)) {
+   ret = -EINVAL;
+   goto out;
+   }
+
+   memset(, 0, sizeof(tmp));
+   tmp.start = 0;
+   tmp.size = size;
+   ret = drm_mm_reserve_node(, );
+   if (ret) {
+   pr_err("failed to reserve whole drm_mm\n");
+   goto out;
+   }
+
+   /* After filling the range entirely, there should be no holes */
+   if (!assert_no_holes()) {
+   ret = -EINVAL;
+   goto out;
+   }
+
+   /* And then after emptying it again, the massive hole should be back */
+   drm_mm_remove_node();
+   if (!assert_one_hole(, 0, size)) {
+   ret = -EINVAL;
+   goto out;
+   }
+
+out:
+   if (ret)
+   drm_mm_debug_table(, __func__);
+   drm_mm_takedown();
+   return ret;
+}
+
 #include "drm_selftest.c"
 
 static int __init test_drm_mm_init(void)
-- 
2.11.0

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


[Intel-gfx] [PATCH v3 21/38] drm: Promote drm_mm alignment to u64

2016-12-16 Thread Chris Wilson
In places (e.g. i915.ko), the alignment is exported to userspace as u64
and there now exists hardware for which we can indeed utilize a u64
alignment. As such, we need to keep 64bit integers throughout when
handling alignment.

Testcase: igt/drm_mm/align64
Testcase: igt/gem_exec_alignment
Signed-off-by: Chris Wilson 
Cc: Joonas Lahtinen 
Cc: Christian König 
Reviewed-by: Christian König 
---
 drivers/gpu/drm/drm_mm.c| 37 +++--
 drivers/gpu/drm/selftests/test-drm_mm.c |  4 ++--
 include/drm/drm_mm.h| 16 +++---
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 9756542abe4c..fd2667052c73 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -93,12 +93,12 @@
 
 static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
u64 size,
-   unsigned alignment,
+   u64 alignment,
unsigned long color,
enum drm_mm_search_flags flags);
 static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct 
drm_mm *mm,
u64 size,
-   unsigned alignment,
+   u64 alignment,
unsigned long color,
u64 start,
u64 end,
@@ -227,7 +227,7 @@ static void drm_mm_interval_tree_add_node(struct 
drm_mm_node *hole_node,
 
 static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
 struct drm_mm_node *node,
-u64 size, unsigned alignment,
+u64 size, u64 alignment,
 unsigned long color,
 enum drm_mm_allocator_flags flags)
 {
@@ -246,10 +246,9 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
adj_start = adj_end - size;
 
if (alignment) {
-   u64 tmp = adj_start;
-   unsigned rem;
+   u64 rem;
 
-   rem = do_div(tmp, alignment);
+   div64_u64_rem(adj_start, alignment, );
if (rem) {
if (flags & DRM_MM_CREATE_TOP)
adj_start -= rem;
@@ -376,7 +375,7 @@ EXPORT_SYMBOL(drm_mm_reserve_node);
  * 0 on success, -ENOSPC if there's no suitable hole.
  */
 int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
-  u64 size, unsigned alignment,
+  u64 size, u64 alignment,
   unsigned long color,
   enum drm_mm_search_flags sflags,
   enum drm_mm_allocator_flags aflags)
@@ -398,7 +397,7 @@ EXPORT_SYMBOL(drm_mm_insert_node_generic);
 
 static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
   struct drm_mm_node *node,
-  u64 size, unsigned alignment,
+  u64 size, u64 alignment,
   unsigned long color,
   u64 start, u64 end,
   enum drm_mm_allocator_flags flags)
@@ -423,10 +422,9 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
adj_start = adj_end - size;
 
if (alignment) {
-   u64 tmp = adj_start;
-   unsigned rem;
+   u64 rem;
 
-   rem = do_div(tmp, alignment);
+   div64_u64_rem(adj_start, alignment, );
if (rem) {
if (flags & DRM_MM_CREATE_TOP)
adj_start -= rem;
@@ -482,7 +480,7 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
  * 0 on success, -ENOSPC if there's no suitable hole.
  */
 int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node 
*node,
-   u64 size, unsigned alignment,
+   u64 size, u64 alignment,
unsigned long color,
u64 start, u64 end,
enum drm_mm_search_flags sflags,
@@ -548,16 +546,15 @@ void drm_mm_remove_node(struct drm_mm_node *node)
 }
 EXPORT_SYMBOL(drm_mm_remove_node);
 
-static int check_free_hole(u64 

[Intel-gfx] [PATCH v3 33/38] drm: Apply tight eviction scanning to color_adjust

2016-12-16 Thread Chris Wilson
Using mm->color_adjust makes the eviction scanner much tricker since we
don't know the actual neighbours of the target hole until after it is
created (after scanning is complete). To work out whether we need to
evict the neighbours because they impact upon the hole, we have to then
check the hole afterwards - requiring an extra step in the user of the
eviction scanner when they apply color_adjust.

v2: Massage kerneldoc.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c| 76 ++---
 drivers/gpu/drm/i915/i915_gem_evict.c   |  7 +++
 drivers/gpu/drm/selftests/test-drm_mm.c | 20 -
 include/drm/drm_mm.h|  1 +
 4 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index ccca8dafb7fc..b59978fe4c6e 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -692,19 +692,21 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  * The DRM range allocator supports this use-case through the scanning
  * interfaces. First a scan operation needs to be initialized with
  * drm_mm_scan_init() or drm_mm_scan_init_with_range(). The driver adds
- * objects to the roaster (probably by walking an LRU list, but this can be
- * freely implemented) until a suitable hole is found or there's no further
- * evictable object.
+ * objects to the roster (probably by walking an LRU list, but this can be
+ * freely implemented) (using drm_mm_scan_add_block()) until a suitable hole
+ * is found or there are no further evictable objects.
  *
  * The driver must walk through all objects again in exactly the reverse
  * order to restore the allocator state. Note that while the allocator is used
  * in the scan mode no other operation is allowed.
  *
- * Finally the driver evicts all objects selected in the scan. Adding and
- * removing an object is O(1), and since freeing a node is also O(1) the 
overall
- * complexity is O(scanned_objects). So like the free stack which needs to be
- * walked before a scan operation even begins this is linear in the number of
- * objects. It doesn't seem to hurt badly.
+ * Finally the driver evicts all objects selected (drm_mm_scan_remove_block()
+ * reported true) in the scan, and any overlapping nodes after color adjustment
+ * (drm_mm_scan_evict_color()). Adding and removing an object is O(1), and
+ * since freeing a node is also O(1) the overall complexity is
+ * O(scanned_objects). So like the free stack which needs to be walked before a
+ * scan operation even begins this is linear in the number of objects. It
+ * doesn't seem to hurt too badly.
  */
 
 /**
@@ -829,23 +831,8 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
}
}
 
-   if (mm->color_adjust) {
-   /* If allocations need adjusting due to neighbouring colours,
-* we do not have enough information to decide if we need
-* to evict nodes on either side of [adj_start, adj_end].
-* What almost works is
-* hit_start = adj_start + (hole_start - col_start);
-* hit_end = adj_start + scan->size + (hole_end - col_end);
-* but because the decision is only made on the final hole,
-* we may underestimate the required adjustments for an
-* interior allocation.
-*/
-   scan->hit_start = hole_start;
-   scan->hit_end = hole_end;
-   } else {
-   scan->hit_start = adj_start;
-   scan->hit_end = adj_start + scan->size;
-   }
+   scan->hit_start = adj_start;
+   scan->hit_end = adj_start + scan->size;
 
DRM_MM_BUG_ON(scan->hit_start >= scan->hit_end);
DRM_MM_BUG_ON(scan->hit_start < hole_start);
@@ -903,6 +890,45 @@ bool drm_mm_scan_remove_block(struct drm_mm_scan *scan,
 EXPORT_SYMBOL(drm_mm_scan_remove_block);
 
 /**
+ * drm_mm_scan_color_evict - evict overlapping nodes on either side of hole
+ * @scan: drm_mm scan with target hole
+ *
+ * After completing an eviction scan and removing the selected nodes, we may
+ * need to remove a few more nodes from either side of the target hole if
+ * mm.color_adjust is being used.
+ *
+ * Returns:
+ * A node to evict, or NULL if there are no overlapping nodes.
+ */
+struct drm_mm_node *drm_mm_scan_color_evict(struct drm_mm_scan *scan)
+{
+   struct drm_mm *mm = scan->mm;
+   struct drm_mm_node *hole;
+   u64 hole_start, hole_end;
+
+   DRM_MM_BUG_ON(list_empty(>hole_stack));
+
+   if (!mm->color_adjust)
+   return NULL;
+
+   hole = list_first_entry(>hole_stack, typeof(*hole), hole_stack);
+   hole_start = __drm_mm_hole_node_start(hole);
+   hole_end = __drm_mm_hole_node_end(hole);
+
+   DRM_MM_BUG_ON(hole_start > scan->hit_start);
+   DRM_MM_BUG_ON(hole_end < scan->hit_end);

[Intel-gfx] [PATCH v3 29/38] drm: Fix application of color vs range restriction when scanning drm_mm

2016-12-16 Thread Chris Wilson
The range restriction should be applied after the color adjustment, or
else we may inadvertently apply the color adjustment to the restricted
hole (and not against its neighbours).

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index c68f79149b9a..1b5613bcb35e 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -772,6 +772,7 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
struct drm_mm *mm = scan->mm;
struct drm_mm_node *hole;
u64 hole_start, hole_end;
+   u64 col_start, col_end;
u64 adj_start, adj_end;
 
DRM_MM_BUG_ON(node->mm != mm);
@@ -789,14 +790,16 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
node->node_list.next = >prev_scanned_node->node_list;
scan->prev_scanned_node = node;
 
-   hole_start = drm_mm_hole_node_start(hole);
-   hole_end = drm_mm_hole_node_end(hole);
-
-   adj_start = max(hole_start, scan->range_start);
-   adj_end = min(hole_end, scan->range_end);
+   hole_start = __drm_mm_hole_node_start(hole);
+   hole_end = __drm_mm_hole_node_end(hole);
 
+   col_start = hole_start;
+   col_end = hole_end;
if (mm->color_adjust)
-   mm->color_adjust(hole, scan->color, _start, _end);
+   mm->color_adjust(hole, scan->color, _start, _end);
+
+   adj_start = max(col_start, scan->range_start);
+   adj_end = min(col_end, scan->range_end);
 
if (check_free_hole(adj_start, adj_end,
scan->size, scan->alignment)) {
-- 
2.11.0

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


[Intel-gfx] [PATCH v3 13/38] drm: kselftest for drm_mm and alignment

2016-12-16 Thread Chris Wilson
Check that we can request alignment to any power-of-two or prime using a
plain drm_mm_node_insert(), and also handle a reasonable selection of
primes.

v2: Exercise all allocation flags

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

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 92b2c1cb10fa..a7a3763f8b20 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -12,3 +12,6 @@ selftest(reserve, igt_reserve)
 selftest(insert, igt_insert)
 selftest(replace, igt_replace)
 selftest(insert_range, igt_insert_range)
+selftest(align, igt_align)
+selftest(align32, igt_align32)
+selftest(align64, igt_align64)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index cbd4f09e6b2f..e1c034ea7e73 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1002,6 +1002,109 @@ static int igt_insert_range(void *ignored)
return 0;
 }
 
+static int igt_align(void *ignored)
+{
+   const struct insert_mode *mode;
+   const unsigned int max_count = min(8192u, max_prime);
+   struct drm_mm mm;
+   struct drm_mm_node *nodes, *node, *next;
+   unsigned int prime;
+   int ret = -EINVAL;
+
+   /* For each of the possible insertion modes, we pick a few
+* arbitrary alignments and check that the inserted node
+* meets our requirements.
+*/
+
+   nodes = vzalloc(max_count * sizeof(*nodes));
+   if (!nodes)
+   goto err;
+
+   drm_mm_init(, 1, U64_MAX - 2);
+
+   for (mode = insert_modes; mode->name; mode++) {
+   unsigned int i = 0;
+
+   for_each_prime_number(prime, max_count) {
+   u64 size = next_prime_number(prime);
+
+   if (!expect_insert(, [i],
+  size, prime, i,
+  mode)) {
+   pr_err("%s insert failed with alignment=%d",
+  mode->name, prime);
+   goto out;
+   }
+
+   i++;
+   }
+
+   drm_mm_for_each_node_safe(node, next, )
+   drm_mm_remove_node(node);
+   DRM_MM_BUG_ON(!drm_mm_clean());
+   }
+
+   ret = 0;
+out:
+   drm_mm_for_each_node_safe(node, next, )
+   drm_mm_remove_node(node);
+   drm_mm_takedown();
+   vfree(nodes);
+err:
+   return ret;
+}
+
+static int igt_align_pot(int max)
+{
+   struct drm_mm mm;
+   struct drm_mm_node *node, *next;
+   int bit;
+   int ret = -EINVAL;
+
+   /* Check that we can align to the full u64 address space */
+
+   drm_mm_init(, 1, U64_MAX - 1);
+
+   for (bit = max - 1; bit; bit--) {
+   u64 align, size;
+
+   node = kzalloc(sizeof(*node), GFP_KERNEL);
+   if (!node) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   align = BIT_ULL(bit);
+   size = BIT_ULL(bit-1) + 1;
+   if (!expect_insert(, node,
+  size, align, bit,
+  _modes[0])) {
+   pr_err("insert failed with alignment=%llx [%d]",
+  align, bit);
+   goto out;
+   }
+   }
+
+   ret = 0;
+out:
+   drm_mm_for_each_node_safe(node, next, ) {
+   drm_mm_remove_node(node);
+   kfree(node);
+   }
+   drm_mm_takedown();
+   return ret;
+}
+
+static int igt_align32(void *ignored)
+{
+   return igt_align_pot(32);
+}
+
+static int igt_align64(void *ignored)
+{
+   return igt_align_pot(64);
+}
+
 #include "drm_selftest.c"
 
 static int __init test_drm_mm_init(void)
-- 
2.11.0

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


[Intel-gfx] [PATCH v3 19/38] drm: kselftest for drm_mm and restricted color eviction

2016-12-16 Thread Chris Wilson
Check that after applying the driver's color adjustment, restricted
eviction scanning find a suitable hole.

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  | 116 ++-
 2 files changed, 113 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 0a3a7e32e5f7..6a4575fdc1c0 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -20,3 +20,4 @@ selftest(evict_range, igt_evict_range)
 selftest(topdown, igt_topdown)
 selftest(color, igt_color)
 selftest(color_evict, igt_color_evict)
+selftest(color_evict_range, igt_color_evict_range)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 9dd94da15bd5..7e90886f5558 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1850,6 +1850,7 @@ static int igt_color(void *ignored)
 }
 
 static int evict_color(struct drm_mm *mm,
+  u64 range_start, u64 range_end,
   struct evict_node *nodes,
   unsigned int *order,
   unsigned int count,
@@ -1863,7 +1864,9 @@ static int evict_color(struct drm_mm *mm,
struct drm_mm_node tmp;
int err;
 
-   drm_mm_init_scan(mm, size, alignment, color);
+   drm_mm_init_scan_with_range(mm,
+   size, alignment, color,
+   range_start, range_end);
if (!evict_nodes(mm,
 nodes, order, count,
 _list))
@@ -1881,6 +1884,12 @@ static int evict_color(struct drm_mm *mm,
return err;
}
 
+   if (tmp.start < range_start || tmp.start + tmp.size > range_end) {
+   pr_err("Inserted [address=%llu + %llu] did not fit into the 
request range [%llu, %llu]\n",
+  tmp.start, tmp.size, range_start, range_end);
+   err = -EINVAL;
+   }
+
if (colors_abutt())
err = -EINVAL;
 
@@ -1949,7 +1958,7 @@ static int igt_color_evict(void *ignored)
for (mode = evict_modes; mode->name; mode++) {
for (n = 1; n <= total_size; n <<= 1) {
drm_random_reorder(order, total_size, );
-   err = evict_color(,
+   err = evict_color(, 0, U64_MAX,
  nodes, order, total_size,
  n, 1, color++,
  mode);
@@ -1962,7 +1971,7 @@ static int igt_color_evict(void *ignored)
 
for (n = 1; n < total_size; n <<= 1) {
drm_random_reorder(order, total_size, );
-   err = evict_color(,
+   err = evict_color(, 0, U64_MAX,
  nodes, order, total_size,
  total_size/2, n, color++,
  mode);
@@ -1979,7 +1988,7 @@ static int igt_color_evict(void *ignored)
DRM_MM_BUG_ON(!nsize);
 
drm_random_reorder(order, total_size, );
-   err = evict_color(,
+   err = evict_color(, 0, U64_MAX,
  nodes, order, total_size,
  nsize, n, color++,
  mode);
@@ -2005,6 +2014,105 @@ static int igt_color_evict(void *ignored)
return ret;
 }
 
+static int igt_color_evict_range(void *ignored)
+{
+   DRM_RND_STATE(prng, random_seed);
+   const unsigned int total_size = 8192;
+   const unsigned int range_size = total_size / 2;
+   const unsigned int range_start = total_size / 4;
+   const unsigned int range_end = range_start + range_size;
+   const struct insert_mode *mode;
+   unsigned long color = 0;
+   struct drm_mm mm;
+   struct evict_node *nodes;
+   struct drm_mm_node *node, *next;
+   unsigned int *order, n;
+   int ret, err;
+
+   /* Like igt_color_evict(), but limited to small portion of the full
+* drm_mm range.
+*/
+
+   ret = -ENOMEM;
+   nodes = vzalloc(total_size * sizeof(*nodes));
+   if (!nodes)
+   goto err;
+
+   order = drm_random_order(total_size, );
+   if (!order)
+   goto err_nodes;
+
+   ret = -EINVAL;
+   drm_mm_init(, 0, 2*total_size - 1);
+   mm.color_adjust = separate_adjacent_colors;
+   for (n = 0; n < total_size; n++) {
+   if (!expect_insert(, [n].node,
+  1, 0, color++,
+  

[Intel-gfx] [PATCH v3 31/38] drm: Optimise power-of-two alignments in drm_mm_scan_add_block()

2016-12-16 Thread Chris Wilson
For power-of-two alignments, we can avoid the 64bit divide and do a
simple bitwise add instead.

v2: s/alignment_mask/remainder_mask/

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 9 -
 include/drm/drm_mm.h | 1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 189ab84c5a59..0441d84fba74 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -742,8 +742,12 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
 
scan->mm = mm;
 
+   if (alignment <= 1)
+   alignment = 0;
+
scan->color = color;
scan->alignment = alignment;
+   scan->remainder_mask = is_power_of_2(alignment) ? alignment - 1 : 0;
scan->size = size;
scan->flags = flags;
 
@@ -811,7 +815,10 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
if (scan->alignment) {
u64 rem;
 
-   div64_u64_rem(adj_start, scan->alignment, );
+   if (likely(scan->remainder_mask))
+   rem = adj_start & scan->remainder_mask;
+   else
+   div64_u64_rem(adj_start, scan->alignment, );
if (rem) {
adj_start -= rem;
if (scan->flags != DRM_MM_CREATE_TOP)
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 606336fc229a..d6701d56ea74 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -110,6 +110,7 @@ struct drm_mm_scan {
 
u64 size;
u64 alignment;
+   u64 remainder_mask;
 
u64 range_start;
u64 range_end;
-- 
2.11.0

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


[Intel-gfx] [PATCH v3 14/38] drm: kselftest for drm_mm and eviction

2016-12-16 Thread Chris Wilson
Check that we add arbitrary blocks to the eviction scanner in order to
find the first minimal hole that matches our request.

v2: Refactor out some common eviction code for later

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  | 337 +++
 2 files changed, 338 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index a7a3763f8b20..a31b4458c7eb 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -15,3 +15,4 @@ selftest(insert_range, igt_insert_range)
 selftest(align, igt_align)
 selftest(align32, igt_align32)
 selftest(align64, igt_align64)
+selftest(evict, igt_evict)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index e1c034ea7e73..10142bc4e07e 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -36,6 +36,10 @@ static const struct insert_mode {
[TOPDOWN] = { "top-down", DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP },
[BEST] = { "best", DRM_MM_SEARCH_BEST, DRM_MM_CREATE_DEFAULT },
{}
+}, evict_modes[] = {
+   { "default", DRM_MM_SEARCH_DEFAULT, DRM_MM_CREATE_DEFAULT },
+   { "top-down", DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP },
+   {}
 };
 
 static int igt_sanitycheck(void *ignored)
@@ -1105,6 +1109,339 @@ static int igt_align64(void *ignored)
return igt_align_pot(64);
 }
 
+static void show_scan(const struct drm_mm *scan)
+{
+   pr_info("scan: hit [%llx, %llx], size=%lld, align=%d, color=%ld\n",
+   scan->scan_hit_start, scan->scan_hit_end,
+   scan->scan_size, scan->scan_alignment, scan->scan_color);
+}
+
+static void show_holes(const struct drm_mm *mm, int count)
+{
+   u64 hole_start, hole_end;
+   struct drm_mm_node *hole;
+
+   drm_mm_for_each_hole(hole, mm, hole_start, hole_end) {
+   struct drm_mm_node *next = list_next_entry(hole, node_list);
+   const char *node1 = NULL, *node2 = NULL;
+
+   if (hole->allocated)
+   node1 = kasprintf(GFP_KERNEL,
+ "[%llx + %lld, color=%ld], ",
+ hole->start, hole->size, hole->color);
+
+   if (next->allocated)
+   node2 = kasprintf(GFP_KERNEL,
+ ", [%llx + %lld, color=%ld]",
+ next->start, next->size, next->color);
+
+   pr_info("%sHole [%llx - %llx, size %lld]%s\n",
+   node1,
+   hole_start, hole_end, hole_end - hole_start,
+   node2);
+
+   kfree(node2);
+   kfree(node1);
+
+   if (!--count)
+   break;
+   }
+}
+
+struct evict_node {
+   struct drm_mm_node node;
+   struct list_head link;
+};
+
+static bool evict_nodes(struct drm_mm *mm,
+   struct evict_node *nodes,
+   unsigned int *order,
+   unsigned int count,
+   struct list_head *evict_list)
+{
+   struct evict_node *e, *en;
+   unsigned int i;
+
+   for (i = 0; i < count; i++) {
+   e = [order ? order[i] : i];
+   list_add(>link, evict_list);
+   if (drm_mm_scan_add_block(>node))
+   break;
+   }
+   list_for_each_entry_safe(e, en, evict_list, link) {
+   if (!drm_mm_scan_remove_block(>node))
+   list_del(>link);
+   }
+   if (list_empty(evict_list)) {
+   pr_err("Failed to find eviction: size=%lld [avail=%d], align=%d 
(color=%lu)\n",
+  mm->scan_size, count,
+  mm->scan_alignment,
+  mm->scan_color);
+   return false;
+   }
+
+   list_for_each_entry(e, evict_list, link)
+   drm_mm_remove_node(>node);
+
+   return true;
+}
+
+static bool evict_nothing(struct drm_mm *mm,
+ unsigned int total_size,
+ struct evict_node *nodes)
+{
+   LIST_HEAD(evict_list);
+   struct evict_node *e;
+   struct drm_mm_node *node;
+   unsigned int n;
+
+   drm_mm_init_scan(mm, 1, 0, 0);
+   for (n = 0; n < total_size; n++) {
+   e = [n];
+   list_add(>link, _list);
+   drm_mm_scan_add_block(>node);
+   }
+   list_for_each_entry(e, _list, link)
+   drm_mm_scan_remove_block(>node);
+
+   for (n = 0; n < total_size; n++) {
+   e = [n];
+
+   if (!drm_mm_node_allocated(>node)) {
+   

[Intel-gfx] [PATCH v3 15/38] drm: kselftest for drm_mm and range restricted eviction

2016-12-16 Thread Chris Wilson
Check that we add arbitrary blocks to a restrited eviction scanner in
order to find the first minimal hole that matches our request.

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  | 113 ++-
 2 files changed, 110 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index a31b4458c7eb..965aca65c160 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -16,3 +16,4 @@ selftest(align, igt_align)
 selftest(align32, igt_align32)
 selftest(align64, igt_align64)
 selftest(evict, igt_evict)
+selftest(evict_range, igt_evict_range)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 10142bc4e07e..f662d98177ee 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1274,6 +1274,7 @@ static bool evict_everything(struct drm_mm *mm,
 }
 
 static int evict_something(struct drm_mm *mm,
+  u64 range_start, u64 range_end,
   struct evict_node *nodes,
   unsigned int *order,
   unsigned int count,
@@ -1286,7 +1287,9 @@ static int evict_something(struct drm_mm *mm,
struct drm_mm_node tmp;
int err;
 
-   drm_mm_init_scan(mm, size, alignment, 0);
+   drm_mm_init_scan_with_range(mm,
+   size, alignment, 0,
+   range_start, range_end);
if (!evict_nodes(mm,
 nodes, order, count,
 _list))
@@ -1304,6 +1307,12 @@ static int evict_something(struct drm_mm *mm,
return err;
}
 
+   if (tmp.start < range_start || tmp.start + tmp.size > range_end) {
+   pr_err("Inserted [address=%llu + %llu] did not fit into the 
request range [%llu, %llu]\n",
+  tmp.start, tmp.size, range_start, range_end);
+   err = -EINVAL;
+   }
+
if (!assert_node(, mm, size, alignment, 0) || tmp.hole_follows) {
pr_err("Inserted did not fill the eviction hole: size=%lld 
[%d], align=%d [rem=%lld], start=%llx, hole-follows?=%d\n",
   tmp.size, size,
@@ -1385,7 +1394,7 @@ static int igt_evict(void *ignored)
for (mode = evict_modes; mode->name; mode++) {
for (n = 1; n <= size; n <<= 1) {
drm_random_reorder(order, size, );
-   err = evict_something(,
+   err = evict_something(, 0, U64_MAX,
  nodes, order, size,
  n, 1,
  mode);
@@ -1399,7 +1408,7 @@ static int igt_evict(void *ignored)
 
for (n = 1; n < size; n <<= 1) {
drm_random_reorder(order, size, );
-   err = evict_something(,
+   err = evict_something(, 0, U64_MAX,
  nodes, order, size,
  size/2, n,
  mode);
@@ -1417,7 +1426,7 @@ static int igt_evict(void *ignored)
DRM_MM_BUG_ON(!nsize);
 
drm_random_reorder(order, size, );
-   err = evict_something(,
+   err = evict_something(, 0, U64_MAX,
  nodes, order, size,
  nsize, n,
  mode);
@@ -1442,6 +1451,102 @@ static int igt_evict(void *ignored)
return ret;
 }
 
+static int igt_evict_range(void *ignored)
+{
+   DRM_RND_STATE(prng, random_seed);
+   const unsigned int size = 8192;
+   const unsigned int range_size = size / 2;
+   const unsigned int range_start = size / 4;
+   const unsigned int range_end = range_start + range_size;
+   const struct insert_mode *mode;
+   struct drm_mm mm;
+   struct evict_node *nodes;
+   struct drm_mm_node *node, *next;
+   unsigned int *order, n;
+   int ret, err;
+
+   /* Like igt_evict() but now we are limiting the search to a
+* small portion of the full drm_mm.
+*/
+
+   ret = -ENOMEM;
+   nodes = vzalloc(size * sizeof(*nodes));
+   if (!nodes)
+   goto err;
+
+   order = drm_random_order(size, );
+   if (!order)
+   goto err_nodes;
+
+   ret = -EINVAL;
+   drm_mm_init(, 0, size);
+   for (n = 0; n < size; n++) {
+   err = drm_mm_insert_node(, [n].node, 1, 0,
+   

[Intel-gfx] [PATCH v3 18/38] drm: kselftest for drm_mm and color eviction

2016-12-16 Thread Chris Wilson
Check that after applying the driver's color adjustment, eviction
scanning find a suitable hole.

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  | 156 +++
 2 files changed, 157 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index ff44f39a1826..0a3a7e32e5f7 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -19,3 +19,4 @@ selftest(evict, igt_evict)
 selftest(evict_range, igt_evict_range)
 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 71520a21de8d..9dd94da15bd5 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1849,6 +1849,162 @@ static int igt_color(void *ignored)
return ret;
 }
 
+static int evict_color(struct drm_mm *mm,
+  struct evict_node *nodes,
+  unsigned int *order,
+  unsigned int count,
+  unsigned int size,
+  unsigned int alignment,
+  unsigned long color,
+  const struct insert_mode *mode)
+{
+   LIST_HEAD(evict_list);
+   struct evict_node *e;
+   struct drm_mm_node tmp;
+   int err;
+
+   drm_mm_init_scan(mm, size, alignment, color);
+   if (!evict_nodes(mm,
+nodes, order, count,
+_list))
+   return -EINVAL;
+
+   memset(, 0, sizeof(tmp));
+   err = drm_mm_insert_node_generic(mm, , size, alignment, color,
+mode->search_flags,
+mode->create_flags);
+   if (err) {
+   pr_err("Failed to insert into eviction hole: size=%d, align=%d, 
color=%lu, err=%d\n",
+  size, alignment, color, err);
+   show_scan(mm);
+   show_holes(mm, 3);
+   return err;
+   }
+
+   if (colors_abutt())
+   err = -EINVAL;
+
+   if (!assert_node(, mm, size, alignment, color)) {
+   pr_err("Inserted did not fit the eviction hole: size=%lld [%d], 
align=%d [rem=%lld], start=%llx\n",
+  tmp.size, size,
+  alignment, misalignment(, alignment), tmp.start);
+   err = -EINVAL;
+   }
+
+   drm_mm_remove_node();
+   if (err)
+   return err;
+
+   list_for_each_entry(e, _list, link) {
+   err = drm_mm_reserve_node(mm, >node);
+   if (err) {
+   pr_err("Failed to reinsert node after eviction: 
start=%llx\n",
+  e->node.start);
+   return err;
+   }
+   }
+
+   return 0;
+}
+
+static int igt_color_evict(void *ignored)
+{
+   DRM_RND_STATE(prng, random_seed);
+   const unsigned int total_size = min(8192u, max_iterations);
+   const struct insert_mode *mode;
+   unsigned long color = 0;
+   struct drm_mm mm;
+   struct evict_node *nodes;
+   struct drm_mm_node *node, *next;
+   unsigned int *order, n;
+   int ret, err;
+
+   /* Check that the drm_mm_scan also honours color adjustment when
+* choosing its victims to create a hole. Our color_adjust does not
+* allow two nodes to be placed together without an intervening hole
+* enlarging the set of victims that must be evicted.
+*/
+
+   ret = -ENOMEM;
+   nodes = vzalloc(total_size * sizeof(*nodes));
+   if (!nodes)
+   goto err;
+
+   order = drm_random_order(total_size, );
+   if (!order)
+   goto err_nodes;
+
+   ret = -EINVAL;
+   drm_mm_init(, 0, 2*total_size - 1);
+   mm.color_adjust = separate_adjacent_colors;
+   for (n = 0; n < total_size; n++) {
+   if (!expect_insert(, [n].node,
+  1, 0, color++,
+  _modes[0])) {
+   pr_err("insert failed, step %d\n", n);
+   goto out;
+   }
+   }
+
+   for (mode = evict_modes; mode->name; mode++) {
+   for (n = 1; n <= total_size; n <<= 1) {
+   drm_random_reorder(order, total_size, );
+   err = evict_color(,
+ nodes, order, total_size,
+ n, 1, color++,
+ mode);
+   if (err) {
+   pr_err("%s evict_color(size=%u) failed\n",
+ 

[Intel-gfx] [PATCH v3 34/38] drm: Wrap drm_mm_node.hole_follows

2016-12-16 Thread Chris Wilson
Insulate users from changed to the internal hole tracking within
struct drm_mm_node by using an accessor for hole_follows.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c| 12 ++--
 drivers/gpu/drm/i915/i915_vma.c |  4 ++--
 drivers/gpu/drm/selftests/test-drm_mm.c | 18 ++
 include/drm/drm_mm.h| 22 +++---
 4 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index b59978fe4c6e..c0024719f32b 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -323,7 +323,7 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct 
drm_mm_node *node)
}
 
hole = list_last_entry(>node_list, typeof(*hole), node_list);
-   if (!hole->hole_follows)
+   if (!drm_mm_hole_follows(hole))
return -ENOSPC;
 
adj_start = hole_start = __drm_mm_hole_node_start(hole);
@@ -408,7 +408,7 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
u64 adj_start = hole_start;
u64 adj_end = hole_end;
 
-   DRM_MM_BUG_ON(!hole_node->hole_follows || node->allocated);
+   DRM_MM_BUG_ON(!drm_mm_hole_follows(hole_node) || node->allocated);
 
if (adj_start < start)
adj_start = start;
@@ -523,16 +523,16 @@ void drm_mm_remove_node(struct drm_mm_node *node)
prev_node =
list_entry(node->node_list.prev, struct drm_mm_node, node_list);
 
-   if (node->hole_follows) {
+   if (drm_mm_hole_follows(node)) {
DRM_MM_BUG_ON(__drm_mm_hole_node_start(node) ==
  __drm_mm_hole_node_end(node));
list_del(>hole_stack);
-   } else
+   } else {
DRM_MM_BUG_ON(__drm_mm_hole_node_start(node) !=
  __drm_mm_hole_node_end(node));
+   }
 
-
-   if (!prev_node->hole_follows) {
+   if (!drm_mm_hole_follows(prev_node)) {
prev_node->hole_follows = 1;
list_add(_node->hole_stack, >hole_stack);
} else
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index f709c9b76358..34374c4133b5 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -322,11 +322,11 @@ bool i915_gem_valid_gtt_space(struct i915_vma *vma, 
unsigned long cache_level)
GEM_BUG_ON(list_empty(>node_list));
 
other = list_prev_entry(node, node_list);
-   if (color_differs(other, cache_level) && !other->hole_follows)
+   if (color_differs(other, cache_level) && !drm_mm_hole_follows(other))
return false;
 
other = list_next_entry(node, node_list);
-   if (color_differs(other, cache_level) && !node->hole_follows)
+   if (color_differs(other, cache_level) && !drm_mm_hole_follows(node))
return false;
 
return true;
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 8b9d8956fb51..989e49e49f1c 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -63,7 +63,7 @@ static bool assert_no_holes(const struct drm_mm *mm)
}
 
drm_mm_for_each_node(hole, mm) {
-   if (hole->hole_follows) {
+   if (drm_mm_hole_follows(hole)) {
pr_err("Hole follows node, expected none!\n");
return false;
}
@@ -125,7 +125,7 @@ static bool assert_continuous(const struct drm_mm *mm, u64 
size)
return false;
}
 
-   if (node->hole_follows) {
+   if (drm_mm_hole_follows(node)) {
pr_err("node[%ld] is followed by a hole!\n", n);
return false;
}
@@ -828,7 +828,8 @@ static bool assert_contiguous_in_range(struct drm_mm *mm,
return false;
}
 
-   if (node->hole_follows && drm_mm_hole_node_end(node) < end) {
+   if (drm_mm_hole_follows(node) &&
+   drm_mm_hole_node_end(node) < end) {
pr_err("node %d is followed by a hole!\n", n);
return false;
}
@@ -1332,11 +1333,12 @@ static int evict_something(struct drm_mm *mm,
err = -EINVAL;
}
 
-   if (!assert_node(, mm, size, alignment, 0) || tmp.hole_follows) {
+   if (!assert_node(, mm, size, alignment, 0) ||
+   drm_mm_hole_follows()) {
pr_err("Inserted did not fill the eviction hole: size=%lld 
[%d], align=%d [rem=%lld], start=%llx, hole-follows?=%d\n",
   tmp.size, size,
   alignment, misalignment(, alignment),
-  tmp.start, tmp.hole_follows);
+   

[Intel-gfx] [PATCH v3 36/38] drm: Use drm_mm_insert_node_in_range_generic() for everyone

2016-12-16 Thread Chris Wilson
Remove a superfluous helper as drm_mm_insert_node is equivalent to
insert_node_in_range with a range of (0, U64_MAX).

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 166 ---
 include/drm/drm_mm.h |  90 +++--
 2 files changed, 67 insertions(+), 189 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index e279ac7c7aaf..58a7e3bbe130 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -92,11 +92,6 @@
  * some basic allocator dumpers for debugging.
  */
 
-static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
-   u64 size,
-   u64 alignment,
-   unsigned long color,
-   enum drm_mm_search_flags flags);
 static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct 
drm_mm *mm,
u64 size,
u64 alignment,
@@ -230,6 +225,7 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
 struct drm_mm_node *node,
 u64 size, u64 alignment,
 unsigned long color,
+u64 range_start, u64 range_end,
 enum drm_mm_allocator_flags flags)
 {
struct drm_mm *mm = hole_node->mm;
@@ -238,11 +234,14 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
u64 adj_start = hole_start;
u64 adj_end = hole_end;
 
-   DRM_MM_BUG_ON(node->allocated);
+   DRM_MM_BUG_ON(!drm_mm_hole_follows(hole_node) || node->allocated);
 
if (mm->color_adjust)
mm->color_adjust(hole_node, color, _start, _end);
 
+   adj_start = max(adj_start, range_start);
+   adj_end = min(adj_end, range_end);
+
if (flags & DRM_MM_CREATE_TOP)
adj_start = adj_end - size;
 
@@ -258,9 +257,6 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
}
}
 
-   DRM_MM_BUG_ON(adj_start < hole_start);
-   DRM_MM_BUG_ON(adj_end > hole_end);
-
if (adj_start == hole_start) {
hole_node->hole_follows = 0;
list_del(_node->hole_stack);
@@ -276,7 +272,10 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
 
drm_mm_interval_tree_add_node(hole_node, node);
 
+   DRM_MM_BUG_ON(node->start < range_start);
+   DRM_MM_BUG_ON(node->start < adj_start);
DRM_MM_BUG_ON(node->start + node->size > adj_end);
+   DRM_MM_BUG_ON(node->start + node->size > range_end);
 
node->hole_follows = 0;
if (__drm_mm_hole_node_start(node) < hole_end) {
@@ -360,107 +359,6 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct 
drm_mm_node *node)
 EXPORT_SYMBOL(drm_mm_reserve_node);
 
 /**
- * drm_mm_insert_node_generic - search for space and insert @node
- * @mm: drm_mm to allocate from
- * @node: preallocate node to insert
- * @size: size of the allocation
- * @alignment: alignment of the allocation
- * @color: opaque tag value to use for this node
- * @sflags: flags to fine-tune the allocation search
- * @aflags: flags to fine-tune the allocation behavior
- *
- * The preallocated node must be cleared to 0.
- *
- * Returns:
- * 0 on success, -ENOSPC if there's no suitable hole.
- */
-int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
-  u64 size, u64 alignment,
-  unsigned long color,
-  enum drm_mm_search_flags sflags,
-  enum drm_mm_allocator_flags aflags)
-{
-   struct drm_mm_node *hole_node;
-
-   if (WARN_ON(size == 0))
-   return -EINVAL;
-
-   hole_node = drm_mm_search_free_generic(mm, size, alignment,
-  color, sflags);
-   if (!hole_node)
-   return -ENOSPC;
-
-   drm_mm_insert_helper(hole_node, node, size, alignment, color, aflags);
-   return 0;
-}
-EXPORT_SYMBOL(drm_mm_insert_node_generic);
-
-static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
-  struct drm_mm_node *node,
-  u64 size, u64 alignment,
-  unsigned long color,
-  u64 start, u64 end,
-  enum drm_mm_allocator_flags flags)
-{
-   struct drm_mm *mm = hole_node->mm;
-   u64 hole_start = drm_mm_hole_node_start(hole_node);
-   u64 hole_end = drm_mm_hole_node_end(hole_node);
-   u64 adj_start = 

[Intel-gfx] [PATCH v3 04/38] lib: Add a simple prime number generator

2016-12-16 Thread Chris Wilson
Prime numbers are interesting for testing components that use multiplies
and divides, such as testing DRM's struct drm_mm alignment computations.

v2: Move to lib/, add selftest
v3: Fix initial constants (exclude 0/1 from being primes)
v4: More RCU markup to keep 0day/sparse happy

Signed-off-by: Chris Wilson 
Cc: Lukas Wunner 
---
 include/linux/prime_numbers.h |  13 +++
 lib/Kconfig   |   7 ++
 lib/Makefile  |   2 +
 lib/prime_numbers.c   | 238 ++
 4 files changed, 260 insertions(+)
 create mode 100644 include/linux/prime_numbers.h
 create mode 100644 lib/prime_numbers.c

diff --git a/include/linux/prime_numbers.h b/include/linux/prime_numbers.h
new file mode 100644
index ..877f6acbd0b6
--- /dev/null
+++ b/include/linux/prime_numbers.h
@@ -0,0 +1,13 @@
+#ifndef __LINUX_PRIME_NUMBERS_H
+#define __LINUX_PRIME_NUMBERS_H
+
+#include 
+
+bool is_prime_number(unsigned long x);
+unsigned long next_prime_number(unsigned long x);
+
+/* A useful white-lie here is that 1 is prime. */
+#define for_each_prime_number(prime, max) \
+   for (prime = 1; prime < (max); prime = next_prime_number(prime))
+
+#endif /* !__LINUX_PRIME_NUMBERS_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index 260a80e313b9..1788a1f50d28 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -550,4 +550,11 @@ config STACKDEPOT
 config SBITMAP
bool
 
+config PRIME_NUMBERS
+   tristate "Prime number generator"
+   default n
+   help
+ Provides a helper module to generate prime numbers. Useful for writing
+ test code, especially when checking multiplication and divison.
+
 endmenu
diff --git a/lib/Makefile b/lib/Makefile
index 50144a3aeebd..c664143fd917 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -197,6 +197,8 @@ obj-$(CONFIG_ASN1) += asn1_decoder.o
 
 obj-$(CONFIG_FONT_SUPPORT) += fonts/
 
+obj-$(CONFIG_PRIME_NUMBERS) += prime_numbers.o
+
 hostprogs-y:= gen_crc32table
 clean-files:= crc32table.h
 
diff --git a/lib/prime_numbers.c b/lib/prime_numbers.c
new file mode 100644
index ..ec2959520653
--- /dev/null
+++ b/lib/prime_numbers.c
@@ -0,0 +1,238 @@
+#define pr_fmt(fmt) "prime numbers: " fmt "\n"
+
+#include 
+#include 
+#include 
+#include 
+
+struct primes {
+   struct rcu_head rcu;
+   unsigned long last, sz;
+   unsigned long primes[];
+};
+
+#if BITS_PER_LONG == 64
+static const struct primes small_primes = {
+   .last = 61,
+   .sz = 64,
+   .primes = { 0x28208a20a08a28acUL }
+};
+#elif BITS_PER_LONG == 32
+static const struct primes small_primes = {
+   .last = 31,
+   .sz = 32,
+   .primes = { 0xa08a28acUL }
+};
+#else
+#error "unhandled BITS_PER_LONG"
+#endif
+
+static DEFINE_MUTEX(lock);
+static const struct primes __rcu *primes = RCU_INITIALIZER(_primes);
+
+static unsigned long selftest_max;
+
+static bool slow_is_prime_number(unsigned long x)
+{
+   unsigned long y = int_sqrt(x);
+
+   while (y > 1) {
+   if ((x % y) == 0)
+   break;
+   y--;
+   }
+
+   return y == 1;
+}
+
+static unsigned long slow_next_prime_number(unsigned long x)
+{
+   for (;;) {
+   if (slow_is_prime_number(++x))
+   return x;
+   }
+}
+
+static unsigned long mark_multiples(unsigned long x,
+   unsigned long *p,
+   unsigned long start,
+   unsigned long end)
+{
+   unsigned long m;
+
+   m = 2 * x;
+   if (m < start)
+   m = roundup(start, x);
+
+   while (m < end) {
+   __clear_bit(m, p);
+   m += x;
+   }
+
+   return x;
+}
+
+static const struct primes *expand_to_next(unsigned long x)
+{
+   const struct primes *p;
+   struct primes *new;
+   unsigned long sz, y;
+
+   rcu_read_unlock();
+
+   /* Betrand's Theorem states:
+*  For all n > 1, there exists a prime p: n < p <= 2*n.
+*/
+   sz = 2 * x + 1;
+   if (sz < x)
+   return NULL;
+
+   sz = round_up(sz, BITS_PER_LONG);
+   new = kmalloc(sizeof(*new) + sz / sizeof(long), GFP_KERNEL);
+   if (!new)
+   return NULL;
+
+   mutex_lock();
+   p = rcu_dereference_protected(primes, lockdep_is_held());
+   if (x < p->last) {
+   kfree(new);
+   goto relock;
+   }
+
+   /* Where memory permits, track the primes using the
+* Sieve of Eratosthenes.
+*/
+   memcpy(new->primes, p->primes, p->sz / BITS_PER_LONG * sizeof(long));
+   memset(new->primes + p->sz / BITS_PER_LONG,
+  0xff, (sz - p->sz) / BITS_PER_LONG * sizeof(long));
+   for (y = 2UL; y < sz; y = find_next_bit(new->primes, sz, y + 1))
+   new->last = mark_multiples(y, new->primes, p->sz, sz);
+   

[Intel-gfx] [PATCH v3 22/38] drm: Fix kerneldoc for drm_mm_scan_remove_block()

2016-12-16 Thread Chris Wilson
The nodes must be removed in the *reverse* order. This is correct in the
overview, but backwards in the function description. Whilst here add
Intel's copyright statement and tweak some formatting.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 34 ++
 include/drm/drm_mm.h | 19 +--
 2 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index fd2667052c73..767cfd05c628 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -1,6 +1,7 @@
 /**
  *
  * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA.
+ * Copyright 2016 Intel Corporation
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -31,9 +32,9 @@
  * class implementation for more advanced memory managers.
  *
  * Note that the algorithm used is quite simple and there might be substantial
- * performance gains if a smarter free list is implemented. Currently it is 
just an
- * unordered stack of free regions. This could easily be improved if an RB-tree
- * is used instead. At least if we expect heavy fragmentation.
+ * performance gains if a smarter free list is implemented. Currently it is
+ * just an unordered stack of free regions. This could easily be improved if
+ * an RB-tree is used instead. At least if we expect heavy fragmentation.
  *
  * Aligned allocations can also see improvement.
  *
@@ -67,7 +68,7 @@
  * where an object needs to be created which exactly matches the firmware's
  * scanout target. As long as the range is still free it can be inserted 
anytime
  * after the allocator is initialized, which helps with avoiding looped
- * depencies in the driver load sequence.
+ * dependencies in the driver load sequence.
  *
  * drm_mm maintains a stack of most recently freed holes, which of all
  * simplistic datastructures seems to be a fairly decent approach to clustering
@@ -78,14 +79,14 @@
  *
  * drm_mm supports a few features: Alignment and range restrictions can be
  * supplied. Further more every _mm_node has a color value (which is just 
an
- * opaqua unsigned long) which in conjunction with a driver callback can be 
used
+ * opaque unsigned long) which in conjunction with a driver callback can be 
used
  * to implement sophisticated placement restrictions. The i915 DRM driver uses
  * this to implement guard pages between incompatible caching domains in the
  * graphics TT.
  *
- * Two behaviors are supported for searching and allocating: bottom-up and 
top-down.
- * The default is bottom-up. Top-down allocation can be used if the memory area
- * has different restrictions, or just to reduce fragmentation.
+ * Two behaviors are supported for searching and allocating: bottom-up and
+ * top-down. The default is bottom-up. Top-down allocation can be used if the
+ * memory area has different restrictions, or just to reduce fragmentation.
  *
  * Finally iteration helpers to walk all nodes and all holes are provided as 
are
  * some basic allocator dumpers for debugging.
@@ -510,7 +511,7 @@ EXPORT_SYMBOL(drm_mm_insert_node_in_range_generic);
  *
  * This just removes a node from its drm_mm allocator. The node does not need 
to
  * be cleared again before it can be re-inserted into this or any other drm_mm
- * allocator. It is a bug to call this function on a un-allocated node.
+ * allocator. It is a bug to call this function on a unallocated node.
  */
 void drm_mm_remove_node(struct drm_mm_node *node)
 {
@@ -689,16 +690,16 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  * efficient when we simply start to select all objects from the tail of an LRU
  * until there's a suitable hole: Especially for big objects or nodes that
  * otherwise have special allocation constraints there's a good chance we evict
- * lots of (smaller) objects unecessarily.
+ * lots of (smaller) objects unnecessarily.
  *
  * The DRM range allocator supports this use-case through the scanning
  * interfaces. First a scan operation needs to be initialized with
- * drm_mm_init_scan() or drm_mm_init_scan_with_range(). The the driver adds
+ * drm_mm_init_scan() or drm_mm_init_scan_with_range(). The driver adds
  * objects to the roaster (probably by walking an LRU list, but this can be
  * freely implemented) until a suitable hole is found or there's no further
- * evitable object.
+ * evictable object.
  *
- * The the driver must walk through all objects again in exactly the reverse
+ * The driver must walk through all objects again in exactly the reverse
  * order to restore the allocator state. Note that while the allocator is used
  * in the scan mode no other operation is allowed.
  *
@@ -838,9 +839,10 @@ EXPORT_SYMBOL(drm_mm_scan_add_block);
  * drm_mm_scan_remove_block - remove a node from the scan list
  

[Intel-gfx] [PATCH v3 02/38] drm: Use drm_mm_nodes() as shorthand for the list of nodes under struct drm_mm

2016-12-16 Thread Chris Wilson
Fairly commonly we want to inspect the node list on the struct drm_mm,
which is buried within an embedded node. Bring it to the surface with a
bit of syntatic sugar.

Note this was intended to be split from commit ad579002c8ec ("drm: Add
drm_mm_for_each_node_safe()") before being applied, but my timing sucks.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
Cc: Daniel Vetter 
---
 drivers/gpu/drm/drm_mm.c |  8 
 include/drm/drm_mm.h | 18 +++---
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 7573661302a4..4257c86cc305 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -138,7 +138,7 @@ static void show_leaks(struct drm_mm *mm)
if (!buf)
return;
 
-   list_for_each_entry(node, __drm_mm_nodes(mm), node_list) {
+   list_for_each_entry(node, drm_mm_nodes(mm), node_list) {
struct stack_trace trace = {
.entries = entries,
.max_entries = STACKDEPTH
@@ -320,7 +320,7 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct 
drm_mm_node *node)
if (hole->start < end)
return -ENOSPC;
} else {
-   hole = list_entry(__drm_mm_nodes(mm), typeof(*hole), node_list);
+   hole = list_entry(drm_mm_nodes(mm), typeof(*hole), node_list);
}
 
hole = list_last_entry(>node_list, typeof(*hole), node_list);
@@ -883,7 +883,7 @@ EXPORT_SYMBOL(drm_mm_scan_remove_block);
  */
 bool drm_mm_clean(const struct drm_mm *mm)
 {
-   const struct list_head *head = __drm_mm_nodes(mm);
+   const struct list_head *head = drm_mm_nodes(mm);
 
return (head->next->next == head);
 }
@@ -929,7 +929,7 @@ EXPORT_SYMBOL(drm_mm_init);
  */
 void drm_mm_takedown(struct drm_mm *mm)
 {
-   if (WARN(!list_empty(__drm_mm_nodes(mm)),
+   if (WARN(!list_empty(drm_mm_nodes(mm)),
 "Memory manager not clean during takedown.\n"))
show_leaks(mm);
 
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 5c7f15875b6a..f6a68ed5ecaf 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -180,7 +180,19 @@ static inline u64 drm_mm_hole_node_end(const struct 
drm_mm_node *hole_node)
return __drm_mm_hole_node_end(hole_node);
 }
 
-#define __drm_mm_nodes(mm) (&(mm)->head_node.node_list)
+/**
+ * drm_mm_nodes - list of nodes under the drm_mm range manager
+ * @mm: the struct drm_mm range manger
+ *
+ * As the drm_mm range manager hides its node_list deep with its
+ * structure, extracting it looks painful and repetitive. This is
+ * not expected to be used outside of the drm_mm_for_each_node()
+ * macros and similar internal functions.
+ *
+ * Returns:
+ * The node list, may be empty.
+ */
+#define drm_mm_nodes(mm) (&(mm)->head_node.node_list)
 
 /**
  * drm_mm_for_each_node - iterator to walk over all allocated nodes
@@ -191,7 +203,7 @@ static inline u64 drm_mm_hole_node_end(const struct 
drm_mm_node *hole_node)
  * with list_for_each, so not save against removal of elements.
  */
 #define drm_mm_for_each_node(entry, mm) \
-   list_for_each_entry(entry, __drm_mm_nodes(mm), node_list)
+   list_for_each_entry(entry, drm_mm_nodes(mm), node_list)
 
 /**
  * drm_mm_for_each_node_safe - iterator to walk over all allocated nodes
@@ -203,7 +215,7 @@ static inline u64 drm_mm_hole_node_end(const struct 
drm_mm_node *hole_node)
  * with list_for_each_safe, so save against removal of elements.
  */
 #define drm_mm_for_each_node_safe(entry, next, mm) \
-   list_for_each_entry_safe(entry, next, __drm_mm_nodes(mm), node_list)
+   list_for_each_entry_safe(entry, next, drm_mm_nodes(mm), node_list)
 
 #define __drm_mm_for_each_hole(entry, mm, hole_start, hole_end, backwards) \
for (entry = list_entry((backwards) ? (mm)->hole_stack.prev : 
(mm)->hole_stack.next, struct drm_mm_node, hole_stack); \
-- 
2.11.0

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


[Intel-gfx] [PATCH v3 11/38] drm: kselftest for drm_mm_replace_node()

2016-12-16 Thread Chris Wilson
Reuse drm_mm_insert_node() with a temporary node to exercise
drm_mm_replace_node(). We use the previous test in order to exercise the
various lists following replacement.

v2: Check that we copy across the important (user) details of the node.
The internal details (such as lists and hole tracking) we hope to detect
errors by exercise.

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  | 65 +---
 2 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 727c6d7255e0..dca726baa65d 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -10,3 +10,4 @@ selftest(init, igt_init)
 selftest(debug, igt_debug)
 selftest(reserve, igt_reserve)
 selftest(insert, igt_insert)
+selftest(replace, igt_replace)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 2d78a5a0f98c..fa5b12c57161 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -554,7 +554,7 @@ static bool expect_insert_fail(struct drm_mm *mm, u64 size)
return false;
 }
 
-static int __igt_insert(unsigned int count, u64 size)
+static int __igt_insert(unsigned int count, u64 size, bool replace)
 {
DRM_RND_STATE(prng, random_seed);
const struct insert_mode *mode;
@@ -569,7 +569,7 @@ static int __igt_insert(unsigned int count, u64 size)
DRM_MM_BUG_ON(!size);
 
ret = -ENOMEM;
-   nodes = vzalloc(count * sizeof(*nodes));
+   nodes = vmalloc(count * sizeof(*nodes));
if (!nodes)
goto err;
 
@@ -582,11 +582,37 @@ static int __igt_insert(unsigned int count, u64 size)
 
for (mode = insert_modes; mode->name; mode++) {
for (n = 0; n < count; n++) {
-   if (!expect_insert(, [n], size, 0, n, mode)) {
+   struct drm_mm_node tmp;
+
+   node = replace ?  : [n];
+   memset(node, 0, sizeof(*node));
+   if (!expect_insert(, node, size, 0, n, mode)) {
pr_err("%s insert failed, size %llu step %d\n",
   mode->name, size, n);
goto out;
}
+
+   if (replace) {
+   drm_mm_replace_node(, [n]);
+   if (drm_mm_node_allocated()) {
+   pr_err("replaced old-node still 
allocated! step %d\n",
+  n);
+   goto out;
+   }
+
+   if (!assert_node([n], , size, 0, n)) {
+   pr_err("replaced node did not inherit 
parameters, size %llu step %d\n",
+  size, n);
+   goto out;
+   }
+
+   if (tmp.start != nodes[n].start) {
+   pr_err("replaced node mismatch location 
expected [%llx + %llx], found [%llx + %llx]\n",
+  tmp.start, size,
+  nodes[n].start, nodes[n].size);
+   goto out;
+   }
+   }
}
 
/* After random insertion the nodes should be in order */
@@ -669,17 +695,44 @@ static int igt_insert(void *ignored)
for_each_prime_number(n, 54) {
u64 size = BIT_ULL(n);
 
-   ret = __igt_insert(count, size - 1);
+   ret = __igt_insert(count, size - 1, false);
if (ret)
return ret;
 
-   ret = __igt_insert(count, size);
+   ret = __igt_insert(count, size, false);
if (ret)
return ret;
 
-   ret = __igt_insert(count, size + 1);
+   ret = __igt_insert(count, size + 1, false);
+   }
+
+   return 0;
+}
+
+static int igt_replace(void *ignored)
+{
+   const unsigned int count = min_t(unsigned int, BIT(10), max_iterations);
+   unsigned int n;
+   int ret;
+
+   /* Reuse igt_insert to exercise replacement by inserting a dummy node,
+* then replacing it with the intended node. We want to check that
+* the tree is intact and all the information we need is carried
+* across to the target node.
+*/
+
+   for_each_prime_number(n, 54) {
+   u64 size = BIT_ULL(n);
+
+   

[Intel-gfx] [PATCH v3 20/38] drm/i915: Build DRM range manager selftests for CI

2016-12-16 Thread Chris Wilson
Build the struct drm_mm selftests so that we can trivially run them
within our CI.

"Enable debug, become developer." - Joonas Lahtinen

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/Kconfig.debug | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/Kconfig.debug 
b/drivers/gpu/drm/i915/Kconfig.debug
index 597648c7a645..598551dbf62c 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -24,6 +24,7 @@ config DRM_I915_DEBUG
 select X86_MSR # used by igt/pm_rpm
 select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
 select DRM_DEBUG_MM if DRM=y
+   select DRM_DEBUG_MM_SELFTEST
select DRM_I915_SW_FENCE_DEBUG_OBJECTS
 default n
 help
-- 
2.11.0

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


[Intel-gfx] [PATCH v3 10/38] drm: kselftest for drm_mm_insert_node()

2016-12-16 Thread Chris Wilson
Exercise drm_mm_insert_node(), check that we can't overfill a range and
that the lists are correct after reserving/removing.

v2: Extract helpers for the repeated tests
v3: Iterate over all allocation flags

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  | 234 +++
 2 files changed, 235 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 693d85677e7f..727c6d7255e0 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -9,3 +9,4 @@ selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck 
for igt) */
 selftest(init, igt_init)
 selftest(debug, igt_debug)
 selftest(reserve, igt_reserve)
+selftest(insert, igt_insert)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 673519cf41e1..2d78a5a0f98c 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -21,6 +21,23 @@ static unsigned int random_seed;
 static unsigned int max_iterations = 8192;
 static unsigned int max_prime = 128;
 
+enum {
+   DEFAULT,
+   TOPDOWN,
+   BEST,
+};
+
+static const struct insert_mode {
+   const char *name;
+   unsigned int search_flags;
+   unsigned int create_flags;
+} insert_modes[] = {
+   [DEFAULT] = { "default", DRM_MM_SEARCH_DEFAULT, DRM_MM_CREATE_DEFAULT },
+   [TOPDOWN] = { "top-down", DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP },
+   [BEST] = { "best", DRM_MM_SEARCH_BEST, DRM_MM_CREATE_DEFAULT },
+   {}
+};
+
 static int igt_sanitycheck(void *ignored)
 {
pr_info("%s - ok!\n", __func__);
@@ -131,6 +148,48 @@ static bool assert_continuous(const struct drm_mm *mm, u64 
size)
return true;
 }
 
+static u64 misalignment(struct drm_mm_node *node, u64 alignment)
+{
+   u64 rem;
+
+   if (!alignment)
+   return 0;
+
+   div64_u64_rem(node->start, alignment, );
+   return rem;
+}
+
+static bool assert_node(struct drm_mm_node *node, struct drm_mm *mm,
+   u64 size, u64 alignment, unsigned long color)
+{
+   bool ok = true;
+
+   if (!drm_mm_node_allocated(node) || node->mm != mm) {
+   pr_err("node not allocated\n");
+   ok = false;
+   }
+
+   if (node->size != size) {
+   pr_err("node has wrong size, found %llu, expected %llu\n",
+  node->size, size);
+   ok = false;
+   }
+
+   if (misalignment(node, alignment)) {
+   pr_err("node is misalinged, start %llx rem %llu, expected 
alignment %llu\n",
+  node->start, misalignment(node, alignment), alignment);
+   ok = false;
+   }
+
+   if (node->color != color) {
+   pr_err("node has wrong color, found %lu, expected %lu\n",
+  node->color, color);
+   ok = false;
+   }
+
+   return ok;
+}
+
 static int igt_init(void *ignored)
 {
const unsigned int size = 4096;
@@ -451,6 +510,181 @@ static int igt_reserve(void *ignored)
return 0;
 }
 
+static bool expect_insert(struct drm_mm *mm, struct drm_mm_node *node,
+ u64 size, u64 alignment, unsigned long color,
+ const struct insert_mode *mode)
+{
+   int err;
+
+   err = drm_mm_insert_node_generic(mm, node,
+size, alignment, color,
+mode->search_flags,
+mode->create_flags);
+   if (err) {
+   pr_err("insert (size=%llu, alignment=%llu, color=%lu, mode=%s) 
failed with err=%d\n",
+  size, alignment, color, mode->name, err);
+   return false;
+   }
+
+   if (!assert_node(node, mm, size, alignment, color)) {
+   drm_mm_remove_node(node);
+   return false;
+   }
+
+   return true;
+}
+
+static bool expect_insert_fail(struct drm_mm *mm, u64 size)
+{
+   struct drm_mm_node tmp = {};
+   int err;
+
+   err = drm_mm_insert_node(mm, , size, 0, DRM_MM_SEARCH_DEFAULT);
+   if (likely(err == -ENOSPC))
+   return true;
+
+   if (!err) {
+   pr_err("impossible insert succeeded, node %llu + %llu\n",
+  tmp.start, tmp.size);
+   drm_mm_remove_node();
+   } else {
+   pr_err("impossible insert failed with wrong error %d [expected 
%d], size %llu\n",
+  err, -ENOSPC, size);
+   }
+   return false;
+}
+
+static int __igt_insert(unsigned int count, u64 size)
+{
+   DRM_RND_STATE(prng, random_seed);
+   const struct insert_mode *mode;
+   struct 

[Intel-gfx] [PATCH v3 06/38] drm: Add some kselftests for the DRM range manager (struct drm_mm)

2016-12-16 Thread Chris Wilson
First we introduce a smattering of infrastructure for writing selftests.
The idea is that we have a test module that exercises a particular
portion of the exported API, and that module provides a set of tests
that can either be run as an ensemble via kselftest or individually via
an igt harness (in this case igt/drm_mm). To accommodate selecting
individual tests, we export a boolean parameter to control selection of
each test - that is hidden inside a bunch of reusable boilerplate macros
to keep writing the tests simple.

v2: Choose a random random_seed unless one is specified by the user.
v3: More parameters to control max_iterations and max_prime of the
tests.

Testcase: igt/drm_mm
Signed-off-by: Chris Wilson 
Acked-by: Christian König 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/Kconfig   |  15 
 drivers/gpu/drm/Makefile  |   1 +
 drivers/gpu/drm/selftests/drm_mm_selftests.h  |   8 ++
 drivers/gpu/drm/selftests/drm_selftest.c  | 109 ++
 drivers/gpu/drm/selftests/drm_selftest.h  |  41 ++
 drivers/gpu/drm/selftests/test-drm_mm.c   |  58 ++
 tools/testing/selftests/drivers/gpu/drm_mm.sh |  15 
 7 files changed, 247 insertions(+)
 create mode 100644 drivers/gpu/drm/selftests/drm_mm_selftests.h
 create mode 100644 drivers/gpu/drm/selftests/drm_selftest.c
 create mode 100644 drivers/gpu/drm/selftests/drm_selftest.h
 create mode 100644 drivers/gpu/drm/selftests/test-drm_mm.c
 create mode 100755 tools/testing/selftests/drivers/gpu/drm_mm.sh

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 45a1c7468e88..29146fa83001 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -48,6 +48,21 @@ config DRM_DEBUG_MM
 
  If in doubt, say "N".
 
+config DRM_DEBUG_MM_SELFTEST
+   tristate "kselftests for DRM range manager (struct drm_mm)"
+   depends on DRM
+   depends on DEBUG_KERNEL
+   select PRIME_NUMBERS
+   select DRM_LIB_RANDOM
+   default n
+   help
+ This option provides a kernel module that can be used to test
+ the DRM range manager (drm_mm) and its API. This option is not
+ useful for distributions or general kernels, but only for kernel
+ developers working on DRM and associated drivers.
+
+ If in doubt, say "N".
+
 config DRM_KMS_HELPER
tristate
depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 6bb416360ae4..c0d1aed8588b 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -38,6 +38,7 @@ drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += 
drm_fb_cma_helper.o
 drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
 
 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
+obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/test-drm_mm.o
 
 CFLAGS_drm_trace_points.o := -I$(src)
 
diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
new file mode 100644
index ..1610e0a63a5b
--- /dev/null
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -0,0 +1,8 @@
+/* List each unit test as selftest(name, function)
+ *
+ * The name is used as both an enum and expanded as igt__name to create
+ * a module parameter. It must be unique and legal for a C identifier.
+ *
+ * Tests are executed in order by igt/drm_mm
+ */
+selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck for igt) */
diff --git a/drivers/gpu/drm/selftests/drm_selftest.c 
b/drivers/gpu/drm/selftests/drm_selftest.c
new file mode 100644
index ..e29ed9faef5b
--- /dev/null
+++ b/drivers/gpu/drm/selftests/drm_selftest.c
@@ -0,0 +1,109 @@
+/*
+ * 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 
+

[Intel-gfx] [PATCH v3 05/38] drm: Add a simple generator of random permutations

2016-12-16 Thread Chris Wilson
When testing, we want a random but yet reproducible order in which to
process elements. Here we create an array which is a random (using the
Tausworthe PRNG) permutation of the order in which to execute.

Note these are simple helpers intended to be merged upstream in lib/

v2: Tidier code by David Herrmann
v3: Add reminder that this code is intended to be temporary, with at
least the bulk of the prandom changes going to lib/

Signed-off-by: Chris Wilson 
Cc: Joonas Lahtinen 
Cc: David Herrmann 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/Kconfig  |  4 
 drivers/gpu/drm/Makefile |  1 +
 drivers/gpu/drm/lib/drm_random.c | 41 
 drivers/gpu/drm/lib/drm_random.h | 25 
 4 files changed, 71 insertions(+)
 create mode 100644 drivers/gpu/drm/lib/drm_random.c
 create mode 100644 drivers/gpu/drm/lib/drm_random.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index ebfe8404c25f..45a1c7468e88 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -321,3 +321,7 @@ config DRM_SAVAGE
  chipset. If M is selected the module will be called savage.
 
 endif # DRM_LEGACY
+
+config DRM_LIB_RANDOM
+   bool
+   default n
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index b9ae4280de9d..6bb416360ae4 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -18,6 +18,7 @@ drm-y   :=drm_auth.o drm_bufs.o drm_cache.o \
drm_plane.o drm_color_mgmt.o drm_print.o \
drm_dumb_buffers.o drm_mode_config.o
 
+drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
 drm-$(CONFIG_PCI) += ati_pcigart.o
diff --git a/drivers/gpu/drm/lib/drm_random.c b/drivers/gpu/drm/lib/drm_random.c
new file mode 100644
index ..7b12a68c3b54
--- /dev/null
+++ b/drivers/gpu/drm/lib/drm_random.c
@@ -0,0 +1,41 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "drm_random.h"
+
+static inline u32 drm_prandom_u32_max_state(u32 ep_ro, struct rnd_state *state)
+{
+   return upper_32_bits((u64)prandom_u32_state(state) * ep_ro);
+}
+
+void drm_random_reorder(unsigned int *order, unsigned int count,
+   struct rnd_state *state)
+{
+   unsigned int i, j;
+
+   for (i = 0; i < count; ++i) {
+   BUILD_BUG_ON(sizeof(unsigned int) > sizeof(u32));
+   j = drm_prandom_u32_max_state(count, state);
+   swap(order[i], order[j]);
+   }
+}
+EXPORT_SYMBOL(drm_random_reorder);
+
+unsigned int *drm_random_order(unsigned int count, struct rnd_state *state)
+{
+   unsigned int *order, i;
+
+   order = kmalloc_array(count, sizeof(*order), GFP_TEMPORARY);
+   if (!order)
+   return order;
+
+   for (i = 0; i < count; i++)
+   order[i] = i;
+
+   drm_random_reorder(order, count, state);
+   return order;
+}
+EXPORT_SYMBOL(drm_random_order);
diff --git a/drivers/gpu/drm/lib/drm_random.h b/drivers/gpu/drm/lib/drm_random.h
new file mode 100644
index ..a78644bea7f9
--- /dev/null
+++ b/drivers/gpu/drm/lib/drm_random.h
@@ -0,0 +1,25 @@
+#ifndef __DRM_RANDOM_H__
+#define __DRM_RANDOM_H__
+
+/* This is a temporary home for a couple of utility functions that should
+ * be transposed to lib/ at the earliest convenience.
+ */
+
+#include 
+
+#define DRM_RND_STATE_INITIALIZER(seed__) ({   \
+   struct rnd_state state__;   \
+   prandom_seed_state(__, (seed__)); \
+   state__;\
+})
+
+#define DRM_RND_STATE(name__, seed__) \
+   struct rnd_state name__ = DRM_RND_STATE_INITIALIZER(seed__)
+
+unsigned int *drm_random_order(unsigned int count,
+  struct rnd_state *state);
+void drm_random_reorder(unsigned int *order,
+   unsigned int count,
+   struct rnd_state *state);
+
+#endif /* !__DRM_RANDOM_H__ */
-- 
2.11.0

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


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

2016-12-16 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 26e7001c846d..52a1a1d0ba7c 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1682,6 +1682,106 @@ static int igt_topdown(void *ignored)
return ret;
 }
 
+static int igt_bottomup(void *ignored)
+{
+   const struct insert_mode *bottomup = _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, );
+   if (!order)
+   goto err_bitmap;
+
+   ret = -EINVAL;
+   for (size = 1; size <= 64; size <<= 1) {
+   drm_mm_init(, 0, size*count);
+   for (n = 0; n < count; n++) {
+   if (!expect_insert(, [n],
+  size, 0, n,
+  bottomup)) {
+   pr_err("bottomup insert failed, size %u step 
%d\n", size, n);
+   goto out;
+   }
+
+   if (!assert_one_hole(, size*(n + 1), size*count))
+   goto out;
+   }
+
+   if (!assert_continuous(, size))
+   goto out;
+
+   drm_random_reorder(order, count, );
+   for_each_prime_number(n, min(count, max_prime)) {
+   for (m = 0; m < n; m++) {
+   node = [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 = [order[(o + m) % count]];
+   if (!expect_insert(, 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, )
+   drm_mm_remove_node(node);
+   DRM_MM_BUG_ON(!drm_mm_clean());
+   }
+
+   ret = 0;
+out:
+   drm_mm_for_each_node_safe(node, next, )
+   drm_mm_remove_node(node);
+   drm_mm_takedown();
+   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 v3 01/38] drm/i915: Use the MRU stack search after evicting

2016-12-16 Thread Chris Wilson
When we evict from the GTT to make room for an object, the hole we
create is put onto the MRU stack inside the drm_mm range manager. On the
next search pass, we can speed up a PIN_HIGH allocation by referencing
that stack for the new hole.

v2: Pull together the 3 identical implements (ahem, a couple were
outdated) into a common routine for allocating a node and evicting as
necessary.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gvt/aperture_gm.c | 33 +---
 drivers/gpu/drm/i915/i915_gem_gtt.c| 72 --
 drivers/gpu/drm/i915/i915_gem_gtt.h|  5 +++
 drivers/gpu/drm/i915/i915_vma.c| 40 ++-
 4 files changed, 70 insertions(+), 80 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c 
b/drivers/gpu/drm/i915/gvt/aperture_gm.c
index 7d33b607bc89..1bb7a5b80d47 100644
--- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
+++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
@@ -48,47 +48,34 @@ static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
 {
struct intel_gvt *gvt = vgpu->gvt;
struct drm_i915_private *dev_priv = gvt->dev_priv;
-   u32 alloc_flag, search_flag;
+   unsigned int flags;
u64 start, end, size;
struct drm_mm_node *node;
-   int retried = 0;
int ret;
 
if (high_gm) {
-   search_flag = DRM_MM_SEARCH_BELOW;
-   alloc_flag = DRM_MM_CREATE_TOP;
node = >gm.high_gm_node;
size = vgpu_hidden_sz(vgpu);
start = gvt_hidden_gmadr_base(gvt);
end = gvt_hidden_gmadr_end(gvt);
+   flags = PIN_HIGH;
} else {
-   search_flag = DRM_MM_SEARCH_DEFAULT;
-   alloc_flag = DRM_MM_CREATE_DEFAULT;
node = >gm.low_gm_node;
size = vgpu_aperture_sz(vgpu);
start = gvt_aperture_gmadr_base(gvt);
end = gvt_aperture_gmadr_end(gvt);
+   flags = PIN_MAPPABLE;
}
 
mutex_lock(_priv->drm.struct_mutex);
-search_again:
-   ret = drm_mm_insert_node_in_range_generic(_priv->ggtt.base.mm,
- node, size, 4096,
- I915_COLOR_UNEVICTABLE,
- start, end, search_flag,
- alloc_flag);
-   if (ret) {
-   ret = i915_gem_evict_something(_priv->ggtt.base,
-  size, 4096,
-  I915_COLOR_UNEVICTABLE,
-  start, end, 0);
-   if (ret == 0 && ++retried < 3)
-   goto search_again;
-
-   gvt_err("fail to alloc %s gm space from host, retried %d\n",
-   high_gm ? "high" : "low", retried);
-   }
+   ret = i915_gem_gtt_insert(_priv->ggtt.base, node,
+ size, 4096, I915_COLOR_UNEVICTABLE,
+ start, end, flags);
mutex_unlock(_priv->drm.struct_mutex);
+   if (ret)
+   gvt_err("fail to alloc %s gm space from host\n",
+   high_gm ? "high" : "low");
+
return ret;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 2083c899ab78..97fd66e4e3d0 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2056,7 +2056,6 @@ static int gen6_ppgtt_allocate_page_directories(struct 
i915_hw_ppgtt *ppgtt)
struct i915_address_space *vm = >base;
struct drm_i915_private *dev_priv = ppgtt->base.i915;
struct i915_ggtt *ggtt = _priv->ggtt;
-   bool retried = false;
int ret;
 
/* PPGTT PDEs reside in the GGTT and consists of 512 entries. The
@@ -2069,29 +2068,14 @@ static int gen6_ppgtt_allocate_page_directories(struct 
i915_hw_ppgtt *ppgtt)
if (ret)
return ret;
 
-alloc:
-   ret = drm_mm_insert_node_in_range_generic(>base.mm, >node,
- GEN6_PD_SIZE, GEN6_PD_ALIGN,
- I915_COLOR_UNEVICTABLE,
- 0, ggtt->base.total,
- DRM_MM_TOPDOWN);
-   if (ret == -ENOSPC && !retried) {
-   ret = i915_gem_evict_something(>base,
-  GEN6_PD_SIZE, GEN6_PD_ALIGN,
-  I915_COLOR_UNEVICTABLE,
-  0, ggtt->base.total,
-  0);
-   if (ret)
-   goto err_out;
-
-   retried = true;
-  

[Intel-gfx] [PATCH v3 08/38] drm: kselftest for drm_mm_debug()

2016-12-16 Thread Chris Wilson
Simple test to just exercise calling the debug dumper on the drm_mm.

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  | 35 
 2 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 844dd29db540..0265f09e92fa 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -7,3 +7,4 @@
  */
 selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck for igt) */
 selftest(init, igt_init)
+selftest(debug, igt_debug)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 87ad147670da..434320061d9e 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -141,6 +141,41 @@ static int igt_init(void *ignored)
return ret;
 }
 
+static int igt_debug(void *ignored)
+{
+   struct drm_mm mm;
+   struct drm_mm_node nodes[2];
+   int ret;
+
+   /* Create a small drm_mm with a couple of nodes and a few holes, and
+* check that the debug iterator doesn't explode over a trivial drm_mm.
+*/
+
+   drm_mm_init(, 0, 4096);
+
+   memset(nodes, 0, sizeof(nodes));
+   nodes[0].start = 512;
+   nodes[0].size = 1024;
+   ret = drm_mm_reserve_node(, [0]);
+   if (ret) {
+   pr_err("failed to reserve node[0] {start=%lld, size=%lld)\n",
+  nodes[0].start, nodes[0].size);
+   return ret;
+   }
+
+   nodes[1].size = 1024;
+   nodes[1].start = 4096 - 512 - nodes[1].size;
+   ret = drm_mm_reserve_node(, [1]);
+   if (ret) {
+   pr_err("failed to reserve node[1] {start=%lld, size=%lld)\n",
+  nodes[1].start, nodes[1].size);
+   return ret;
+   }
+
+   drm_mm_debug_table(, __func__);
+   return 0;
+}
+
 #include "drm_selftest.c"
 
 static int __init test_drm_mm_init(void)
-- 
2.11.0

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


[Intel-gfx] [PATCH v3 03/38] drm: Compile time enabling for asserts in drm_mm

2016-12-16 Thread Chris Wilson
Use CONFIG_DRM_DEBUG_MM to conditionally enable the internal and
validation checking using BUG_ON. Ideally these paths should all be
exercised by CI selftests (with the asserts enabled).

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 45 +++--
 include/drm/drm_mm.h |  8 +++-
 2 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 4257c86cc305..9756542abe4c 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -237,7 +237,7 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
u64 adj_start = hole_start;
u64 adj_end = hole_end;
 
-   BUG_ON(node->allocated);
+   DRM_MM_BUG_ON(node->allocated);
 
if (mm->color_adjust)
mm->color_adjust(hole_node, color, _start, _end);
@@ -258,8 +258,8 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
}
}
 
-   BUG_ON(adj_start < hole_start);
-   BUG_ON(adj_end > hole_end);
+   DRM_MM_BUG_ON(adj_start < hole_start);
+   DRM_MM_BUG_ON(adj_end > hole_end);
 
if (adj_start == hole_start) {
hole_node->hole_follows = 0;
@@ -276,7 +276,7 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
 
drm_mm_interval_tree_add_node(hole_node, node);
 
-   BUG_ON(node->start + node->size > adj_end);
+   DRM_MM_BUG_ON(node->start + node->size > adj_end);
 
node->hole_follows = 0;
if (__drm_mm_hole_node_start(node) < hole_end) {
@@ -409,7 +409,7 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
u64 adj_start = hole_start;
u64 adj_end = hole_end;
 
-   BUG_ON(!hole_node->hole_follows || node->allocated);
+   DRM_MM_BUG_ON(!hole_node->hole_follows || node->allocated);
 
if (adj_start < start)
adj_start = start;
@@ -450,10 +450,10 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
 
drm_mm_interval_tree_add_node(hole_node, node);
 
-   BUG_ON(node->start < start);
-   BUG_ON(node->start < adj_start);
-   BUG_ON(node->start + node->size > adj_end);
-   BUG_ON(node->start + node->size > end);
+   DRM_MM_BUG_ON(node->start < start);
+   DRM_MM_BUG_ON(node->start < adj_start);
+   DRM_MM_BUG_ON(node->start + node->size > adj_end);
+   DRM_MM_BUG_ON(node->start + node->size > end);
 
node->hole_follows = 0;
if (__drm_mm_hole_node_start(node) < hole_end) {
@@ -519,22 +519,21 @@ void drm_mm_remove_node(struct drm_mm_node *node)
struct drm_mm *mm = node->mm;
struct drm_mm_node *prev_node;
 
-   if (WARN_ON(!node->allocated))
-   return;
-
-   BUG_ON(node->scanned_block || node->scanned_prev_free
-  || node->scanned_next_free);
+   DRM_MM_BUG_ON(!node->allocated);
+   DRM_MM_BUG_ON(node->scanned_block ||
+ node->scanned_prev_free ||
+ node->scanned_next_free);
 
prev_node =
list_entry(node->node_list.prev, struct drm_mm_node, node_list);
 
if (node->hole_follows) {
-   BUG_ON(__drm_mm_hole_node_start(node) ==
-  __drm_mm_hole_node_end(node));
+   DRM_MM_BUG_ON(__drm_mm_hole_node_start(node) ==
+ __drm_mm_hole_node_end(node));
list_del(>hole_stack);
} else
-   BUG_ON(__drm_mm_hole_node_start(node) !=
-  __drm_mm_hole_node_end(node));
+   DRM_MM_BUG_ON(__drm_mm_hole_node_start(node) !=
+ __drm_mm_hole_node_end(node));
 
 
if (!prev_node->hole_follows) {
@@ -578,7 +577,7 @@ static struct drm_mm_node *drm_mm_search_free_generic(const 
struct drm_mm *mm,
u64 adj_end;
u64 best_size;
 
-   BUG_ON(mm->scanned_blocks);
+   DRM_MM_BUG_ON(mm->scanned_blocks);
 
best = NULL;
best_size = ~0UL;
@@ -622,7 +621,7 @@ static struct drm_mm_node 
*drm_mm_search_free_in_range_generic(const struct drm_
u64 adj_end;
u64 best_size;
 
-   BUG_ON(mm->scanned_blocks);
+   DRM_MM_BUG_ON(mm->scanned_blocks);
 
best = NULL;
best_size = ~0UL;
@@ -668,6 +667,8 @@ static struct drm_mm_node 
*drm_mm_search_free_in_range_generic(const struct drm_
  */
 void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new)
 {
+   DRM_MM_BUG_ON(!old->allocated);
+
list_replace(>node_list, >node_list);
list_replace(>hole_stack, >hole_stack);
rb_replace_node(>rb, >rb, >mm->interval_tree);
@@ -798,7 +799,7 @@ bool drm_mm_scan_add_block(struct drm_mm_node *node)
 
mm->scanned_blocks++;
 
-   BUG_ON(node->scanned_block);
+   

[Intel-gfx] [PATCH v3 27/38] drm: Rename prev_node to hole in drm_mm_scan_add_block()

2016-12-16 Thread Chris Wilson
Acknowledging that we were building up the hole was more useful to me
when reading the code, than knowing the relationship between this node
and the previous node.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 21bd2e13738b..459f10ca5714 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -811,7 +811,7 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
   struct drm_mm_node *node)
 {
struct drm_mm *mm = scan->mm;
-   struct drm_mm_node *prev_node;
+   struct drm_mm_node *hole;
u64 hole_start, hole_end;
u64 adj_start, adj_end;
 
@@ -821,17 +821,17 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
node->scanned_block = 1;
mm->scan_active++;
 
-   prev_node = list_prev_entry(node, node_list);
+   hole = list_prev_entry(node, node_list);
 
-   node->scanned_preceeds_hole = prev_node->hole_follows;
-   prev_node->hole_follows = 1;
+   node->scanned_preceeds_hole = hole->hole_follows;
+   hole->hole_follows = 1;
list_del(>node_list);
-   node->node_list.prev = _node->node_list;
+   node->node_list.prev = >node_list;
node->node_list.next = >prev_scanned_node->node_list;
scan->prev_scanned_node = node;
 
-   adj_start = hole_start = drm_mm_hole_node_start(prev_node);
-   adj_end = hole_end = drm_mm_hole_node_end(prev_node);
+   adj_start = hole_start = drm_mm_hole_node_start(hole);
+   adj_end = hole_end = drm_mm_hole_node_end(hole);
 
if (scan->check_range) {
if (adj_start < scan->range_start)
@@ -841,7 +841,7 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
}
 
if (mm->color_adjust)
-   mm->color_adjust(prev_node, scan->color, _start, _end);
+   mm->color_adjust(hole, scan->color, _start, _end);
 
if (check_free_hole(adj_start, adj_end,
scan->size, scan->alignment)) {
-- 
2.11.0

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


[Intel-gfx] drm_mm fixes, take 3, final?

2016-12-16 Thread Chris Wilson
With a lot of polish applied, Joonas has reviewed the series - all but
for [04/38] "lib: Add a simple prime number generator"
[lib/prime_numbers.c]. Anyone feel like poking around at a bit of number
theory?

Other than it would appear to be ready for Daniel to sort out the merge
between drm-misc/i915... Please do take a look and see if you can spot
anything else that needs fixing/improving.
-Chris

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


Re: [Intel-gfx] [PATCH i-g-t v2 10/12] tests/kms_atomic_transition: add out_fences tests

2016-12-16 Thread Brian Starkey

On Fri, Dec 16, 2016 at 03:59:00AM -0500, Robert Foss wrote:



On 2016-12-14 11:57 AM, Brian Starkey wrote:

On Wed, Dec 14, 2016 at 04:05:07AM -0500, Robert Foss wrote:

From: Gustavo Padovan 

Signed-off-by: Gustavo Padovan 
Signed-off-by: Robert Foss 
---
lib/igt_kms.c | 22 ++
tests/kms_atomic_transition.c | 32 ++--
2 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index fe1b356d..eb59ab36 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -49,6 +49,7 @@
#include "intel_chipset.h"
#include "igt_debugfs.h"
#include "igt_sysfs.h"
+#include "sw_sync.h"

/**
* SECTION:igt_kms
@@ -2184,6 +2185,27 @@ static int igt_atomic_commit(igt_display_t
*display, uint32_t flags, void *user_
   }

   ret = drmModeAtomicCommit(display->drm_fd, req, flags, user_data);
+if (!ret) {
+int64_t *fence_ptr;
+
+for_each_pipe(display, pipe) {
+igt_pipe_t *pipe_obj = >pipes[pipe];
+
+fence_ptr = pipe_obj->out_fence_ptr;
+if (!fence_ptr)
+continue;
+
+if (flags & DRM_MODE_ATOMIC_TEST_ONLY) {
+igt_assert(*fence_ptr == -1);
+} else {
+igt_assert(*fence_ptr >= 0);
+ret = sw_sync_wait(*fence_ptr, 1000);
+igt_assert(ret == 0);
+close(*fence_ptr);
+}
+}
+}
+
   drmModeAtomicFree(req);
   return ret;

diff --git a/tests/kms_atomic_transition.c
b/tests/kms_atomic_transition.c
index b7d99975..08f9499f 100644
--- a/tests/kms_atomic_transition.c
+++ b/tests/kms_atomic_transition.c
@@ -132,6 +132,7 @@ run_transition_test(igt_display_t *display, enum
pipe pipe, igt_output_t *output
   struct plane_parms parms[IGT_MAX_PLANES];
   bool skip_test = false;
   unsigned flags = DRM_MODE_PAGE_FLIP_EVENT;
+int out_fence, ret;


out_fence needs to be 64-bit.


Ack, fixed in v3.





   if (nonblocking)
   flags |= DRM_MODE_ATOMIC_NONBLOCK;
@@ -198,9 +199,11 @@ run_transition_test(igt_display_t *display, enum
pipe pipe, igt_output_t *output
* planes to fix this
*/
   while (1) {
-int ret;
-
   wm_setup_plane(display, pipe, iter_max - 1, parms);
+
+if (fencing)
+igt_pipe_set_out_fence_ptr(>pipes[pipe],
+(int64_t *) _fence);
   ret = igt_display_try_commit_atomic(display,
DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);

   if (ret != -EINVAL || n_planes < 3)
@@ -231,6 +234,9 @@ run_transition_test(igt_display_t *display, enum
pipe pipe, igt_output_t *output

   wm_setup_plane(display, pipe, i, parms);

+if (fencing)
+igt_pipe_set_out_fence_ptr(>pipes[pipe],
_fence);
+
   igt_display_commit_atomic(display, flags, (void *)(unsigned
long)i);
   drmHandleEvent(display->drm_fd, _events);

@@ -239,6 +245,10 @@ run_transition_test(igt_display_t *display, enum
pipe pipe, igt_output_t *output

   wm_setup_plane(display, pipe, 0, parms);

+if (fencing)
+igt_pipe_set_out_fence_ptr(>pipes[pipe],
+(int64_t *) _fence);
+
   igt_display_commit_atomic(display, flags, (void *)0UL);

   drmHandleEvent(display->drm_fd, _events);
@@ -252,6 +262,9 @@ run_transition_test(igt_display_t *display, enum
pipe pipe, igt_output_t *output
   if (type == TRANSITION_MODESET)
   igt_output_override_mode(output, _mode);

+if (fencing)
+igt_pipe_set_out_fence_ptr(>pipes[pipe],
_fence);
+
   igt_display_commit_atomic(display, flags, (void
*)(unsigned long)j);
   drmHandleEvent(display->drm_fd, _events);

@@ -259,6 +272,9 @@ run_transition_test(igt_display_t *display, enum
pipe pipe, igt_output_t *output
   if (type == TRANSITION_MODESET)
   igt_output_override_mode(output, NULL);

+if (fencing)
+igt_pipe_set_out_fence_ptr(>pipes[pipe],
_fence);
+
   igt_display_commit_atomic(display, flags, (void
*)(unsigned long)i);
   drmHandleEvent(display->drm_fd, _events);
   }
@@ -588,14 +604,26 @@ igt_main
   for_each_pipe_with_valid_output(, pipe, output)
   run_transition_test(, pipe, output,
TRANSITION_PLANES, false, false);

+igt_subtest("plane-all-transition-fencing")
+for_each_pipe_with_valid_output(, pipe, output)
+run_transition_test(, pipe, output,
TRANSITION_PLANES, false, true);
+
   igt_subtest("plane-all-transition-nonblocking")
   for_each_pipe_with_valid_output(, pipe, output)
   run_transition_test(, pipe, output,
TRANSITION_PLANES, true, false);

+igt_subtest("plane-all-transition-nonblocking-fencing")
+for_each_pipe_with_valid_output(, pipe, output)
+  

Re: [Intel-gfx] [PATCH i-g-t v2 08/12] tests/kms_atomic: stress possible fence settings

2016-12-16 Thread Brian Starkey

On Fri, Dec 16, 2016 at 03:35:36AM -0500, Robert Foss wrote:



On 2016-12-14 11:39 AM, Brian Starkey wrote:

Hi,

On Wed, Dec 14, 2016 at 04:05:05AM -0500, Robert Foss wrote:

From: Gustavo Padovan 

Signed-off-by: Gustavo Padovan 
Signed-off-by: Robert Foss 
---
tests/kms_atomic.c | 186
++---
1 file changed, 176 insertions(+), 10 deletions(-)

diff --git a/tests/kms_atomic.c b/tests/kms_atomic.c
index 8b648eba..a557ac60 100644
--- a/tests/kms_atomic.c
+++ b/tests/kms_atomic.c
@@ -44,6 +44,7 @@
#include "drmtest.h"
#include "igt.h"
#include "igt_aux.h"
+#include "sw_sync.h"

#ifndef DRM_CLIENT_CAP_ATOMIC
#define DRM_CLIENT_CAP_ATOMIC 3
@@ -126,6 +127,7 @@ struct kms_atomic_plane_state {
   uint32_t fb_id; /* 0 to disable */
   uint32_t src_x, src_y, src_w, src_h; /* 16.16 fixed-point */
   uint32_t crtc_x, crtc_y, crtc_w, crtc_h; /* normal integers */
+int32_t fence_fd;
};

struct kms_atomic_crtc_state {
@@ -133,6 +135,7 @@ struct kms_atomic_crtc_state {
   uint32_t obj;
   int idx;
   bool active;
+uint64_t out_fence_ptr;
   struct kms_atomic_blob mode;
};

@@ -190,11 +193,13 @@ static uint32_t blob_duplicate(int fd, uint32_t
id_orig)
   crtc_populate_req(crtc, req); \
   plane_populate_req(plane, req); \
   do_atomic_commit((crtc)->state->desc->fd, req, flags); \
-crtc_check_current_state(crtc, plane, relax); \
-plane_check_current_state(plane, relax); \
+if (!(flags & DRM_MODE_ATOMIC_TEST_ONLY)) { \
+crtc_check_current_state(crtc, plane, relax); \
+plane_check_current_state(plane, relax); \
+} \
}

-#define crtc_commit_atomic_err(crtc, plane, crtc_old, plane_old, req,
relax, e) { \
+#define crtc_commit_atomic_err(crtc, plane, crtc_old, plane_old, req,
flags, relax, e) { \
   drmModeAtomicSetCursor(req, 0); \
   crtc_populate_req(crtc, req); \
   plane_populate_req(plane, req); \
@@ -299,6 +304,9 @@ find_connector(struct kms_atomic_state *state,
static void plane_populate_req(struct kms_atomic_plane_state *plane,
  drmModeAtomicReq *req)
{
+if (plane->fence_fd)
+plane_set_prop(req, plane, IGT_PLANE_IN_FENCE_FD,
plane->fence_fd);
+
   plane_set_prop(req, plane, IGT_PLANE_CRTC_ID, plane->crtc_id);
   plane_set_prop(req, plane, IGT_PLANE_FB_ID, plane->fb_id);
   plane_set_prop(req, plane, IGT_PLANE_SRC_X, plane->src_x);
@@ -424,6 +432,10 @@ find_plane(struct kms_atomic_state *state, enum
plane_type type,
static void crtc_populate_req(struct kms_atomic_crtc_state *crtc,
 drmModeAtomicReq *req)
{
+if (crtc->out_fence_ptr)
+crtc_set_prop(req, crtc, IGT_CRTC_OUT_FENCE_PTR,
+  crtc->out_fence_ptr);
+
   crtc_set_prop(req, crtc, IGT_CRTC_MODE_ID, crtc->mode.id);
   crtc_set_prop(req, crtc, IGT_CRTC_ACTIVE, crtc->active);
}
@@ -1052,6 +1064,37 @@ static void plane_invalid_params(struct
kms_atomic_crtc_state *crtc,
   drmModeAtomicFree(req);
}

+static void plane_invalid_params_fence(struct kms_atomic_crtc_state
*crtc,
+struct kms_atomic_plane_state *plane_old,
+struct kms_atomic_connector_state *conn)
+{
+struct kms_atomic_plane_state plane = *plane_old;
+drmModeAtomicReq *req = drmModeAtomicAlloc();
+int timeline, fence_fd;
+
+igt_require_sw_sync();
+
+/* invalid fence fd */
+plane.fence_fd = plane.state->desc->fd;
+plane.crtc_id = plane_old->crtc_id;
+plane_commit_atomic_err(, plane_old, req,
+ATOMIC_RELAX_NONE, EINVAL);
+
+/* Valid fence_fd but invalid CRTC */
+timeline = sw_sync_timeline_create();
+fence_fd =  sw_sync_fence_create(timeline, 1);
+plane.fence_fd = fence_fd;
+plane.crtc_id = ~0U;
+plane_commit_atomic_err(, plane_old, req,
+ATOMIC_RELAX_NONE, EINVAL);
+
+plane.fence_fd = -1;
+close(fence_fd);
+close(timeline);
+
+drmModeAtomicFree(req);
+}
+
static void crtc_invalid_params(struct kms_atomic_crtc_state *crtc_old,
   struct kms_atomic_plane_state *plane,
   struct kms_atomic_connector_state *conn)
@@ -1063,30 +1106,32 @@ static void crtc_invalid_params(struct
kms_atomic_crtc_state *crtc_old,

   /* Pass a series of invalid object IDs for the mode ID. */
   crtc.mode.id = plane->obj;
-crtc_commit_atomic_err(, plane, crtc_old, plane, req,
+crtc_commit_atomic_err(, plane, crtc_old, plane, req, 0,
  ATOMIC_RELAX_NONE, EINVAL);

   crtc.mode.id = crtc.obj;
-crtc_commit_atomic_err(, plane, crtc_old, plane, req,
+crtc_commit_atomic_err(, plane, crtc_old, plane, req, 0,
  ATOMIC_RELAX_NONE, EINVAL);

   crtc.mode.id = conn->obj;
-crtc_commit_atomic_err(, plane, crtc_old, plane, req,
+crtc_commit_atomic_err(, plane, crtc_old, plane, req, 0,
  ATOMIC_RELAX_NONE, EINVAL);

   

Re: [Intel-gfx] [PATCH i-g-t v2 07/12] lib/igt_kms: Add support for the OUT_FENCE_PTR property

2016-12-16 Thread Brian Starkey

On Fri, Dec 16, 2016 at 03:21:45AM -0500, Robert Foss wrote:



On 2016-12-14 11:13 AM, Brian Starkey wrote:

Hi,

On Wed, Dec 14, 2016 at 04:05:04AM -0500, Robert Foss wrote:

From: Gustavo Padovan 

Add support for the OUT_FENCE_PTR property to enable setting out
fences for
atomic commits.

Signed-off-by: Gustavo Padovan 
Signed-off-by: Robert Foss 
---
lib/igt_kms.c | 21 -
lib/igt_kms.h |  3 +++
2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 8ca49d86..fe1b356d 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -175,7 +175,8 @@ const char
*igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
   "DEGAMMA_LUT",
   "GAMMA_LUT",
   "MODE_ID",
-"ACTIVE"
+"ACTIVE",
+"OUT_FENCE_PTR"
};

const char *igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
@@ -2103,6 +2104,10 @@ static void
igt_atomic_prepare_crtc_commit(igt_pipe_t *pipe_obj, drmModeAtomicRe
   igt_atomic_populate_crtc_req(req, pipe_obj, IGT_CRTC_ACTIVE,
!!output);
   }

+if (pipe_obj->out_fence_ptr)
+igt_atomic_populate_crtc_req(req, pipe_obj,
IGT_CRTC_OUT_FENCE_PTR,
+(uint64_t)(uintptr_t) pipe_obj->out_fence_ptr);
+
   /*
*TODO: Add all crtc level properties here
*/
@@ -2683,6 +2688,20 @@ igt_pipe_set_gamma_lut(igt_pipe_t *pipe, void
*ptr, size_t length)
}

/**
+ * igt_pipe_set_out_fence_ptr:
+ * @pipe: pipe pointer to which background color to be set
+ * @fence_ptr: out fence pointer
+ *
+ * Sets the out fence pointer that will be passed to the kernel in
+ * the atomic ioctl. When the kernel returns the out fence pointer
+ * will contain the fd number of the out fence created by KMS.
+ */
+void igt_pipe_set_out_fence_ptr(igt_pipe_t *pipe, int64_t *fence_ptr)
+{
+pipe->out_fence_ptr = fence_ptr;
+}
+
+/**
* igt_crtc_set_background:
* @pipe: pipe pointer to which background color to be set
* @background: background color value in BGR 16bpc
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 9766807c..8eb611c0 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -110,6 +110,7 @@ enum igt_atomic_crtc_properties {
  IGT_CRTC_GAMMA_LUT,
  IGT_CRTC_MODE_ID,
  IGT_CRTC_ACTIVE,
+   IGT_CRTC_OUT_FENCE_PTR,
  IGT_NUM_CRTC_PROPS
};

@@ -316,6 +317,7 @@ struct igt_pipe {

   uint64_t mode_blob;
   bool mode_changed;
+int64_t *out_fence_ptr;


I prefer the interface that got suggested before - igt_pipe gets an
"int64_t out_fence;" member which tests can query to get the fence
value:

int igt_pipe_get_last_out_fence(igt_pipe_t *pipe);

..and the kernel only ever receives a pointer to pipe->out_fence.

The only reason I can see for a test to want to provide its own fence
pointer is to test invalid pointer values - and I think it's OK for
that test to set the property directly instead of making setting a
custom fence pointer the common case for all users.

If we don't want to get a fence for every commit then I guess there
could be a way for a test to request an out-fence for just the next
commit on a pipe (or the inverse - disable fencing for a particular
commit):

void igt_pipe_request_out_fence(igt_pipe_t *pipe);

-Brian


Now I see what you meant in the v1 discussion, I'll amend the 
implementation in v3 to be the one mentioned above.




Partly... my main point on v1 was just to make sure the pointer was to
a 64-bit type.

The only question I have is about igt_pipe_get_last_out_fence(), is 
it really necessary? I don't foresee a function like that ever doing 
more than just returning a struct member. Is it not a bit redundant?




I see two reasons for it:
 - It means tests only deal with plain ints, which I think Chris was
   fairly adamant about on v1.
 - The getter can set pipe->out_fence to -1 when its called, making
   the ownership of the fd obvious.

In this case I guess before each commit out_fence needs to be checked,
close()'d if it looks valid, and set to -1 too.

Cheers,
Brian



Rob.




};

typedef struct {
@@ -369,6 +371,7 @@ static inline bool
igt_plane_supports_rotation(igt_plane_t *plane)
void igt_pipe_set_degamma_lut(igt_pipe_t *pipe, void *ptr, size_t
length);
void igt_pipe_set_ctm_matrix(igt_pipe_t *pipe, void *ptr, size_t length);
void igt_pipe_set_gamma_lut(igt_pipe_t *pipe, void *ptr, size_t length);
+void igt_pipe_set_out_fence_ptr(igt_pipe_t *pipe, int64_t *fence_ptr);

void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb);
void igt_plane_set_fence_fd(igt_plane_t *plane, uint32_t fence_fd);
--
2.11.0


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


Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams

2016-12-16 Thread Srivatsa, Anusha


>-Original Message-
>From: Chris Wilson [mailto:ch...@chris-wilson.co.uk]
>Sent: Friday, December 16, 2016 10:47 AM
>To: Srivatsa, Anusha 
>Cc: Hiler, Arkadiusz ; 
>intel-gfx@lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to
>getparams
>
>On Fri, Dec 16, 2016 at 06:31:46PM +, Srivatsa, Anusha wrote:
>>
>>
>> >-Original Message-
>> >From: Chris Wilson [mailto:ch...@chris-wilson.co.uk]
>> >Sent: Friday, December 16, 2016 8:31 AM
>> >To: Hiler, Arkadiusz 
>> >Cc: Srivatsa, Anusha ; intel-
>> >g...@lists.freedesktop.org
>> >Subject: Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC
>> >status to getparams
>> >
>> >On Fri, Dec 16, 2016 at 05:21:38PM +0100, Arkadiusz Hiler wrote:
>> >> On Fri, Dec 16, 2016 at 04:12:36PM +, Chris Wilson wrote:
>> >> > On Fri, Dec 16, 2016 at 03:43:46PM +0100, Arkadiusz Hiler wrote:
>> >> > > On Thu, Dec 15, 2016 at 10:42:53PM +, Chris Wilson wrote:
>> >> > > > On Thu, Dec 15, 2016 at 02:29:50PM -0800, anushasr wrote:
>> >> > > > > From: Peter Antoine 
>> >> > > > >
>> >> > > > > This patch will allow for getparams to return the status of the 
>> >> > > > > HuC.
>> >> > > > > As the HuC has to be validated by the GuC this patch uses
>> >> > > > > the validated status to show when the HuC is loaded and
>> >> > > > > ready for use. You cannot use the loaded status as with the
>> >> > > > > GuC as the HuC is verified after it is loaded and is not usable 
>> >> > > > > until it is
>verified.
>> >> > > > >
>> >> > > > > v2: removed the forewakes as the registers are already 
>> >> > > > > force-woken.
>> >> > > > >  (T.Ursulin)
>> >> > > > > v4: rebased.
>> >> > > > > v5: rebased on top of drm-tip.
>> >> > > > > v6: rebased. Removed any reference to intel_huc.h
>> >> > > > > v7: rebased. Rename I915_PARAM_HAS_HUC to
>> >I915_PARAM_HUC_STATUS.
>> >> > > > > Remove intel_is_huc_valid() since it is used only in one place.
>> >> > > > > Put the case of I915_PARAM_HAS_HUC() in the right place.
>> >> > > > >
>> >> > > > > Signed-off-by: Peter Antoine 
>> >> > > > > Reviewed-by: Arkadiusz Hiler 
>> >> > > > > ---
>> >> > > > >  drivers/gpu/drm/i915/i915_drv.c | 4 
>> >> > > > >  drivers/gpu/drm/i915/intel_huc_loader.c | 1 -
>> >> > > > >  include/uapi/drm/i915_drm.h | 1 +
>> >> > > > >  3 files changed, 5 insertions(+), 1 deletion(-)
>> >> > > > >
>> >> > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.c
>> >> > > > > b/drivers/gpu/drm/i915/i915_drv.c index 85a47c2..0bc016d
>> >> > > > > 100644
>> >> > > > > --- a/drivers/gpu/drm/i915/i915_drv.c
>> >> > > > > +++ b/drivers/gpu/drm/i915/i915_drv.c
>> >> > > > > @@ -49,6 +49,7 @@
>> >> > > > >  #include "i915_trace.h"
>> >> > > > >  #include "i915_vgpu.h"
>> >> > > > >  #include "intel_drv.h"
>> >> > > > > +#include "intel_uc.h"
>> >> > > > >
>> >> > > > >  static struct drm_driver driver;
>> >> > > > >
>> >> > > > > @@ -315,6 +316,9 @@ static int i915_getparam(struct
>> >> > > > > drm_device
>> >*dev, void *data,
>> >> > > > >   case I915_PARAM_MIN_EU_IN_POOL:
>> >> > > > >   value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
>> >> > > > >   break;
>> >> > > > > + case I915_PARAM_HUC_STATUS:
>> >> > > > > + value = I915_READ(HUC_STATUS2) &
>> >HUC_FW_VERIFIED;
>> >> > > >
>> >> > > > Same question as last time: does the device need to be awake?
>> >> > > > We know is one of the GT power wells, so presumably we need
>> >> > > > an rpm_get/rpm_put as well to access the register.
>> >> > > > -Chris
>> >> > >
>> >> > > I get:
>> >> > >
>> >> > > [ 1588.570174] [drm:i915_huc_load_status_info [i915]]
>> >> > > HUC_STATUS2 PRE  24704 [ 1588.571285]
>> >> > > [drm:intel_runtime_suspend [i915]] Suspending device [
>> >> > > 1588.575768] [drm:intel_runtime_suspend [i915]] Device
>> >> > > suspended [ 1588.577156] [drm:i915_huc_load_status_info [i915]]
>> >> > > HUC_STATUS2 POST 24704 [ 1588.578259] [drm:intel_runtime_resume
>> >> > > [i915]] Resuming device
>> >> > >
>> >> > > consistently from:
>> >> > >
>> >> > > value = I915_READ(HUC_STATUS2);
>> >> > > DRM_DEBUG_DRIVER("HUC_STATUS2 PRE  %d\n", value);
>> >> > > i915_pm_ops.runtime_suspend(dev_priv->drm.dev);
>> >> > >
>> >> > > value = I915_READ(HUC_STATUS2);
>> >> > > DRM_DEBUG_DRIVER("HUC_STATUS2 POST %d\n", value);
>> >> > > i915_pm_ops.runtime_resume(dev_priv->drm.dev);
>> >> >
>> >> > Also do the test with i915.mmio_debug= -Chris
>> >>
>> >> Same effect. Works.
>> Thanks Arek for confirming.
>>
>> >Ok, then just mark up that we don't need rpm here so that we don't
>> >freak out in future scans for mmio access outside of rpm.
>> >-Chris
>> Chris, v2 as changed by Tvrtko suggests that forcewakes are removed since the
>register is force waken. Are you suggesting that adding 

Re: [Intel-gfx] [PATCH v3] lib: Add a simple prime number generator

2016-12-16 Thread kbuild test robot
Hi Chris,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.9 next-20161216]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Chris-Wilson/lib-Add-a-simple-prime-number-generator/20161217-013805
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   include/linux/compiler.h:253:8: sparse: attribute 'no_sanitize_address': 
unknown attribute
>> lib/prime_numbers.c:220:20: sparse: incompatible types in comparison 
>> expression (different address spaces)

vim +220 lib/prime_numbers.c

   204  return -EINVAL;
   205  }
   206  last = x;
   207  }
   208  
   209  pr_info("selftest(%lu) passed, last prime was %lu", x, last);
   210  return 0;
   211  }
   212  
   213  static int __init primes_init(void)
   214  {
   215  return selftest(selftest_max);
   216  }
   217  
   218  static void __exit primes_exit(void)
   219  {
 > 220  if (primes != _primes)
   221  kfree_rcu((struct primes *)primes, rcu);
   222  }
   223  
   224  module_init(primes_init);
   225  module_exit(primes_exit);
   226  
   227  module_param_named(selftest, selftest_max, ulong, 0400);
   228  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams

2016-12-16 Thread Chris Wilson
On Fri, Dec 16, 2016 at 06:31:46PM +, Srivatsa, Anusha wrote:
> 
> 
> >-Original Message-
> >From: Chris Wilson [mailto:ch...@chris-wilson.co.uk]
> >Sent: Friday, December 16, 2016 8:31 AM
> >To: Hiler, Arkadiusz 
> >Cc: Srivatsa, Anusha ; intel-
> >g...@lists.freedesktop.org
> >Subject: Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to
> >getparams
> >
> >On Fri, Dec 16, 2016 at 05:21:38PM +0100, Arkadiusz Hiler wrote:
> >> On Fri, Dec 16, 2016 at 04:12:36PM +, Chris Wilson wrote:
> >> > On Fri, Dec 16, 2016 at 03:43:46PM +0100, Arkadiusz Hiler wrote:
> >> > > On Thu, Dec 15, 2016 at 10:42:53PM +, Chris Wilson wrote:
> >> > > > On Thu, Dec 15, 2016 at 02:29:50PM -0800, anushasr wrote:
> >> > > > > From: Peter Antoine 
> >> > > > >
> >> > > > > This patch will allow for getparams to return the status of the 
> >> > > > > HuC.
> >> > > > > As the HuC has to be validated by the GuC this patch uses the
> >> > > > > validated status to show when the HuC is loaded and ready for
> >> > > > > use. You cannot use the loaded status as with the GuC as the
> >> > > > > HuC is verified after it is loaded and is not usable until it is 
> >> > > > > verified.
> >> > > > >
> >> > > > > v2: removed the forewakes as the registers are already force-woken.
> >> > > > >  (T.Ursulin)
> >> > > > > v4: rebased.
> >> > > > > v5: rebased on top of drm-tip.
> >> > > > > v6: rebased. Removed any reference to intel_huc.h
> >> > > > > v7: rebased. Rename I915_PARAM_HAS_HUC to
> >I915_PARAM_HUC_STATUS.
> >> > > > > Remove intel_is_huc_valid() since it is used only in one place.
> >> > > > > Put the case of I915_PARAM_HAS_HUC() in the right place.
> >> > > > >
> >> > > > > Signed-off-by: Peter Antoine 
> >> > > > > Reviewed-by: Arkadiusz Hiler 
> >> > > > > ---
> >> > > > >  drivers/gpu/drm/i915/i915_drv.c | 4 
> >> > > > >  drivers/gpu/drm/i915/intel_huc_loader.c | 1 -
> >> > > > >  include/uapi/drm/i915_drm.h | 1 +
> >> > > > >  3 files changed, 5 insertions(+), 1 deletion(-)
> >> > > > >
> >> > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.c
> >> > > > > b/drivers/gpu/drm/i915/i915_drv.c index 85a47c2..0bc016d
> >> > > > > 100644
> >> > > > > --- a/drivers/gpu/drm/i915/i915_drv.c
> >> > > > > +++ b/drivers/gpu/drm/i915/i915_drv.c
> >> > > > > @@ -49,6 +49,7 @@
> >> > > > >  #include "i915_trace.h"
> >> > > > >  #include "i915_vgpu.h"
> >> > > > >  #include "intel_drv.h"
> >> > > > > +#include "intel_uc.h"
> >> > > > >
> >> > > > >  static struct drm_driver driver;
> >> > > > >
> >> > > > > @@ -315,6 +316,9 @@ static int i915_getparam(struct drm_device
> >*dev, void *data,
> >> > > > >case I915_PARAM_MIN_EU_IN_POOL:
> >> > > > >value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
> >> > > > >break;
> >> > > > > +  case I915_PARAM_HUC_STATUS:
> >> > > > > +  value = I915_READ(HUC_STATUS2) &
> >HUC_FW_VERIFIED;
> >> > > >
> >> > > > Same question as last time: does the device need to be awake? We
> >> > > > know is one of the GT power wells, so presumably we need an
> >> > > > rpm_get/rpm_put as well to access the register.
> >> > > > -Chris
> >> > >
> >> > > I get:
> >> > >
> >> > > [ 1588.570174] [drm:i915_huc_load_status_info [i915]] HUC_STATUS2
> >> > > PRE  24704 [ 1588.571285] [drm:intel_runtime_suspend [i915]]
> >> > > Suspending device [ 1588.575768] [drm:intel_runtime_suspend
> >> > > [i915]] Device suspended [ 1588.577156]
> >> > > [drm:i915_huc_load_status_info [i915]] HUC_STATUS2 POST 24704 [
> >> > > 1588.578259] [drm:intel_runtime_resume [i915]] Resuming device
> >> > >
> >> > > consistently from:
> >> > >
> >> > > value = I915_READ(HUC_STATUS2);
> >> > > DRM_DEBUG_DRIVER("HUC_STATUS2 PRE  %d\n", value);
> >> > > i915_pm_ops.runtime_suspend(dev_priv->drm.dev);
> >> > >
> >> > > value = I915_READ(HUC_STATUS2);
> >> > > DRM_DEBUG_DRIVER("HUC_STATUS2 POST %d\n", value);
> >> > > i915_pm_ops.runtime_resume(dev_priv->drm.dev);
> >> >
> >> > Also do the test with i915.mmio_debug= -Chris
> >>
> >> Same effect. Works.
> Thanks Arek for confirming.
> 
> >Ok, then just mark up that we don't need rpm here so that we don't freak out 
> >in
> >future scans for mmio access outside of rpm.
> >-Chris
> Chris, v2 as changed by Tvrtko suggests that forcewakes are removed since the 
> register is force waken. Are you suggesting that adding that rpm not  being 
> required in the commit message will make things much more clearer?

No, if you are eschewing taking rpm around mmio access, I want that
commented upon in the code so that it is visible the next time we do an
audit for rpm abuse/misuse.
-Chris

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

Re: [Intel-gfx] [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading Support

2016-12-16 Thread Srivatsa, Anusha


>-Original Message-
>From: Tvrtko Ursulin [mailto:tvrtko.ursu...@linux.intel.com]
>Sent: Friday, December 16, 2016 8:16 AM
>To: Srivatsa, Anusha ; intel-
>g...@lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading Support
>
>
>On 15/12/2016 22:29, anushasr wrote:
>> From: Anusha Srivatsa 
>>
>> This patch adds the HuC Loading for the BXT by using the updated file
>> construction.
>>
>> Version 1.7 of the HuC firmware.
>>
>> v2: rebased.
>> v3: rebased on top of drm-tip
>> v4: rebased.
>> v5: rebased. Rename BXT_FW_MAJOR to BXT_HUC_FW_
>>
>> Cc: Jeff Mcgee 
>> Signed-off-by: Anusha Srivatsa 
>> Reviewed-by: Jeff McGee 
>> ---
>>  drivers/gpu/drm/i915/intel_huc_loader.c | 11 +++
>>  1 file changed, 11 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c
>> b/drivers/gpu/drm/i915/intel_huc_loader.c
>> index 0f929cc..f36efd4 100644
>> --- a/drivers/gpu/drm/i915/intel_huc_loader.c
>> +++ b/drivers/gpu/drm/i915/intel_huc_loader.c
>> @@ -40,6 +40,10 @@
>>   * Note that HuC firmware loading must be done before GuC loading.
>>   */
>>
>> +#define BXT_HUC_FW_MAJOR 01
>> +#define BXT_HUC_FW_MINOR 07
>> +#define BXT_BLD_NUM 1398
>> +
>>  #define SKL_HUC_FW_MAJOR 01
>>  #define SKL_HUC_FW_MINOR 07
>>  #define SKL_BLD_NUM 1398
>> @@ -52,6 +56,9 @@
>>  SKL_HUC_FW_MINOR, SKL_BLD_NUM)
>>  MODULE_FIRMWARE(I915_SKL_HUC_UCODE);
>>
>> +#define I915_BXT_HUC_UCODE HUC_FW_PATH(bxt, BXT_HUC_FW_MAJOR, \
>> +BXT_HUC_FW_MINOR, BXT_BLD_NUM)
>> +MODULE_FIRMWARE(I915_BXT_HUC_UCODE);
>
>More curiosity - given the versions between SKL and BXT are identical - is it
>actually the same binary file in both cases?


Hi Tvrtko its different binary file.
Cheers,
Anusha
>Regards,
>Tvrtko
>
>>  /**
>>   * huc_ucode_xfer() - DMA's the firmware
>>   * @dev_priv: the drm device
>> @@ -157,6 +164,10 @@ void intel_huc_init(struct drm_i915_private *dev_priv)
>>  fw_path = I915_SKL_HUC_UCODE;
>>  huc_fw->major_ver_wanted = SKL_HUC_FW_MAJOR;
>>  huc_fw->minor_ver_wanted = SKL_HUC_FW_MINOR;
>> +} else if (IS_BROXTON(dev_priv)) {
>> +fw_path = I915_BXT_HUC_UCODE;
>> +huc_fw->major_ver_wanted = BXT_HUC_FW_MAJOR;
>> +huc_fw->minor_ver_wanted = BXT_HUC_FW_MINOR;
>>  }
>>
>>  huc_fw->uc_fw_path = fw_path;
>>
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams

2016-12-16 Thread Srivatsa, Anusha


>-Original Message-
>From: Chris Wilson [mailto:ch...@chris-wilson.co.uk]
>Sent: Friday, December 16, 2016 8:31 AM
>To: Hiler, Arkadiusz 
>Cc: Srivatsa, Anusha ; intel-
>g...@lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to
>getparams
>
>On Fri, Dec 16, 2016 at 05:21:38PM +0100, Arkadiusz Hiler wrote:
>> On Fri, Dec 16, 2016 at 04:12:36PM +, Chris Wilson wrote:
>> > On Fri, Dec 16, 2016 at 03:43:46PM +0100, Arkadiusz Hiler wrote:
>> > > On Thu, Dec 15, 2016 at 10:42:53PM +, Chris Wilson wrote:
>> > > > On Thu, Dec 15, 2016 at 02:29:50PM -0800, anushasr wrote:
>> > > > > From: Peter Antoine 
>> > > > >
>> > > > > This patch will allow for getparams to return the status of the HuC.
>> > > > > As the HuC has to be validated by the GuC this patch uses the
>> > > > > validated status to show when the HuC is loaded and ready for
>> > > > > use. You cannot use the loaded status as with the GuC as the
>> > > > > HuC is verified after it is loaded and is not usable until it is 
>> > > > > verified.
>> > > > >
>> > > > > v2: removed the forewakes as the registers are already force-woken.
>> > > > >  (T.Ursulin)
>> > > > > v4: rebased.
>> > > > > v5: rebased on top of drm-tip.
>> > > > > v6: rebased. Removed any reference to intel_huc.h
>> > > > > v7: rebased. Rename I915_PARAM_HAS_HUC to
>I915_PARAM_HUC_STATUS.
>> > > > > Remove intel_is_huc_valid() since it is used only in one place.
>> > > > > Put the case of I915_PARAM_HAS_HUC() in the right place.
>> > > > >
>> > > > > Signed-off-by: Peter Antoine 
>> > > > > Reviewed-by: Arkadiusz Hiler 
>> > > > > ---
>> > > > >  drivers/gpu/drm/i915/i915_drv.c | 4 
>> > > > >  drivers/gpu/drm/i915/intel_huc_loader.c | 1 -
>> > > > >  include/uapi/drm/i915_drm.h | 1 +
>> > > > >  3 files changed, 5 insertions(+), 1 deletion(-)
>> > > > >
>> > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.c
>> > > > > b/drivers/gpu/drm/i915/i915_drv.c index 85a47c2..0bc016d
>> > > > > 100644
>> > > > > --- a/drivers/gpu/drm/i915/i915_drv.c
>> > > > > +++ b/drivers/gpu/drm/i915/i915_drv.c
>> > > > > @@ -49,6 +49,7 @@
>> > > > >  #include "i915_trace.h"
>> > > > >  #include "i915_vgpu.h"
>> > > > >  #include "intel_drv.h"
>> > > > > +#include "intel_uc.h"
>> > > > >
>> > > > >  static struct drm_driver driver;
>> > > > >
>> > > > > @@ -315,6 +316,9 @@ static int i915_getparam(struct drm_device
>*dev, void *data,
>> > > > >  case I915_PARAM_MIN_EU_IN_POOL:
>> > > > >  value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
>> > > > >  break;
>> > > > > +case I915_PARAM_HUC_STATUS:
>> > > > > +value = I915_READ(HUC_STATUS2) &
>HUC_FW_VERIFIED;
>> > > >
>> > > > Same question as last time: does the device need to be awake? We
>> > > > know is one of the GT power wells, so presumably we need an
>> > > > rpm_get/rpm_put as well to access the register.
>> > > > -Chris
>> > >
>> > > I get:
>> > >
>> > > [ 1588.570174] [drm:i915_huc_load_status_info [i915]] HUC_STATUS2
>> > > PRE  24704 [ 1588.571285] [drm:intel_runtime_suspend [i915]]
>> > > Suspending device [ 1588.575768] [drm:intel_runtime_suspend
>> > > [i915]] Device suspended [ 1588.577156]
>> > > [drm:i915_huc_load_status_info [i915]] HUC_STATUS2 POST 24704 [
>> > > 1588.578259] [drm:intel_runtime_resume [i915]] Resuming device
>> > >
>> > > consistently from:
>> > >
>> > > value = I915_READ(HUC_STATUS2);
>> > > DRM_DEBUG_DRIVER("HUC_STATUS2 PRE  %d\n", value);
>> > > i915_pm_ops.runtime_suspend(dev_priv->drm.dev);
>> > >
>> > > value = I915_READ(HUC_STATUS2);
>> > > DRM_DEBUG_DRIVER("HUC_STATUS2 POST %d\n", value);
>> > > i915_pm_ops.runtime_resume(dev_priv->drm.dev);
>> >
>> > Also do the test with i915.mmio_debug= -Chris
>>
>> Same effect. Works.
Thanks Arek for confirming.

>Ok, then just mark up that we don't need rpm here so that we don't freak out in
>future scans for mmio access outside of rpm.
>-Chris
Chris, v2 as changed by Tvrtko suggests that forcewakes are removed since the 
register is force waken. Are you suggesting that adding that rpm not  being 
required in the commit message will make things much more clearer?

Anusha
>
>--
>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 3/5] drm/i915/guc: Simplify intel_guc_load()

2016-12-16 Thread Daniele Ceraolo Spurio




+
+fail:
+   /*
+* We've failed to load the firmware :(
+*
+* Decide whether to disable GuC submission and fall back to
+* execlist mode, and whether to hide the error by returning
+* zero or to return -EIO, which the caller will treat as a
+* nonfatal error (i.e. it doesn't prevent driver load, but
+* marks the GPU as wedged until reset).
+*/
+   if (i915.enable_guc_loading > 1 || i915.enable_guc_submission > 1)
+   ret = -EIO;
+   else
+   ret = 0;
+
+   if (i915.enable_guc_submission) {
+   i915.enable_guc_submission = 0;
+   DRM_INFO("GuC submission without firmware not supported\n");
+   DRM_NOTE("Falling back from GuC submission to execlist mode\n");


If i915.enable_guc_submission > 1 we will mark the GPU as wedged so it might
be worth retaining an error level message here in that scenario.


If we are wedging the GPU you do not really care about the fallback, so
theres no real use in having that promoted + those are the original
levels that were already here.

Anyway, it seems like the `enable_guc_* > 1` are likely to be gone. I've
discussed that on IRC yesterday and no one seems to really remember why
we've got it in the first place.

Anusha posted similar concern here with her HuC series as well.



Just to clarify (because as you said the case will probably go away), 
what I meant was an extra log for the > 1 case like we had in the 
original code, i.e:


DRM_ERROR("GuC init failed: %d\n", ret);

as otherwise we would have declared the GPU wedged without printing any 
error-level message to explain why.


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


[Intel-gfx] ✗ Fi.CI.BAT: failure for series starting with [1/3] drm/i915/DMC/GLK: Load DMC on GLK

2016-12-16 Thread Patchwork
== Series Details ==

Series: series starting with [1/3] drm/i915/DMC/GLK: Load DMC on GLK
URL   : https://patchwork.freedesktop.org/series/16926/
State : failure

== Summary ==

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

Test drv_module_reload:
Subgroup basic-reload-inject:
pass   -> INCOMPLETE (fi-kbl-7500u)
Test kms_pipe_crc_basic:
Subgroup suspend-read-crc-pipe-b:
pass   -> SKIP   (fi-bxt-j4205)

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:222  dwarn:0   dfail:0   fail:0   skip:25 
fi-bxt-t5700 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
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-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
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:7pass:6dwarn:0   dfail:0   fail:0   skip:0  
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:224  dwarn:3   dfail:0   fail:0   skip:20 
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 

705f1e8fef81d504f0032df8e21bdc2e74850b3a drm-tip: 2016y-12m-16d-15h-40m-02s UTC 
integration manifest
376d7cf drm/i915/glk: Convert a few more IS_BROXTON() to IS_GEN9_LP()
8c9049c drm/i915/glk: Add missing bits to allow runtime pm suspend on GLK.
2a48676 drm/i915/DMC/GLK: Load DMC on GLK

== Logs ==

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


Re: [Intel-gfx] [PATCH 2/2] drm/i915: Dump more configuration information for DSI

2016-12-16 Thread Chris Wilson
On Wed, Dec 14, 2016 at 07:14:05PM +0200, ville.syrj...@linux.intel.com wrote:
> From: Ville Syrjälä 
> 
> Dump out more of the DSI configuration details during init.
> This includes pclk, burst_mode_ratio, lane_count, pixel_overlap,
> video_mode_format and reset_timer_val.
> 
> v2: Dump more info (Chris)

dphy_reg? No idea what it is, just another one I couldn't find printed.

> Cc: Chris Wilson 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 9 +
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c 
> b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> index 3fd3bac5fccc..d2e3aa9c5022 100644
> --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> @@ -808,6 +808,15 @@ struct drm_panel *vbt_panel_init(struct intel_dsi 
> *intel_dsi, u16 panel_id)
>   8);
>   intel_dsi->clk_hs_to_lp_count += extra_byte_count;
>  
> + DRM_DEBUG_KMS("Pclk %d\n", intel_dsi->pclk);
> + DRM_DEBUG_KMS("Pixel overlap %d\n", intel_dsi->pixel_overlap);
> + DRM_DEBUG_KMS("Lane count %d\n", intel_dsi->lane_count);
> + DRM_DEBUG_KMS("Video mode format %s\n",
> +   intel_dsi->video_mode_format == NON_BURST_SYNC_PULSE ? 
> "non-burst with sync pulse" :
> +   intel_dsi->video_mode_format == NON_BURST_SYNC_EVENTS ? 
> "non-burst with sync events" :
> +   intel_dsi->video_mode_format == BURST_MODE ? "burst" : 
> "");

Argh. The mipi_config.video_transfer_mode:2 has
#define NON_BURST_SYNC_PULSE0x1
#define NON_BURST_SYNC_EVENTS   0x2
#define BURST_MODE  0x3

but intel_dist.video_mode_format is
#define  VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE   (1 << 0)
#define  VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS  (2 << 0)
#define  VIDEO_MODE_BURST   (3 << 0)

They match just usage is consistent.

However you want to resolve that,
Reviewed-by: Chris Wilson 
-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: failure for drm: Use drm_mm_nodes() as shorthand for the list of nodes under struct drm_mm

2016-12-16 Thread Patchwork
== Series Details ==

Series: drm: Use drm_mm_nodes() as shorthand for the list of nodes under struct 
drm_mm
URL   : https://patchwork.freedesktop.org/series/16920/
State : failure

== Summary ==

Series 16920v1 drm: Use drm_mm_nodes() as shorthand for the list of nodes under 
struct drm_mm
https://patchwork.freedesktop.org/api/1.0/series/16920/revisions/1/mbox/

Test gem_ctx_switch:
Subgroup basic-default:
pass   -> INCOMPLETE (fi-byt-j1900)
Test kms_pipe_crc_basic:
Subgroup suspend-read-crc-pipe-b:
pass   -> SKIP   (fi-bxt-j4205)

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:222  dwarn:0   dfail:0   fail:0   skip:25 
fi-bxt-t5700 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-j1900 total:24   pass:23   dwarn:0   dfail:0   fail:0   skip:0  
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-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
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:226  dwarn:0   dfail:0   fail:0   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:224  dwarn:3   dfail:0   fail:0   skip:20 
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 

705f1e8fef81d504f0032df8e21bdc2e74850b3a drm-tip: 2016y-12m-16d-15h-40m-02s UTC 
integration manifest
4a8cc5a drm: Use drm_mm_nodes() as shorthand for the list of nodes under struct 
drm_mm

== Logs ==

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


Re: [Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading support

2016-12-16 Thread Tvrtko Ursulin


On 16/12/2016 16:29, Arkadiusz Hiler wrote:

On Fri, Dec 16, 2016 at 04:13:14PM +, Tvrtko Ursulin wrote:


On 15/12/2016 22:29, anushasr wrote:

From: Anusha Srivatsa 

The HuC loading process is similar to GuC. The intel_uc_fw_fetch()
is used for both cases.

HuC loading needs to be before GuC loading. The WOPCM setting must
be done early before loading any of them.

v2: rebased on-top of drm-intel-nightly.
removed if(HAS_GUC()) before the guc call. (D.Gordon)
update huc_version number of format.
v3: rebased to drm-intel-nightly, changed the file name format to
match the one in the huc package.
Changed dev->dev_private to to_i915()
v4: moved function back to where it was.
change wait_for_atomic to wait_for.
v5: rebased + comment changes.
v7: rebased.
v8: rebased.
v9: rebased. Changed the year in the copyright message to reflect
the right year.Correct the comments,remove the unwanted WARN message,
replace drm_gem_object_unreference() with i915_gem_object_put().Make the
prototypes in intel_huc.h non-extern.
v10: rebased. Update the file construction done by HuC. It is similar to
GuC.Adopted the approach used in-
https://patchwork.freedesktop.org/patch/104355/ 
v11: Fix warnings remove old declaration
v12: Change dev to dev_priv in macro definition.
Corrected comments.
v13: rebased.
v14: rebased on top of drm-tip
v15: rebased. Updated functions intel_huc_load(),intel_huc_init() and
intel_uc_fw_fetch() to accept dev_priv instead of dev. Moved contents
of intel_huc.h to intel_uc.h
v16: change SKL_FW_ to SKL_HUC_FW_. Add intel_ prefix to guc_wopcm_size().
Remove unwanted checks in intel_uc.h. Rename huc_fw in struct intel_huc to
simply fw to avoid redundency.

Cc: Tvrtko Ursulin 
Tested-by: Xiang Haihao 
Signed-off-by: Anusha Srivatsa 
Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/i915/Makefile   |   1 +
 drivers/gpu/drm/i915/i915_drv.c |   4 +-
 drivers/gpu/drm/i915/i915_drv.h |   3 +-
 drivers/gpu/drm/i915/i915_guc_reg.h |   3 +
 drivers/gpu/drm/i915/intel_guc_loader.c |  11 +-
 drivers/gpu/drm/i915/intel_huc_loader.c | 264 
 drivers/gpu/drm/i915/intel_uc.h |  18 +++
 7 files changed, 297 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 5196509..45ae124 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -57,6 +57,7 @@ i915-y += i915_cmd_parser.o \
 # general-purpose microcontroller (GuC) support
 i915-y += intel_uc.o \
  intel_guc_loader.o \
+ intel_huc_loader.o \
  i915_guc_submission.o

 # autogenerated null render state
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6428588..85a47c2 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -600,6 +600,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret)
goto cleanup_irq;

+   intel_huc_init(dev_priv);
intel_guc_init(dev_priv);

ret = i915_gem_init(dev_priv);
@@ -627,6 +628,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
DRM_ERROR("failed to idle hardware; continuing to unload!\n");
i915_gem_fini(dev_priv);
 cleanup_irq:
+   intel_huc_fini(dev);
intel_guc_fini(dev_priv);
drm_irq_uninstall(dev);
intel_teardown_gmbus(dev_priv);
@@ -1313,7 +1315,7 @@ void i915_driver_unload(struct drm_device *dev)

/* Flush any outstanding unpin_work. */
drain_workqueue(dev_priv->wq);
-
+   intel_huc_fini(dev);
intel_guc_fini(dev_priv);
i915_gem_fini(dev_priv);
intel_fbc_cleanup_cfb(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4199d26..bd5f235 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2134,6 +2134,7 @@ struct drm_i915_private {

struct intel_gvt *gvt;

+   struct intel_huc huc;
struct intel_guc guc;

struct intel_csr csr;
@@ -2908,7 +2909,7 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define HAS_GUC(dev_priv)  ((dev_priv)->info.has_guc)
 #define HAS_GUC_UCODE(dev_priv)(HAS_GUC(dev_priv))
 #define HAS_GUC_SCHED(dev_priv)(HAS_GUC(dev_priv))
-
+#define HAS_HUC_UCODE(dev_priv)(HAS_GUC(dev_priv))
 #define HAS_RESOURCE_STREAMER(dev_priv) 
((dev_priv)->info.has_resource_streamer)

 #define HAS_POOLED_EU(dev_priv)((dev_priv)->info.has_pooled_eu)
diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h 
b/drivers/gpu/drm/i915/i915_guc_reg.h
index 5e638fc..f9829f6 100644
--- a/drivers/gpu/drm/i915/i915_guc_reg.h
+++ 

[Intel-gfx] ✗ Fi.CI.BAT: failure for series starting with [v2,01/40] drm/i915: Use the MRU stack search after evicting (rev3)

2016-12-16 Thread Patchwork
== Series Details ==

Series: series starting with [v2,01/40] drm/i915: Use the MRU stack search 
after evicting (rev3)
URL   : https://patchwork.freedesktop.org/series/16906/
State : failure

== Summary ==

  CC  net/ipv4/tcp_cubic.o
  CC  net/ipv4/xfrm4_policy.o
  LD  drivers/net/phy/built-in.o
  CC  net/ipv4/xfrm4_state.o
  CC  net/ipv4/xfrm4_input.o
  CC  net/ipv4/xfrm4_output.o
  CC  net/ipv4/xfrm4_protocol.o
  CC  net/ipv6/exthdrs_offload.o
  CC  net/ipv6/inet6_hashtables.o
  CC  net/ipv6/mcast_snoop.o
  LD  drivers/rtc/built-in.o
  LD  drivers/pci/pcie/pcieportdrv.o
  LD [M]  drivers/net/ethernet/intel/igbvf/igbvf.o
  LD  drivers/acpi/acpica/acpi.o
  LD  kernel/events/built-in.o
  LD  net/netlink/built-in.o
  LD  net/unix/unix_diag.o
  LD  kernel/sched/built-in.o
  LD  drivers/acpi/acpica/built-in.o
  LD  drivers/pci/pcie/aer/aerdriver.o
  LD  kernel/built-in.o
  LD  drivers/pci/pcie/aer/built-in.o
  LD  drivers/usb/gadget/libcomposite.o
  LD  drivers/usb/storage/usb-storage.o
  LD  drivers/pci/pcie/built-in.o
  LD  drivers/acpi/built-in.o
  LD  drivers/usb/storage/built-in.o
  LD  net/key/built-in.o
  LD  drivers/tty/serial/8250/8250.o
  LD [M]  drivers/usb/serial/usbserial.o
  LD  drivers/thermal/thermal_sys.o
  LD  mm/built-in.o
  LD  drivers/thermal/built-in.o
  LD [M]  drivers/misc/mei/mei-me.o
  LD  lib/raid6/raid6_pq.o
  LD  drivers/misc/built-in.o
  LD  lib/raid6/built-in.o
  LD  drivers/spi/built-in.o
  LD  drivers/iommu/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
scripts/Makefile.build:544: recipe for target 'drivers/gpu/drm' failed
make[2]: *** [drivers/gpu/drm] Error 2
scripts/Makefile.build:544: recipe for target 'drivers/gpu' failed
make[1]: *** [drivers/gpu] Error 2
make[1]: *** Waiting for unfinished jobs
  LD  net/packet/built-in.o
  LD  drivers/video/fbdev/core/fb.o
  LD  drivers/video/fbdev/core/built-in.o
  LD [M]  sound/pci/hda/snd-hda-codec-generic.o
  LD  drivers/video/fbdev/built-in.o
  LD [M]  drivers/net/ethernet/intel/e1000/e1000.o
  LD  sound/pci/built-in.o
  LD  net/unix/unix.o
  LD  net/unix/built-in.o
  LD  drivers/scsi/scsi_mod.o
  LD  drivers/video/console/built-in.o
  LD  drivers/video/built-in.o
  LD  sound/built-in.o
  LD [M]  drivers/net/ethernet/broadcom/genet/genet.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  drivers/pci/built-in.o
  LD  drivers/scsi/sd_mod.o
  LD  drivers/scsi/built-in.o
  LD [M]  drivers/net/ethernet/intel/igb/igb.o
  LD  drivers/md/md-mod.o
  AR  lib/lib.a
  LD  drivers/md/built-in.o
  EXPORTS lib/lib-ksyms.o
  CC  arch/x86/kernel/cpu/capflags.o
  LD  arch/x86/kernel/cpu/built-in.o
  LD  drivers/usb/core/usbcore.o
  LD  arch/x86/kernel/built-in.o
  LD  drivers/usb/core/built-in.o
  LD  drivers/usb/host/xhci-hcd.o
  LD  arch/x86/built-in.o
  LD  drivers/tty/vt/built-in.o
  LD  net/xfrm/built-in.o
  LD  drivers/tty/built-in.o
  LD  net/ipv6/ipv6.o
  LD  fs/btrfs/btrfs.o
  LD  net/ipv6/built-in.o
  LD  lib/built-in.o
  LD  fs/btrfs/built-in.o
  LD  fs/ext4/ext4.o
  LD  fs/ext4/built-in.o
  LD  drivers/usb/host/built-in.o
  LD  drivers/usb/built-in.o
  LD  fs/built-in.o
  LD  net/ipv4/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
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 8/8] drm/i915/get_params: Add HuC status to getparams

2016-12-16 Thread Chris Wilson
On Fri, Dec 16, 2016 at 05:21:38PM +0100, Arkadiusz Hiler wrote:
> On Fri, Dec 16, 2016 at 04:12:36PM +, Chris Wilson wrote:
> > On Fri, Dec 16, 2016 at 03:43:46PM +0100, Arkadiusz Hiler wrote:
> > > On Thu, Dec 15, 2016 at 10:42:53PM +, Chris Wilson wrote:
> > > > On Thu, Dec 15, 2016 at 02:29:50PM -0800, anushasr wrote:
> > > > > From: Peter Antoine 
> > > > > 
> > > > > This patch will allow for getparams to return the status of the HuC.
> > > > > As the HuC has to be validated by the GuC this patch uses the 
> > > > > validated
> > > > > status to show when the HuC is loaded and ready for use. You cannot 
> > > > > use
> > > > > the loaded status as with the GuC as the HuC is verified after it is
> > > > > loaded and is not usable until it is verified.
> > > > > 
> > > > > v2: removed the forewakes as the registers are already force-woken.
> > > > >  (T.Ursulin)
> > > > > v4: rebased.
> > > > > v5: rebased on top of drm-tip.
> > > > > v6: rebased. Removed any reference to intel_huc.h
> > > > > v7: rebased. Rename I915_PARAM_HAS_HUC to I915_PARAM_HUC_STATUS.
> > > > > Remove intel_is_huc_valid() since it is used only in one place.
> > > > > Put the case of I915_PARAM_HAS_HUC() in the right place.
> > > > > 
> > > > > Signed-off-by: Peter Antoine 
> > > > > Reviewed-by: Arkadiusz Hiler 
> > > > > ---
> > > > >  drivers/gpu/drm/i915/i915_drv.c | 4 
> > > > >  drivers/gpu/drm/i915/intel_huc_loader.c | 1 -
> > > > >  include/uapi/drm/i915_drm.h | 1 +
> > > > >  3 files changed, 5 insertions(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.c 
> > > > > b/drivers/gpu/drm/i915/i915_drv.c
> > > > > index 85a47c2..0bc016d 100644
> > > > > --- a/drivers/gpu/drm/i915/i915_drv.c
> > > > > +++ b/drivers/gpu/drm/i915/i915_drv.c
> > > > > @@ -49,6 +49,7 @@
> > > > >  #include "i915_trace.h"
> > > > >  #include "i915_vgpu.h"
> > > > >  #include "intel_drv.h"
> > > > > +#include "intel_uc.h"
> > > > >  
> > > > >  static struct drm_driver driver;
> > > > >  
> > > > > @@ -315,6 +316,9 @@ static int i915_getparam(struct drm_device *dev, 
> > > > > void *data,
> > > > >   case I915_PARAM_MIN_EU_IN_POOL:
> > > > >   value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
> > > > >   break;
> > > > > + case I915_PARAM_HUC_STATUS:
> > > > > + value = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED;
> > > > 
> > > > Same question as last time: does the device need to be awake? We know is
> > > > one of the GT power wells, so presumably we need an rpm_get/rpm_put as
> > > > well to access the register.
> > > > -Chris
> > > 
> > > I get:
> > > 
> > > [ 1588.570174] [drm:i915_huc_load_status_info [i915]] HUC_STATUS2 PRE  
> > > 24704
> > > [ 1588.571285] [drm:intel_runtime_suspend [i915]] Suspending device
> > > [ 1588.575768] [drm:intel_runtime_suspend [i915]] Device suspended
> > > [ 1588.577156] [drm:i915_huc_load_status_info [i915]] HUC_STATUS2 POST 
> > > 24704
> > > [ 1588.578259] [drm:intel_runtime_resume [i915]] Resuming device
> > > 
> > > consistently from:
> > > 
> > > value = I915_READ(HUC_STATUS2);
> > > DRM_DEBUG_DRIVER("HUC_STATUS2 PRE  %d\n", value);
> > > i915_pm_ops.runtime_suspend(dev_priv->drm.dev);
> > > 
> > > value = I915_READ(HUC_STATUS2);
> > > DRM_DEBUG_DRIVER("HUC_STATUS2 POST %d\n", value);
> > > i915_pm_ops.runtime_resume(dev_priv->drm.dev);
> > 
> > Also do the test with i915.mmio_debug=
> > -Chris
> 
> Same effect. Works.

Ok, then just mark up that we don't need rpm here so that we don't freak
out in future scans for mmio access outside of rpm.
-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 3/8] drm/i915/huc: Add HuC fw loading support

2016-12-16 Thread Arkadiusz Hiler
On Fri, Dec 16, 2016 at 04:13:14PM +, Tvrtko Ursulin wrote:
> 
> On 15/12/2016 22:29, anushasr wrote:
> > From: Anusha Srivatsa 
> > 
> > The HuC loading process is similar to GuC. The intel_uc_fw_fetch()
> > is used for both cases.
> > 
> > HuC loading needs to be before GuC loading. The WOPCM setting must
> > be done early before loading any of them.
> > 
> > v2: rebased on-top of drm-intel-nightly.
> > removed if(HAS_GUC()) before the guc call. (D.Gordon)
> > update huc_version number of format.
> > v3: rebased to drm-intel-nightly, changed the file name format to
> > match the one in the huc package.
> > Changed dev->dev_private to to_i915()
> > v4: moved function back to where it was.
> > change wait_for_atomic to wait_for.
> > v5: rebased + comment changes.
> > v7: rebased.
> > v8: rebased.
> > v9: rebased. Changed the year in the copyright message to reflect
> > the right year.Correct the comments,remove the unwanted WARN message,
> > replace drm_gem_object_unreference() with i915_gem_object_put().Make the
> > prototypes in intel_huc.h non-extern.
> > v10: rebased. Update the file construction done by HuC. It is similar to
> > GuC.Adopted the approach used in-
> > https://patchwork.freedesktop.org/patch/104355/ 
> > v11: Fix warnings remove old declaration
> > v12: Change dev to dev_priv in macro definition.
> > Corrected comments.
> > v13: rebased.
> > v14: rebased on top of drm-tip
> > v15: rebased. Updated functions intel_huc_load(),intel_huc_init() and
> > intel_uc_fw_fetch() to accept dev_priv instead of dev. Moved contents
> > of intel_huc.h to intel_uc.h
> > v16: change SKL_FW_ to SKL_HUC_FW_. Add intel_ prefix to guc_wopcm_size().
> > Remove unwanted checks in intel_uc.h. Rename huc_fw in struct intel_huc to
> > simply fw to avoid redundency.
> > 
> > Cc: Tvrtko Ursulin 
> > Tested-by: Xiang Haihao 
> > Signed-off-by: Anusha Srivatsa 
> > Signed-off-by: Alex Dai 
> > Signed-off-by: Peter Antoine 
> > ---
> >  drivers/gpu/drm/i915/Makefile   |   1 +
> >  drivers/gpu/drm/i915/i915_drv.c |   4 +-
> >  drivers/gpu/drm/i915/i915_drv.h |   3 +-
> >  drivers/gpu/drm/i915/i915_guc_reg.h |   3 +
> >  drivers/gpu/drm/i915/intel_guc_loader.c |  11 +-
> >  drivers/gpu/drm/i915/intel_huc_loader.c | 264 
> > 
> >  drivers/gpu/drm/i915/intel_uc.h |  18 +++
> >  7 files changed, 297 insertions(+), 7 deletions(-)
> >  create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c
> > 
> > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> > index 5196509..45ae124 100644
> > --- a/drivers/gpu/drm/i915/Makefile
> > +++ b/drivers/gpu/drm/i915/Makefile
> > @@ -57,6 +57,7 @@ i915-y += i915_cmd_parser.o \
> >  # general-purpose microcontroller (GuC) support
> >  i915-y += intel_uc.o \
> >   intel_guc_loader.o \
> > + intel_huc_loader.o \
> >   i915_guc_submission.o
> > 
> >  # autogenerated null render state
> > diff --git a/drivers/gpu/drm/i915/i915_drv.c 
> > b/drivers/gpu/drm/i915/i915_drv.c
> > index 6428588..85a47c2 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.c
> > +++ b/drivers/gpu/drm/i915/i915_drv.c
> > @@ -600,6 +600,7 @@ static int i915_load_modeset_init(struct drm_device 
> > *dev)
> > if (ret)
> > goto cleanup_irq;
> > 
> > +   intel_huc_init(dev_priv);
> > intel_guc_init(dev_priv);
> > 
> > ret = i915_gem_init(dev_priv);
> > @@ -627,6 +628,7 @@ static int i915_load_modeset_init(struct drm_device 
> > *dev)
> > DRM_ERROR("failed to idle hardware; continuing to unload!\n");
> > i915_gem_fini(dev_priv);
> >  cleanup_irq:
> > +   intel_huc_fini(dev);
> > intel_guc_fini(dev_priv);
> > drm_irq_uninstall(dev);
> > intel_teardown_gmbus(dev_priv);
> > @@ -1313,7 +1315,7 @@ void i915_driver_unload(struct drm_device *dev)
> > 
> > /* Flush any outstanding unpin_work. */
> > drain_workqueue(dev_priv->wq);
> > -
> > +   intel_huc_fini(dev);
> > intel_guc_fini(dev_priv);
> > i915_gem_fini(dev_priv);
> > intel_fbc_cleanup_cfb(dev_priv);
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h 
> > b/drivers/gpu/drm/i915/i915_drv.h
> > index 4199d26..bd5f235 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -2134,6 +2134,7 @@ struct drm_i915_private {
> > 
> > struct intel_gvt *gvt;
> > 
> > +   struct intel_huc huc;
> > struct intel_guc guc;
> > 
> > struct intel_csr csr;
> > @@ -2908,7 +2909,7 @@ intel_info(const struct drm_i915_private *dev_priv)
> >  #define HAS_GUC(dev_priv)  ((dev_priv)->info.has_guc)
> >  #define HAS_GUC_UCODE(dev_priv)(HAS_GUC(dev_priv))
> >  #define HAS_GUC_SCHED(dev_priv)(HAS_GUC(dev_priv))
> > -
> > +#define HAS_HUC_UCODE(dev_priv)(HAS_GUC(dev_priv))
> >  #define 

Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams

2016-12-16 Thread Arkadiusz Hiler
On Fri, Dec 16, 2016 at 04:12:36PM +, Chris Wilson wrote:
> On Fri, Dec 16, 2016 at 03:43:46PM +0100, Arkadiusz Hiler wrote:
> > On Thu, Dec 15, 2016 at 10:42:53PM +, Chris Wilson wrote:
> > > On Thu, Dec 15, 2016 at 02:29:50PM -0800, anushasr wrote:
> > > > From: Peter Antoine 
> > > > 
> > > > This patch will allow for getparams to return the status of the HuC.
> > > > As the HuC has to be validated by the GuC this patch uses the validated
> > > > status to show when the HuC is loaded and ready for use. You cannot use
> > > > the loaded status as with the GuC as the HuC is verified after it is
> > > > loaded and is not usable until it is verified.
> > > > 
> > > > v2: removed the forewakes as the registers are already force-woken.
> > > >  (T.Ursulin)
> > > > v4: rebased.
> > > > v5: rebased on top of drm-tip.
> > > > v6: rebased. Removed any reference to intel_huc.h
> > > > v7: rebased. Rename I915_PARAM_HAS_HUC to I915_PARAM_HUC_STATUS.
> > > > Remove intel_is_huc_valid() since it is used only in one place.
> > > > Put the case of I915_PARAM_HAS_HUC() in the right place.
> > > > 
> > > > Signed-off-by: Peter Antoine 
> > > > Reviewed-by: Arkadiusz Hiler 
> > > > ---
> > > >  drivers/gpu/drm/i915/i915_drv.c | 4 
> > > >  drivers/gpu/drm/i915/intel_huc_loader.c | 1 -
> > > >  include/uapi/drm/i915_drm.h | 1 +
> > > >  3 files changed, 5 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/i915_drv.c 
> > > > b/drivers/gpu/drm/i915/i915_drv.c
> > > > index 85a47c2..0bc016d 100644
> > > > --- a/drivers/gpu/drm/i915/i915_drv.c
> > > > +++ b/drivers/gpu/drm/i915/i915_drv.c
> > > > @@ -49,6 +49,7 @@
> > > >  #include "i915_trace.h"
> > > >  #include "i915_vgpu.h"
> > > >  #include "intel_drv.h"
> > > > +#include "intel_uc.h"
> > > >  
> > > >  static struct drm_driver driver;
> > > >  
> > > > @@ -315,6 +316,9 @@ static int i915_getparam(struct drm_device *dev, 
> > > > void *data,
> > > > case I915_PARAM_MIN_EU_IN_POOL:
> > > > value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
> > > > break;
> > > > +   case I915_PARAM_HUC_STATUS:
> > > > +   value = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED;
> > > 
> > > Same question as last time: does the device need to be awake? We know is
> > > one of the GT power wells, so presumably we need an rpm_get/rpm_put as
> > > well to access the register.
> > > -Chris
> > 
> > I get:
> > 
> > [ 1588.570174] [drm:i915_huc_load_status_info [i915]] HUC_STATUS2 PRE  24704
> > [ 1588.571285] [drm:intel_runtime_suspend [i915]] Suspending device
> > [ 1588.575768] [drm:intel_runtime_suspend [i915]] Device suspended
> > [ 1588.577156] [drm:i915_huc_load_status_info [i915]] HUC_STATUS2 POST 24704
> > [ 1588.578259] [drm:intel_runtime_resume [i915]] Resuming device
> > 
> > consistently from:
> > 
> > value = I915_READ(HUC_STATUS2);
> > DRM_DEBUG_DRIVER("HUC_STATUS2 PRE  %d\n", value);
> > i915_pm_ops.runtime_suspend(dev_priv->drm.dev);
> > 
> > value = I915_READ(HUC_STATUS2);
> > DRM_DEBUG_DRIVER("HUC_STATUS2 POST %d\n", value);
> > i915_pm_ops.runtime_resume(dev_priv->drm.dev);
> 
> Also do the test with i915.mmio_debug=
> -Chris

Same effect. Works.

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


Re: [Intel-gfx] [PATCH 5/8] drm/i915/HuC: Add KBL huC loading Support

2016-12-16 Thread Tvrtko Ursulin


On 15/12/2016 22:29, anushasr wrote:

From: Anusha Srivatsa 

This patch adds the support to load HuC on KBL
Version 2.0

v2: rebased.
v3: rebased on top of drm-tip
v4: rebased.
v5: rebased. Rename KBL_FW_ to KBL_HUC_FW_

Cc: Jeff Mcgee 
Signed-off-by: Anusha Srivatsa 
Reviewed-by: Jeff McGee 
---
 drivers/gpu/drm/i915/intel_huc_loader.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c 
b/drivers/gpu/drm/i915/intel_huc_loader.c
index f36efd4..d8c5266 100644
--- a/drivers/gpu/drm/i915/intel_huc_loader.c
+++ b/drivers/gpu/drm/i915/intel_huc_loader.c
@@ -48,6 +48,10 @@
 #define SKL_HUC_FW_MINOR 07
 #define SKL_BLD_NUM 1398

+#define KBL_HUC_FW_MAJOR 02
+#define KBL_HUC_FW_MINOR 00
+#define KBL_BLD_NUM 1810
+
 #define HUC_FW_PATH(platform, major, minor, bld_num) \
"i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \
__stringify(minor) "_" __stringify(bld_num) ".bin"
@@ -59,6 +63,11 @@ MODULE_FIRMWARE(I915_SKL_HUC_UCODE);
 #define I915_BXT_HUC_UCODE HUC_FW_PATH(bxt, BXT_HUC_FW_MAJOR, \
BXT_HUC_FW_MINOR, BXT_BLD_NUM)
 MODULE_FIRMWARE(I915_BXT_HUC_UCODE);
+
+#define I915_KBL_HUC_UCODE HUC_FW_PATH(kbl, KBL_HUC_FW_MAJOR, \
+   KBL_HUC_FW_MINOR, KBL_BLD_NUM)
+MODULE_FIRMWARE(I915_KBL_HUC_UCODE);
+
 /**
  * huc_ucode_xfer() - DMA's the firmware
  * @dev_priv: the drm device
@@ -168,8 +177,15 @@ void intel_huc_init(struct drm_i915_private *dev_priv)
fw_path = I915_BXT_HUC_UCODE;
huc_fw->major_ver_wanted = BXT_HUC_FW_MAJOR;
huc_fw->minor_ver_wanted = BXT_HUC_FW_MINOR;
+   } else if (IS_KABYLAKE(dev_priv)) {
+   fw_path = I915_KBL_HUC_UCODE;
+   huc_fw->major_ver_wanted = KBL_HUC_FW_MAJOR;
+   huc_fw->minor_ver_wanted = KBL_HUC_FW_MINOR;
}

+   if (fw_path == NULL)
+   return;
+


This looks suspiciously out of place in this patch. What's the reason 
for it?


Regards,

Tvrtko


huc_fw->uc_fw_path = fw_path;
huc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;



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


Re: [Intel-gfx] [PATCH 7/8] drm/i915/huc: Support HuC authentication

2016-12-16 Thread Arkadiusz Hiler
On Thu, Dec 15, 2016 at 02:29:49PM -0800, anushasr wrote:
> From: Peter Antoine 
> 
> The HuC authentication is done by host2guc call. The HuC RSA keys
> are sent to GuC for authentication.
> 
> v2: rebased on top of drm-intel-nightly.
> changed name format and upped version 1.7.
> v3: rebased on top of drm-intel-nightly.
> v4: changed wait_for_automic to wait_for
> v5: rebased.
> v7: rebased.
> v8: rebased.
> v9: rebased. Rename intel_huc_auh() to intel_guc_auth_huc()
> and place the prototype in intel_guc.h,correct the comments.
> v10: rebased.
> v11: rebased.
> v12: rebased on top of drm-tip
> v13: rebased. Moved intel_guc_auth_huc from i915_guc_submission.c
> to intel_uc.c.Update dev to dev_priv in intel_guc_auth_huc().
> Renamed HOST2GUC_ACTION_AUTHENTICATE_HUC TO INTEL_GUC_ACTION_
> AUTHENTICATE_HUC
> v14: rebased.
> 
> Tested-by: Xiang Haihao 
> Signed-off-by: Anusha Srivatsa 
> Signed-off-by: Alex Dai 
> Signed-off-by: Peter Antoine 
> ---
>  drivers/gpu/drm/i915/intel_guc_fwif.h   |  1 +
>  drivers/gpu/drm/i915/intel_guc_loader.c |  2 ++
>  drivers/gpu/drm/i915/intel_uc.c | 62 
> +
>  drivers/gpu/drm/i915/intel_uc.h |  1 +
>  4 files changed, 66 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h 
> b/drivers/gpu/drm/i915/intel_guc_fwif.h
> index ed1ab40..ce4e05e 100644
> --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
> +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
> @@ -506,6 +506,7 @@ enum intel_guc_action {
>   INTEL_GUC_ACTION_EXIT_S_STATE = 0x502,
>   INTEL_GUC_ACTION_SLPC_REQUEST = 0x3003,
>   INTEL_GUC_ACTION_UK_LOG_ENABLE_LOGGING = 0x0E000,
> + INTEL_GUC_ACTION_AUTHENTICATE_HUC = 0x4000,
>   INTEL_GUC_ACTION_LIMIT
>  };
>  
> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
> b/drivers/gpu/drm/i915/intel_guc_loader.c
> index 2257495..7605f36 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -529,6 +529,8 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
>   intel_uc_fw_status_repr(guc_fw->fetch_status),
>   intel_uc_fw_status_repr(guc_fw->load_status));
>  
> + intel_guc_auth_huc(dev_priv);
> +
>   if (i915.enable_guc_submission) {
>   if (i915.guc_log_level >= 0)
>   gen9_enable_guc_interrupts(dev_priv);
> diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
> index 8ae6795..b90ac57 100644
> --- a/drivers/gpu/drm/i915/intel_uc.c
> +++ b/drivers/gpu/drm/i915/intel_uc.c
> @@ -138,3 +138,65 @@ int intel_guc_log_control(struct intel_guc *guc, u32 
> control_val)
>  
>   return intel_guc_send(guc, action, ARRAY_SIZE(action));
>  }
> +
> +/**
> + * intel_guc_auth_huc() - authenticate ucode
> + * @dev_priv: the drm_i915_device
> + *
> + * Triggers a HuC fw authentication request to the GuC via intel_guc_action_
> + * authenticate_huc interface.
> + * interface.
> + */
> +void intel_guc_auth_huc(struct drm_i915_private *dev_priv)
> +{
> + struct intel_guc *guc = _priv->guc;
> + struct intel_huc *huc = _priv->huc;
> + struct i915_vma *vma;
> + int ret;
> + u32 data[2];
> +
> + /* Bypass the case where there is no HuC firmware */
> + if (huc->fw.fetch_status == INTEL_UC_FIRMWARE_NONE ||
> + huc->fw.load_status == INTEL_UC_FIRMWARE_NONE)
> + return;
> +
> + if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) {
> + DRM_ERROR("HuC: GuC fw wasn't loaded. Can't authenticate");

Why this DRM_ERROR does not have tailing "\n"?
Same goes for couple more in here.

> + return;
> + }
> +
> + if (huc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) {
> + DRM_ERROR("HuC: fw wasn't loaded. Nothing to authenticate");
> + return;
> + }
> +
> + vma = i915_gem_object_ggtt_pin(huc->fw.uc_fw_obj, NULL, 0, 0, 0);
> + if (IS_ERR(vma)) {
> + DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
> + return;
> + }
> +
> +
> + /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
> + I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
> +
> + /* Specify auth action and where public signature is. */
> + data[0] = INTEL_GUC_ACTION_AUTHENTICATE_HUC;
> + data[1] = i915_ggtt_offset(vma) + huc->fw.rsa_offset;
> +
> + ret = intel_guc_send(guc, data, ARRAY_SIZE(data));
> + if (ret) {
> + DRM_ERROR("HuC: GuC did not ack Auth request\n");
> + goto out;
> + }
> +
> + /* Check authentication status, it should be done by now */
> + ret = wait_for((I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED) > 0, 50);
> + if (ret) {
> + DRM_ERROR("HuC: Authentication failed\n");
> + goto out;
> + }
> +
> +out:
> + i915_vma_unpin(vma);
> +}

Re: [Intel-gfx] [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading Support

2016-12-16 Thread Tvrtko Ursulin


On 15/12/2016 22:29, anushasr wrote:

From: Anusha Srivatsa 

This patch adds the HuC Loading for the BXT by using
the updated file construction.

Version 1.7 of the HuC firmware.

v2: rebased.
v3: rebased on top of drm-tip
v4: rebased.
v5: rebased. Rename BXT_FW_MAJOR to BXT_HUC_FW_

Cc: Jeff Mcgee 
Signed-off-by: Anusha Srivatsa 
Reviewed-by: Jeff McGee 
---
 drivers/gpu/drm/i915/intel_huc_loader.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c 
b/drivers/gpu/drm/i915/intel_huc_loader.c
index 0f929cc..f36efd4 100644
--- a/drivers/gpu/drm/i915/intel_huc_loader.c
+++ b/drivers/gpu/drm/i915/intel_huc_loader.c
@@ -40,6 +40,10 @@
  * Note that HuC firmware loading must be done before GuC loading.
  */

+#define BXT_HUC_FW_MAJOR 01
+#define BXT_HUC_FW_MINOR 07
+#define BXT_BLD_NUM 1398
+
 #define SKL_HUC_FW_MAJOR 01
 #define SKL_HUC_FW_MINOR 07
 #define SKL_BLD_NUM 1398
@@ -52,6 +56,9 @@
SKL_HUC_FW_MINOR, SKL_BLD_NUM)
 MODULE_FIRMWARE(I915_SKL_HUC_UCODE);

+#define I915_BXT_HUC_UCODE HUC_FW_PATH(bxt, BXT_HUC_FW_MAJOR, \
+   BXT_HUC_FW_MINOR, BXT_BLD_NUM)
+MODULE_FIRMWARE(I915_BXT_HUC_UCODE);


More curiosity - given the versions between SKL and BXT are identical - 
is it actually the same binary file in both cases?


Regards,

Tvrtko


 /**
  * huc_ucode_xfer() - DMA's the firmware
  * @dev_priv: the drm device
@@ -157,6 +164,10 @@ void intel_huc_init(struct drm_i915_private *dev_priv)
fw_path = I915_SKL_HUC_UCODE;
huc_fw->major_ver_wanted = SKL_HUC_FW_MAJOR;
huc_fw->minor_ver_wanted = SKL_HUC_FW_MINOR;
+   } else if (IS_BROXTON(dev_priv)) {
+   fw_path = I915_BXT_HUC_UCODE;
+   huc_fw->major_ver_wanted = BXT_HUC_FW_MAJOR;
+   huc_fw->minor_ver_wanted = BXT_HUC_FW_MINOR;
}

huc_fw->uc_fw_path = fw_path;


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


Re: [Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading support

2016-12-16 Thread Tvrtko Ursulin


On 15/12/2016 22:29, anushasr wrote:

From: Anusha Srivatsa 

The HuC loading process is similar to GuC. The intel_uc_fw_fetch()
is used for both cases.

HuC loading needs to be before GuC loading. The WOPCM setting must
be done early before loading any of them.

v2: rebased on-top of drm-intel-nightly.
removed if(HAS_GUC()) before the guc call. (D.Gordon)
update huc_version number of format.
v3: rebased to drm-intel-nightly, changed the file name format to
match the one in the huc package.
Changed dev->dev_private to to_i915()
v4: moved function back to where it was.
change wait_for_atomic to wait_for.
v5: rebased + comment changes.
v7: rebased.
v8: rebased.
v9: rebased. Changed the year in the copyright message to reflect
the right year.Correct the comments,remove the unwanted WARN message,
replace drm_gem_object_unreference() with i915_gem_object_put().Make the
prototypes in intel_huc.h non-extern.
v10: rebased. Update the file construction done by HuC. It is similar to
GuC.Adopted the approach used in-
https://patchwork.freedesktop.org/patch/104355/ 
v11: Fix warnings remove old declaration
v12: Change dev to dev_priv in macro definition.
Corrected comments.
v13: rebased.
v14: rebased on top of drm-tip
v15: rebased. Updated functions intel_huc_load(),intel_huc_init() and
intel_uc_fw_fetch() to accept dev_priv instead of dev. Moved contents
of intel_huc.h to intel_uc.h
v16: change SKL_FW_ to SKL_HUC_FW_. Add intel_ prefix to guc_wopcm_size().
Remove unwanted checks in intel_uc.h. Rename huc_fw in struct intel_huc to
simply fw to avoid redundency.

Cc: Tvrtko Ursulin 
Tested-by: Xiang Haihao 
Signed-off-by: Anusha Srivatsa 
Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/i915/Makefile   |   1 +
 drivers/gpu/drm/i915/i915_drv.c |   4 +-
 drivers/gpu/drm/i915/i915_drv.h |   3 +-
 drivers/gpu/drm/i915/i915_guc_reg.h |   3 +
 drivers/gpu/drm/i915/intel_guc_loader.c |  11 +-
 drivers/gpu/drm/i915/intel_huc_loader.c | 264 
 drivers/gpu/drm/i915/intel_uc.h |  18 +++
 7 files changed, 297 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 5196509..45ae124 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -57,6 +57,7 @@ i915-y += i915_cmd_parser.o \
 # general-purpose microcontroller (GuC) support
 i915-y += intel_uc.o \
  intel_guc_loader.o \
+ intel_huc_loader.o \
  i915_guc_submission.o

 # autogenerated null render state
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6428588..85a47c2 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -600,6 +600,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret)
goto cleanup_irq;

+   intel_huc_init(dev_priv);
intel_guc_init(dev_priv);

ret = i915_gem_init(dev_priv);
@@ -627,6 +628,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
DRM_ERROR("failed to idle hardware; continuing to unload!\n");
i915_gem_fini(dev_priv);
 cleanup_irq:
+   intel_huc_fini(dev);
intel_guc_fini(dev_priv);
drm_irq_uninstall(dev);
intel_teardown_gmbus(dev_priv);
@@ -1313,7 +1315,7 @@ void i915_driver_unload(struct drm_device *dev)

/* Flush any outstanding unpin_work. */
drain_workqueue(dev_priv->wq);
-
+   intel_huc_fini(dev);
intel_guc_fini(dev_priv);
i915_gem_fini(dev_priv);
intel_fbc_cleanup_cfb(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4199d26..bd5f235 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2134,6 +2134,7 @@ struct drm_i915_private {

struct intel_gvt *gvt;

+   struct intel_huc huc;
struct intel_guc guc;

struct intel_csr csr;
@@ -2908,7 +2909,7 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define HAS_GUC(dev_priv)  ((dev_priv)->info.has_guc)
 #define HAS_GUC_UCODE(dev_priv)(HAS_GUC(dev_priv))
 #define HAS_GUC_SCHED(dev_priv)(HAS_GUC(dev_priv))
-
+#define HAS_HUC_UCODE(dev_priv)(HAS_GUC(dev_priv))
 #define HAS_RESOURCE_STREAMER(dev_priv) 
((dev_priv)->info.has_resource_streamer)

 #define HAS_POOLED_EU(dev_priv)((dev_priv)->info.has_pooled_eu)
diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h 
b/drivers/gpu/drm/i915/i915_guc_reg.h
index 5e638fc..f9829f6 100644
--- a/drivers/gpu/drm/i915/i915_guc_reg.h
+++ b/drivers/gpu/drm/i915/i915_guc_reg.h
@@ -61,9 +61,12 @@
 #define   DMA_ADDRESS_SPACE_GTT  (8 << 16)
 #define DMA_COPY_SIZE  

Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams

2016-12-16 Thread Chris Wilson
On Fri, Dec 16, 2016 at 03:43:46PM +0100, Arkadiusz Hiler wrote:
> On Thu, Dec 15, 2016 at 10:42:53PM +, Chris Wilson wrote:
> > On Thu, Dec 15, 2016 at 02:29:50PM -0800, anushasr wrote:
> > > From: Peter Antoine 
> > > 
> > > This patch will allow for getparams to return the status of the HuC.
> > > As the HuC has to be validated by the GuC this patch uses the validated
> > > status to show when the HuC is loaded and ready for use. You cannot use
> > > the loaded status as with the GuC as the HuC is verified after it is
> > > loaded and is not usable until it is verified.
> > > 
> > > v2: removed the forewakes as the registers are already force-woken.
> > >  (T.Ursulin)
> > > v4: rebased.
> > > v5: rebased on top of drm-tip.
> > > v6: rebased. Removed any reference to intel_huc.h
> > > v7: rebased. Rename I915_PARAM_HAS_HUC to I915_PARAM_HUC_STATUS.
> > > Remove intel_is_huc_valid() since it is used only in one place.
> > > Put the case of I915_PARAM_HAS_HUC() in the right place.
> > > 
> > > Signed-off-by: Peter Antoine 
> > > Reviewed-by: Arkadiusz Hiler 
> > > ---
> > >  drivers/gpu/drm/i915/i915_drv.c | 4 
> > >  drivers/gpu/drm/i915/intel_huc_loader.c | 1 -
> > >  include/uapi/drm/i915_drm.h | 1 +
> > >  3 files changed, 5 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.c 
> > > b/drivers/gpu/drm/i915/i915_drv.c
> > > index 85a47c2..0bc016d 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.c
> > > +++ b/drivers/gpu/drm/i915/i915_drv.c
> > > @@ -49,6 +49,7 @@
> > >  #include "i915_trace.h"
> > >  #include "i915_vgpu.h"
> > >  #include "intel_drv.h"
> > > +#include "intel_uc.h"
> > >  
> > >  static struct drm_driver driver;
> > >  
> > > @@ -315,6 +316,9 @@ static int i915_getparam(struct drm_device *dev, void 
> > > *data,
> > >   case I915_PARAM_MIN_EU_IN_POOL:
> > >   value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
> > >   break;
> > > + case I915_PARAM_HUC_STATUS:
> > > + value = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED;
> > 
> > Same question as last time: does the device need to be awake? We know is
> > one of the GT power wells, so presumably we need an rpm_get/rpm_put as
> > well to access the register.
> > -Chris
> 
> I get:
> 
> [ 1588.570174] [drm:i915_huc_load_status_info [i915]] HUC_STATUS2 PRE  24704
> [ 1588.571285] [drm:intel_runtime_suspend [i915]] Suspending device
> [ 1588.575768] [drm:intel_runtime_suspend [i915]] Device suspended
> [ 1588.577156] [drm:i915_huc_load_status_info [i915]] HUC_STATUS2 POST 24704
> [ 1588.578259] [drm:intel_runtime_resume [i915]] Resuming device
> 
> consistently from:
> 
> value = I915_READ(HUC_STATUS2);
> DRM_DEBUG_DRIVER("HUC_STATUS2 PRE  %d\n", value);
> i915_pm_ops.runtime_suspend(dev_priv->drm.dev);
> 
> value = I915_READ(HUC_STATUS2);
> DRM_DEBUG_DRIVER("HUC_STATUS2 POST %d\n", value);
> i915_pm_ops.runtime_resume(dev_priv->drm.dev);

Also do the test with i915.mmio_debug=
-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] Guc parameter Handling

2016-12-16 Thread Arkadiusz Hiler
On Thu, Dec 15, 2016 at 10:36:40PM +, Srivatsa, Anusha wrote:
> Hi All,
> 
> I was wondering if we intend to keep -1 and 2 for the
> enable_guc_submission parameter. Since now we are gating guc loads if
> either guc_submission or enable_huc parameter is set, why have a
> -1(platform default) and 2(forcefully load) option? We anyway do not
> have any special default set per platform. For now the default is 0 on
> all platforms. Moving forward if GuC gets more stable and we want to
> set a default to a certain platform, we can add -1 then.
> 
> Also, why have a 2? We can use enable_guc_submission=1 in order to
> make sure the guc is loaded and guc_submission is enabled and set
> enable_guc_submission=0 to make sure guc submission is not used.

I've asked around on IRC yesterday for the exact same thing, and it
seems that no one realy does remembery why the "2" was introduced in the
first place.

We not simplifying it, if we do not have real use case for having 1 and
2 separate?

> Any thought on this?

> Cheers,
> Anusha

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


Re: [Intel-gfx] [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general

2016-12-16 Thread Tvrtko Ursulin


On 15/12/2016 22:29, anushasr wrote:

From: Peter Antoine 

Rename some of the GuC fw loading code to make them more general. We
will utilise them for HuC loading as well.
 s/intel_guc_fw/intel_uc_fw/g
 s/GUC_FIRMWARE/UC_FIRMWARE/g

Struct intel_guc_fw is renamed to intel_uc_fw. Prefix of tts members,
such as 'guc' or 'guc_fw' either is renamed to 'uc' or removed for
same purpose.

v2: rebased on top of nightly.
reapplied the search/replace as upstream code as changed.
v3: rebased again on drm-nightly.
v4: removed G from messages in shared fw fetch function.
v5: rebased.
v7: rebased.
v8: rebased.
v9: rebased.
v10: rebased.
v11: rebased.
v12: rebased on top of drm-tip
v13: rebased.Updated dev to dev_priv in intel_guc_setup(), guc_fw_getch()
and intel_guc_init().
v14: rebased. Remove uint32_t fw_type to patch 2. Add INTEL_ prefix for
fields in enum intel_uc_fw_status. Remove uc_dev field since its never
used.Rename uc_fw to just fw and guc_fw to fw to avoid redundency.

Signed-off-by: Anusha Srivatsa 
Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/i915/i915_debugfs.c|  12 +--
 drivers/gpu/drm/i915/i915_guc_submission.c |   4 +-
 drivers/gpu/drm/i915/intel_guc_loader.c| 157 +++--
 drivers/gpu/drm/i915/intel_uc.h|  36 +++
 4 files changed, 105 insertions(+), 104 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 15deb2b..008afe6 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2328,7 +2328,7 @@ static int i915_llc(struct seq_file *m, void *data)
 static int i915_guc_load_status_info(struct seq_file *m, void *data)
 {
struct drm_i915_private *dev_priv = node_to_i915(m->private);
-   struct intel_guc_fw *guc_fw = _priv->guc.guc_fw;
+   struct intel_uc_fw *guc_fw = _priv->guc.fw;
u32 tmp, i;

if (!HAS_GUC_UCODE(dev_priv))
@@ -2336,15 +2336,15 @@ static int i915_guc_load_status_info(struct seq_file 
*m, void *data)

seq_printf(m, "GuC firmware status:\n");
seq_printf(m, "\tpath: %s\n",
-   guc_fw->guc_fw_path);
+   guc_fw->uc_fw_path);
seq_printf(m, "\tfetch: %s\n",
-   intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
+   intel_uc_fw_status_repr(guc_fw->fetch_status));
seq_printf(m, "\tload: %s\n",
-   intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
+   intel_uc_fw_status_repr(guc_fw->load_status));
seq_printf(m, "\tversion wanted: %d.%d\n",
-   guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
+   guc_fw->major_ver_wanted, guc_fw->minor_ver_wanted);
seq_printf(m, "\tversion found: %d.%d\n",
-   guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found);
+   guc_fw->major_ver_found, guc_fw->minor_ver_found);
seq_printf(m, "\theader: offset is %d; size = %d\n",
guc_fw->header_offset, guc_fw->header_size);
seq_printf(m, "\tuCode: offset is %d; size = %d\n",
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c 
b/drivers/gpu/drm/i915/i915_guc_submission.c
index 7fa4e74..b8ad8ff 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -1493,7 +1493,7 @@ int intel_guc_suspend(struct drm_i915_private *dev_priv)
struct i915_gem_context *ctx;
u32 data[3];

-   if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS)
+   if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
return 0;

gen9_disable_guc_interrupts(dev_priv);
@@ -1520,7 +1520,7 @@ int intel_guc_resume(struct drm_i915_private *dev_priv)
struct i915_gem_context *ctx;
u32 data[3];

-   if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS)
+   if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
return 0;

if (i915.guc_log_level >= 0)
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index 21db697..9b3dbea 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -81,16 +81,16 @@ MODULE_FIRMWARE(I915_BXT_GUC_UCODE);
 MODULE_FIRMWARE(I915_KBL_GUC_UCODE);

 /* User-friendly representation of an enum */
-const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status)
+const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status)
 {
switch (status) {
-   case GUC_FIRMWARE_FAIL:
+   case INTEL_UC_FIRMWARE_FAIL:
return "FAIL";
-   case GUC_FIRMWARE_NONE:
+   case INTEL_UC_FIRMWARE_NONE:
return "NONE";
-   case GUC_FIRMWARE_PENDING:
+   case INTEL_UC_FIRMWARE_PENDING:
return "PENDING";
-   case 

Re: [Intel-gfx] [PATCH 5/5] drm/i915/guc: Simplify guc_fw_path

2016-12-16 Thread Tvrtko Ursulin


On 15/12/2016 15:47, Arkadiusz Hiler wrote:

Currently guc_fw_path values can represent one of three possible states:

 1) NULL - device without GuC
 2) '\0' - device with GuC but no known firmware
 3) else - device with GuC and known firmware

Second case is used only to WARN at the later stage.

We can WARN right away and merge cases 1 and 2 for later handling.

Cc: Anusha Srivatsa 
Cc: Jeff McGee 
Cc: Michal Winiarski 
Signed-off-by: Arkadiusz Hiler 
---
 drivers/gpu/drm/i915/intel_guc_loader.c | 22 +++---
 1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index 0bb5fd1..075a103 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -460,12 +460,8 @@ int intel_guc_load(struct drm_i915_private *dev_priv)
intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));

if (fw_path == NULL) {
-   /* Device is known to have no uCode (e.g. no GuC) */
+   /* We do not have uCode for the device */
return -ENXIO;
-   } else if (*fw_path == '\0') {
-   /* Device has a GuC but we don't know what f/w to load? */
-   WARN(1, "No GuC firmware known for this platform!\n");
-   return -ENODEV;
}

/* Fetch failed, or already fetched but failed to load? */
@@ -628,11 +624,9 @@ static void guc_fw_fetch(struct drm_i915_private *dev_priv,
 void intel_guc_init(struct drm_i915_private *dev_priv)
 {
struct intel_guc_fw *guc_fw = _priv->guc.guc_fw;
-   const char *fw_path;
+   const char *fw_path = NULL;

-   if (!HAS_GUC_UCODE(dev_priv)) {
-   fw_path = NULL;
-   } else if (IS_SKYLAKE(dev_priv)) {
+   if (IS_SKYLAKE(dev_priv)) {
fw_path = I915_SKL_GUC_UCODE;
guc_fw->guc_fw_major_wanted = SKL_FW_MAJOR;
guc_fw->guc_fw_minor_wanted = SKL_FW_MINOR;
@@ -644,24 +638,22 @@ void intel_guc_init(struct drm_i915_private *dev_priv)
fw_path = I915_KBL_GUC_UCODE;
guc_fw->guc_fw_major_wanted = KBL_FW_MAJOR;
guc_fw->guc_fw_minor_wanted = KBL_FW_MINOR;
-   } else {
-   fw_path = ""; /* unknown device */
+   } else if (HAS_GUC_UCODE(dev_priv)) {
+   WARN(1, "No GuC firmware known for platform with GuC!\n");


I think you should also set i915.enable_guc_loading to zero here to 
avoid the later stages bothering with partial setup and cleanup.


intel_uc_load specifically I think would with this patch run some setup 
then immediately fail and have to unwind.


Regards,

Tvrtko


}

guc_fw->guc_fw_path = fw_path;
guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_NONE;
guc_fw->guc_fw_load_status = GUC_FIRMWARE_NONE;

-   /* Early (and silent) return if GuC loading is disabled */
+   /* Early return if we do not have firmware to fetch */
if (fw_path == NULL)
return;
-   if (*fw_path == '\0')
-   return;

guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_PENDING;
DRM_DEBUG_DRIVER("GuC firmware pending, path %s\n", fw_path);
+
guc_fw_fetch(dev_priv, guc_fw);
-   /* status must now be FAIL or SUCCESS */
 }

 /**


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


Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams

2016-12-16 Thread Arkadiusz Hiler
On Thu, Dec 15, 2016 at 02:29:50PM -0800, anushasr wrote:
> From: Peter Antoine 
> 
> This patch will allow for getparams to return the status of the HuC.
> As the HuC has to be validated by the GuC this patch uses the validated
> status to show when the HuC is loaded and ready for use. You cannot use
> the loaded status as with the GuC as the HuC is verified after it is
> loaded and is not usable until it is verified.
> 
> v2: removed the forewakes as the registers are already force-woken.
>  (T.Ursulin)
> v4: rebased.
> v5: rebased on top of drm-tip.
> v6: rebased. Removed any reference to intel_huc.h
> v7: rebased. Rename I915_PARAM_HAS_HUC to I915_PARAM_HUC_STATUS.
> Remove intel_is_huc_valid() since it is used only in one place.
> Put the case of I915_PARAM_HAS_HUC() in the right place.
> 
> Signed-off-by: Peter Antoine 
> Reviewed-by: Arkadiusz Hiler 

You've retained my rb without asking me.

With the changes you've made and confirmation that MEDIA FW that
I915_READ() assumes:

Reviewed-by: Arkadiusz Hiler 

> ---
>  drivers/gpu/drm/i915/i915_drv.c | 4 
>  drivers/gpu/drm/i915/intel_huc_loader.c | 1 -
>  include/uapi/drm/i915_drm.h | 1 +
>  3 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 85a47c2..0bc016d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -49,6 +49,7 @@
>  #include "i915_trace.h"
>  #include "i915_vgpu.h"
>  #include "intel_drv.h"
> +#include "intel_uc.h"
>  
>  static struct drm_driver driver;
>  
> @@ -315,6 +316,9 @@ static int i915_getparam(struct drm_device *dev, void 
> *data,
>   case I915_PARAM_MIN_EU_IN_POOL:
>   value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
>   break;
> + case I915_PARAM_HUC_STATUS:
> + value = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED;
> + break;
>   case I915_PARAM_MMAP_GTT_VERSION:
>   /* Though we've started our numbering from 1, and so class all
>* earlier versions as 0, in effect their value is undefined as
> diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c 
> b/drivers/gpu/drm/i915/intel_huc_loader.c
> index d8c5266..b06a613 100644
> --- a/drivers/gpu/drm/i915/intel_huc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_huc_loader.c
> @@ -288,4 +288,3 @@ void intel_huc_fini(struct drm_device *dev)
>  
>   huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
>  }
> -
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index da32c2f..57093b4 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -395,6 +395,7 @@ typedef struct drm_i915_irq_wait {
>   * priorities and the driver will attempt to execute batches in priority 
> order.
>   */
>  #define I915_PARAM_HAS_SCHEDULER  41
> +#define I915_PARAM_HUC_STATUS 42
>  
>  typedef struct drm_i915_getparam {
>   __s32 param;
> -- 
> 2.7.4
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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


Re: [Intel-gfx] [PATCH 3/5] drm/i915/guc: Simplify intel_guc_load()

2016-12-16 Thread Tvrtko Ursulin


On 15/12/2016 15:47, Arkadiusz Hiler wrote:

Current version of intel_guc_load() does a lot:
 - cares about submission
 - loads huc


Not yet, no? So instead you could say that you are preparing the 
groundworks to make adding in the HuC fit better.



 - implement WA

This change offloads some of the logic to intel_uc_load(), which now
cares about the above.

Cc: Anusha Srivatsa 
Cc: Jeff McGee 
Cc: Michal Winiarski 
Signed-off-by: Arkadiusz Hiler 
---
 drivers/gpu/drm/i915/i915_gem.c |   2 +-
 drivers/gpu/drm/i915/intel_guc_loader.c | 126 +---
 drivers/gpu/drm/i915/intel_uc.c |  83 +
 drivers/gpu/drm/i915/intel_uc.h |   8 ++
 4 files changed, 110 insertions(+), 109 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6af4e85..76b52c6 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4412,7 +4412,7 @@ i915_gem_init_hw(struct drm_i915_private *dev_priv)
intel_mocs_init_l3cc_table(dev_priv);

/* We can't enable contexts until all firmware is loaded */
-   ret = intel_guc_load(dev_priv);
+   ret = intel_uc_load(dev_priv);
if (ret)
goto out;

diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index f8b28b1..b76b556 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -97,7 +97,7 @@ const char *intel_guc_fw_status_repr(enum intel_guc_fw_status 
status)
}
 };

-static void guc_interrupts_release(struct drm_i915_private *dev_priv)
+void guc_interrupts_release(struct drm_i915_private *dev_priv)
 {
struct intel_engine_cs *engine;
enum intel_engine_id id;
@@ -115,7 +115,7 @@ static void guc_interrupts_release(struct drm_i915_private 
*dev_priv)
I915_WRITE(GUC_WD_VECS_IER, 0);
 }

-static void guc_interrupts_capture(struct drm_i915_private *dev_priv)
+void guc_interrupts_capture(struct drm_i915_private *dev_priv)
 {
struct intel_engine_cs *engine;
enum intel_engine_id id;
@@ -334,7 +334,7 @@ static int guc_ucode_xfer_dma(struct drm_i915_private 
*dev_priv,
return ret;
 }

-static u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
+u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
 {
u32 wopcm_size = GUC_WOPCM_TOP;

@@ -417,7 +417,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
return ret;
 }

-static int guc_hw_reset(struct drm_i915_private *dev_priv)
+int guc_hw_reset(struct drm_i915_private *dev_priv)
 {
int ret;
u32 guc_status;
@@ -452,75 +452,37 @@ int intel_guc_load(struct drm_i915_private *dev_priv)
 {
struct intel_guc_fw *guc_fw = _priv->guc.guc_fw;
const char *fw_path = guc_fw->guc_fw_path;
-   int retries, ret, err;
+   int ret;

DRM_DEBUG_DRIVER("GuC fw status: path %s, fetch %s, load %s\n",
fw_path,
intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));

-   /* Loading forbidden, or no firmware to load? */
-   if (!i915.enable_guc_loading) {
-   err = 0;
-   goto fail;
-   } else if (fw_path == NULL) {
+   if (fw_path == NULL) {
/* Device is known to have no uCode (e.g. no GuC) */
-   err = -ENXIO;
-   goto fail;
+   return -ENXIO;
} else if (*fw_path == '\0') {
/* Device has a GuC but we don't know what f/w to load? */
WARN(1, "No GuC firmware known for this platform!\n");
-   err = -ENODEV;
-   goto fail;
+   return -ENODEV;
}

/* Fetch failed, or already fetched but failed to load? */
if (guc_fw->guc_fw_fetch_status != GUC_FIRMWARE_SUCCESS) {
-   err = -EIO;
-   goto fail;
+   return -EIO;
} else if (guc_fw->guc_fw_load_status == GUC_FIRMWARE_FAIL) {
-   err = -ENOEXEC;
-   goto fail;
+   return -ENOEXEC;
}

-   guc_interrupts_release(dev_priv);
-   gen9_reset_guc_interrupts(dev_priv);
-
guc_fw->guc_fw_load_status = GUC_FIRMWARE_PENDING;

-   DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n",
-   intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
-   intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
-
-   err = i915_guc_submission_init(dev_priv);
-   if (err)
-   goto fail;
-
-   /*
-* WaEnableuKernelHeaderValidFix:skl,bxt
-* For BXT, this is only upto B0 but below WA is required for later
-* steppings also so this is extended as well.
-*/
/* 

[Intel-gfx] [drm-intel:drm-intel-nightly 922/930] include/linux/list.h:385:29: error: initialization discards 'const' qualifier from pointer target type

2016-12-16 Thread kbuild test robot
tree:   git://anongit.freedesktop.org/drm-intel drm-intel-nightly
head:   ca1c03136b168816ac65c5945776908e464fca6b
commit: 45b186f111f1623b257d183920cd4aab16a1acd5 [922/930] drm: Constify the 
drm_mm API
config: x86_64-randconfig-x008-201650 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
git checkout 45b186f111f1623b257d183920cd4aab16a1acd5
# save the attached .config to linux build tree
make ARCH=x86_64 

All errors (new ones prefixed by >>):

   In file included from include/linux/mutex.h:14:0,
from include/linux/seq_file.h:7,
from drivers/gpu/drm/i915/i915_gem_gtt.c:26:
   drivers/gpu/drm/i915/i915_gem_gtt.c: In function 'i915_gtt_color_adjust':
>> include/linux/list.h:385:29: error: initialization discards 'const' 
>> qualifier from pointer target type [-Werror=discarded-qualifiers]
 struct list_head *head__ = (ptr); \
^
   drivers/gpu/drm/i915/i915_gem_gtt.c:2732:9: note: in expansion of macro 
'list_first_entry_or_null'
 node = list_first_entry_or_null(>node_list,
^~~~
   cc1: all warnings being treated as errors

vim +/const +385 include/linux/list.h

3943f42c Andrey Utkin  2014-11-14  369   * @member: the name of the 
list_head within the struct.
93be3c2e Oleg Nesterov 2013-11-12  370   *
93be3c2e Oleg Nesterov 2013-11-12  371   * Note, that list is expected to be 
not empty.
93be3c2e Oleg Nesterov 2013-11-12  372   */
93be3c2e Oleg Nesterov 2013-11-12  373  #define list_last_entry(ptr, type, 
member) \
93be3c2e Oleg Nesterov 2013-11-12  374  list_entry((ptr)->prev, type, 
member)
93be3c2e Oleg Nesterov 2013-11-12  375  
93be3c2e Oleg Nesterov 2013-11-12  376  /**
6d7581e6 Jiri Pirko2013-05-29  377   * list_first_entry_or_null - get the 
first element from a list
6d7581e6 Jiri Pirko2013-05-29  378   * @ptr:the list head to take 
the element from.
6d7581e6 Jiri Pirko2013-05-29  379   * @type:   the type of the struct 
this is embedded in.
3943f42c Andrey Utkin  2014-11-14  380   * @member: the name of the 
list_head within the struct.
6d7581e6 Jiri Pirko2013-05-29  381   *
6d7581e6 Jiri Pirko2013-05-29  382   * Note that if the list is empty, it 
returns NULL.
6d7581e6 Jiri Pirko2013-05-29  383   */
12adfd88 Chris Wilson  2016-07-23  384  #define list_first_entry_or_null(ptr, 
type, member) ({ \
12adfd88 Chris Wilson  2016-07-23 @385  struct list_head *head__ = 
(ptr); \
12adfd88 Chris Wilson  2016-07-23  386  struct list_head *pos__ = 
READ_ONCE(head__->next); \
12adfd88 Chris Wilson  2016-07-23  387  pos__ != head__ ? 
list_entry(pos__, type, member) : NULL; \
12adfd88 Chris Wilson  2016-07-23  388  })
6d7581e6 Jiri Pirko2013-05-29  389  
6d7581e6 Jiri Pirko2013-05-29  390  /**
008208c6 Oleg Nesterov 2013-11-12  391   * list_next_entry - get the next 
element in list
008208c6 Oleg Nesterov 2013-11-12  392   * @pos:the type * to cursor
3943f42c Andrey Utkin  2014-11-14  393   * @member: the name of the 
list_head within the struct.

:: The code at line 385 was first introduced by commit
:: 12adfd882c5f37548acaba4f043a158b3c54468b list: Expand 
list_first_entry_or_null()

:: TO: Chris Wilson 
:: CC: Paul E. McKenney 

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/3] drm/i915/glk: Add missing bits to allow runtime pm suspend on GLK.

2016-12-16 Thread Ander Conselvan de Oliveira
From: Rodrigo Vivi 

Besides having the DMC firmware in place and loaded let's
handle runtime suspend and dc9 as we do for Broxton.

Cc: Ander Conselvan de Oliveira 
Signed-off-by: Rodrigo Vivi 
Reviewed-by: Ander Conselvan de Oliveira 
---
 drivers/gpu/drm/i915/i915_drv.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6428588..034de9a 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1472,7 +1472,7 @@ static int i915_drm_suspend_late(struct drm_device *dev, 
bool hibernation)
 
intel_display_set_init_power(dev_priv, false);
 
-   fw_csr = !IS_BROXTON(dev_priv) &&
+   fw_csr = !IS_GEN9_LP(dev_priv) &&
suspend_to_idle(dev_priv) && dev_priv->csr.dmc_payload;
/*
 * In case of firmware assisted context save/restore don't manually
@@ -1485,7 +1485,7 @@ static int i915_drm_suspend_late(struct drm_device *dev, 
bool hibernation)
intel_power_domains_suspend(dev_priv);
 
ret = 0;
-   if (IS_BROXTON(dev_priv))
+   if (IS_GEN9_LP(dev_priv))
bxt_enable_dc9(dev_priv);
else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
hsw_enable_pc8(dev_priv);
@@ -1693,7 +1693,7 @@ static int i915_drm_resume_early(struct drm_device *dev)
 
intel_uncore_early_sanitize(dev_priv, true);
 
-   if (IS_BROXTON(dev_priv)) {
+   if (IS_GEN9_LP(dev_priv)) {
if (!dev_priv->suspended_to_idle)
gen9_sanitize_dc_state(dev_priv);
bxt_disable_dc9(dev_priv);
@@ -1703,7 +1703,7 @@ static int i915_drm_resume_early(struct drm_device *dev)
 
intel_uncore_sanitize(dev_priv);
 
-   if (IS_BROXTON(dev_priv) ||
+   if (IS_GEN9_LP(dev_priv) ||
!(dev_priv->suspended_to_idle && dev_priv->csr.dmc_payload))
intel_power_domains_init_hw(dev_priv, true);
 
@@ -2326,7 +2326,7 @@ static int intel_runtime_suspend(struct device *kdev)
intel_runtime_pm_disable_interrupts(dev_priv);
 
ret = 0;
-   if (IS_BROXTON(dev_priv)) {
+   if (IS_GEN9_LP(dev_priv)) {
bxt_display_core_uninit(dev_priv);
bxt_enable_dc9(dev_priv);
} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
@@ -2411,7 +2411,7 @@ static int intel_runtime_resume(struct device *kdev)
if (IS_GEN6(dev_priv))
intel_init_pch_refclk(dev_priv);
 
-   if (IS_BROXTON(dev_priv)) {
+   if (IS_GEN9_LP(dev_priv)) {
bxt_disable_dc9(dev_priv);
bxt_display_core_init(dev_priv, true);
if (dev_priv->csr.dmc_payload &&
-- 
2.5.5

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


[Intel-gfx] [PATCH 1/3] drm/i915/DMC/GLK: Load DMC on GLK

2016-12-16 Thread Ander Conselvan de Oliveira
From: Anusha Srivatsa 

This patch loads the DMC on GLK. There is a single
firmware image for all steppings on a GLK.

Cc: Rodrigo Vivi 
Signed-off-by: Anusha Srivatsa 
Reviewed-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/intel_csr.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c
index 9cbb8d8..0085bc7 100644
--- a/drivers/gpu/drm/i915/intel_csr.c
+++ b/drivers/gpu/drm/i915/intel_csr.c
@@ -34,6 +34,10 @@
  * low-power state and comes back to normal.
  */
 
+#define I915_CSR_GLK "i915/glk_dmc_ver1_01.bin"
+MODULE_FIRMWARE(I915_CSR_GLK);
+#define GLK_CSR_VERSION_REQUIRED   CSR_VERSION(1, 1)
+
 #define I915_CSR_KBL "i915/kbl_dmc_ver1_01.bin"
 MODULE_FIRMWARE(I915_CSR_KBL);
 #define KBL_CSR_VERSION_REQUIRED   CSR_VERSION(1, 1)
@@ -286,7 +290,9 @@ static uint32_t *parse_csr_fw(struct drm_i915_private 
*dev_priv,
 
csr->version = css_header->version;
 
-   if (IS_KABYLAKE(dev_priv)) {
+   if (IS_GEMINILAKE(dev_priv)) {
+   required_version = GLK_CSR_VERSION_REQUIRED;
+   } else if (IS_KABYLAKE(dev_priv)) {
required_version = KBL_CSR_VERSION_REQUIRED;
} else if (IS_SKYLAKE(dev_priv)) {
required_version = SKL_CSR_VERSION_REQUIRED;
@@ -435,7 +441,9 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv)
if (!HAS_CSR(dev_priv))
return;
 
-   if (IS_KABYLAKE(dev_priv))
+   if (IS_GEMINILAKE(dev_priv))
+   csr->fw_path = I915_CSR_GLK;
+   else if (IS_KABYLAKE(dev_priv))
csr->fw_path = I915_CSR_KBL;
else if (IS_SKYLAKE(dev_priv))
csr->fw_path = I915_CSR_SKL;
-- 
2.5.5

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


[Intel-gfx] [PATCH 3/3] drm/i915/glk: Convert a few more IS_BROXTON() to IS_GEN9_LP()

2016-12-16 Thread Ander Conselvan de Oliveira
From: Michel Thierry 

Commit 89b3c3c7ee9d ("drm/i915/glk: Reuse broxton's cdclk code for GLK")
missed a few of occurences of IS_BROXTON() that should have been
coverted to IS_GEN9_LP().

Fixes: 89b3c3c7ee9d ("drm/i915/glk: Reuse broxton's cdclk code for GLK")
Cc: Ander Conselvan de Oliveira 
Cc: Rodrigo Vivi 
Cc: Daniel Vetter 
Cc: Jani Nikula 
Cc: intel-gfx@lists.freedesktop.org
Signed-off-by: Michel Thierry 
Signed-off-by: Tomasz Lis 
Signed-off-by: Ander Conselvan de Oliveira 

---
 drivers/gpu/drm/i915/i915_sysfs.c| 2 +-
 drivers/gpu/drm/i915/intel_device_info.c | 2 +-
 drivers/gpu/drm/i915/intel_dp.c  | 2 +-
 drivers/gpu/drm/i915/intel_guc_loader.c  | 4 ++--
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_sysfs.c 
b/drivers/gpu/drm/i915/i915_sysfs.c
index 40c0ac7..376ac95 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -58,7 +58,7 @@ static u32 calc_residency(struct drm_i915_private *dev_priv,
 
if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH)
units <<= 8;
-   } else if (IS_BROXTON(dev_priv)) {
+   } else if (IS_GEN9_LP(dev_priv)) {
units = 1;
div = 1200; /* 833.33ns */
}
diff --git a/drivers/gpu/drm/i915/intel_device_info.c 
b/drivers/gpu/drm/i915/intel_device_info.c
index c46415b..6aeb1ed 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -192,7 +192,7 @@ static void gen9_sseu_info_init(struct drm_i915_private 
*dev_priv)
(IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) &&
hweight8(sseu->slice_mask) > 1;
sseu->has_subslice_pg =
-   IS_BROXTON(dev_priv) && sseu_subslice_total(sseu) > 1;
+   IS_GEN9_LP(dev_priv) && sseu_subslice_total(sseu) > 1;
sseu->has_eu_pg = sseu->eu_per_subslice > 2;
 
if (IS_BROXTON(dev_priv)) {
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 45ebc96..ae08c19 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3375,7 +3375,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
if (HAS_DDI(dev_priv)) {
signal_levels = ddi_signal_levels(intel_dp);
 
-   if (IS_BROXTON(dev_priv))
+   if (IS_GEN9_LP(dev_priv))
signal_levels = 0;
else
mask = DDI_BUF_EMP_MASK;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index 21db697..8b74525 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -339,7 +339,7 @@ static u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
u32 wopcm_size = GUC_WOPCM_TOP;
 
/* On BXT, the top of WOPCM is reserved for RC6 context */
-   if (IS_BROXTON(dev_priv))
+   if (IS_GEN9_LP(dev_priv))
wopcm_size -= BXT_GUC_WOPCM_RC6_RESERVED;
 
return wopcm_size;
@@ -388,7 +388,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0))
I915_WRITE(GEN6_GFXPAUSE, 0x30FFF);
 
-   if (IS_BROXTON(dev_priv))
+   if (IS_GEN9_LP(dev_priv))
I915_WRITE(GEN9LP_GT_PM_CONFIG, GT_DOORBELL_ENABLE);
else
I915_WRITE(GEN9_GT_PM_CONFIG, GT_DOORBELL_ENABLE);
-- 
2.5.5

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


[Intel-gfx] [drm-intel:drm-intel-nightly 922/930] drivers/gpu/drm/i915/i915_gem_gtt.c:2732:9: note: in expansion of macro 'list_first_entry_or_null'

2016-12-16 Thread kbuild test robot
tree:   git://anongit.freedesktop.org/drm-intel drm-intel-nightly
head:   ca1c03136b168816ac65c5945776908e464fca6b
commit: 45b186f111f1623b257d183920cd4aab16a1acd5 [922/930] drm: Constify the 
drm_mm API
config: i386-randconfig-x005-201650 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
git checkout 45b186f111f1623b257d183920cd4aab16a1acd5
# save the attached .config to linux build tree
make ARCH=i386 

All warnings (new ones prefixed by >>):

   In file included from include/linux/mutex.h:14:0,
from include/linux/seq_file.h:7,
from drivers/gpu/drm/i915/i915_gem_gtt.c:26:
   drivers/gpu/drm/i915/i915_gem_gtt.c: In function 'i915_gtt_color_adjust':
>> include/linux/list.h:385:29: warning: initialization discards 'const' 
>> qualifier from pointer target type [-Wdiscarded-qualifiers]
 struct list_head *head__ = (ptr); \
^
>> drivers/gpu/drm/i915/i915_gem_gtt.c:2732:9: note: in expansion of macro 
>> 'list_first_entry_or_null'
 node = list_first_entry_or_null(>node_list,
^~~~

vim +/list_first_entry_or_null +2732 drivers/gpu/drm/i915/i915_gem_gtt.c

307dc25b Chris Wilson   2016-08-05  2716/* Wait a bit, 
in hopes it avoids the hang */
307dc25b Chris Wilson   2016-08-05  2717udelay(10);
307dc25b Chris Wilson   2016-08-05  2718}
307dc25b Chris Wilson   2016-08-05  2719}
5c042287 Ben Widawsky   2011-10-17  2720  
03ac84f1 Chris Wilson   2016-10-28  2721dma_unmap_sg(kdev, pages->sgl, 
pages->nents, PCI_DMA_BIDIRECTIONAL);
7c2e6fdf Daniel Vetter  2010-11-06  2722  }
644ec02b Daniel Vetter  2012-03-26  2723  
45b186f1 Chris Wilson   2016-12-16  2724  static void 
i915_gtt_color_adjust(const struct drm_mm_node *node,
42d6ab48 Chris Wilson   2012-07-26  2725  
unsigned long color,
440fd528 Thierry Reding 2015-01-23  2726  u64 
*start,
440fd528 Thierry Reding 2015-01-23  2727  u64 
*end)
42d6ab48 Chris Wilson   2012-07-26  2728  {
42d6ab48 Chris Wilson   2012-07-26  2729if (node->color != color)
42d6ab48 Chris Wilson   2012-07-26  2730*start += 4096;
42d6ab48 Chris Wilson   2012-07-26  2731  
2a1d7752 Chris Wilson   2016-07-26 @2732node = 
list_first_entry_or_null(>node_list,
42d6ab48 Chris Wilson   2012-07-26  2733
struct drm_mm_node,
42d6ab48 Chris Wilson   2012-07-26  2734
node_list);
2a1d7752 Chris Wilson   2016-07-26  2735if (node && node->allocated && 
node->color != color)
42d6ab48 Chris Wilson   2012-07-26  2736*end -= 4096;
42d6ab48 Chris Wilson   2012-07-26  2737  }
fbe5d36e Ben Widawsky   2013-11-04  2738  
f6b9d5ca Chris Wilson   2016-08-04  2739  int i915_gem_init_ggtt(struct 
drm_i915_private *dev_priv)
644ec02b Daniel Vetter  2012-03-26  2740  {

:: The code at line 2732 was first introduced by commit
:: 2a1d775201081c400d7e60ceb8e5ac887d11b1f7 drm/i915: Prefer 
list_first_entry_or_null

:: TO: Chris Wilson 
:: CC: Chris Wilson 

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 09/13] drm: Tighten locking in drm_mode_getconnector

2016-12-16 Thread Sean Paul
On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter  wrote:
> - Modeset state needs mode_config->connection mutex, that covers
>   figuring out the encoder, and reading properties (since in the
>   atomic case those need to look at connector->state).
>
> - Don't hold any locks for stuff that's invariant (i.e. possible
>   connectors).
>
> - Same for connector lookup and unref, those don't need any locks.
>
> - And finally the probe stuff is only protected by mode_config->mutex.
>
> While at it updated the kerneldoc for these fields in drm_connector
> and add docs explaining what's protected by which locks.
>


Reviewed-by: Sean Paul 

> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_connector.c | 92 
> -
>  include/drm/drm_connector.h | 23 +--
>  2 files changed, 63 insertions(+), 52 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 0d4728704099..44b556d5d40c 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1160,43 +1160,65 @@ int drm_mode_getconnector(struct drm_device *dev, 
> void *data,
>
> memset(_mode, 0, sizeof(struct drm_mode_modeinfo));
>
> -   mutex_lock(>mode_config.mutex);
> -
> connector = drm_connector_lookup(dev, out_resp->connector_id);
> -   if (!connector) {
> -   ret = -ENOENT;
> -   goto out_unlock;
> -   }
> +   if (!connector)
> +   return -ENOENT;
> +
> +   drm_modeset_lock(>mode_config.connection_mutex, NULL);
> +   encoder = drm_connector_get_encoder(connector);
> +   if (encoder)
> +   out_resp->encoder_id = encoder->base.id;
> +   else
> +   out_resp->encoder_id = 0;
> +
> +   ret = drm_mode_object_get_properties(>base, 
> file_priv->atomic,
> +   (uint32_t __user *)(unsigned 
> long)(out_resp->props_ptr),
> +   (uint64_t __user *)(unsigned 
> long)(out_resp->prop_values_ptr),
> +   _resp->count_props);
> +   drm_modeset_unlock(>mode_config.connection_mutex);
> +   if (ret)
> +   goto out_unref;
>
> for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
> if (connector->encoder_ids[i] != 0)
> encoders_count++;
>
> +   if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
> +   copied = 0;
> +   encoder_ptr = (uint32_t __user *)(unsigned 
> long)(out_resp->encoders_ptr);
> +   for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
> +   if (connector->encoder_ids[i] != 0) {
> +   if (put_user(connector->encoder_ids[i],
> +encoder_ptr + copied)) {
> +   ret = -EFAULT;
> +   goto out_unref;
> +   }
> +   copied++;
> +   }
> +   }
> +   }
> +   out_resp->count_encoders = encoders_count;
> +
> +   out_resp->connector_id = connector->base.id;
> +   out_resp->connector_type = connector->connector_type;
> +   out_resp->connector_type_id = connector->connector_type_id;
> +
> +   mutex_lock(>mode_config.mutex);
> if (out_resp->count_modes == 0) {
> connector->funcs->fill_modes(connector,
>  dev->mode_config.max_width,
>  dev->mode_config.max_height);
> }
>
> -   /* delayed so we get modes regardless of pre-fill_modes state */
> -   list_for_each_entry(mode, >modes, head)
> -   if (drm_mode_expose_to_userspace(mode, file_priv))
> -   mode_count++;
> -
> -   out_resp->connector_id = connector->base.id;
> -   out_resp->connector_type = connector->connector_type;
> -   out_resp->connector_type_id = connector->connector_type_id;
> out_resp->mm_width = connector->display_info.width_mm;
> out_resp->mm_height = connector->display_info.height_mm;
> out_resp->subpixel = connector->display_info.subpixel_order;
> out_resp->connection = connector->status;
>
> -   drm_modeset_lock(>mode_config.connection_mutex, NULL);
> -   encoder = drm_connector_get_encoder(connector);
> -   if (encoder)
> -   out_resp->encoder_id = encoder->base.id;
> -   else
> -   out_resp->encoder_id = 0;
> +   /* delayed so we get modes regardless of pre-fill_modes state */
> +   list_for_each_entry(mode, >modes, head)
> +   if (drm_mode_expose_to_userspace(mode, file_priv))
> +   mode_count++;
>
> /*
>  * This ioctl is called twice, once to determine how much 

Re: [Intel-gfx] [PATCH 07/13] drm: Clean up connectors by unreferencing them

2016-12-16 Thread Sean Paul
On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter  wrote:
> Only static connectors should be left at this point, and we should be
> able to clean them out by simply dropping that last reference still
> around from drm_connector_init.
>
> If that leaves anything behind then we have a driver bug.
>
> Doing the final cleanup this way also allows us to use
> drm_connector_iter, removing the very last place where we walk
> connector_list explicitly in drm core
>
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_mode_config.c | 15 +++
>  1 file changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_mode_config.c 
> b/drivers/gpu/drm/drm_mode_config.c
> index 747a26df0e90..a942536abd60 100644
> --- a/drivers/gpu/drm/drm_mode_config.c
> +++ b/drivers/gpu/drm/drm_mode_config.c
> @@ -397,7 +397,8 @@ EXPORT_SYMBOL(drm_mode_config_init);
>   */
>  void drm_mode_config_cleanup(struct drm_device *dev)
>  {
> -   struct drm_connector *connector, *ot;
> +   struct drm_connector *connector;
> +   struct drm_connector_list_iter conn_iter;
> struct drm_crtc *crtc, *ct;
> struct drm_encoder *encoder, *enct;
> struct drm_framebuffer *fb, *fbt;
> @@ -410,10 +411,16 @@ void drm_mode_config_cleanup(struct drm_device *dev)
> encoder->funcs->destroy(encoder);
> }
>
> -   list_for_each_entry_safe(connector, ot,
> ->mode_config.connector_list, head) {
> -   connector->funcs->destroy(connector);
> +   drm_connector_list_iter_get(dev, _iter);
> +   drm_for_each_connector_iter(connector, _iter) {
> +   /* drm_connector_list_iter holds an full reference to the
> +* current connector itself, which means it is inherently safe
> +* against unreferencing the current connector - but not 
> against
> +* deleting it right away. */

pedantic nit: doesn't conform to CodingStyle

Reviewed-by: Sean Paul 

> +   drm_connector_unreference(connector);
> }
> +   drm_connector_list_iter_put(_iter);
> +   WARN_ON(!list_empty(>mode_config.connector_list));
>
> list_for_each_entry_safe(property, pt, 
> >mode_config.property_list,
>  head) {
> --
> 2.11.0
>
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Sean Paul, Software Engineer, Google / Chromium OS
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 08/13] drm: prevent double-(un)registration for connectors

2016-12-16 Thread Sean Paul
On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter  wrote:
> If we're unlucky then the registration from a hotplugged connector
> might race with the final registration step on driver load. And since
> MST topology discover is asynchronous that's even somewhat likely.
>
> v2: Also update the kerneldoc for @registered!
>
> Cc: Chris Wilson 
> Reported-by: Chris Wilson 


With Chris' suggested improvements

Reviewed-by: Sean Paul 

> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_connector.c | 18 +-
>  include/drm/drm_connector.h | 12 +++-
>  2 files changed, 24 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index b4e09b00..0d4728704099 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -223,6 +223,7 @@ int drm_connector_init(struct drm_device *dev,
>
> INIT_LIST_HEAD(>probed_modes);
> INIT_LIST_HEAD(>modes);
> +   mutex_init(>mutex);
> connector->edid_blob_ptr = NULL;
> connector->status = connector_status_unknown;
>
> @@ -373,14 +374,15 @@ EXPORT_SYMBOL(drm_connector_cleanup);
>   */
>  int drm_connector_register(struct drm_connector *connector)
>  {
> -   int ret;
> +   int ret = 0;
>
> +   mutex_lock(>mutex);
> if (connector->registered)
> -   return 0;
> +   goto unlock;
>
> ret = drm_sysfs_connector_add(connector);
> if (ret)
> -   return ret;
> +   goto unlock;
>
> ret = drm_debugfs_connector_add(connector);
> if (ret) {
> @@ -396,12 +398,14 @@ int drm_connector_register(struct drm_connector 
> *connector)
> drm_mode_object_register(connector->dev, >base);
>
> connector->registered = true;
> -   return 0;
> +   goto unlock;
>
>  err_debugfs:
> drm_debugfs_connector_remove(connector);
>  err_sysfs:
> drm_sysfs_connector_remove(connector);
> +unlock:
> +   mutex_unlock(>mutex);
> return ret;
>  }
>  EXPORT_SYMBOL(drm_connector_register);
> @@ -414,8 +418,11 @@ EXPORT_SYMBOL(drm_connector_register);
>   */
>  void drm_connector_unregister(struct drm_connector *connector)
>  {
> -   if (!connector->registered)
> +   mutex_lock(>mutex);
> +   if (!connector->registered) {
> +   mutex_unlock(>mutex);
> return;
> +   }
>
> if (connector->funcs->early_unregister)
> connector->funcs->early_unregister(connector);
> @@ -424,6 +431,7 @@ void drm_connector_unregister(struct drm_connector 
> *connector)
> drm_debugfs_connector_remove(connector);
>
> connector->registered = false;
> +   mutex_unlock(>mutex);
>  }
>  EXPORT_SYMBOL(drm_connector_unregister);
>
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 0e41a2e184a9..a24559ef8bb7 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -559,7 +559,6 @@ struct drm_cmdline_mode {
>   * @interlace_allowed: can this connector handle interlaced modes?
>   * @doublescan_allowed: can this connector handle doublescan?
>   * @stereo_allowed: can this connector handle stereo modes?
> - * @registered: is this connector exposed (registered) with userspace?
>   * @modes: modes available on this connector (from fill_modes() + user)
>   * @status: one of the drm_connector_status enums (connected, not, or 
> unknown)
>   * @probed_modes: list of modes derived directly from the display
> @@ -608,6 +607,13 @@ struct drm_connector {
> char *name;
>
> /**
> +* @mutex: Lock for general connector state, but currently only 
> protects
> +* @registered. Most of the connector state is still protected by the
> +* mutex in _mode_config.
> +*/
> +   struct mutex mutex;
> +
> +   /**
>  * @index: Compacted connector index, which matches the position 
> inside
>  * the mode_config.list for drivers not supporting hot-add/removing. 
> Can
>  * be used as an array index. It is invariant over the lifetime of the
> @@ -620,6 +626,10 @@ struct drm_connector {
> bool interlace_allowed;
> bool doublescan_allowed;
> bool stereo_allowed;
> +   /**
> +* @registered: Is this connector exposed (registered) with userspace?
> +* Protected by @mutex.
> +*/
> bool registered;
> struct list_head modes; /* list of modes on this connector */
>
> --
> 2.11.0
>
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Sean Paul, Software Engineer, Google / Chromium OS
___
Intel-gfx mailing list

Re: [Intel-gfx] [PATCH] drm: Convert all helpers to drm_connector_list_iter

2016-12-16 Thread Sean Paul
On Thu, Dec 15, 2016 at 10:58 AM, Daniel Vetter  wrote:
> Mostly nothing special (except making sure that really all error paths
> and friends call iter_put).
>
> v2: Don't forget the raw connector_list walking in
> drm_helper_move_panel_connectors_to_head. That one unfortunately can't
> be converted to the iterator helpers, but since it's just some list
> splicing best to just wrap the entire thing up in one critical
> section.
>
> v3: Bail out after iter_put (Harry).
>
> Cc: Harry Wentland 


Reviewed-by: Sean Paul 

> Reviewed-by: Harry Wentland 
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_atomic_helper.c  | 39 
>  drivers/gpu/drm/drm_crtc_helper.c| 49 
> 
>  drivers/gpu/drm/drm_fb_helper.c  | 12 ++---
>  drivers/gpu/drm/drm_modeset_helper.c |  2 ++
>  drivers/gpu/drm/drm_plane_helper.c   |  5 +++-
>  drivers/gpu/drm/drm_probe_helper.c   | 18 -
>  6 files changed, 92 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> b/drivers/gpu/drm/drm_atomic_helper.c
> index 23767df72615..e2e15a9903a9 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -94,9 +94,10 @@ static int handle_conflicting_encoders(struct 
> drm_atomic_state *state,
>  {
> struct drm_connector_state *conn_state;
> struct drm_connector *connector;
> +   struct drm_connector_list_iter conn_iter;
> struct drm_encoder *encoder;
> unsigned encoder_mask = 0;
> -   int i, ret;
> +   int i, ret = 0;
>
> /*
>  * First loop, find all newly assigned encoders from the connectors
> @@ -144,7 +145,8 @@ static int handle_conflicting_encoders(struct 
> drm_atomic_state *state,
>  * and the crtc is disabled if no encoder is left. This preserves
>  * compatibility with the legacy set_config behavior.
>  */
> -   drm_for_each_connector(connector, state->dev) {
> +   drm_connector_list_iter_get(state->dev, _iter);
> +   drm_for_each_connector_iter(connector, _iter) {
> struct drm_crtc_state *crtc_state;
>
> if (drm_atomic_get_existing_connector_state(state, connector))
> @@ -160,12 +162,15 @@ static int handle_conflicting_encoders(struct 
> drm_atomic_state *state,
>  connector->state->crtc->base.id,
>  connector->state->crtc->name,
>  connector->base.id, connector->name);
> -   return -EINVAL;
> +   ret = -EINVAL;
> +   goto out;
> }
>
> conn_state = drm_atomic_get_connector_state(state, connector);
> -   if (IS_ERR(conn_state))
> -   return PTR_ERR(conn_state);
> +   if (IS_ERR(conn_state)) {
> +   ret = PTR_ERR(conn_state);
> +   goto out;
> +   }
>
> DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], 
> disabling [CONNECTOR:%d:%s]\n",
>  encoder->base.id, encoder->name,
> @@ -176,19 +181,21 @@ static int handle_conflicting_encoders(struct 
> drm_atomic_state *state,
>
> ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
> if (ret)
> -   return ret;
> +   goto out;
>
> if (!crtc_state->connector_mask) {
> ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
> NULL);
> if (ret < 0)
> -   return ret;
> +   goto out;
>
> crtc_state->active = false;
> }
> }
> +out:
> +   drm_connector_list_iter_put(_iter);
>
> -   return 0;
> +   return ret;
>  }
>
>  static void
> @@ -2442,6 +2449,7 @@ int drm_atomic_helper_disable_all(struct drm_device 
> *dev,
>  {
> struct drm_atomic_state *state;
> struct drm_connector *conn;
> +   struct drm_connector_list_iter conn_iter;
> int err;
>
> state = drm_atomic_state_alloc(dev);
> @@ -2450,7 +2458,8 @@ int drm_atomic_helper_disable_all(struct drm_device 
> *dev,
>
> state->acquire_ctx = ctx;
>
> -   drm_for_each_connector(conn, dev) {
> +   drm_connector_list_iter_get(dev, _iter);
> +   drm_for_each_connector_iter(conn, _iter) {
> struct drm_crtc *crtc = conn->state->crtc;
> struct drm_crtc_state *crtc_state;
>
> @@ -2468,6 +2477,7 @@ int drm_atomic_helper_disable_all(struct drm_device 
> *dev,
>
> err = drm_atomic_commit(state);
>  

Re: [Intel-gfx] [PATCH 04/13] drm: Drop locking cargo-cult from drm_mode_config_init

2016-12-16 Thread Sean Paul
On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter  wrote:
> This is single-threaded setup code, no need for locks. And anyway,
> all properties need to be set up before the driver is registered
> anyway, they can't be hot-added.
>


Reviewed-by: Sean Paul 

> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_mode_config.c | 2 --
>  1 file changed, 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_mode_config.c 
> b/drivers/gpu/drm/drm_mode_config.c
> index b1e8bbceaf39..85a25fd9eff8 100644
> --- a/drivers/gpu/drm/drm_mode_config.c
> +++ b/drivers/gpu/drm/drm_mode_config.c
> @@ -374,9 +374,7 @@ void drm_mode_config_init(struct drm_device *dev)
> idr_init(>mode_config.tile_idr);
> ida_init(>mode_config.connector_ida);
>
> -   drm_modeset_lock_all(dev);
> drm_mode_create_standard_properties(dev);
> -   drm_modeset_unlock_all(dev);
>
> /* Just to be sure */
> dev->mode_config.num_fb = 0;
> --
> 2.11.0
>
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Sean Paul, Software Engineer, Google / Chromium OS
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 05/13] drm: locking iterators for connector_list

2016-12-16 Thread Sean Paul
On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter  wrote:
> The requirements for connector_list locking are a bit tricky:
> - We need to be able to jump over zombie conectors (i.e. with refcount
>   == 0, but not yet removed from the list). If instead we require that
>   there's no zombies on the list then the final kref_put must happen
>   under the list protection lock, which means that locking context
>   leaks all over the place. Not pretty - better to deal with zombies
>   and wrap the locking just around the list_del in the destructor.
>
> - When we walk the list we must _not_ hold the connector list lock. We
>   walk the connector list at an absolutely massive amounts of places,
>   if all those places can't ever call drm_connector_unreference the
>   code would get unecessarily complicated.
>
> - connector_list needs it own lock, again too many places that walk it
>   that we could reuse e.g. mode_config.mutex without resulting in
>   inversions.
>
> - Lots of code uses these loops to look-up a connector, i.e. they want
>   to be able to call drm_connector_reference. But on the other hand we
>   want connectors to stay on that list until they're dead (i.e.
>   connector_list can't hold a full reference), which means despite the
>   "can't hold lock for the loop body" rule we need to make sure a
>   connector doesn't suddenly become a zombie.
>
> At first Dave discussed various horror-show approaches using srcu,
> but turns out it's fairly easy:
>
> - For the loop body we always hold an additional reference to the
>   current connector. That means it can't zombify, and it also means
>   it'll stay on the list, which means we can use it as our iterator to
>   find the next connector.
>
> - When we try to find the next connector we only have to jump over
>   zombies. To make sure we don't chase bad pointers that entire loop
>   is protected with the new connect_list_lock spinlock. And because we
>   know that we're starting out with a non-zombie (need to drop our
>   reference for the old connector only after we have our new one),
>   we're guranteed to still be on the connector_list and either find
>   the next non-zombie or complete the iteration.
>
> - Only downside is that we need to make sure that the temporary
>   reference for the loop body doesn't leak. iter_get/put() functions +
>   lockdep make sure that's the case.
>
> - To avoid a flag day the new iterator macro has an _iter postfix. We
>   can rename it back once all the users of the unsafe version are gone
>   (there's about 100 list walkers for the connector_list).
>
> For now this patch only converts all the list walking in the core,
> leaving helpers and drivers for later patches. The nice thing is that
> we can now finally remove 2 FIXME comments from the
> register/unregister functions.
>
> v2:
> - use irqsafe spinlocks, so that we can use this in drm_state_dump
>   too.
> - nuke drm_modeset_lock_all from drm_connector_init, now entirely
>   cargo-culted nonsense.
>
> v3:
> - do {} while (!kref_get_unless_zero), makes for a tidier loop (Dave).
> - pretty kerneldoc
> - add EXPORT_SYMBOL, helpers are supposed to use this.
>
> v4: Change lockdep annotations to only check whether we release the
> iter fake lock again (i.e. make sure that iter_put is called), but
> not check any locking dependecies itself. That seams to require a
> recursive read lock in trylock mode.
>
> Cc: Dave Airlie 
> Cc: Chris Wilson 



Reviewed-by: Sean Paul 

> Signed-off-by: Daniel Vetter 


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


Re: [Intel-gfx] [PATCH 02/13] drm: Move atomic debugfs functions into drm_crtc_internal.h

2016-12-16 Thread Sean Paul
On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter  wrote:
> This is not driver interface stuff.
>


Reviewed-by: Sean Paul 

> Fixes: 6559c901cb48 ("drm/atomic: add debugfs file to dump out atomic state")
> Cc: Rob Clark 
> Cc: Sean Paul 
> Cc: Daniel Vetter 
> Cc: Jani Nikula 
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_crtc_internal.h | 6 ++
>  drivers/gpu/drm/drm_debugfs.c   | 1 +
>  include/drm/drm_atomic.h| 6 --
>  3 files changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc_internal.h 
> b/drivers/gpu/drm/drm_crtc_internal.h
> index cdf6860c9d22..0b8454c7dc00 100644
> --- a/drivers/gpu/drm/drm_crtc_internal.h
> +++ b/drivers/gpu/drm/drm_crtc_internal.h
> @@ -174,6 +174,12 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
>void *data, struct drm_file *file_priv);
>
>  /* drm_atomic.c */
> +#ifdef CONFIG_DEBUG_FS
> +struct drm_minor;
> +int drm_atomic_debugfs_init(struct drm_minor *minor);
> +int drm_atomic_debugfs_cleanup(struct drm_minor *minor);
> +#endif
> +
>  int drm_atomic_get_property(struct drm_mode_object *obj,
> struct drm_property *property, uint64_t *val);
>  int drm_mode_atomic_ioctl(struct drm_device *dev,
> diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
> index 2e3e46a53805..37fd612d57a6 100644
> --- a/drivers/gpu/drm/drm_debugfs.c
> +++ b/drivers/gpu/drm/drm_debugfs.c
> @@ -38,6 +38,7 @@
>  #include 
>  #include 
>  #include "drm_internal.h"
> +#include "drm_crtc_internal.h"
>
>  #if defined(CONFIG_DEBUG_FS)
>
> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> index 01d02e1935b1..c35b4aba36b6 100644
> --- a/include/drm/drm_atomic.h
> +++ b/include/drm/drm_atomic.h
> @@ -379,12 +379,6 @@ int __must_check drm_atomic_nonblocking_commit(struct 
> drm_atomic_state *state);
>
>  void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
>
> -#ifdef CONFIG_DEBUG_FS
> -struct drm_minor;
> -int drm_atomic_debugfs_init(struct drm_minor *minor);
> -int drm_atomic_debugfs_cleanup(struct drm_minor *minor);
> -#endif
> -
>  #define for_each_connector_in_state(__state, connector, connector_state, 
> __i) \
> for ((__i) = 0; \
>  (__i) < (__state)->num_connector &&  
>   \
> --
> 2.11.0
>



-- 
Sean Paul, Software Engineer, Google / Chromium OS
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 01/13] drm/irq: drm_legacy_ prefix for legacy ioctls

2016-12-16 Thread Sean Paul
On Tue, Dec 13, 2016 at 6:08 PM, Daniel Vetter  wrote:
> Spotted while auditing our ioctl table. Also nuke the
> not-really-kerneldoc comments, we don't document internals and
> definitely don't want to mislead people with the old dragons.
>
> I think with this all the legacy ioctls now have proper drm_legacy_
> prefixes.
>


Reviewed-by: Sean Paul 

> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_internal.h |  8 
>  drivers/gpu/drm/drm_ioctl.c|  4 ++--
>  drivers/gpu/drm/drm_irq.c  | 30 --
>  3 files changed, 10 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index db80ec860e33..a6213f814345 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -58,10 +58,10 @@ extern unsigned int drm_timestamp_monotonic;
>  /* IOCTLS */
>  int drm_wait_vblank(struct drm_device *dev, void *data,
> struct drm_file *filp);
> -int drm_control(struct drm_device *dev, void *data,
> -   struct drm_file *file_priv);
> -int drm_modeset_ctl(struct drm_device *dev, void *data,
> -   struct drm_file *file_priv);
> +int drm_legacy_irq_control(struct drm_device *dev, void *data,
> +  struct drm_file *file_priv);
> +int drm_legacy_modeset_ctl(struct drm_device *dev, void *data,
> +  struct drm_file *file_priv);
>
>  /* drm_auth.c */
>  int drm_getmagic(struct drm_device *dev, void *data,
> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> index e21a18ac968e..a16b6fbd1004 100644
> --- a/drivers/gpu/drm/drm_ioctl.c
> +++ b/drivers/gpu/drm/drm_ioctl.c
> @@ -581,7 +581,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
> DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_legacy_freebufs, DRM_AUTH),
> DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_legacy_dma_ioctl, DRM_AUTH),
>
> -   DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, 
> DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> +   DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_legacy_irq_control, 
> DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
>
>  #if IS_ENABLED(CONFIG_AGP)
> DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, 
> DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> @@ -599,7 +599,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>
> DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 
> DRM_MASTER|DRM_UNLOCKED),
>
> -   DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
> +   DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_legacy_modeset_ctl, 0),
>
> DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, 
> DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
>
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 273625a85036..feb091310ffe 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -579,19 +579,8 @@ int drm_irq_uninstall(struct drm_device *dev)
>  }
>  EXPORT_SYMBOL(drm_irq_uninstall);
>
> -/*
> - * IRQ control ioctl.
> - *
> - * \param inode device inode.
> - * \param file_priv DRM file private.
> - * \param cmd command.
> - * \param arg user argument, pointing to a drm_control structure.
> - * \return zero on success or a negative number on failure.
> - *
> - * Calls irq_install() or irq_uninstall() according to \p arg.
> - */
> -int drm_control(struct drm_device *dev, void *data,
> -   struct drm_file *file_priv)
> +int drm_legacy_irq_control(struct drm_device *dev, void *data,
> +  struct drm_file *file_priv)
>  {
> struct drm_control *ctl = data;
> int ret = 0, irq;
> @@ -1442,19 +1431,8 @@ static void drm_legacy_vblank_post_modeset(struct 
> drm_device *dev,
> }
>  }
>
> -/*
> - * drm_modeset_ctl - handle vblank event counter changes across mode switch
> - * @DRM_IOCTL_ARGS: standard ioctl arguments
> - *
> - * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
> - * ioctls around modesetting so that any lost vblank events are accounted 
> for.
> - *
> - * Generally the counter will reset across mode sets.  If interrupts are
> - * enabled around this call, we don't have to do anything since the counter
> - * will have already been incremented.
> - */
> -int drm_modeset_ctl(struct drm_device *dev, void *data,
> -   struct drm_file *file_priv)
> +int drm_legacy_modeset_ctl(struct drm_device *dev, void *data,
> +  struct drm_file *file_priv)
>  {
> struct drm_modeset_ctl *modeset = data;
> unsigned int pipe;
> --
> 2.11.0
>
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Sean Paul, Software Engineer, Google / Chromium OS
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org

Re: [Intel-gfx] [PATCH v2 12/40] drm: kselftest for drm_mm_insert_node()

2016-12-16 Thread Chris Wilson
On Fri, Dec 16, 2016 at 04:02:12PM +0200, Joonas Lahtinen wrote:
> On pe, 2016-12-16 at 07:46 +, Chris Wilson wrote:
> > Exercise drm_mm_insert_node(), check that we can't overfill a range and
> > that the lists are correct after reserving/removing.
> > 
> > v2: Extract helpers for the repeated tests
> > v3: Iterate over all allocation flags
> > 
> > Signed-off-by: Chris Wilson 
> 
> 
>  
> > +static u64 misaligned(struct drm_mm_node *node, u64 alignment)
> 
> I'm not sure if 'misalignment' would be better name or not. This makes
> me think of bool returning one.
> 
> > +static bool expect_insert_fail(struct drm_mm *mm, u64 size)
> > +{
> > +   struct drm_mm_node tmp = {};
> > +   int err;
> > +
> > +   err = drm_mm_insert_node(mm, , size, 0, DRM_MM_SEARCH_DEFAULT);
> > +   if (err != -ENOSPC)  {
> 
> For speed (this function gets called a lot);
> 
> if (likely(err == -ENOSPC))
>   return true;
> 
> > +static int __igt_insert(unsigned int count, u64 size)
> > +{
> 
> 
> 
> > 
> > +   for (mode = insert_modes; mode->name; mode++) {
> > +   for (n = 0; n < count; n++) {
> > +   node = [n];
> > +   err = drm_mm_insert_node_generic(, node, size, 0, n,
> > +    mode->search_flags,
> > +    mode->create_flags);
> > +   if (err || !assert_node(node, , size, 0, n)) {
> > +   pr_err("%s insert failed, size %llu step %d\n",
> > +      mode->name, size, n);
> > +   ret = err ?: -EINVAL;
> > +   goto out;
> > +   }
> 
> This construct is three times in this patch; Could be
> expect_insert_generic?

In this patch alone, indeed it gets used again and again. I resisted
making it an insert and check function simply because I didn't want to
fall into the trap of using it everywhere and so missing out exercising
drm_mm_insert_node and friends.

However, 3 occurences of the same in one patch...
-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   >