Re: Re: [PATCH v3 05/16] drm/i915: Disable the "binder"

2024-01-25 Thread Michał Winiarski
On Thu, Jan 25, 2024 at 11:08:04AM +0200, Ville Syrjälä wrote:
> On Fri, Jan 19, 2024 at 01:12:11AM +0200, Ville Syrjälä wrote:
> > On Wed, Jan 17, 2024 at 06:46:24PM +0100, Nirmoy Das wrote:
> > > 
> > > On 1/17/2024 3:13 PM, Michał Winiarski wrote:
> > > > On Tue, Jan 16, 2024 at 09:56:25AM +0200, Ville Syrjala wrote:
> > > >> From: Ville Syrjälä 
> > > >>
> > > >> Now that the GGTT PTE updates go straight to GSMBASE (bypassing
> > > >> GTTMMADR) there should be no more risk of system hangs? So the
> > > >> "binder" (ie. update the PTEs via MI_UPDATE_GTT) is no longer
> > > >> necessary, disable it.
> > > >>
> > > >> My main worry with the MI_UPDATE_GTT are:
> > > >> - only used on this one platform so very limited testing coverage
> > > >> - async so more opprtunities to screw things up
> > > >> - what happens if the engine hangs while we're waiting for 
> > > >> MI_UPDATE_GTT
> > > >>to finish?
> > > >> - requires working command submission, so even getting a working
> > > >>display now depends on a lot more extra components working correctly
> > > >>
> > > >> TODO: MI_UPDATE_GTT might be interesting as an optimization
> > > >> though, so perhaps someone should look into always using it
> > > >> (assuming the GPU is alive and well)?
> > > >>
> > > >> v2: Keep using MI_UPDATE_GTT on VM guests
> > > >>
> > > >> Cc: Paz Zcharya 
> > > >> Cc: Nirmoy Das 
> > > >> Signed-off-by: Ville Syrjälä 
> > > >> ---
> > > >>   drivers/gpu/drm/i915/gt/intel_gtt.c | 3 ++-
> > > >>   1 file changed, 2 insertions(+), 1 deletion(-)
> > > >>
> > > >> diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c 
> > > >> b/drivers/gpu/drm/i915/gt/intel_gtt.c
> > > >> index 86f73fe558ca..e83dabc56a14 100644
> > > >> --- a/drivers/gpu/drm/i915/gt/intel_gtt.c
> > > >> +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
> > > >> @@ -24,7 +24,8 @@
> > > >>   bool i915_ggtt_require_binder(struct drm_i915_private *i915)
> > > >>   {
> > > >>/* Wa_13010847436 & Wa_14019519902 */
> > > >> -  return MEDIA_VER_FULL(i915) == IP_VER(13, 0);
> > > >> +  return i915_run_as_guest() &&
> > > >> +  MEDIA_VER_FULL(i915) == IP_VER(13, 0);
> > > > Note that i915_run_as_guest() is not the most reliable way to decide
> > > > whether to use MI_UPDATE_GTT or straight to GSMBASE, as it requires the
> > > > hypervisor to "opt-in" and set the X86_FEATURE_HYPERVISOR.
> > > > If it's not set - the driver will go into GSMBASE, which is not mapped
> > > > inside the guest.
> > > > Does the system firmware advertise whether GSMBASE is "open" or "closed"
> > > > to CPU access in any way?
> > > 
> > > Had a chat with David from IVE team, David suggested to read 0x138914 to 
> > > determine that.  "GOP needs to qualify the WA by reading GFX MMIO offset 
> > > 0x138914 and verify the value there is 0x1." -> as per the HSD-22018444074
> > 
> > OK, so we can confirm the firmware is on board. I suppose no real harm
> > in doing so even though it would clearly be a rather weird if someone
> > would ship some ancient firmware that doesn't handle this.
> > 
> > But that still won't help with the guest side handling because that
> > register will read the same in the guest.
> 
> I guess we have two options here:
> 1) ignore non-standard vms that don't advertise themselves
> 2) try some other heuristics to detect them (eg. host/isa bridge PCI
>IDs/DMI/etc.)
> 
> My preference is to just go with option 1, and if someone comes across
> a real world use case when the vm is hiding then we can think of some
> way to handle it. Trying to come up with heuristics for that without
> anything to test against would be 100% guesswork anyway.
> 
> -- 
> Ville Syrjälä
> Intel

Option 1 can work, but there is a heuristic that should work for most
cases.
If we can assume that on bare-metal, e820 memory map excludes the stolen
region (it's marked as reserved), we should be able to do something that
looks roughly like this (warning - not tested, just a pseudo-code):

static int is_reserved(struct resource *res, void *arg)
{
return 1;
}

static bool _stolen_is_reserved(u64 addr)
{
int ret;

ret = walk_iomem_res_desc(IORES_DESC_RESERVED, IORESOURCE_MEM,
  gsm, gsm + gsm_size, NULL, is_reserved)
if (ret != 1)
return false;

return true;
}

if (i915_run_as_guest() || !_stolen_is_reserved(gsm, gsm_size))
fallback_to_mi_ggtt()

Similar sanity check for stolen being reserved should probably also be
done in the regular stolen init path - currently we're creating a
resource named "Graphics Stolen Memory" somewhere in the middle of
System RAM when i915 runs inside VM with native device passthrough.

-Michał


Re: [PATCH v3 05/16] drm/i915: Disable the "binder"

2024-01-17 Thread Michał Winiarski
On Tue, Jan 16, 2024 at 09:56:25AM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Now that the GGTT PTE updates go straight to GSMBASE (bypassing
> GTTMMADR) there should be no more risk of system hangs? So the
> "binder" (ie. update the PTEs via MI_UPDATE_GTT) is no longer
> necessary, disable it.
> 
> My main worry with the MI_UPDATE_GTT are:
> - only used on this one platform so very limited testing coverage
> - async so more opprtunities to screw things up
> - what happens if the engine hangs while we're waiting for MI_UPDATE_GTT
>   to finish?
> - requires working command submission, so even getting a working
>   display now depends on a lot more extra components working correctly
> 
> TODO: MI_UPDATE_GTT might be interesting as an optimization
> though, so perhaps someone should look into always using it
> (assuming the GPU is alive and well)?
> 
> v2: Keep using MI_UPDATE_GTT on VM guests
> 
> Cc: Paz Zcharya 
> Cc: Nirmoy Das 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/gt/intel_gtt.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c 
> b/drivers/gpu/drm/i915/gt/intel_gtt.c
> index 86f73fe558ca..e83dabc56a14 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gtt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
> @@ -24,7 +24,8 @@
>  bool i915_ggtt_require_binder(struct drm_i915_private *i915)
>  {
>   /* Wa_13010847436 & Wa_14019519902 */
> - return MEDIA_VER_FULL(i915) == IP_VER(13, 0);
> + return i915_run_as_guest() &&
> + MEDIA_VER_FULL(i915) == IP_VER(13, 0);

Note that i915_run_as_guest() is not the most reliable way to decide
whether to use MI_UPDATE_GTT or straight to GSMBASE, as it requires the
hypervisor to "opt-in" and set the X86_FEATURE_HYPERVISOR.
If it's not set - the driver will go into GSMBASE, which is not mapped
inside the guest.
Does the system firmware advertise whether GSMBASE is "open" or "closed"
to CPU access in any way?

-Michał

>  }
>  
>  static bool intel_ggtt_update_needs_vtd_wa(struct drm_i915_private *i915)
> -- 
> 2.41.0
> 


Re: [Intel-gfx] [PATCH 0/3] drm/i915: nuke i915->gt0

2023-10-02 Thread Michał Winiarski
On Mon, Oct 02, 2023 at 04:04:51PM +0200, Andi Shyti wrote:
> Hi Jani,
> 
> adding a few folks in Cc for some extra eyes on this series.
> 
> On Mon, Oct 02, 2023 at 11:47:01AM +0300, Jani Nikula wrote:
> > Chopping up [1] to more digestable pieces. Start off with nuking
> > i915->gt0.
> > 
> > [1] https://patchwork.freedesktop.org/series/124418/
> > 
> > Jani Nikula (3):
> >   drm/i915/mocs: use to_gt() instead of direct >gt
> >   drm/i915: allocate i915->gt0 dynamically
> >   drm/i915/gt: remove i915->gt0 in favour of i915->gt[0]
> > 
> >  drivers/gpu/drm/i915/gt/intel_gt.c   | 10 +++---
> >  drivers/gpu/drm/i915/gt/intel_mocs.c |  4 ++--
> >  drivers/gpu/drm/i915/i915_drv.h  | 10 ++
> >  drivers/gpu/drm/i915/selftests/mock_gem_device.c |  1 -
> >  4 files changed, 11 insertions(+), 14 deletions(-)
> 
> Michal, Michal and Tomasz, can you please check here?
> 
> Thanks,
> Andi

Acked-by: Michał Winiarski 

-Michał


Re: [Intel-gfx] [PATCH v6 1/4] drm: Use XArray instead of IDR for minors

2023-08-28 Thread Michał Winiarski
On Fri, Aug 25, 2023 at 12:59:26PM -0400, James Zhu wrote:
> 
> On 2023-07-24 17:14, Michał Winiarski wrote:
> > IDR is deprecated, and since XArray manages its own state with internal
> > locking, it simplifies the locking on DRM side.
> > Additionally, don't use the IRQ-safe variant, since operating on drm
> > minor is not done in IRQ context.
> > 
> > Signed-off-by: Michał Winiarski
> > Suggested-by: Matthew Wilcox
> > ---
> >   drivers/gpu/drm/drm_drv.c | 63 ---
> >   1 file changed, 25 insertions(+), 38 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > index 3eda026ffac6..3faecb01186f 100644
> > --- a/drivers/gpu/drm/drm_drv.c
> > +++ b/drivers/gpu/drm/drm_drv.c
> > @@ -34,6 +34,7 @@
> >   #include 
> >   #include 
> >   #include 
> > +#include 
> >   #include 
> >   #include 
> > @@ -54,8 +55,7 @@ MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, 
> > Jon Smirl");
> >   MODULE_DESCRIPTION("DRM shared core routines");
> >   MODULE_LICENSE("GPL and additional rights");
> > -static DEFINE_SPINLOCK(drm_minor_lock);
> > -static struct idr drm_minors_idr;
> > +static DEFINE_XARRAY_ALLOC(drm_minors_xa);
> >   /*
> >* If the drm core fails to init for whatever reason,
> > @@ -101,26 +101,23 @@ static struct drm_minor **drm_minor_get_slot(struct 
> > drm_device *dev,
> >   static void drm_minor_alloc_release(struct drm_device *dev, void *data)
> >   {
> > struct drm_minor *minor = data;
> > -   unsigned long flags;
> > WARN_ON(dev != minor->dev);
> > put_device(minor->kdev);
> > -   if (minor->type == DRM_MINOR_ACCEL) {
> > +   if (minor->type == DRM_MINOR_ACCEL)
> > accel_minor_remove(minor->index);
> > -   } else {
> > -   spin_lock_irqsave(_minor_lock, flags);
> > -   idr_remove(_minors_idr, minor->index);
> > -   spin_unlock_irqrestore(_minor_lock, flags);
> > -   }
> > +   else
> > +   xa_erase(_minors_xa, minor->index);
> >   }
> > +#define DRM_MINOR_LIMIT(t) ({ typeof(t) _t = (t); XA_LIMIT(64 * _t, 64 * 
> > _t + 63); })
> > +
> >   static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type 
> > type)
> >   {
> > struct drm_minor *minor;
> > -   unsigned long flags;
> > -   int r;
> > +   int index, r;
> > minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
> > if (!minor)
> > @@ -129,24 +126,17 @@ static int drm_minor_alloc(struct drm_device *dev, 
> > enum drm_minor_type type)
> > minor->type = type;
> > minor->dev = dev;
> > -   idr_preload(GFP_KERNEL);
> > if (type == DRM_MINOR_ACCEL) {
> > r = accel_minor_alloc();
> > +   index = r;
> > } else {
> > -   spin_lock_irqsave(_minor_lock, flags);
> > -   r = idr_alloc(_minors_idr,
> > -   NULL,
> > -   64 * type,
> > -   64 * (type + 1),
> > -   GFP_NOWAIT);
> > -   spin_unlock_irqrestore(_minor_lock, flags);
> > +   r = xa_alloc(_minors_xa, , NULL, 
> > DRM_MINOR_LIMIT(type), GFP_KERNEL);
> > }
> > -   idr_preload_end();
> > if (r < 0)
> > return r;
> > -   minor->index = r;
> > +   minor->index = index;
> > r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
> > if (r)
> > @@ -163,7 +153,7 @@ static int drm_minor_alloc(struct drm_device *dev, enum 
> > drm_minor_type type)
> >   static int drm_minor_register(struct drm_device *dev, enum drm_minor_type 
> > type)
> >   {
> > struct drm_minor *minor;
> > -   unsigned long flags;
> > +   void *entry;
> > int ret;
> > DRM_DEBUG("\n");
> > @@ -190,9 +180,12 @@ static int drm_minor_register(struct drm_device *dev, 
> > enum drm_minor_type type)
> > if (minor->type == DRM_MINOR_ACCEL) {
> > accel_minor_replace(minor, minor->index);
> > } else {
> > -   spin_lock_irqsave(_minor_lock, flags);
> > -   idr_replace(_minors_idr, minor, minor->index);
> > -   spin_unlock_irqrestore(_minor_lock, flags);
> > +   entry = xa_store(_minors_xa, minor->index, minor, 
> > GFP_KERNEL);
> > +   if (xa_is_err(entry)) {
> > +   ret = xa_err(entry);
> &

[Intel-gfx] [PATCH v6 4/4] drm: Introduce force_extended_minors modparam

2023-07-24 Thread Michał Winiarski
While there is support for >64 DRM devices on kernel side, existing
userspace may still have some hardcoded assumptions and it's possible
that it will require changes to be able to use more than 64 devices.
Add a modparam to simplify testing and development of >64 devices
support on userspace side by allocating minors from the >=192 range
(without the need of having >64 physical devices connected).

Signed-off-by: Michał Winiarski 
---
 drivers/gpu/drm/drm_drv.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index c2c6e80e6b31..ef6d7b498784 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -57,6 +57,11 @@ MODULE_LICENSE("GPL and additional rights");
 
 DEFINE_XARRAY_ALLOC(drm_minors_xa);
 
+static bool force_extended_minors;
+module_param_unsafe(force_extended_minors, bool, 0400);
+MODULE_PARM_DESC(force_extended_minors,
+"Don't allocate minors in 0-192 range. This can be used for 
testing userspace support for >64 drm devices (default: false)");
+
 /*
  * If the drm core fails to init for whatever reason,
  * we should prevent any drivers from registering with it.
@@ -138,7 +143,7 @@ static void drm_minor_alloc_release(struct drm_device *dev, 
void *data)
 static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type)
 {
struct drm_minor *minor;
-   int r;
+   int r = -EBUSY;
 
minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
if (!minor)
@@ -147,8 +152,9 @@ static int drm_minor_alloc(struct drm_device *dev, enum 
drm_minor_type type)
minor->type = type;
minor->dev = dev;
 
-   r = xa_alloc(drm_minor_get_xa(type), >index,
-NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL);
+   if (type == DRM_MINOR_ACCEL || !force_extended_minors)
+   r = xa_alloc(drm_minor_get_xa(type), >index,
+NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL);
if (r == -EBUSY && (type == DRM_MINOR_PRIMARY || type == 
DRM_MINOR_RENDER))
r = xa_alloc(_minors_xa, >index,
 NULL, DRM_EXTENDED_MINOR_LIMIT, GFP_KERNEL);
-- 
2.41.0



[Intel-gfx] [PATCH v6 3/4] drm: Expand max DRM device number to full MINORBITS

2023-07-24 Thread Michał Winiarski
Having a limit of 64 DRM devices is not good enough for modern world
where we have multi-GPU servers, SR-IOV virtual functions and virtual
devices used for testing.
Let's utilize full minor range for DRM devices.
To avoid regressing the existing userspace, we're still maintaining the
numbering scheme where 0-63 is used for primary, 64-127 is reserved
(formerly for control) and 128-191 is used for render.
For minors >= 192, we're allocating minors dynamically on a first-come,
first-served basis.

Signed-off-by: Michał Winiarski 
---
 drivers/gpu/drm/drm_drv.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 34b60196c443..c2c6e80e6b31 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -121,10 +121,19 @@ static void drm_minor_alloc_release(struct drm_device 
*dev, void *data)
xa_erase(drm_minor_get_xa(minor->type), minor->index);
 }
 
+/*
+ * DRM used to support 64 devices, for backwards compatibility we need to 
maintain the
+ * minor allocation scheme where minors 0-63 are primary nodes, 64-127 are 
control nodes,
+ * and 128-191 are render nodes.
+ * After reaching the limit, we're allocating minors dynamically - first-come, 
first-serve.
+ * Accel nodes are using a distinct major, so the minors are allocated in 
continuous 0-MAX
+ * range.
+ */
 #define DRM_MINOR_LIMIT(t) ({ \
typeof(t) _t = (t); \
_t == DRM_MINOR_ACCEL ? XA_LIMIT(0, ACCEL_MAX_MINORS) : XA_LIMIT(64 * 
_t, 64 * _t + 63); \
 })
+#define DRM_EXTENDED_MINOR_LIMIT XA_LIMIT(192, (1 << MINORBITS) - 1)
 
 static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type)
 {
@@ -140,6 +149,9 @@ static int drm_minor_alloc(struct drm_device *dev, enum 
drm_minor_type type)
 
r = xa_alloc(drm_minor_get_xa(type), >index,
 NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL);
+   if (r == -EBUSY && (type == DRM_MINOR_PRIMARY || type == 
DRM_MINOR_RENDER))
+   r = xa_alloc(_minors_xa, >index,
+NULL, DRM_EXTENDED_MINOR_LIMIT, GFP_KERNEL);
if (r < 0)
return r;
 
-- 
2.41.0



[Intel-gfx] [PATCH v6 2/4] accel: Use XArray instead of IDR for minors

2023-07-24 Thread Michał Winiarski
Accel minor management is based on DRM (and is also using struct
drm_minor internally), since DRM is using XArray for minors, it makes
sense to also convert accel.
As the two implementations are identical (only difference being the
underlying xarray), move the accel_minor_* functionality to DRM.

Signed-off-by: Michał Winiarski 
---
 drivers/accel/drm_accel.c  | 110 +++--
 drivers/gpu/drm/drm_drv.c  |  66 ++--
 drivers/gpu/drm/drm_file.c |   2 +-
 drivers/gpu/drm/drm_internal.h |   4 --
 include/drm/drm_accel.h|  18 +-
 include/drm/drm_file.h |   5 ++
 6 files changed, 47 insertions(+), 158 deletions(-)

diff --git a/drivers/accel/drm_accel.c b/drivers/accel/drm_accel.c
index 4a9baf02439e..8827cb78ca9d 100644
--- a/drivers/accel/drm_accel.c
+++ b/drivers/accel/drm_accel.c
@@ -8,7 +8,7 @@
 
 #include 
 #include 
-#include 
+#include 
 
 #include 
 #include 
@@ -17,8 +17,7 @@
 #include 
 #include 
 
-static DEFINE_SPINLOCK(accel_minor_lock);
-static struct idr accel_minors_idr;
+DEFINE_XARRAY_ALLOC(accel_minors_xa);
 
 static struct dentry *accel_debugfs_root;
 static struct class *accel_class;
@@ -120,99 +119,6 @@ void accel_set_device_instance_params(struct device *kdev, 
int index)
kdev->type = _sysfs_device_minor;
 }
 
-/**
- * accel_minor_alloc() - Allocates a new accel minor
- *
- * This function access the accel minors idr and allocates from it
- * a new id to represent a new accel minor
- *
- * Return: A new id on success or error code in case idr_alloc failed
- */
-int accel_minor_alloc(void)
-{
-   unsigned long flags;
-   int r;
-
-   spin_lock_irqsave(_minor_lock, flags);
-   r = idr_alloc(_minors_idr, NULL, 0, ACCEL_MAX_MINORS, GFP_NOWAIT);
-   spin_unlock_irqrestore(_minor_lock, flags);
-
-   return r;
-}
-
-/**
- * accel_minor_remove() - Remove an accel minor
- * @index: The minor id to remove.
- *
- * This function access the accel minors idr and removes from
- * it the member with the id that is passed to this function.
- */
-void accel_minor_remove(int index)
-{
-   unsigned long flags;
-
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_remove(_minors_idr, index);
-   spin_unlock_irqrestore(_minor_lock, flags);
-}
-
-/**
- * accel_minor_replace() - Replace minor pointer in accel minors idr.
- * @minor: Pointer to the new minor.
- * @index: The minor id to replace.
- *
- * This function access the accel minors idr structure and replaces the pointer
- * that is associated with an existing id. Because the minor pointer can be
- * NULL, we need to explicitly pass the index.
- *
- * Return: 0 for success, negative value for error
- */
-void accel_minor_replace(struct drm_minor *minor, int index)
-{
-   unsigned long flags;
-
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_replace(_minors_idr, minor, index);
-   spin_unlock_irqrestore(_minor_lock, flags);
-}
-
-/*
- * Looks up the given minor-ID and returns the respective DRM-minor object. The
- * refence-count of the underlying device is increased so you must release this
- * object with accel_minor_release().
- *
- * The object can be only a drm_minor that represents an accel device.
- *
- * As long as you hold this minor, it is guaranteed that the object and the
- * minor->dev pointer will stay valid! However, the device may get unplugged 
and
- * unregistered while you hold the minor.
- */
-static struct drm_minor *accel_minor_acquire(unsigned int minor_id)
-{
-   struct drm_minor *minor;
-   unsigned long flags;
-
-   spin_lock_irqsave(_minor_lock, flags);
-   minor = idr_find(_minors_idr, minor_id);
-   if (minor)
-   drm_dev_get(minor->dev);
-   spin_unlock_irqrestore(_minor_lock, flags);
-
-   if (!minor) {
-   return ERR_PTR(-ENODEV);
-   } else if (drm_dev_is_unplugged(minor->dev)) {
-   drm_dev_put(minor->dev);
-   return ERR_PTR(-ENODEV);
-   }
-
-   return minor;
-}
-
-static void accel_minor_release(struct drm_minor *minor)
-{
-   drm_dev_put(minor->dev);
-}
-
 /**
  * accel_open - open method for ACCEL file
  * @inode: device inode
@@ -230,7 +136,7 @@ int accel_open(struct inode *inode, struct file *filp)
struct drm_minor *minor;
int retcode;
 
-   minor = accel_minor_acquire(iminor(inode));
+   minor = drm_minor_acquire(_minors_xa, iminor(inode));
if (IS_ERR(minor))
return PTR_ERR(minor);
 
@@ -249,7 +155,7 @@ int accel_open(struct inode *inode, struct file *filp)
 
 err_undo:
atomic_dec(>open_count);
-   accel_minor_release(minor);
+   drm_minor_release(minor);
return retcode;
 }
 EXPORT_SYMBOL_GPL(accel_open);
@@ -260,7 +166,7 @@ static int accel_stub_open(struct inode *inode, struct file 
*filp)
struct drm_minor *minor;
int err;
 
-   minor = accel_minor_acquire(iminor(i

[Intel-gfx] [PATCH v6 1/4] drm: Use XArray instead of IDR for minors

2023-07-24 Thread Michał Winiarski
IDR is deprecated, and since XArray manages its own state with internal
locking, it simplifies the locking on DRM side.
Additionally, don't use the IRQ-safe variant, since operating on drm
minor is not done in IRQ context.

Signed-off-by: Michał Winiarski 
Suggested-by: Matthew Wilcox 
---
 drivers/gpu/drm/drm_drv.c | 63 ---
 1 file changed, 25 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 3eda026ffac6..3faecb01186f 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -54,8 +55,7 @@ MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon 
Smirl");
 MODULE_DESCRIPTION("DRM shared core routines");
 MODULE_LICENSE("GPL and additional rights");
 
-static DEFINE_SPINLOCK(drm_minor_lock);
-static struct idr drm_minors_idr;
+static DEFINE_XARRAY_ALLOC(drm_minors_xa);
 
 /*
  * If the drm core fails to init for whatever reason,
@@ -101,26 +101,23 @@ static struct drm_minor **drm_minor_get_slot(struct 
drm_device *dev,
 static void drm_minor_alloc_release(struct drm_device *dev, void *data)
 {
struct drm_minor *minor = data;
-   unsigned long flags;
 
WARN_ON(dev != minor->dev);
 
put_device(minor->kdev);
 
-   if (minor->type == DRM_MINOR_ACCEL) {
+   if (minor->type == DRM_MINOR_ACCEL)
accel_minor_remove(minor->index);
-   } else {
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_remove(_minors_idr, minor->index);
-   spin_unlock_irqrestore(_minor_lock, flags);
-   }
+   else
+   xa_erase(_minors_xa, minor->index);
 }
 
+#define DRM_MINOR_LIMIT(t) ({ typeof(t) _t = (t); XA_LIMIT(64 * _t, 64 * _t + 
63); })
+
 static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type)
 {
struct drm_minor *minor;
-   unsigned long flags;
-   int r;
+   int index, r;
 
minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
if (!minor)
@@ -129,24 +126,17 @@ static int drm_minor_alloc(struct drm_device *dev, enum 
drm_minor_type type)
minor->type = type;
minor->dev = dev;
 
-   idr_preload(GFP_KERNEL);
if (type == DRM_MINOR_ACCEL) {
r = accel_minor_alloc();
+   index = r;
} else {
-   spin_lock_irqsave(_minor_lock, flags);
-   r = idr_alloc(_minors_idr,
-   NULL,
-   64 * type,
-   64 * (type + 1),
-   GFP_NOWAIT);
-   spin_unlock_irqrestore(_minor_lock, flags);
+   r = xa_alloc(_minors_xa, , NULL, 
DRM_MINOR_LIMIT(type), GFP_KERNEL);
}
-   idr_preload_end();
 
if (r < 0)
return r;
 
-   minor->index = r;
+   minor->index = index;
 
r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
if (r)
@@ -163,7 +153,7 @@ static int drm_minor_alloc(struct drm_device *dev, enum 
drm_minor_type type)
 static int drm_minor_register(struct drm_device *dev, enum drm_minor_type type)
 {
struct drm_minor *minor;
-   unsigned long flags;
+   void *entry;
int ret;
 
DRM_DEBUG("\n");
@@ -190,9 +180,12 @@ static int drm_minor_register(struct drm_device *dev, enum 
drm_minor_type type)
if (minor->type == DRM_MINOR_ACCEL) {
accel_minor_replace(minor, minor->index);
} else {
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_replace(_minors_idr, minor, minor->index);
-   spin_unlock_irqrestore(_minor_lock, flags);
+   entry = xa_store(_minors_xa, minor->index, minor, 
GFP_KERNEL);
+   if (xa_is_err(entry)) {
+   ret = xa_err(entry);
+   goto err_debugfs;
+   }
+   WARN_ON(entry);
}
 
DRM_DEBUG("new minor registered %d\n", minor->index);
@@ -206,20 +199,16 @@ static int drm_minor_register(struct drm_device *dev, 
enum drm_minor_type type)
 static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type 
type)
 {
struct drm_minor *minor;
-   unsigned long flags;
 
minor = *drm_minor_get_slot(dev, type);
if (!minor || !device_is_registered(minor->kdev))
return;
 
/* replace @minor with NULL so lookups will fail from now on */
-   if (minor->type == DRM_MINOR_ACCEL) {
+   if (minor->type == DRM_MINOR_ACCEL)
accel_minor_replace(NULL, minor->index);
-   } else {
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_replace(_minors_idr, NULL, minor->index);
-   spin_unlock_irqres

[Intel-gfx] [PATCH v6 0/4] drm: Use full allocated minor range for DRM

2023-07-24 Thread Michał Winiarski
64 DRM device nodes is not enough for everyone.
Upgrade it to ~512K (which definitely is more than enough).

To allow testing userspace support for >64 devices, add additional DRM
modparam (force_extended_minors) which causes DRM to skip allocating minors
in 0-192 range.
Additionally - convert minors to use XArray instead of IDR to simplify the
locking.

v1 -> v2:
Don't touch DRM_MINOR_CONTROL and its range (Simon Ser)

v2 -> v3:
Don't use legacy scheme for >=192 minor range (Dave Airlie)
Add modparam for testing (Dave Airlie)
Add lockdep annotation for IDR (Daniel Vetter)

v3 -> v4:
Convert from IDR to XArray (Matthew Wilcox)

v4 -> v5:
Fixup IDR to XArray conversion (Matthew Wilcox)

v5 -> v6:
Also convert Accel to XArray
Rename skip_legacy_minors to force_extended_minors

Michał Winiarski (4):
  drm: Use XArray instead of IDR for minors
  accel: Use XArray instead of IDR for minors
  drm: Expand max DRM device number to full MINORBITS
  drm: Introduce force_extended_minors modparam

 drivers/accel/drm_accel.c  | 110 +++--
 drivers/gpu/drm/drm_drv.c  | 105 ---
 drivers/gpu/drm/drm_file.c |   2 +-
 drivers/gpu/drm/drm_internal.h |   4 --
 include/drm/drm_accel.h|  18 +-
 include/drm/drm_file.h |   5 ++
 6 files changed, 69 insertions(+), 175 deletions(-)

-- 
2.41.0



Re: [Intel-gfx] [PATCH RESEND] drm/tests: Suballocator test

2023-03-26 Thread Michał Winiarski
On Thu, Mar 02, 2023 at 09:34:22AM +0100, Thomas Hellström wrote:
> Add a suballocator test to get some test coverage for the new drm
> suballocator, and perform some basic timing (elapsed time).
> 
> Signed-off-by: Thomas Hellström 
> ---
>  drivers/gpu/drm/Kconfig   |   1 +
>  drivers/gpu/drm/tests/Makefile|   3 +-
>  drivers/gpu/drm/tests/drm_suballoc_test.c | 356 ++
>  3 files changed, 359 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/tests/drm_suballoc_test.c
> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 8fbe57407c60..dced53723721 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -78,6 +78,7 @@ config DRM_KUNIT_TEST
>   select DRM_LIB_RANDOM
>   select DRM_KMS_HELPER
>   select DRM_BUDDY
> + select DRM_SUBALLOC_HELPER
>   select DRM_EXPORT_FOR_TESTS if m
>   select DRM_KUNIT_TEST_HELPERS
>   default KUNIT_ALL_TESTS
> diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile
> index bca726a8f483..c664944a48ab 100644
> --- a/drivers/gpu/drm/tests/Makefile
> +++ b/drivers/gpu/drm/tests/Makefile
> @@ -17,6 +17,7 @@ obj-$(CONFIG_DRM_KUNIT_TEST) += \
>   drm_modes_test.o \
>   drm_plane_helper_test.o \
>   drm_probe_helper_test.o \
> - drm_rect_test.o
> + drm_rect_test.o \
> + drm_suballoc_test.o
>  
>  CFLAGS_drm_mm_test.o := $(DISABLE_STRUCTLEAK_PLUGIN)
> diff --git a/drivers/gpu/drm/tests/drm_suballoc_test.c 
> b/drivers/gpu/drm/tests/drm_suballoc_test.c
> new file mode 100644
> index ..e7303a5505a0
> --- /dev/null
> +++ b/drivers/gpu/drm/tests/drm_suballoc_test.c
> @@ -0,0 +1,356 @@
> +// SPDX-License-Identifier: GPL-2.0 OR MIT
> +/*
> + * Test case for the drm_suballoc suballocator manager
> + * Copyright 2023 Intel Corporation.
> + */
> +
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define SA_ITERATIONS 1
> +#define SA_SIZE SZ_1M
> +#define SA_DEFAULT_ALIGN SZ_4K
> +
> +static bool intr = true;
> +static bool from_reclaim;
> +static bool pre_throttle;
> +static unsigned int num_rings = 4;
> +static unsigned int iterations = SA_ITERATIONS;
> +
> +static atomic64_t free_space;
> +
> +static atomic_t other_id;
> +
> +struct suballoc_fence;
> +
> +/**
> + * struct suballoc_ring - fake gpu engine.
> + * @list: List of fences to signal.
> + * @signal_time: Accumulated fence signal execution time.
> + * @lock: Protects the suballoc ring members. hardirq safe.
> + * @hrtimer: Fake execution time timer.
> + * @active: The currently active fence for which we have pending work or a
> + *  timer running.
> + * @seqno: Fence submissin seqno.
> + * @idx: Index for calculation of fake execution time.
> + * @work: Work struct used solely to move the timer start to a different
> + *processor than that used for submission.
> + */
> +struct suballoc_ring {
> + ktime_t signal_time;
> + struct list_head list;
> + /* Protect the ring processing. */
> + spinlock_t lock;
> + struct hrtimer hrtimer;
> + struct suballoc_fence *active;
> + atomic64_t seqno;
> + u32 idx;
> + struct work_struct work;
> +};
> +
> +/**
> + * struct suballoc_fence - Hrtimer-driven fence.
> + * @fence: The base class fence struct.
> + * @link: Link for the ring's fence list.
> + * @size: The size of the suballocator range associated with this fence.
> + * @id: Cpu id likely used by the submission thread for suballoc allocation.
> + */
> +struct suballoc_fence {
> + struct dma_fence fence;
> + struct list_head link;
> + size_t size;
> + unsigned int id;
> +};
> +
> +/* A varying but repeatable fake execution time */
> +static ktime_t ring_next_delay(struct suballoc_ring *ring)
> +{
> + return ns_to_ktime((u64)(++ring->idx % 8) * 200 * NSEC_PER_USEC);
> +}

Is there any way we can avoid using time (and large number of
iterations) here, while keeping the coverage?
drm_suballoc have longest runtime out of all tests in DRM (taking ~60%
of the whole DRM kunit execution, drm_mm being the second and taking
~35%, without those two suites DRM tests execute in milliseconds rather
than tens of seconds),
Building test cases in a way that operate on time basis makes it tricky
to optimize the runtime.
If we extract various parameters from modparams to separate test cases,
it's going to get even worse.

> +
> +/*
> + * Launch from a work item to decrease the likelyhood of the timer expiry
> + * callback getting called from the allocating cpu.
> + * We want to trigger cache-line bouncing between allocating and signalling
> + * cpus.
> + */
> +static void ring_launch_timer_work(struct work_struct *work)
> +{
> + struct suballoc_ring *ring =
> + container_of(work, typeof(*ring), work);
> +
> + spin_lock_irq(>lock);
> + if (ring->active)
> + 

Re: [Intel-gfx] KUnit issues - Was: [igt-dev] [PATCH RFC v2 8/8] drm/i915: check if current->mm is not NULL

2022-11-07 Thread Michał Winiarski
On Thu, Nov 03, 2022 at 04:23:02PM +0100, Mauro Carvalho Chehab wrote:
> Hi,
> 
> I'm facing a couple of issues when testing KUnit with the i915 driver.
> 
> The DRM subsystem and the i915 driver has, for a long time, his own
> way to do unit tests, which seems to be added before KUnit.
> 
> I'm now checking if it is worth start using KUnit at i915. So, I wrote
> a RFC with some patches adding support for the tests we have to be
> reported using Kernel TAP and KUnit.
> 
> There are basically 3 groups of tests there:
> 
> - mock tests - check i915 hardware-independent logic;
> - live tests - run some hardware-specific tests;
> - perf tests - check perf support - also hardware-dependent.
> 
> As they depend on i915 driver, they run only on x86, with PCI
> stack enabled, but the mock tests run nicely via qemu.
> 
> The live and perf tests require a real hardware. As we run them
> together with our CI, which, among other things, test module
> unload/reload and test loading i915 driver with different
> modprobe parameters, the KUnit tests should be able to run as
> a module.

Note that KUnit tests that are doing more of a functional/integration
testing (on "live" hardware) rather than unit testing (where hardware
interactions are mocked) are not very common.
Do we have other KUnit tests like this merged?
Some of the "live tests" are not even that, being more of a pure
hardware tests (e.g. live_workarounds, which is checking whether values
in MMIO regs stick over various HW state transitions).

I'm wondering, is KUnit the right tool for this job?

-Michał


Re: [Intel-gfx] [PATCH v5 1/3] drm: Use XArray instead of IDR for minors

2022-11-07 Thread Michał Winiarski
On Sun, Nov 06, 2022 at 04:51:39PM +0200, Oded Gabbay wrote:
> On Wed, Nov 2, 2022 at 4:23 PM Oded Gabbay  wrote:
> >
> > On Mon, Sep 12, 2022 at 12:17 AM Michał Winiarski
> >  wrote:
> > >
> > > IDR is deprecated, and since XArray manages its own state with internal
> > > locking, it simplifies the locking on DRM side.
> > > Additionally, don't use the IRQ-safe variant, since operating on drm
> > > minor is not done in IRQ context.
> > >
> > > Signed-off-by: Michał Winiarski 
> > > Suggested-by: Matthew Wilcox 
> > > ---
> > >  drivers/gpu/drm/drm_drv.c | 51 ++-
> > >  1 file changed, 18 insertions(+), 33 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > > index 8214a0b1ab7f..61d24cdcd0f8 100644
> > > --- a/drivers/gpu/drm/drm_drv.c
> > > +++ b/drivers/gpu/drm/drm_drv.c
> > > @@ -34,6 +34,7 @@
> > >  #include 
> > >  #include 
> > >  #include 
> > > +#include 
> > >
> > >  #include 
> > >  #include 
> > > @@ -53,8 +54,7 @@ MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José 
> > > Fonseca, Jon Smirl");
> > >  MODULE_DESCRIPTION("DRM shared core routines");
> > >  MODULE_LICENSE("GPL and additional rights");
> > >
> > > -static DEFINE_SPINLOCK(drm_minor_lock);
> > > -static struct idr drm_minors_idr;
> > > +static DEFINE_XARRAY_ALLOC(drm_minors_xa);
> > >
> > >  /*
> > >   * If the drm core fails to init for whatever reason,
> > > @@ -98,21 +98,19 @@ static struct drm_minor **drm_minor_get_slot(struct 
> > > drm_device *dev,
> > >  static void drm_minor_alloc_release(struct drm_device *dev, void *data)
> > >  {
> > > struct drm_minor *minor = data;
> > > -   unsigned long flags;
> > >
> > > WARN_ON(dev != minor->dev);
> > >
> > > put_device(minor->kdev);
> > >
> > > -   spin_lock_irqsave(_minor_lock, flags);
> > > -   idr_remove(_minors_idr, minor->index);
> > > -   spin_unlock_irqrestore(_minor_lock, flags);
> > > +   xa_erase(_minors_xa, minor->index);
> > >  }
> > >
> > > +#define DRM_MINOR_LIMIT(t) ({ typeof(t) _t = (t); XA_LIMIT(64 * _t, 64 * 
> > > _t + 63); })
> > > +
> > >  static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
> > >  {
> > > struct drm_minor *minor;
> > > -   unsigned long flags;
> > > int r;
> > >
> > > minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
> > > @@ -122,21 +120,10 @@ static int drm_minor_alloc(struct drm_device *dev, 
> > > unsigned int type)
> > > minor->type = type;
> > > minor->dev = dev;
> > >
> > > -   idr_preload(GFP_KERNEL);
> > > -   spin_lock_irqsave(_minor_lock, flags);
> > > -   r = idr_alloc(_minors_idr,
> > > - NULL,
> > > - 64 * type,
> > > - 64 * (type + 1),
> > > - GFP_NOWAIT);
> > > -   spin_unlock_irqrestore(_minor_lock, flags);
> > > -   idr_preload_end();
> > > -
> > > +   r = xa_alloc(_minors_xa, >index, NULL, 
> > > DRM_MINOR_LIMIT(type), GFP_KERNEL);
> This was GFP_NOWAIT in the original code.

Because we were using spinlock and idr_preload.
We're actually fine with GFP_KERNEL (and we could just use mutex with
idr):
https://lore.kernel.org/dri-devel/20220823210612.296922-3-michal.winiar...@intel.com/

> 
> > > if (r < 0)
> > > return r;
> > >
> > > -   minor->index = r;
> > > -
> > > r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
> > > if (r)
> > > return r;
> > > @@ -152,7 +139,7 @@ static int drm_minor_alloc(struct drm_device *dev, 
> > > unsigned int type)
> > >  static int drm_minor_register(struct drm_device *dev, unsigned int type)
> > >  {
> > > struct drm_minor *minor;
> > > -   unsigned long flags;
> > > +   void *entry;
> > > int ret;
> > >
> > > DRM_DEBUG("\n");
> > > @@ -172,9 +159,12 @@ static int drm_minor_register(struct drm_device 
> > > *dev, unsigned i

[Intel-gfx] [PATCH v3] drm: Use XArray instead of IDR for minors

2022-11-07 Thread Michał Winiarski
IDR is deprecated, and since XArray manages its own state with internal
locking, it simplifies the locking on DRM side.
Additionally, don't use the IRQ-safe variant, since operating on drm
minor is not done in IRQ context.

Signed-off-by: Michał Winiarski 
Suggested-by: Matthew Wilcox 
---
This was originally sent as v4/v5 in larger series:
https://lore.kernel.org/dri-devel/20220911211443.581481-2-michal.winiar...@intel.com/
v1 -> v2:
Fixed locking and corrected some misuse of XArray API (Matthew Wilcox)
v2 -> v3:
Store correct pointer, use xa_store rather than xa_cmpxchg (Oded Gabbay)

 drivers/gpu/drm/drm_drv.c | 51 ++-
 1 file changed, 18 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 8214a0b1ab7f..bdcdfeac76bf 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -53,8 +54,7 @@ MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon 
Smirl");
 MODULE_DESCRIPTION("DRM shared core routines");
 MODULE_LICENSE("GPL and additional rights");
 
-static DEFINE_SPINLOCK(drm_minor_lock);
-static struct idr drm_minors_idr;
+static DEFINE_XARRAY_ALLOC(drm_minors_xa);
 
 /*
  * If the drm core fails to init for whatever reason,
@@ -98,21 +98,19 @@ static struct drm_minor **drm_minor_get_slot(struct 
drm_device *dev,
 static void drm_minor_alloc_release(struct drm_device *dev, void *data)
 {
struct drm_minor *minor = data;
-   unsigned long flags;
 
WARN_ON(dev != minor->dev);
 
put_device(minor->kdev);
 
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_remove(_minors_idr, minor->index);
-   spin_unlock_irqrestore(_minor_lock, flags);
+   xa_erase(_minors_xa, minor->index);
 }
 
+#define DRM_MINOR_LIMIT(t) ({ typeof(t) _t = (t); XA_LIMIT(64 * _t, 64 * _t + 
63); })
+
 static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 {
struct drm_minor *minor;
-   unsigned long flags;
int r;
 
minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
@@ -122,21 +120,10 @@ static int drm_minor_alloc(struct drm_device *dev, 
unsigned int type)
minor->type = type;
minor->dev = dev;
 
-   idr_preload(GFP_KERNEL);
-   spin_lock_irqsave(_minor_lock, flags);
-   r = idr_alloc(_minors_idr,
- NULL,
- 64 * type,
- 64 * (type + 1),
- GFP_NOWAIT);
-   spin_unlock_irqrestore(_minor_lock, flags);
-   idr_preload_end();
-
+   r = xa_alloc(_minors_xa, >index, NULL, 
DRM_MINOR_LIMIT(type), GFP_KERNEL);
if (r < 0)
return r;
 
-   minor->index = r;
-
r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
if (r)
return r;
@@ -152,7 +139,7 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned 
int type)
 static int drm_minor_register(struct drm_device *dev, unsigned int type)
 {
struct drm_minor *minor;
-   unsigned long flags;
+   void *entry;
int ret;
 
DRM_DEBUG("\n");
@@ -172,9 +159,12 @@ static int drm_minor_register(struct drm_device *dev, 
unsigned int type)
goto err_debugfs;
 
/* replace NULL with @minor so lookups will succeed from now on */
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_replace(_minors_idr, minor, minor->index);
-   spin_unlock_irqrestore(_minor_lock, flags);
+   entry = xa_store(_minors_xa, minor->index, minor, GFP_KERNEL);
+   if (xa_is_err(entry)) {
+   ret = xa_err(entry);
+   goto err_debugfs;
+   }
+   WARN_ON(entry);
 
DRM_DEBUG("new minor registered %d\n", minor->index);
return 0;
@@ -187,16 +177,13 @@ static int drm_minor_register(struct drm_device *dev, 
unsigned int type)
 static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
 {
struct drm_minor *minor;
-   unsigned long flags;
 
minor = *drm_minor_get_slot(dev, type);
if (!minor || !device_is_registered(minor->kdev))
return;
 
/* replace @minor with NULL so lookups will fail from now on */
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_replace(_minors_idr, NULL, minor->index);
-   spin_unlock_irqrestore(_minor_lock, flags);
+   xa_store(_minors_xa, minor->index, NULL, GFP_KERNEL);
 
device_del(minor->kdev);
dev_set_drvdata(minor->kdev, NULL); /* safety belt */
@@ -215,13 +202,12 @@ static void drm_minor_unregister(struct drm_device *dev, 
unsigned int type)
 struct drm_minor *drm_minor_acquire(unsigned int minor_id)
 {
struct drm_minor *minor;
-   unsigned long flags;
 
-   spin_lock_irqsave(_minor_lock, flags);
-

Re: [Intel-gfx] [PATCH v5 07/22] drm/client: Add some tests for drm_connector_pick_cmdline_mode()

2022-10-20 Thread Michał Winiarski
On Thu, Oct 13, 2022 at 03:18:51PM +0200, Maxime Ripard wrote:
> +static struct kunit_case drm_pick_cmdline_tests[] = {
> + KUNIT_CASE(drm_pick_cmdline_res_1920_1080_60),
> + {}
> +};

drm_test_pick_cmdline_res_1920_1080_60, since we adopted a consistent naming
convention for test cases in DRM.

-Michał

> +
> +static struct kunit_suite drm_pick_cmdline_test_suite = {
> + .name = "drm_pick_cmdline",
> + .init = drm_client_modeset_test_init,
> + .test_cases = drm_pick_cmdline_tests
> +};
> +
> +kunit_test_suite(drm_pick_cmdline_test_suite);
> 
> -- 
> b4 0.11.0-dev-7da52
> 


[Intel-gfx] [PATCH v5 2/3] drm: Expand max DRM device number to full MINORBITS

2022-09-11 Thread Michał Winiarski
Having a limit of 64 DRM devices is not good enough for modern world
where we have multi-GPU servers, SR-IOV virtual functions and virtual
devices used for testing.
Let's utilize full minor range for DRM devices.
To avoid regressing the existing userspace, we're still maintaining the
numbering scheme where 0-63 is used for primary, 64-127 is reserved
(formerly for control) and 128-191 is used for render.
For minors >= 192, we're allocating minors dynamically on a first-come,
first-served basis.

Signed-off-by: Michał Winiarski 
---
 drivers/gpu/drm/drm_drv.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 61d24cdcd0f8..3718bd6bbef6 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -106,7 +106,8 @@ static void drm_minor_alloc_release(struct drm_device *dev, 
void *data)
xa_erase(_minors_xa, minor->index);
 }
 
-#define DRM_MINOR_LIMIT(t) ({ typeof(t) _t = (t); XA_LIMIT(64 * _t, 64 * _t + 
63); })
+#define DRM_LEGACY_MINOR_LIMIT(t) ({ typeof(t) _t = (t); XA_LIMIT(64 * _t, 64 
* _t + 63); })
+#define DRM_MINOR_LIMIT XA_LIMIT(192, (1 << MINORBITS) - 1)
 
 static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 {
@@ -120,7 +121,15 @@ static int drm_minor_alloc(struct drm_device *dev, 
unsigned int type)
minor->type = type;
minor->dev = dev;
 
-   r = xa_alloc(_minors_xa, >index, NULL, 
DRM_MINOR_LIMIT(type), GFP_KERNEL);
+   /*
+* DRM used to support 64 devices, for backwards compatibility we need 
to maintain the
+* minor allocation scheme where minors 0-63 are primary nodes, 64-127 
are control nodes,
+* and 128-191 are render nodes.
+* After reaching the limit, we're allocating minors dynamically - 
first-come, first-serve.
+*/
+   r = xa_alloc(_minors_xa, >index, NULL, 
DRM_LEGACY_MINOR_LIMIT(type), GFP_KERNEL);
+   if (r == -EBUSY)
+   r = xa_alloc(_minors_xa, >index, NULL, 
DRM_MINOR_LIMIT, GFP_KERNEL);
if (r < 0)
return r;
 
-- 
2.37.3



[Intel-gfx] [PATCH v5 3/3] drm: Introduce skip_legacy_minors modparam

2022-09-11 Thread Michał Winiarski
While there is support for >64 DRM devices on kernel side, existing
userspace may still have some hardcoded assumptions and it's possible
that it will require changes to be able to use more than 64 devices.
Add a modparam to simplify testing and development of >64 devices
support on userspace side by allocating minors from the >=192 range
(without the need of having >64 physical devices connected).

Signed-off-by: Michał Winiarski 
---
 drivers/gpu/drm/drm_drv.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 3718bd6bbef6..368408997fed 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -56,6 +56,11 @@ MODULE_LICENSE("GPL and additional rights");
 
 static DEFINE_XARRAY_ALLOC(drm_minors_xa);
 
+static bool skip_legacy_minors;
+module_param_unsafe(skip_legacy_minors, bool, 0400);
+MODULE_PARM_DESC(skip_legacy_minors,
+"Don't allocate minors in 0-192 range. This can be used for 
testing userspace support for >64 drm devices (default: false)");
+
 /*
  * If the drm core fails to init for whatever reason,
  * we should prevent any drivers from registering with it.
@@ -112,7 +117,7 @@ static void drm_minor_alloc_release(struct drm_device *dev, 
void *data)
 static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 {
struct drm_minor *minor;
-   int r;
+   int r = -EBUSY;
 
minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
if (!minor)
@@ -127,7 +132,8 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned 
int type)
 * and 128-191 are render nodes.
 * After reaching the limit, we're allocating minors dynamically - 
first-come, first-serve.
 */
-   r = xa_alloc(_minors_xa, >index, NULL, 
DRM_LEGACY_MINOR_LIMIT(type), GFP_KERNEL);
+   if (!skip_legacy_minors)
+   r = xa_alloc(_minors_xa, >index, NULL, 
DRM_LEGACY_MINOR_LIMIT(type), GFP_KERNEL);
if (r == -EBUSY)
r = xa_alloc(_minors_xa, >index, NULL, 
DRM_MINOR_LIMIT, GFP_KERNEL);
if (r < 0)
-- 
2.37.3



[Intel-gfx] [PATCH v5 1/3] drm: Use XArray instead of IDR for minors

2022-09-11 Thread Michał Winiarski
IDR is deprecated, and since XArray manages its own state with internal
locking, it simplifies the locking on DRM side.
Additionally, don't use the IRQ-safe variant, since operating on drm
minor is not done in IRQ context.

Signed-off-by: Michał Winiarski 
Suggested-by: Matthew Wilcox 
---
 drivers/gpu/drm/drm_drv.c | 51 ++-
 1 file changed, 18 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 8214a0b1ab7f..61d24cdcd0f8 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -53,8 +54,7 @@ MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon 
Smirl");
 MODULE_DESCRIPTION("DRM shared core routines");
 MODULE_LICENSE("GPL and additional rights");
 
-static DEFINE_SPINLOCK(drm_minor_lock);
-static struct idr drm_minors_idr;
+static DEFINE_XARRAY_ALLOC(drm_minors_xa);
 
 /*
  * If the drm core fails to init for whatever reason,
@@ -98,21 +98,19 @@ static struct drm_minor **drm_minor_get_slot(struct 
drm_device *dev,
 static void drm_minor_alloc_release(struct drm_device *dev, void *data)
 {
struct drm_minor *minor = data;
-   unsigned long flags;
 
WARN_ON(dev != minor->dev);
 
put_device(minor->kdev);
 
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_remove(_minors_idr, minor->index);
-   spin_unlock_irqrestore(_minor_lock, flags);
+   xa_erase(_minors_xa, minor->index);
 }
 
+#define DRM_MINOR_LIMIT(t) ({ typeof(t) _t = (t); XA_LIMIT(64 * _t, 64 * _t + 
63); })
+
 static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 {
struct drm_minor *minor;
-   unsigned long flags;
int r;
 
minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
@@ -122,21 +120,10 @@ static int drm_minor_alloc(struct drm_device *dev, 
unsigned int type)
minor->type = type;
minor->dev = dev;
 
-   idr_preload(GFP_KERNEL);
-   spin_lock_irqsave(_minor_lock, flags);
-   r = idr_alloc(_minors_idr,
- NULL,
- 64 * type,
- 64 * (type + 1),
- GFP_NOWAIT);
-   spin_unlock_irqrestore(_minor_lock, flags);
-   idr_preload_end();
-
+   r = xa_alloc(_minors_xa, >index, NULL, 
DRM_MINOR_LIMIT(type), GFP_KERNEL);
if (r < 0)
return r;
 
-   minor->index = r;
-
r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
if (r)
return r;
@@ -152,7 +139,7 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned 
int type)
 static int drm_minor_register(struct drm_device *dev, unsigned int type)
 {
struct drm_minor *minor;
-   unsigned long flags;
+   void *entry;
int ret;
 
DRM_DEBUG("\n");
@@ -172,9 +159,12 @@ static int drm_minor_register(struct drm_device *dev, 
unsigned int type)
goto err_debugfs;
 
/* replace NULL with @minor so lookups will succeed from now on */
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_replace(_minors_idr, minor, minor->index);
-   spin_unlock_irqrestore(_minor_lock, flags);
+   entry = xa_cmpxchg(_minors_xa, minor->index, NULL, , 
GFP_KERNEL);
+   if (xa_is_err(entry)) {
+   ret = xa_err(entry);
+   goto err_debugfs;
+   }
+   WARN_ON(entry);
 
DRM_DEBUG("new minor registered %d\n", minor->index);
return 0;
@@ -187,16 +177,13 @@ static int drm_minor_register(struct drm_device *dev, 
unsigned int type)
 static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
 {
struct drm_minor *minor;
-   unsigned long flags;
 
minor = *drm_minor_get_slot(dev, type);
if (!minor || !device_is_registered(minor->kdev))
return;
 
/* replace @minor with NULL so lookups will fail from now on */
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_replace(_minors_idr, NULL, minor->index);
-   spin_unlock_irqrestore(_minor_lock, flags);
+   xa_store(_minors_xa, minor->index, NULL, GFP_KERNEL);
 
device_del(minor->kdev);
dev_set_drvdata(minor->kdev, NULL); /* safety belt */
@@ -215,13 +202,12 @@ static void drm_minor_unregister(struct drm_device *dev, 
unsigned int type)
 struct drm_minor *drm_minor_acquire(unsigned int minor_id)
 {
struct drm_minor *minor;
-   unsigned long flags;
 
-   spin_lock_irqsave(_minor_lock, flags);
-   minor = idr_find(_minors_idr, minor_id);
+   xa_lock(_minors_xa);
+   minor = xa_load(_minors_xa, minor_id);
if (minor)
drm_dev_get(minor->dev);
-   spin_unlock_irqrestore(_minor_lock, flags);
+   xa_unlock(_minors_xa);
 
if (!minor) {

[Intel-gfx] [PATCH v5 0/3] drm: Use full allocated minor range for DRM

2022-09-11 Thread Michał Winiarski
64 DRM device nodes is not enough for everyone.
Upgrade it to ~512K (which definitely is more than enough).

To allow testing userspace support for >64 devices, add additional DRM
modparam (skip_legacy_minors) which causes DRM to skip allocating minors
in 0-192 range.
Additionally - convert minors to use XArray instead of IDR to simplify the
locking.

v1 -> v2:
Don't touch DRM_MINOR_CONTROL and its range (Simon Ser)

v2 -> v3:
Don't use legacy scheme for >=192 minor range (Dave Airlie)
Add modparam for testing (Dave Airlie)
Add lockdep annotation for IDR (Daniel Vetter)

v3 -> v4:
Convert from IDR to XArray (Matthew Wilcox)

v4 -> v5:
Fixup IDR to XArray conversion (Matthew Wilcox)

Michał Winiarski (3):
  drm: Use XArray instead of IDR for minors
  drm: Expand max DRM device number to full MINORBITS
  drm: Introduce skip_legacy_minors modparam

 drivers/gpu/drm/drm_drv.c | 68 +++
 1 file changed, 34 insertions(+), 34 deletions(-)

-- 
2.37.3



Re: [Intel-gfx] [PATCH v4 1/3] drm: Use XArray instead of IDR for minors

2022-09-11 Thread Michał Winiarski
On Tue, Sep 06, 2022 at 10:02:24PM +0100, Matthew Wilcox wrote:
> On Tue, Sep 06, 2022 at 10:16:27PM +0200, Michał Winiarski wrote:
> > IDR is deprecated, and since XArray manages its own state with internal
> > locking, it simplifies the locking on DRM side.
> > Additionally, don't use the IRQ-safe variant, since operating on drm
> > minor is not done in IRQ context.
> > 
> > Signed-off-by: Michał Winiarski 
> > Suggested-by: Matthew Wilcox 
> 
> I have a few questions, but I like where you're going.
> 
> > @@ -98,21 +98,18 @@ static struct drm_minor **drm_minor_get_slot(struct 
> > drm_device *dev,
> >  static void drm_minor_alloc_release(struct drm_device *dev, void *data)
> >  {
> > struct drm_minor *minor = data;
> > -   unsigned long flags;
> >  
> > WARN_ON(dev != minor->dev);
> >  
> > put_device(minor->kdev);
> >  
> > -   spin_lock_irqsave(_minor_lock, flags);
> > -   idr_remove(_minors_idr, minor->index);
> > -   spin_unlock_irqrestore(_minor_lock, flags);
> > +   xa_release(_minors_xa, minor->index);
> 
> Has it definitely been unused at this point?  I would think that
> xa_erase() (an unconditional store) would be the correct function to
> call.

Yes, unless there's a programmers error somewhere - I'll replace it though.

> 
> > @@ -122,20 +119,12 @@ static int drm_minor_alloc(struct drm_device *dev, 
> > unsigned int type)
> > minor->type = type;
> > minor->dev = dev;
> >  
> > -   idr_preload(GFP_KERNEL);
> > -   spin_lock_irqsave(_minor_lock, flags);
> > -   r = idr_alloc(_minors_idr,
> > - NULL,
> > - 64 * type,
> > - 64 * (type + 1),
> > - GFP_NOWAIT);
> > -   spin_unlock_irqrestore(_minor_lock, flags);
> > -   idr_preload_end();
> > -
> > +   r = xa_alloc(_minors_xa, , NULL,
> > +XA_LIMIT(64 * type, 64 * (type + 1) - 1), GFP_KERNEL);
> > if (r < 0)
> > return r;
> >  
> > -   minor->index = r;
> > +   minor->index = id;
> 
> Wouldn't it be better to call:
> 
>   r = xa_alloc(_minors_xa, >index, NULL,
>   XA_LIMIT(64 * type, 64 * (type + 1) - 1), GFP_KERNEL);
> 
> I might also prefer a little syntactic sugar like:
> 
> #define DRM_MINOR_LIMIT(type) XA_LIMIT(64 * (type), 64 * (type) + 63)
> 
> but that's definitely a matter of taste.

Sure.

> 
> > @@ -172,9 +161,12 @@ static int drm_minor_register(struct drm_device *dev, 
> > unsigned int type)
> > goto err_debugfs;
> >  
> > /* replace NULL with @minor so lookups will succeed from now on */
> > -   spin_lock_irqsave(_minor_lock, flags);
> > -   idr_replace(_minors_idr, minor, minor->index);
> > -   spin_unlock_irqrestore(_minor_lock, flags);
> > +   entry = xa_store(_minors_xa, minor->index, , GFP_KERNEL);
> > +   if (xa_is_err(entry)) {
> > +   ret = xa_err(entry);
> > +   goto err_debugfs;
> > +   }
> > +   WARN_ON(entry);
> 
> Might be better as an xa_cmpxchg()?

Ack.

> 
> > @@ -187,16 +179,13 @@ static int drm_minor_register(struct drm_device *dev, 
> > unsigned int type)
> >  static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
> >  {
> > struct drm_minor *minor;
> > -   unsigned long flags;
> >  
> > minor = *drm_minor_get_slot(dev, type);
> > if (!minor || !device_is_registered(minor->kdev))
> > return;
> >  
> > /* replace @minor with NULL so lookups will fail from now on */
> > -   spin_lock_irqsave(_minor_lock, flags);
> > -   idr_replace(_minors_idr, NULL, minor->index);
> > -   spin_unlock_irqrestore(_minor_lock, flags);
> > +   xa_erase(_minors_xa, minor->index);
> 
> This isn't an exact replacement, but I'm not sure whether that makes a
> difference.  xa_erase() allows allocation of this ID again while
> idr_replace() means that lookups return NULL, but the ID remains in
> use.  The equivalent of idr_replace() is:
>   xa_store(_minors_xa, minor->index, NULL, GFP_KERNEL);

It does makes a difference, I'll change it to the equivalent.

> 
> > @@ -215,13 +204,10 @@ static void drm_minor_unregister(struct drm_device 
> > *dev, unsigned int type)
> >  struct drm_minor *drm_minor_acquire(unsigned int minor_id)
> >  {
> > struct drm_minor *minor;
> > -   unsigned long flags;
> >  
> > -   spin_lock_irqsave(_minor_lock, flags);
> > -   minor = idr_find(_minors_idr, minor

[Intel-gfx] [PATCH v4 2/3] drm: Expand max DRM device number to full MINORBITS

2022-09-06 Thread Michał Winiarski
Having a limit of 64 DRM devices is not good enough for modern world
where we have multi-GPU servers, SR-IOV virtual functions and virtual
devices used for testing.
Let's utilize full minor range for DRM devices.
To avoid regressing the existing userspace, we're still maintaining the
numbering scheme where 0-63 is used for primary, 64-127 is reserved
(formerly for control) and 128-191 is used for render.
For minors >= 192, we're allocating minors dynamically on a first-come,
first-served basis.

Signed-off-by: Michał Winiarski 
---
 drivers/gpu/drm/drm_drv.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 41799e4d0432..2c6e0b8d3b7a 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -119,8 +119,17 @@ static int drm_minor_alloc(struct drm_device *dev, 
unsigned int type)
minor->type = type;
minor->dev = dev;
 
+   /*
+* DRM used to support 64 devices, for backwards compatibility we need 
to maintain the
+* minor allocation scheme where minors 0-63 are primary nodes, 64-127 
are control nodes,
+* and 128-191 are render nodes.
+* After reaching the limit, we're allocating minors dynamically - 
first-come, first-serve.
+*/
r = xa_alloc(_minors_xa, , NULL,
 XA_LIMIT(64 * type, 64 * (type + 1) - 1), GFP_KERNEL);
+   if (r == -EBUSY)
+   r = xa_alloc(_minors_xa, , NULL,
+XA_LIMIT(192, (1 << MINORBITS) - 1), GFP_KERNEL);
if (r < 0)
return r;
 
-- 
2.37.3



[Intel-gfx] [PATCH v4 3/3] drm: Introduce skip_legacy_minors modparam

2022-09-06 Thread Michał Winiarski
While there is support for >64 DRM devices on kernel side, existing
userspace may still have some hardcoded assumptions and it's possible
that it will require changes to be able to use more than 64 devices.
Add a modparam to simplify testing and development of >64 devices
support on userspace side by allocating minors from the >=192 range
(without the need of having >64 physical devices connected).

Signed-off-by: Michał Winiarski 
---
 drivers/gpu/drm/drm_drv.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 2c6e0b8d3b7a..11c691543fec 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -56,6 +56,11 @@ MODULE_LICENSE("GPL and additional rights");
 
 static DEFINE_XARRAY_ALLOC(drm_minors_xa);
 
+static bool skip_legacy_minors;
+module_param_unsafe(skip_legacy_minors, bool, 0400);
+MODULE_PARM_DESC(skip_legacy_minors,
+"Don't allocate minors in 0-192 range. This can be used for 
testing userspace support for >64 drm devices (default: false)");
+
 /*
  * If the drm core fails to init for whatever reason,
  * we should prevent any drivers from registering with it.
@@ -110,7 +115,7 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned 
int type)
 {
struct drm_minor *minor;
u32 id;
-   int r;
+   int r = -EBUSY;
 
minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
if (!minor)
@@ -125,8 +130,9 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned 
int type)
 * and 128-191 are render nodes.
 * After reaching the limit, we're allocating minors dynamically - 
first-come, first-serve.
 */
-   r = xa_alloc(_minors_xa, , NULL,
-XA_LIMIT(64 * type, 64 * (type + 1) - 1), GFP_KERNEL);
+   if (!skip_legacy_minors)
+   r = xa_alloc(_minors_xa, , NULL,
+XA_LIMIT(64 * type, 64 * (type + 1) - 1), 
GFP_KERNEL);
if (r == -EBUSY)
r = xa_alloc(_minors_xa, , NULL,
 XA_LIMIT(192, (1 << MINORBITS) - 1), GFP_KERNEL);
-- 
2.37.3



[Intel-gfx] [PATCH v4 1/3] drm: Use XArray instead of IDR for minors

2022-09-06 Thread Michał Winiarski
IDR is deprecated, and since XArray manages its own state with internal
locking, it simplifies the locking on DRM side.
Additionally, don't use the IRQ-safe variant, since operating on drm
minor is not done in IRQ context.

Signed-off-by: Michał Winiarski 
Suggested-by: Matthew Wilcox 
---
 drivers/gpu/drm/drm_drv.c | 49 ++-
 1 file changed, 17 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 8214a0b1ab7f..41799e4d0432 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -53,8 +54,7 @@ MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon 
Smirl");
 MODULE_DESCRIPTION("DRM shared core routines");
 MODULE_LICENSE("GPL and additional rights");
 
-static DEFINE_SPINLOCK(drm_minor_lock);
-static struct idr drm_minors_idr;
+static DEFINE_XARRAY_ALLOC(drm_minors_xa);
 
 /*
  * If the drm core fails to init for whatever reason,
@@ -98,21 +98,18 @@ static struct drm_minor **drm_minor_get_slot(struct 
drm_device *dev,
 static void drm_minor_alloc_release(struct drm_device *dev, void *data)
 {
struct drm_minor *minor = data;
-   unsigned long flags;
 
WARN_ON(dev != minor->dev);
 
put_device(minor->kdev);
 
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_remove(_minors_idr, minor->index);
-   spin_unlock_irqrestore(_minor_lock, flags);
+   xa_release(_minors_xa, minor->index);
 }
 
 static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 {
struct drm_minor *minor;
-   unsigned long flags;
+   u32 id;
int r;
 
minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
@@ -122,20 +119,12 @@ static int drm_minor_alloc(struct drm_device *dev, 
unsigned int type)
minor->type = type;
minor->dev = dev;
 
-   idr_preload(GFP_KERNEL);
-   spin_lock_irqsave(_minor_lock, flags);
-   r = idr_alloc(_minors_idr,
- NULL,
- 64 * type,
- 64 * (type + 1),
- GFP_NOWAIT);
-   spin_unlock_irqrestore(_minor_lock, flags);
-   idr_preload_end();
-
+   r = xa_alloc(_minors_xa, , NULL,
+XA_LIMIT(64 * type, 64 * (type + 1) - 1), GFP_KERNEL);
if (r < 0)
return r;
 
-   minor->index = r;
+   minor->index = id;
 
r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
if (r)
@@ -152,7 +141,7 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned 
int type)
 static int drm_minor_register(struct drm_device *dev, unsigned int type)
 {
struct drm_minor *minor;
-   unsigned long flags;
+   void *entry;
int ret;
 
DRM_DEBUG("\n");
@@ -172,9 +161,12 @@ static int drm_minor_register(struct drm_device *dev, 
unsigned int type)
goto err_debugfs;
 
/* replace NULL with @minor so lookups will succeed from now on */
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_replace(_minors_idr, minor, minor->index);
-   spin_unlock_irqrestore(_minor_lock, flags);
+   entry = xa_store(_minors_xa, minor->index, , GFP_KERNEL);
+   if (xa_is_err(entry)) {
+   ret = xa_err(entry);
+   goto err_debugfs;
+   }
+   WARN_ON(entry);
 
DRM_DEBUG("new minor registered %d\n", minor->index);
return 0;
@@ -187,16 +179,13 @@ static int drm_minor_register(struct drm_device *dev, 
unsigned int type)
 static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
 {
struct drm_minor *minor;
-   unsigned long flags;
 
minor = *drm_minor_get_slot(dev, type);
if (!minor || !device_is_registered(minor->kdev))
return;
 
/* replace @minor with NULL so lookups will fail from now on */
-   spin_lock_irqsave(_minor_lock, flags);
-   idr_replace(_minors_idr, NULL, minor->index);
-   spin_unlock_irqrestore(_minor_lock, flags);
+   xa_erase(_minors_xa, minor->index);
 
device_del(minor->kdev);
dev_set_drvdata(minor->kdev, NULL); /* safety belt */
@@ -215,13 +204,10 @@ static void drm_minor_unregister(struct drm_device *dev, 
unsigned int type)
 struct drm_minor *drm_minor_acquire(unsigned int minor_id)
 {
struct drm_minor *minor;
-   unsigned long flags;
 
-   spin_lock_irqsave(_minor_lock, flags);
-   minor = idr_find(_minors_idr, minor_id);
+   minor = xa_load(_minors_xa, minor_id);
if (minor)
drm_dev_get(minor->dev);
-   spin_unlock_irqrestore(_minor_lock, flags);
 
if (!minor) {
return ERR_PTR(-ENODEV);
@@ -1037,7 +1023,7 @@ static void drm_core_exit(void)
unregister_chrdev(DRM_MAJOR, "

[Intel-gfx] [PATCH v4 0/3] drm: Use full allocated minor range for DRM

2022-09-06 Thread Michał Winiarski
64 DRM device nodes is not enough for everyone.
Upgrade it to ~512K (which definitely is more than enough).

To allow testing userspace support for >64 devices, add additional DRM
modparam (skip_legacy_minors) which causes DRM to skip allocating minors
in 0-192 range.
Additionally - convert minors to use XArray instead of IDR to simplify the
locking.

v1 -> v2:
Don't touch DRM_MINOR_CONTROL and its range (Simon Ser)

v2 -> v3:
Don't use legacy scheme for >=192 minor range (Dave Airlie)
Add modparam for testing (Dave Airlie)
Add lockdep annotation for IDR (Daniel Vetter)

v3 -> v4:
Convert from IDR to XArray (Matthew Wilcox)

Michał Winiarski (3):
  drm: Use XArray instead of IDR for minors
  drm: Expand max DRM device number to full MINORBITS
  drm: Introduce skip_legacy_minors modparam

 drivers/gpu/drm/drm_drv.c | 66 +++
 1 file changed, 33 insertions(+), 33 deletions(-)

-- 
2.37.3



Re: [Intel-gfx] [PATCH RESEND] drm/i915: Mark GPU wedging on driver unregister unrecoverable

2021-09-10 Thread Michał Winiarski

On 03.09.2021 16:28, Janusz Krzysztofik wrote:

GPU wedged flag now set on driver unregister to prevent from further
using the GPU can be then cleared unintentionally when calling
__intel_gt_unset_wedged() still before the flag is finally marked
unrecoverable.  We need to have it marked unrecoverable earlier.
Implement that by replacing a call to intel_gt_set_wedged() in
intel_gt_driver_unregister() with intel_gt_set_wedged_on_fini().

With the above in place, intel_gt_set_wedged_on_fini() is now called
twice on driver remove, second time from __intel_gt_disable().  This
seems harmless, while dropping intel_gt_set_wedged_on_fini() from
__intel_gt_disable() proved to break some driver probe error unwind
paths as well as mock selftest exit path.

Signed-off-by: Janusz Krzysztofik 
Cc: Michał Winiarski 


Reviewed-by: Michał Winiarski 

-Michał


---
Resending with Cc: dri-de...@lists.freedesktop.org as requested.

Thanks,
Janusz

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

diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index 62d40c986642..173b53cb2b47 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -750,7 +750,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
 * all in-flight requests so that we can quickly unbind the active
 * resources.
 */
-   intel_gt_set_wedged(gt);
+   intel_gt_set_wedged_on_fini(gt);
  
  	/* Scrub all HW state upon release */

with_intel_runtime_pm(gt->uncore->rpm, wakeref)





Re: [Intel-gfx] [RFC PATCH 08/97] drm/i915/guc: Keep strict GuC ABI definitions

2021-05-24 Thread Michał Winiarski
Quoting Matthew Brost (2021-05-06 21:13:22)
> From: Michal Wajdeczko 
> 
> Our fwif.h file is now mix of strict firmware ABI definitions and
> set of our helpers. In anticipation of upcoming changes to the GuC
> interface try to keep them separate in smaller maintainable files.
> 
> Signed-off-by: Michal Wajdeczko 
> Signed-off-by: Matthew Brost 
> Cc: Michał Winiarski 

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |  51 +
>  .../gt/uc/abi/guc_communication_ctb_abi.h | 106 +
>  .../gt/uc/abi/guc_communication_mmio_abi.h|  52 +
>  .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  14 ++
>  .../gpu/drm/i915/gt/uc/abi/guc_messages_abi.h |  21 ++
>  drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   | 203 +-
>  6 files changed, 250 insertions(+), 197 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
>  create mode 100644 
> drivers/gpu/drm/i915/gt/uc/abi/guc_communication_mmio_abi.h
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_messages_abi.h
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915/guc: Keep strict GuC ABI definitions separate

2021-02-24 Thread Michał Winiarski
Quoting Michal Wajdeczko (2021-02-20 13:44:43)
> Our fwif.h file is now mix of strict firmware ABI definitions and
> set of our helpers. In anticipation of upcoming changes to the GuC
> interface try to keep them separate in smaller maintainable files.
> 
> Signed-off-by: Michal Wajdeczko 
> Cc: Daniele Ceraolo Spurio 
> Cc: John Harrison 
> Cc: Jon Ewins 

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |  55 
>  .../gt/uc/abi/guc_communication_ctb_abi.h | 106 
>  .../gt/uc/abi/guc_communication_mmio_abi.h|  52 
>  .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  14 +
>  .../drm/i915/gt/uc/abi/guc_log_buffer_abi.h   |  56 
>  .../gpu/drm/i915/gt/uc/abi/guc_messages_abi.h |  21 ++
>  drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   | 257 +-
>  7 files changed, 312 insertions(+), 249 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
>  create mode 100644 
> drivers/gpu/drm/i915/gt/uc/abi/guc_communication_mmio_abi.h
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_log_buffer_abi.h
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_messages_abi.h
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH i-g-t v6 00/24] tests/core_hotunplug: Fixes and enhancements

2020-09-14 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-09-11 12:30:15)
> Clean up the test code, add some new basic subtests, then unblock
> unbind test variants.
> 
> No incompletes / aborts nor subsequently run test issues have been
> reported by Trybot.  The hotrebind-lateclose subtest fails on a so far
> unidentified driver sysfs issue but the device is fully recovered and
> left in a usable state.  Perceived Haswell/Broadwell issue with audio
> power management has been worked around and its potential occurrence
> is reported as an IGT warning.
> 
> Series changelog:
> v2: New patch "Un-blocklist *bind* subtests added.
> v3: Patch "Follow failed subtests with healthcheck" renamed to "Recover
> from subtest failures".
>   - a new patche "Clean up device open error handling" added, an old
> patch "Fix missing newline" obsoleted by the new one dropped,
>   - other new patches added:
> - "Let the driver time out essential sysfs operations",
> - "More thorough i915 healthcheck and recovery",
>   - a patch "Add 'lateclose before restore' variants" from another
> series included.
> v4: Optional patch "Duplicate debug messages in dmesg" from another
> series included.
> v5: New patch added with Haswell audio related kernel warning worked
> around and replaced with an IGT warning to preserve visibility of
> the issue.
> v6: New patch added for also checking health of render device nodes,
>   - new patch added with proper handling of health check before late
> close,
>   - inclusion of unbind-rebind scenario to BAT scope proposed.
> 
> @Michał: Since some patch updates are trivial, I've preserved your
> v1/v2 Reviewd-by: except for patches with non-trivial changes, where I
> marked your R-b as v1/v2 applicable.  Please have a look and confirm if
> you are still OK with them.

Feel free to add:
Reviewed-by: Michał Winiarski 

For the whole series (with the exception of intel-ci part).

-Michał

> 
> @Tvrtko: As I already asked before, please support my attempt to remove
> the unbind test variants from the blocklist.
> 
> @Petri, @Martin: Assuming CI results will be as good as those obtained
> on Trybot, please give me your green light for merging this series if
> you have no objections.
> 
> Thanks,
> Janusz
> 
> Janusz Krzysztofik (24):
>   tests/core_hotunplug: Use igt_assert_fd()
>   tests/core_hotunplug: Constify dev_bus_addr string
>   tests/core_hotunplug: Clean up device open error handling
>   tests/core_hotunplug: Consolidate duplicated debug messages
>   tests/core_hotunplug: Assert successful device filter application
>   tests/core_hotunplug: Maintain a single data structure instance
>   tests/core_hotunplug: Pass errors via a data structure field
>   tests/core_hotunplug: Handle device close errors
>   tests/core_hotunplug: Prepare invariant data once per test run
>   tests/core_hotunplug: Skip selectively on sysfs close errors
>   tests/core_hotunplug: Recover from subtest failures
>   tests/core_hotunplug: Fail subtests on device close errors
>   tests/core_hotunplug: Let the driver time out essential sysfs
> operations
>   tests/core_hotunplug: Process return values of sysfs operations
>   tests/core_hotunplug: Assert expected device presence/absence
>   tests/core_hotunplug: Explicitly ignore unused return values
>   tests/core_hotunplug: Also check health of render device node
>   tests/core_hotunplug: More thorough i915 healthcheck and recovery
>   tests/core_hotunplug: Add 'lateclose before restore' variants
>   tests/core_hotunplug: Check health both before and after late close
>   tests/core_hotunplug: HSW/BDW audio issue workaround
>   tests/core_hotunplug: Duplicate debug messages in dmesg
>   tests/core_hotunplug: Un-blocklist *bind* subtests
>   tests/core_hotunplug: Add unbind-rebind subtest to BAT scope
> 
>  tests/core_hotunplug.c| 560 --
>  tests/intel-ci/blacklist.txt  |   2 +-
>  tests/intel-ci/fast-feedback.testlist |   1 +
>  3 files changed, 431 insertions(+), 132 deletions(-)
> 
> -- 
> 2.21.1
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [RFC PATH i-g-t 00/15] tests/core_hotunplug: Fixes and enhancements

2020-07-22 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-07-20 14:18:53)
> Since the test is still blocklisted due to driver issues and won't be
> executed on CI, I'm providing a link where results obtained from a 
> rybot run with the test removed from the blocklist can be found:
> https://patchwork.freedesktop.org/series/79662/
> Failures reported there come from driver and not test issues, I
> believe.
> 
> Thanks,
> Janusz

I'd probably squash some of the patches (e.g. 06/15 with 07/15, maybe more),
but that's just a matter of opinion (and I guess such fine-grained split makes
it easier to review).

LGTM.

Reviewed-by: Michał Winiarski 

-Michał

> 
> Janusz Krzysztofik (15):
>   tests/core_hotunplug: Use igt_assert_fd()
>   tests/core_hotunplug: Constify dev_bus_addr string
>   tests/core_hotunplug: Consolidate duplicated debug messages
>   tests/core_hotunplug: Assert successful device filter application
>   tests/core_hotunplug: Fix missing newline
>   tests/core_hotunplug: Maintain a single data structure instance
>   tests/core_hotunplug: Pass errors via a data structure field
>   tests/core_hotunplug: Handle device close errors
>   tests/core_hotunplug: Prepare invariant data once per test run
>   tests/core_hotunplug: Skip selectively on sysfs close errors
>   tests/core_hotunplug: Follow failed subtests with health checks
>   tests/core_hotunplug: Fail subtests on device close errors
>   tests/core_hotunplug: Process return values of sysfs operations
>   tests/core_hotunplug: Assert expected device presence/absence
>   tests/core_hotunplug: Explicitly ignore unused return values
> 
>  tests/core_hotunplug.c | 333 +
>  1 file changed, 202 insertions(+), 131 deletions(-)
> 
> -- 
> 2.21.1
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 2/2] drm/i915/huc: Adjust HuC state accordingly after GuC fetch error

2020-07-08 Thread Michał Winiarski
From: Michał Winiarski 

Firmware "Selected" state is a transient state - we don't expect to see
it after finishing driver probe, we even have asserts sprinkled over
i915 to confirm whether that's the case.
Unfortunately - we don't handle the transition out of "Selected" in case
of GuC fetch error, leading those asserts to fire when calling
"intel_huc_is_used()".

v2: Add dbg print when moving HuC into error state (Daniele)

Reported-by: Marcin Bernatowicz 
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Daniele Ceraolo Spurio 
Cc: Marcin Bernatowicz 
Cc: Michal Wajdeczko 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 1c2d6358826c..d6f55f70889d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -267,8 +267,17 @@ static void __uc_fetch_firmwares(struct intel_uc *uc)
GEM_BUG_ON(!intel_uc_wants_guc(uc));
 
err = intel_uc_fw_fetch(>guc.fw);
-   if (err)
+   if (err) {
+   /* Make sure we transition out of transient "SELECTED" state */
+   if (intel_uc_wants_huc(uc)) {
+   drm_dbg(_to_gt(uc)->i915->drm,
+   "Failed to fetch GuC: %d disabling HuC\n", err);
+   intel_uc_fw_change_status(>huc.fw,
+ INTEL_UC_FIRMWARE_ERROR);
+   }
+
return;
+   }
 
if (intel_uc_wants_huc(uc))
intel_uc_fw_fetch(>huc.fw);
-- 
2.27.0

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


[Intel-gfx] [PATCH 1/2] drm/i915/uc: Extract uc usage details into separate debugfs

2020-07-08 Thread Michał Winiarski
From: Michał Winiarski 

It has been pointed out that information about HuC usage doesn't belong
in guc_info debugfs. Let's move "supported/used/wanted" matrix to a
separate debugfs file, keeping guc_info strictly about GuC.

Suggested-by: Daniele Ceraolo Spurio 
Signed-off-by: Michał Winiarski 
Cc: Daniele Ceraolo Spurio 
Cc: Lukasz Fiedorowicz 
Cc: Michal Wajdeczko 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c| 23 +--
 drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c | 29 +++
 2 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 446a41946f56..861657897c0f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -733,28 +733,19 @@ int intel_guc_allocate_and_map_vma(struct intel_guc *guc, 
u32 size,
  */
 void intel_guc_load_status(struct intel_guc *guc, struct drm_printer *p)
 {
-   struct intel_uc *uc = container_of(guc, struct intel_uc, guc);
struct intel_gt *gt = guc_to_gt(guc);
struct intel_uncore *uncore = gt->uncore;
intel_wakeref_t wakeref;
 
-   drm_printf(p, "[guc] supported:%s wanted:%s used:%s\n",
-  yesno(intel_uc_supports_guc(uc)),
-  yesno(intel_uc_wants_guc(uc)),
-  yesno(intel_uc_uses_guc(uc)));
-   drm_printf(p, "[huc] supported:%s wanted:%s used:%s\n",
-  yesno(intel_uc_supports_huc(uc)),
-  yesno(intel_uc_wants_huc(uc)),
-  yesno(intel_uc_uses_huc(uc)));
-   drm_printf(p, "[submission] supported:%s wanted:%s used:%s\n",
-  yesno(intel_uc_supports_guc_submission(uc)),
-  yesno(intel_uc_wants_guc_submission(uc)),
-  yesno(intel_uc_uses_guc_submission(uc)));
-
-   if (!intel_guc_is_supported(guc) || !intel_guc_is_wanted(guc))
+   if (!intel_guc_is_supported(guc)) {
+   drm_printf(p, "GuC not supported\n");
return;
+   }
 
-   drm_puts(p, "\n");
+   if (!intel_guc_is_wanted(guc)) {
+   drm_printf(p, "GuC disabled\n");
+   return;
+   }
 
intel_uc_fw_dump(>fw, p);
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
index 9d16b784aa0d..089d98662f46 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
@@ -4,14 +4,41 @@
  */
 
 #include 
+#include 
 
+#include "gt/debugfs_gt.h"
 #include "intel_guc_debugfs.h"
 #include "intel_huc_debugfs.h"
 #include "intel_uc.h"
 #include "intel_uc_debugfs.h"
 
+static int uc_usage_show(struct seq_file *m, void *data)
+{
+   struct intel_uc *uc = m->private;
+   struct drm_printer p = drm_seq_file_printer(m);
+
+   drm_printf(, "[guc] supported:%s wanted:%s used:%s\n",
+  yesno(intel_uc_supports_guc(uc)),
+  yesno(intel_uc_wants_guc(uc)),
+  yesno(intel_uc_uses_guc(uc)));
+   drm_printf(, "[huc] supported:%s wanted:%s used:%s\n",
+  yesno(intel_uc_supports_huc(uc)),
+  yesno(intel_uc_wants_huc(uc)),
+  yesno(intel_uc_uses_huc(uc)));
+   drm_printf(, "[submission] supported:%s wanted:%s used:%s\n",
+  yesno(intel_uc_supports_guc_submission(uc)),
+  yesno(intel_uc_wants_guc_submission(uc)),
+  yesno(intel_uc_uses_guc_submission(uc)));
+
+   return 0;
+}
+DEFINE_GT_DEBUGFS_ATTRIBUTE(uc_usage);
+
 void intel_uc_debugfs_register(struct intel_uc *uc, struct dentry *gt_root)
 {
+   static const struct debugfs_gt_file files[] = {
+   { "usage", _usage_fops, NULL },
+   };
struct dentry *root;
 
if (!gt_root)
@@ -25,6 +52,8 @@ void intel_uc_debugfs_register(struct intel_uc *uc, struct 
dentry *gt_root)
if (IS_ERR(root))
return;
 
+   intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), uc);
+
intel_guc_debugfs_register(>guc, root);
intel_huc_debugfs_register(>huc, root);
 }
-- 
2.27.0

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


[Intel-gfx] [PATCH 2/2] drm/i915/huc: Adjust HuC state accordingly after GuC fetch error

2020-07-07 Thread Michał Winiarski
From: Michał Winiarski 

Firmware "Selected" state is a transient state - we don't expect to see
it after finishing driver probe, we even have asserts sprinkled over
i915 to confirm whether that's the case.
Unfortunately - we don't handle the transition out of "Selected" in case
of GuC fetch error, leading those asserts to fire when calling
"intel_huc_is_used()".

Reported-by: Marcin Bernatowicz 
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Daniele Ceraolo Spurio 
Cc: Marcin Bernatowicz 
Cc: Michal Wajdeczko 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 1c2d6358826c..993e9755f317 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -267,8 +267,14 @@ static void __uc_fetch_firmwares(struct intel_uc *uc)
GEM_BUG_ON(!intel_uc_wants_guc(uc));
 
err = intel_uc_fw_fetch(>guc.fw);
-   if (err)
+   if (err) {
+   /* Make sure we transition out of transient "SELECTED" state */
+   if (intel_uc_wants_huc(uc))
+   intel_uc_fw_change_status(>huc.fw,
+ INTEL_UC_FIRMWARE_ERROR);
+
return;
+   }
 
if (intel_uc_wants_huc(uc))
intel_uc_fw_fetch(>huc.fw);
-- 
2.27.0

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


[Intel-gfx] [PATCH 1/2] drm/i915/uc: Extract uc usage details into separate debugfs

2020-07-07 Thread Michał Winiarski
From: Michał Winiarski 

It has been pointed out that information about HuC usage doesn't belong
in guc_info debugfs. Let's move "supported/used/wanted" matrix to a
separate debugfs file, keeping guc_info strictly about GuC.

Suggested-by: Daniele Ceraolo Spurio 
Signed-off-by: Michał Winiarski 
Cc: Daniele Ceraolo Spurio 
Cc: Lukasz Fiedorowicz 
Cc: Michal Wajdeczko 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c| 23 +--
 drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c | 29 +++
 2 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 446a41946f56..861657897c0f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -733,28 +733,19 @@ int intel_guc_allocate_and_map_vma(struct intel_guc *guc, 
u32 size,
  */
 void intel_guc_load_status(struct intel_guc *guc, struct drm_printer *p)
 {
-   struct intel_uc *uc = container_of(guc, struct intel_uc, guc);
struct intel_gt *gt = guc_to_gt(guc);
struct intel_uncore *uncore = gt->uncore;
intel_wakeref_t wakeref;
 
-   drm_printf(p, "[guc] supported:%s wanted:%s used:%s\n",
-  yesno(intel_uc_supports_guc(uc)),
-  yesno(intel_uc_wants_guc(uc)),
-  yesno(intel_uc_uses_guc(uc)));
-   drm_printf(p, "[huc] supported:%s wanted:%s used:%s\n",
-  yesno(intel_uc_supports_huc(uc)),
-  yesno(intel_uc_wants_huc(uc)),
-  yesno(intel_uc_uses_huc(uc)));
-   drm_printf(p, "[submission] supported:%s wanted:%s used:%s\n",
-  yesno(intel_uc_supports_guc_submission(uc)),
-  yesno(intel_uc_wants_guc_submission(uc)),
-  yesno(intel_uc_uses_guc_submission(uc)));
-
-   if (!intel_guc_is_supported(guc) || !intel_guc_is_wanted(guc))
+   if (!intel_guc_is_supported(guc)) {
+   drm_printf(p, "GuC not supported\n");
return;
+   }
 
-   drm_puts(p, "\n");
+   if (!intel_guc_is_wanted(guc)) {
+   drm_printf(p, "GuC disabled\n");
+   return;
+   }
 
intel_uc_fw_dump(>fw, p);
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
index 9d16b784aa0d..089d98662f46 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
@@ -4,14 +4,41 @@
  */
 
 #include 
+#include 
 
+#include "gt/debugfs_gt.h"
 #include "intel_guc_debugfs.h"
 #include "intel_huc_debugfs.h"
 #include "intel_uc.h"
 #include "intel_uc_debugfs.h"
 
+static int uc_usage_show(struct seq_file *m, void *data)
+{
+   struct intel_uc *uc = m->private;
+   struct drm_printer p = drm_seq_file_printer(m);
+
+   drm_printf(, "[guc] supported:%s wanted:%s used:%s\n",
+  yesno(intel_uc_supports_guc(uc)),
+  yesno(intel_uc_wants_guc(uc)),
+  yesno(intel_uc_uses_guc(uc)));
+   drm_printf(, "[huc] supported:%s wanted:%s used:%s\n",
+  yesno(intel_uc_supports_huc(uc)),
+  yesno(intel_uc_wants_huc(uc)),
+  yesno(intel_uc_uses_huc(uc)));
+   drm_printf(, "[submission] supported:%s wanted:%s used:%s\n",
+  yesno(intel_uc_supports_guc_submission(uc)),
+  yesno(intel_uc_wants_guc_submission(uc)),
+  yesno(intel_uc_uses_guc_submission(uc)));
+
+   return 0;
+}
+DEFINE_GT_DEBUGFS_ATTRIBUTE(uc_usage);
+
 void intel_uc_debugfs_register(struct intel_uc *uc, struct dentry *gt_root)
 {
+   static const struct debugfs_gt_file files[] = {
+   { "usage", _usage_fops, NULL },
+   };
struct dentry *root;
 
if (!gt_root)
@@ -25,6 +52,8 @@ void intel_uc_debugfs_register(struct intel_uc *uc, struct 
dentry *gt_root)
if (IS_ERR(root))
return;
 
+   intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), uc);
+
intel_guc_debugfs_register(>guc, root);
intel_huc_debugfs_register(>huc, root);
 }
-- 
2.27.0

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


[Intel-gfx] [PATCH v3 1/3] drm/i915: Reboot CI if we get wedged during driver init

2020-07-06 Thread Michał Winiarski
From: Michał Winiarski 

Getting wedged device on driver init is pretty much unrecoverable.
Since we're running various scenarios that may potentially hit this in
CI (module reload / selftests / hotunplug), and if it happens, it means
that we can't trust any subsequent CI results, we should just apply the
taint to let the CI know that it should reboot (CI checks taint between
test runs).

v2: Comment that WEDGED_ON_INIT is non-recoverable, distinguish
WEDGED_ON_INIT from WEDGED_ON_FINI (Chris)
v3: Appease checkpatch, fixup search-replace logic expression mindbomb
in assert (Chris)

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Michal Wajdeczko 
Cc: Petri Latvala 
Reviewed-by: Chris Wilson 
---
 drivers/gpu/drm/i915/gt/intel_engine_user.c |  2 +-
 drivers/gpu/drm/i915/gt/intel_gt.c  |  2 +-
 drivers/gpu/drm/i915/gt/intel_gt.h  | 12 
 drivers/gpu/drm/i915/gt/intel_gt_pm.c   |  2 +-
 drivers/gpu/drm/i915/gt/intel_reset.c   | 13 +++--
 drivers/gpu/drm/i915/gt/intel_reset.h   | 10 ++
 drivers/gpu/drm/i915/gt/intel_reset_types.h |  7 ++-
 7 files changed, 30 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
b/drivers/gpu/drm/i915/gt/intel_engine_user.c
index 848decee9066..34e6096f196e 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -201,7 +201,7 @@ void intel_engines_driver_register(struct drm_i915_private 
*i915)
 uabi_node);
char old[sizeof(engine->name)];
 
-   if (intel_gt_has_init_error(engine->gt))
+   if (intel_gt_has_unrecoverable_error(engine->gt))
continue; /* ignore incomplete engines */
 
GEM_BUG_ON(engine->class >= ARRAY_SIZE(uabi_classes));
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index ebc29b6ee86c..876f78759095 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -510,7 +510,7 @@ static int __engines_verify_workarounds(struct intel_gt *gt)
 
 static void __intel_gt_disable(struct intel_gt *gt)
 {
-   intel_gt_set_wedged_on_init(gt);
+   intel_gt_set_wedged_on_fini(gt);
 
intel_gt_suspend_prepare(gt);
intel_gt_suspend_late(gt);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h 
b/drivers/gpu/drm/i915/gt/intel_gt.h
index 4fac043750aa..982957ca4e62 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt.h
@@ -58,14 +58,18 @@ static inline u32 intel_gt_scratch_offset(const struct 
intel_gt *gt,
return i915_ggtt_offset(gt->scratch) + field;
 }
 
-static inline bool intel_gt_is_wedged(const struct intel_gt *gt)
+static inline bool intel_gt_has_unrecoverable_error(const struct intel_gt *gt)
 {
-   return __intel_reset_failed(>reset);
+   return test_bit(I915_WEDGED_ON_INIT, >reset.flags) ||
+  test_bit(I915_WEDGED_ON_FINI, >reset.flags);
 }
 
-static inline bool intel_gt_has_init_error(const struct intel_gt *gt)
+static inline bool intel_gt_is_wedged(const struct intel_gt *gt)
 {
-   return test_bit(I915_WEDGED_ON_INIT, >reset.flags);
+   GEM_BUG_ON(intel_gt_has_unrecoverable_error(gt) &&
+  !test_bit(I915_WEDGED, >reset.flags));
+
+   return unlikely(test_bit(I915_WEDGED, >reset.flags));
 }
 
 #endif /* __INTEL_GT_H__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index f1d5333f9456..274aa0dd7050 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -188,7 +188,7 @@ int intel_gt_resume(struct intel_gt *gt)
enum intel_engine_id id;
int err;
 
-   err = intel_gt_has_init_error(gt);
+   err = intel_gt_has_unrecoverable_error(gt);
if (err)
return err;
 
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c 
b/drivers/gpu/drm/i915/gt/intel_reset.c
index 0156f1f5c736..6f94b6479a2f 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -880,7 +880,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
return true;
 
/* Never fully initialised, recovery impossible */
-   if (test_bit(I915_WEDGED_ON_INIT, >reset.flags))
+   if (intel_gt_has_unrecoverable_error(gt))
return false;
 
GT_TRACE(gt, "start\n");
@@ -1342,7 +1342,7 @@ int intel_gt_terminally_wedged(struct intel_gt *gt)
if (!intel_gt_is_wedged(gt))
return 0;
 
-   if (intel_gt_has_init_error(gt))
+   if (intel_gt_has_unrecoverable_error(gt))
return -EIO;
 
/* Reset still in progress? Maybe we will recover? */
@@ -1360,6 +1360,15 @@ void intel_gt_set_wedged_on_init(struct intel_gt *gt)
 I915_WEDGED_O

[Intel-gfx] [PATCH v3 2/3] drm/i915: Print caller when tainting for CI

2020-07-06 Thread Michał Winiarski
From: Michał Winiarski 

We can add taint from multiple places, printing the caller allows us to
have a better overview of what exactly caused us to do the tainting.

v2: Tweak format and print the device (Chris)
v3: Move things around (Chris)

Suggested-by: Michal Wajdeczko 
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Michal Wajdeczko 
Cc: Petri Latvala 
---
 drivers/gpu/drm/i915/gt/intel_reset.c  | 6 +++---
 drivers/gpu/drm/i915/gt/selftest_rc6.c | 2 +-
 drivers/gpu/drm/i915/i915_gem.h| 2 +-
 drivers/gpu/drm/i915/i915_utils.c  | 7 +++
 drivers/gpu/drm/i915/i915_utils.h  | 3 ++-
 drivers/gpu/drm/i915/intel_uncore.c| 4 ++--
 6 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c 
b/drivers/gpu/drm/i915/gt/intel_reset.c
index 6f94b6479a2f..121bf39a6f3e 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -930,7 +930,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
 * Warn CI about the unrecoverable wedged condition.
 * Time for a reboot.
 */
-   add_taint_for_CI(TAINT_WARN);
+   add_taint_for_CI(gt->i915, TAINT_WARN);
return false;
}
 
@@ -1097,7 +1097,7 @@ void intel_gt_reset(struct intel_gt *gt,
 * rather than continue on into oblivion. For everyone else,
 * the system should still plod along, but they have been warned!
 */
-   add_taint_for_CI(TAINT_WARN);
+   add_taint_for_CI(gt->i915, TAINT_WARN);
 error:
__intel_gt_set_wedged(gt);
goto finish;
@@ -1362,7 +1362,7 @@ void intel_gt_set_wedged_on_init(struct intel_gt *gt)
set_bit(I915_WEDGED_ON_INIT, >reset.flags);
 
/* Wedged on init is non-recoverable */
-   add_taint_for_CI(TAINT_WARN);
+   add_taint_for_CI(gt->i915, TAINT_WARN);
 }
 
 void intel_gt_set_wedged_on_fini(struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/gt/selftest_rc6.c 
b/drivers/gpu/drm/i915/gt/selftest_rc6.c
index 3c8434846fa1..64ef5ee5decf 100644
--- a/drivers/gpu/drm/i915/gt/selftest_rc6.c
+++ b/drivers/gpu/drm/i915/gt/selftest_rc6.c
@@ -233,7 +233,7 @@ int live_rc6_ctx_wa(void *arg)
i915_reset_engine_count(error, engine)) {
pr_err("%s: GPU reset required\n",
   engine->name);
-   add_taint_for_CI(TAINT_WARN);
+   add_taint_for_CI(gt->i915, TAINT_WARN);
err = -EIO;
goto out;
}
diff --git a/drivers/gpu/drm/i915/i915_gem.h b/drivers/gpu/drm/i915/i915_gem.h
index 1753c84d6c0d..f333e88a2b6e 100644
--- a/drivers/gpu/drm/i915/i915_gem.h
+++ b/drivers/gpu/drm/i915/i915_gem.h
@@ -72,7 +72,7 @@ struct drm_i915_private;
trace_printk(__VA_ARGS__);  \
 } while (0)
 #define GEM_TRACE_DUMP() \
-   do { ftrace_dump(DUMP_ALL); add_taint_for_CI(TAINT_WARN); } while (0)
+   do { ftrace_dump(DUMP_ALL); __add_taint_for_CI(TAINT_WARN); } while (0)
 #define GEM_TRACE_DUMP_ON(expr) \
do { if (expr) GEM_TRACE_DUMP(); } while (0)
 #else
diff --git a/drivers/gpu/drm/i915/i915_utils.c 
b/drivers/gpu/drm/i915/i915_utils.c
index f42a9e9a0b4f..01a3d3c941bf 100644
--- a/drivers/gpu/drm/i915/i915_utils.c
+++ b/drivers/gpu/drm/i915/i915_utils.c
@@ -49,6 +49,13 @@ __i915_printk(struct drm_i915_private *dev_priv, const char 
*level,
}
 }
 
+void add_taint_for_CI(struct drm_i915_private *i915, unsigned int taint)
+{
+   __i915_printk(i915, KERN_NOTICE, "CI tainted:%#x by %pS\n",
+ taint, (void *)_RET_IP_);
+   __add_taint_for_CI(taint);
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
 static unsigned int i915_probe_fail_count;
 
diff --git a/drivers/gpu/drm/i915/i915_utils.h 
b/drivers/gpu/drm/i915/i915_utils.h
index 03a73d2bd50d..b1c5955a52e1 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -436,7 +436,8 @@ static inline const char *enableddisabled(bool v)
return v ? "enabled" : "disabled";
 }
 
-static inline void add_taint_for_CI(unsigned int taint)
+void add_taint_for_CI(struct drm_i915_private *i915, unsigned int taint);
+static inline void __add_taint_for_CI(unsigned int taint)
 {
/*
 * The system is "ok", just about surviving for the user, but
diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index 592364aed2da..8e2c073da1aa 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -142,7 +142,7 @@ fw_domain_wait_ack_clear(const struct 
intel_uncore_forcewake_domain *d)
if (wait_ack_clear(d, FORCEWAKE_KERNEL)) {
  

[Intel-gfx] [PATCH v2 3/3] drm/i915: Don't taint when using fault injection

2020-07-06 Thread Michał Winiarski
From: Michał Winiarski 

It is not really unexpected to hit wedge on init this way.
We're already downgrading error printk when running with fault injection,
let's use the same approach for CI tainting.

v2: Don't check fault inject in trace dump (Chris)

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Michal Wajdeczko 
Cc: Petri Latvala 
Reviewed-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_utils.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_utils.c 
b/drivers/gpu/drm/i915/i915_utils.c
index 01a3d3c941bf..4c305d838016 100644
--- a/drivers/gpu/drm/i915/i915_utils.c
+++ b/drivers/gpu/drm/i915/i915_utils.c
@@ -53,7 +53,10 @@ void add_taint_for_CI(struct drm_i915_private *i915, 
unsigned int taint)
 {
__i915_printk(i915, KERN_NOTICE, "CI tainted:%#x by %pS\n",
  taint, (void *)_RET_IP_);
-   __add_taint_for_CI(taint);
+
+   /* Failures that occur during fault injection testing are expected */
+   if (!i915_error_injected())
+   __add_taint_for_CI(taint);
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
-- 
2.27.0

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


Re: [Intel-gfx] [PATCH] drm/i915/guc: Expand guc_info debugfs with more information

2020-07-06 Thread Michał Winiarski
Quoting Daniele Ceraolo Spurio (2020-07-01 18:45:52)
> 
> 
> On 7/1/2020 7:27 AM, Michał Winiarski wrote:
> > From: Michał Winiarski 
> >
> > The information about platform/driver/user view of GuC firmware usage
> > currently requires user to either go through kernel log or parse the
> > combination of "enable_guc" modparam and various debugfs entries.
> > Let's keep things simple and add a "supported/used/wanted" matrix
> > (already used internally by i915) in guc_info debugfs.
> >
> > Signed-off-by: Michał Winiarski 
> > Cc: Daniele Ceraolo Spurio 
> > Cc: Lukasz Fiedorowicz 
> > Cc: Michal Wajdeczko 
> > ---
> >   drivers/gpu/drm/i915/gt/uc/intel_guc.c | 23 ---
> >   1 file changed, 16 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
> > b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> > index 861657897c0f..446a41946f56 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> > @@ -733,19 +733,28 @@ int intel_guc_allocate_and_map_vma(struct intel_guc 
> > *guc, u32 size,
> >*/
> >   void intel_guc_load_status(struct intel_guc *guc, struct drm_printer *p)
> >   {
> > + struct intel_uc *uc = container_of(guc, struct intel_uc, guc);
> >   struct intel_gt *gt = guc_to_gt(guc);
> >   struct intel_uncore *uncore = gt->uncore;
> >   intel_wakeref_t wakeref;
> >   
> > - if (!intel_guc_is_supported(guc)) {
> > - drm_printf(p, "GuC not supported\n");
> > + drm_printf(p, "[guc] supported:%s wanted:%s used:%s\n",
> > +yesno(intel_uc_supports_guc(uc)),
> > +yesno(intel_uc_wants_guc(uc)),
> > +yesno(intel_uc_uses_guc(uc)));
> 
> There are intel_guc equivalents for there uc functions, so we can use 
> those and avoid the intel_uc var if we ditch the HuC (see comment below):
> 
> intel_guc_is_supported
> intel_guc_is_wanted
> intel_guc_is_used
> 
> Same for the others.
> 
> > + drm_printf(p, "[huc] supported:%s wanted:%s used:%s\n",
> > +yesno(intel_uc_supports_huc(uc)),
> > +yesno(intel_uc_wants_huc(uc)),
> > +yesno(intel_uc_uses_huc(uc)));
> 
> The HuC view should go to the huc_info debugfs

This was intentional. For HuC the "wants" part is controlled by "enable_guc",
and it's actually helpful to see that "guc is used because the user/platform
wants huc", all in the single "cat guc_info".
In other words - this is still (at least partially) GuC view :)

So, given the above, do you still think we should move it to huc_info?

-Michał

> 
> > + drm_printf(p, "[submission] supported:%s wanted:%s used:%s\n",
> > +yesno(intel_uc_supports_guc_submission(uc)),
> > +yesno(intel_uc_wants_guc_submission(uc)),
> > +yesno(intel_uc_uses_guc_submission(uc)));
> > +
> > + if (!intel_guc_is_supported(guc) || !intel_guc_is_wanted(guc))
> 
> intel_guc_is_wanted implies intel_guc_is_supported so you can 
> potentially test only that, but I agree that having both is clearer to read.
> 
> Daniele
> 
> >   return;
> > - }
> >   
> > - if (!intel_guc_is_wanted(guc)) {
> > - drm_printf(p, "GuC disabled\n");
> > - return;
> > - }
> > + drm_puts(p, "\n");
> >   
> >   intel_uc_fw_dump(>fw, p);
> >   
>
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 2/3] drm/i915: Print caller when tainting for CI

2020-07-06 Thread Michał Winiarski
From: Michał Winiarski 

We can add taint from multiple places, printing the caller allows us to
have a better overview of what exactly caused us to do the tainting.

v2: Tweak format and print the device (Chris)

Suggested-by: Michal Wajdeczko 
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Michal Wajdeczko 
Cc: Petri Latvala 
---
 drivers/gpu/drm/i915/gt/intel_reset.c  |  6 +++---
 drivers/gpu/drm/i915/gt/selftest_rc6.c |  2 +-
 drivers/gpu/drm/i915/i915_gem.h|  2 +-
 drivers/gpu/drm/i915/i915_utils.h  | 12 ++--
 drivers/gpu/drm/i915/intel_uncore.c|  4 ++--
 5 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c 
b/drivers/gpu/drm/i915/gt/intel_reset.c
index 6f94b6479a2f..121bf39a6f3e 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -930,7 +930,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
 * Warn CI about the unrecoverable wedged condition.
 * Time for a reboot.
 */
-   add_taint_for_CI(TAINT_WARN);
+   add_taint_for_CI(gt->i915, TAINT_WARN);
return false;
}
 
@@ -1097,7 +1097,7 @@ void intel_gt_reset(struct intel_gt *gt,
 * rather than continue on into oblivion. For everyone else,
 * the system should still plod along, but they have been warned!
 */
-   add_taint_for_CI(TAINT_WARN);
+   add_taint_for_CI(gt->i915, TAINT_WARN);
 error:
__intel_gt_set_wedged(gt);
goto finish;
@@ -1362,7 +1362,7 @@ void intel_gt_set_wedged_on_init(struct intel_gt *gt)
set_bit(I915_WEDGED_ON_INIT, >reset.flags);
 
/* Wedged on init is non-recoverable */
-   add_taint_for_CI(TAINT_WARN);
+   add_taint_for_CI(gt->i915, TAINT_WARN);
 }
 
 void intel_gt_set_wedged_on_fini(struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/gt/selftest_rc6.c 
b/drivers/gpu/drm/i915/gt/selftest_rc6.c
index 3c8434846fa1..64ef5ee5decf 100644
--- a/drivers/gpu/drm/i915/gt/selftest_rc6.c
+++ b/drivers/gpu/drm/i915/gt/selftest_rc6.c
@@ -233,7 +233,7 @@ int live_rc6_ctx_wa(void *arg)
i915_reset_engine_count(error, engine)) {
pr_err("%s: GPU reset required\n",
   engine->name);
-   add_taint_for_CI(TAINT_WARN);
+   add_taint_for_CI(gt->i915, TAINT_WARN);
err = -EIO;
goto out;
}
diff --git a/drivers/gpu/drm/i915/i915_gem.h b/drivers/gpu/drm/i915/i915_gem.h
index 1753c84d6c0d..f333e88a2b6e 100644
--- a/drivers/gpu/drm/i915/i915_gem.h
+++ b/drivers/gpu/drm/i915/i915_gem.h
@@ -72,7 +72,7 @@ struct drm_i915_private;
trace_printk(__VA_ARGS__);  \
 } while (0)
 #define GEM_TRACE_DUMP() \
-   do { ftrace_dump(DUMP_ALL); add_taint_for_CI(TAINT_WARN); } while (0)
+   do { ftrace_dump(DUMP_ALL); __add_taint_for_CI(TAINT_WARN); } while (0)
 #define GEM_TRACE_DUMP_ON(expr) \
do { if (expr) GEM_TRACE_DUMP(); } while (0)
 #else
diff --git a/drivers/gpu/drm/i915/i915_utils.h 
b/drivers/gpu/drm/i915/i915_utils.h
index 03a73d2bd50d..82fada1e7552 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -436,7 +436,13 @@ static inline const char *enableddisabled(bool v)
return v ? "enabled" : "disabled";
 }
 
-static inline void add_taint_for_CI(unsigned int taint)
+static inline void __add_taint_for_CI(unsigned int taint)
+{
+   add_taint(taint, LOCKDEP_STILL_OK);
+}
+
+static inline void
+add_taint_for_CI(struct drm_i915_private *i915, unsigned int taint)
 {
/*
 * The system is "ok", just about surviving for the user, but
@@ -444,7 +450,9 @@ static inline void add_taint_for_CI(unsigned int taint)
 * CI checks the taint state after every test and will reboot
 * the machine if the kernel is tainted.
 */
-   add_taint(taint, LOCKDEP_STILL_OK);
+   __i915_printk(i915, KERN_NOTICE, "CI tainted:%x by %pS\n",
+ taint, (void *)_RET_IP_);
+   __add_taint_for_CI(taint);
 }
 
 void cancel_timer(struct timer_list *t);
diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index 592364aed2da..8e2c073da1aa 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -142,7 +142,7 @@ fw_domain_wait_ack_clear(const struct 
intel_uncore_forcewake_domain *d)
if (wait_ack_clear(d, FORCEWAKE_KERNEL)) {
DRM_ERROR("%s: timed out waiting for forcewake ack to clear.\n",
  intel_uncore_forcewake_domain_to_str(d->id));
-   add_taint_for_CI(TAINT_WARN); /* CI now unrel

[Intel-gfx] [PATCH 3/3] drm/i915: Don't taint when using fault injection

2020-07-06 Thread Michał Winiarski
From: Michał Winiarski 

It is not really unexpected to hit wedge on init this way.
We're already downgrading error printk when running with fault injection,
let's use the same approach for CI tainting.

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Michal Wajdeczko 
Cc: Petri Latvala 
---
 drivers/gpu/drm/i915/i915_utils.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_utils.h 
b/drivers/gpu/drm/i915/i915_utils.h
index 82fada1e7552..d84c23592942 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -438,7 +438,9 @@ static inline const char *enableddisabled(bool v)
 
 static inline void __add_taint_for_CI(unsigned int taint)
 {
-   add_taint(taint, LOCKDEP_STILL_OK);
+   /* Failures that occur during fault injection testing are expected */
+   if (!i915_error_injected())
+   add_taint(taint, LOCKDEP_STILL_OK);
 }
 
 static inline void
-- 
2.27.0

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


[Intel-gfx] [PATCH v3 1/3] drm/i915: Reboot CI if we get wedged during driver init

2020-07-06 Thread Michał Winiarski
From: Michał Winiarski 

Getting wedged device on driver init is pretty much unrecoverable.
Since we're running various scenarios that may potentially hit this in
CI (module reload / selftests / hotunplug), and if it happens, it means
that we can't trust any subsequent CI results, we should just apply the
taint to let the CI know that it should reboot (CI checks taint between
test runs).

v2: Comment that WEDGED_ON_INIT is non-recoverable, distinguish
WEDGED_ON_INIT from WEDGED_ON_FINI (Chris)
v3: Appease checkpatch, fixup search-replace logic expression mindbomb
in assert (Chris)

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Michal Wajdeczko 
Cc: Petri Latvala 
Reviewed-by: Chris Wilson 
---
 drivers/gpu/drm/i915/gt/intel_engine_user.c |  2 +-
 drivers/gpu/drm/i915/gt/intel_gt.c  |  2 +-
 drivers/gpu/drm/i915/gt/intel_gt.h  | 12 
 drivers/gpu/drm/i915/gt/intel_gt_pm.c   |  2 +-
 drivers/gpu/drm/i915/gt/intel_reset.c   | 13 +++--
 drivers/gpu/drm/i915/gt/intel_reset.h   | 10 ++
 drivers/gpu/drm/i915/gt/intel_reset_types.h |  7 ++-
 7 files changed, 30 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
b/drivers/gpu/drm/i915/gt/intel_engine_user.c
index 848decee9066..34e6096f196e 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -201,7 +201,7 @@ void intel_engines_driver_register(struct drm_i915_private 
*i915)
 uabi_node);
char old[sizeof(engine->name)];
 
-   if (intel_gt_has_init_error(engine->gt))
+   if (intel_gt_has_unrecoverable_error(engine->gt))
continue; /* ignore incomplete engines */
 
GEM_BUG_ON(engine->class >= ARRAY_SIZE(uabi_classes));
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index ebc29b6ee86c..876f78759095 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -510,7 +510,7 @@ static int __engines_verify_workarounds(struct intel_gt *gt)
 
 static void __intel_gt_disable(struct intel_gt *gt)
 {
-   intel_gt_set_wedged_on_init(gt);
+   intel_gt_set_wedged_on_fini(gt);
 
intel_gt_suspend_prepare(gt);
intel_gt_suspend_late(gt);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h 
b/drivers/gpu/drm/i915/gt/intel_gt.h
index 4fac043750aa..982957ca4e62 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt.h
@@ -58,14 +58,18 @@ static inline u32 intel_gt_scratch_offset(const struct 
intel_gt *gt,
return i915_ggtt_offset(gt->scratch) + field;
 }
 
-static inline bool intel_gt_is_wedged(const struct intel_gt *gt)
+static inline bool intel_gt_has_unrecoverable_error(const struct intel_gt *gt)
 {
-   return __intel_reset_failed(>reset);
+   return test_bit(I915_WEDGED_ON_INIT, >reset.flags) ||
+  test_bit(I915_WEDGED_ON_FINI, >reset.flags);
 }
 
-static inline bool intel_gt_has_init_error(const struct intel_gt *gt)
+static inline bool intel_gt_is_wedged(const struct intel_gt *gt)
 {
-   return test_bit(I915_WEDGED_ON_INIT, >reset.flags);
+   GEM_BUG_ON(intel_gt_has_unrecoverable_error(gt) &&
+  !test_bit(I915_WEDGED, >reset.flags));
+
+   return unlikely(test_bit(I915_WEDGED, >reset.flags));
 }
 
 #endif /* __INTEL_GT_H__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index f1d5333f9456..274aa0dd7050 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -188,7 +188,7 @@ int intel_gt_resume(struct intel_gt *gt)
enum intel_engine_id id;
int err;
 
-   err = intel_gt_has_init_error(gt);
+   err = intel_gt_has_unrecoverable_error(gt);
if (err)
return err;
 
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c 
b/drivers/gpu/drm/i915/gt/intel_reset.c
index 0156f1f5c736..6f94b6479a2f 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -880,7 +880,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
return true;
 
/* Never fully initialised, recovery impossible */
-   if (test_bit(I915_WEDGED_ON_INIT, >reset.flags))
+   if (intel_gt_has_unrecoverable_error(gt))
return false;
 
GT_TRACE(gt, "start\n");
@@ -1342,7 +1342,7 @@ int intel_gt_terminally_wedged(struct intel_gt *gt)
if (!intel_gt_is_wedged(gt))
return 0;
 
-   if (intel_gt_has_init_error(gt))
+   if (intel_gt_has_unrecoverable_error(gt))
return -EIO;
 
/* Reset still in progress? Maybe we will recover? */
@@ -1360,6 +1360,15 @@ void intel_gt_set_wedged_on_init(struct intel_gt *gt)
 I915_WEDGED_O

[Intel-gfx] [PATCH v2 1/2] drm/i915: Reboot CI if we get wedged during driver init

2020-07-06 Thread Michał Winiarski
From: Michał Winiarski 

Getting wedged device on driver init is pretty much unrecoverable.
Since we're running various scenarios that may potentially hit this in
CI (module reload / selftests / hotunplug), and if it happens, it means
that we can't trust any subsequent CI results, we should just apply the
taint to let the CI know that it should reboot (CI checks taint between
test runs).

v2: Comment that WEDGED_ON_INIT is non-recoverable, distinguish
WEDGED_ON_INIT from WEDGED_ON_FINI (Chris)

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Michal Wajdeczko 
Cc: Petri Latvala 
---
 drivers/gpu/drm/i915/gt/intel_engine_user.c |  2 +-
 drivers/gpu/drm/i915/gt/intel_gt.c  |  2 +-
 drivers/gpu/drm/i915/gt/intel_gt.h  | 12 
 drivers/gpu/drm/i915/gt/intel_gt_pm.c   |  2 +-
 drivers/gpu/drm/i915/gt/intel_reset.c   | 13 +++--
 drivers/gpu/drm/i915/gt/intel_reset.h   | 10 ++
 drivers/gpu/drm/i915/gt/intel_reset_types.h |  7 ++-
 7 files changed, 30 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
b/drivers/gpu/drm/i915/gt/intel_engine_user.c
index 848decee9066..34e6096f196e 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -201,7 +201,7 @@ void intel_engines_driver_register(struct drm_i915_private 
*i915)
 uabi_node);
char old[sizeof(engine->name)];
 
-   if (intel_gt_has_init_error(engine->gt))
+   if (intel_gt_has_unrecoverable_error(engine->gt))
continue; /* ignore incomplete engines */
 
GEM_BUG_ON(engine->class >= ARRAY_SIZE(uabi_classes));
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index ebc29b6ee86c..876f78759095 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -510,7 +510,7 @@ static int __engines_verify_workarounds(struct intel_gt *gt)
 
 static void __intel_gt_disable(struct intel_gt *gt)
 {
-   intel_gt_set_wedged_on_init(gt);
+   intel_gt_set_wedged_on_fini(gt);
 
intel_gt_suspend_prepare(gt);
intel_gt_suspend_late(gt);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h 
b/drivers/gpu/drm/i915/gt/intel_gt.h
index 4fac043750aa..7201f96723d8 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt.h
@@ -58,14 +58,18 @@ static inline u32 intel_gt_scratch_offset(const struct 
intel_gt *gt,
return i915_ggtt_offset(gt->scratch) + field;
 }
 
-static inline bool intel_gt_is_wedged(const struct intel_gt *gt)
+static inline bool intel_gt_has_unrecoverable_error(const struct intel_gt *gt)
 {
-   return __intel_reset_failed(>reset);
+   return test_bit(I915_WEDGED_ON_INIT, >reset.flags) ||
+   test_bit(I915_WEDGED_ON_FINI, >reset.flags);
 }
 
-static inline bool intel_gt_has_init_error(const struct intel_gt *gt)
+static inline bool intel_gt_is_wedged(const struct intel_gt *gt)
 {
-   return test_bit(I915_WEDGED_ON_INIT, >reset.flags);
+   GEM_BUG_ON(intel_gt_has_unrecoverable_error(gt) ?
+  !test_bit(I915_WEDGED, >reset.flags) : false);
+
+   return unlikely(test_bit(I915_WEDGED, >reset.flags));
 }
 
 #endif /* __INTEL_GT_H__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index f1d5333f9456..274aa0dd7050 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -188,7 +188,7 @@ int intel_gt_resume(struct intel_gt *gt)
enum intel_engine_id id;
int err;
 
-   err = intel_gt_has_init_error(gt);
+   err = intel_gt_has_unrecoverable_error(gt);
if (err)
return err;
 
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c 
b/drivers/gpu/drm/i915/gt/intel_reset.c
index 0156f1f5c736..6f94b6479a2f 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -880,7 +880,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
return true;
 
/* Never fully initialised, recovery impossible */
-   if (test_bit(I915_WEDGED_ON_INIT, >reset.flags))
+   if (intel_gt_has_unrecoverable_error(gt))
return false;
 
GT_TRACE(gt, "start\n");
@@ -1342,7 +1342,7 @@ int intel_gt_terminally_wedged(struct intel_gt *gt)
if (!intel_gt_is_wedged(gt))
return 0;
 
-   if (intel_gt_has_init_error(gt))
+   if (intel_gt_has_unrecoverable_error(gt))
return -EIO;
 
/* Reset still in progress? Maybe we will recover? */
@@ -1360,6 +1360,15 @@ void intel_gt_set_wedged_on_init(struct intel_gt *gt)
 I915_WEDGED_ON_INIT);
intel_gt_set_wedged(gt);
set_bit(I915_WEDGED_ON_INIT, >reset.flags);
+
+   /* Wedged on

[Intel-gfx] [PATCH 2/2] drm/i915: Print caller when tainting for CI

2020-07-06 Thread Michał Winiarski
We can add taint from multiple places, printing the caller allows us to
have a better overview of what exactly caused us to do the tainting.

Suggested-by: Michal Wajdeczko 
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Michal Wajdeczko 
Cc: Petri Latvala 
---
 drivers/gpu/drm/i915/i915_utils.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_utils.h 
b/drivers/gpu/drm/i915/i915_utils.h
index 03a73d2bd50d..1ed5c47eae8f 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -444,6 +444,7 @@ static inline void add_taint_for_CI(unsigned int taint)
 * CI checks the taint state after every test and will reboot
 * the machine if the kernel is tainted.
 */
+   pr_info("CI taint: %ps\n", __builtin_return_address(0));
add_taint(taint, LOCKDEP_STILL_OK);
 }
 
-- 
2.27.0

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


[Intel-gfx] [PATCH] drm/i915: Reboot CI if we get wedged during driver init

2020-07-01 Thread Michał Winiarski
From: Michał Winiarski 

Getting wedged device on driver init is pretty much unrecoverable.
Since we're running verious scenarios that may potentially hit this in
CI (module reload / selftests / hotunplug), and if it happens, it means
that we can't trust any subsequent CI results, we should just apply the
taint to let the CI know that it should reboot (CI checks taint between
test runs).

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Petri Latvala 
---
 drivers/gpu/drm/i915/gt/intel_reset.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c 
b/drivers/gpu/drm/i915/gt/intel_reset.c
index 0156f1f5c736..d27e8bb7d550 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -1360,6 +1360,8 @@ void intel_gt_set_wedged_on_init(struct intel_gt *gt)
 I915_WEDGED_ON_INIT);
intel_gt_set_wedged(gt);
set_bit(I915_WEDGED_ON_INIT, >reset.flags);
+
+   add_taint_for_CI(TAINT_WARN);
 }
 
 void intel_gt_init_reset(struct intel_gt *gt)
-- 
2.27.0

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


[Intel-gfx] [PATCH] drm/i915/guc: Expand guc_info debugfs with more information

2020-07-01 Thread Michał Winiarski
From: Michał Winiarski 

The information about platform/driver/user view of GuC firmware usage
currently requires user to either go through kernel log or parse the
combination of "enable_guc" modparam and various debugfs entries.
Let's keep things simple and add a "supported/used/wanted" matrix
(already used internally by i915) in guc_info debugfs.

Signed-off-by: Michał Winiarski 
Cc: Daniele Ceraolo Spurio 
Cc: Lukasz Fiedorowicz 
Cc: Michal Wajdeczko 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c | 23 ---
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 861657897c0f..446a41946f56 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -733,19 +733,28 @@ int intel_guc_allocate_and_map_vma(struct intel_guc *guc, 
u32 size,
  */
 void intel_guc_load_status(struct intel_guc *guc, struct drm_printer *p)
 {
+   struct intel_uc *uc = container_of(guc, struct intel_uc, guc);
struct intel_gt *gt = guc_to_gt(guc);
struct intel_uncore *uncore = gt->uncore;
intel_wakeref_t wakeref;
 
-   if (!intel_guc_is_supported(guc)) {
-   drm_printf(p, "GuC not supported\n");
+   drm_printf(p, "[guc] supported:%s wanted:%s used:%s\n",
+  yesno(intel_uc_supports_guc(uc)),
+  yesno(intel_uc_wants_guc(uc)),
+  yesno(intel_uc_uses_guc(uc)));
+   drm_printf(p, "[huc] supported:%s wanted:%s used:%s\n",
+  yesno(intel_uc_supports_huc(uc)),
+  yesno(intel_uc_wants_huc(uc)),
+  yesno(intel_uc_uses_huc(uc)));
+   drm_printf(p, "[submission] supported:%s wanted:%s used:%s\n",
+  yesno(intel_uc_supports_guc_submission(uc)),
+  yesno(intel_uc_wants_guc_submission(uc)),
+  yesno(intel_uc_uses_guc_submission(uc)));
+
+   if (!intel_guc_is_supported(guc) || !intel_guc_is_wanted(guc))
return;
-   }
 
-   if (!intel_guc_is_wanted(guc)) {
-   drm_printf(p, "GuC disabled\n");
-   return;
-   }
+   drm_puts(p, "\n");
 
intel_uc_fw_dump(>fw, p);
 
-- 
2.27.0

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


Re: [Intel-gfx] [RFC PATCH i-g-t v2 8/8] tests/core_hotunplug: Add 'GEM batch' variant

2020-06-25 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-06-22 18:44:15)
> Verify if a device with a GEM batch job still running on a GPU can be
> hot-unplugged cleanly and released, then recovered.
> 
> v2: rebase on upstream
> 
> Signed-off-by: Janusz Krzysztofik 
> ---
>  tests/core_hotunplug.c | 34 ++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/tests/core_hotunplug.c b/tests/core_hotunplug.c
> index 7cb699cc2..672ff661d 100644
> --- a/tests/core_hotunplug.c
> +++ b/tests/core_hotunplug.c
> @@ -33,6 +33,7 @@
>  #include "i915/gem_vm.h"
>  #include "igt.h"
>  #include "igt_device_scan.h"
> +#include "igt_dummyload.h"
>  #include "igt_kmod.h"
>  #include "igt_sysfs.h"
>  
> @@ -408,6 +409,32 @@ static void prime_hotunplug_lateclose(void)
> healthcheck();
>  }
>  
> +static void batch_hotunplug_lateclose(void)
> +{
> +   struct hotunplug priv;
> +   igt_spin_t *spin;
> +
> +   prepare_for_rescan();
> +
> +   igt_require_gem(priv.fd.drm);
> +
> +   local_debug("running dummy load");
> +   spin = __igt_spin_new(priv.fd.drm, .flags = IGT_SPIN_POLL_RUN |
> +   IGT_SPIN_NO_PREEMPTION);

Do we need IGT_SPIN_NO_PREEMPTION here?
We're also leaking spin here... And I don't think we can just call igt_spin_free
after unplug, can we?

-Michał

> +   igt_spin_busywait_until_started(spin);
> +
> +   local_debug("hot unplugging the device");
> +   device_unplug(priv.fd.sysfs_dev);
> +
> +   local_debug("late closing the removed device instance");
> +   close(priv.fd.drm);
> +
> +   local_debug("recovering the device");
> +   bus_rescan(priv.fd.sysfs_bus);
> +
> +   healthcheck();
> +}
> +
>  /* Main */
>  
>  igt_main
> @@ -501,4 +528,11 @@ igt_main
>  
> igt_fixture
> igt_abort_on_f(failure, "%s\n", failure);
> +
> +   igt_describe("Check if a device with a still running batch can be 
> cleanly unplugged, then released and recovered");
> +   igt_subtest("batch-hotunplug-lateclose")
> +   batch_hotunplug_lateclose();
> +
> +   igt_fixture
> +   igt_abort_on_f(failure, "%s\n", failure);
>  }
> -- 
> 2.21.1
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [igt-dev] [RFC PATCH i-g-t v2 7/8] tests/core_hotunplug: Add 'PRIME handle' variant

2020-06-25 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-06-22 18:44:14)
> Even if all device file descriptors are closed on device hotunplug,
> PRIME exported objects may still exists, referenced by still open
> dma-buf file handles.  Add a subtest that keeps such handle open on
> device hotunplug.
> 
> v2: rebase on upstream

Would be interesting to see what happens when someone actually imports an
object from unplugged device (or the device is unplugged after it was imported).
But perhaps that's something for the future.

Also - the naming should probably be kept distinct from the other "lateclose"
tests, since here we're closing the device FD before the unplug.
Maybe just "prime-hotunplug"? But that's up to you - either way:

Reviewed-by: Michał Winiarski 

-Michał

> 
> Signed-off-by: Janusz Krzysztofik 
> ---
>  tests/core_hotunplug.c | 36 
>  1 file changed, 36 insertions(+)
> 
> diff --git a/tests/core_hotunplug.c b/tests/core_hotunplug.c
> index c30d98a69..7cb699cc2 100644
> --- a/tests/core_hotunplug.c
> +++ b/tests/core_hotunplug.c
> @@ -379,6 +379,35 @@ static void gem_hotunplug_lateclose(void)
> healthcheck();
>  }
>  
> +static void prime_hotunplug_lateclose(void)
> +{
> +   struct hotunplug priv;
> +   uint32_t handle;
> +   int dmabuf;
> +
> +   prepare_for_rescan();
> +
> +   igt_require_gem(priv.fd.drm);
> +
> +   local_debug("creating and PRIME-exporting a GEM object");
> +   handle = gem_create(priv.fd.drm, 4096);
> +   dmabuf = prime_handle_to_fd(priv.fd.drm, handle);
> +
> +   local_debug("closing the device");
> +   close(priv.fd.drm);
> +
> +   local_debug("hot unplugging the device");
> +   device_unplug(priv.fd.sysfs_dev);
> +
> +   local_debug("late closing the PRIME file handle");
> +   close(dmabuf);
> +
> +   local_debug("recovering the device");
> +   bus_rescan(priv.fd.sysfs_bus);
> +
> +   healthcheck();
> +}
> +
>  /* Main */
>  
>  igt_main
> @@ -465,4 +494,11 @@ igt_main
>  
> igt_fixture
> igt_abort_on_f(failure, "%s\n", failure);
> +
> +   igt_describe("Check if a device with a still open PRIME-exported 
> object can be cleanly unplugged, then released and recovered");
> +   igt_subtest("prime-hotunplug-lateclose")
> +   prime_hotunplug_lateclose();
> +
> +   igt_fixture
> +   igt_abort_on_f(failure, "%s\n", failure);
>  }
> -- 
> 2.21.1
> 
> ___
> igt-dev mailing list
> igt-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [igt-dev] [RFC PATCH i-g-t v2 6/8] tests/core_hotunplug: Add 'GEM object' variant

2020-06-25 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-06-22 18:44:13)
> GEM objects belonging to user file descriptors still open on device
> hotunplug may exhibit still more driver issues.  Add a subtest that
> implements this scenario.
> 
> v2: rebase on upstream
> 
> Signed-off-by: Janusz Krzysztofik 
> ---
>  tests/core_hotunplug.c | 30 ++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/tests/core_hotunplug.c b/tests/core_hotunplug.c
> index 18a963564..c30d98a69 100644
> --- a/tests/core_hotunplug.c
> +++ b/tests/core_hotunplug.c
> @@ -356,6 +356,29 @@ static void vm_hotunplug_lateclose(void)
> healthcheck();
>  }
>  
> +static void gem_hotunplug_lateclose(void)
> +{
> +   struct hotunplug priv;
> +
> +   prepare_for_rescan();
> +
> +   igt_require_gem(priv.fd.drm);
> +
> +   local_debug("creating a GEM user object");
> +   igt_ignore_warn(gem_create(priv.fd.drm, 4096));

Same as previous one.
(note - we could just check for proper error when we attempt to close this
handle after unplug, and the same thing applies to the previous one with the vm)

LGTM otherwise.

Reviewed-by: Michał Winiarski 

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


Re: [Intel-gfx] [igt-dev] [RFC PATCH i-g-t v2 5/8] tests/core_hotunplug: Add 'GEM address space' variant

2020-06-25 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-06-22 18:44:12)
> Verify if an additional address space associated with an open device
> file descriptor is cleaned up correctly on device hotunplug.
> 
> v2: rebase on upstream, update includes order
> 
> Signed-off-by: Janusz Krzysztofik 
> ---
>  tests/core_hotunplug.c | 31 +++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/tests/core_hotunplug.c b/tests/core_hotunplug.c
> index 0892e1927..18a963564 100644
> --- a/tests/core_hotunplug.c
> +++ b/tests/core_hotunplug.c
> @@ -30,6 +30,7 @@
>  #include 
>  
>  #include "i915/gem.h"
> +#include "i915/gem_vm.h"
>  #include "igt.h"
>  #include "igt_device_scan.h"
>  #include "igt_kmod.h"
> @@ -332,6 +333,29 @@ static void hotreplug_lateclose(void)
> healthcheck();
>  }
>  
> +static void vm_hotunplug_lateclose(void)
> +{
> +   struct hotunplug priv;
> +
> +   prepare_for_rescan();
> +
> +   gem_require_vm(priv.fd.drm);
> +
> +   local_debug("creating additional GEM user address space");
> +   igt_ignore_warn(gem_vm_create(priv.fd.drm));

Why the "ignore_warn"?
This deserves a comment. And perhaps a word of information about why we picked
this partucular operation in the commit message (vm_create).
This is a regression test, right?

LGTM otherwise (but again - see previous patches):

Reviewed-by: Michał Winiarski 

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


Re: [Intel-gfx] [RFC PATCH i-g-t v2 4/8] tests/core_hotunplug: Add 'lateclose before recover' variants

2020-06-25 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-06-22 18:44:11)
> If a GPU gets wedged during driver rebind or device re-plug for some
> reason, current hotunbind/hotunplug test variants may time out before
> lateclose phase, resulting in incomplete CI reports.  Let's rename
> those variants to more adequate hotrebind/hotreplug-lateclose and add
> new variants focused on exercising the lateclose phase regardless of
> potential rebind/re-plug issues under old names.
> 
> v2: rebase on upstream
> 
> Signed-off-by: Janusz Krzysztofik 

After addressing comments from preceding patches:

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  tests/core_hotunplug.c | 57 +++---
>  1 file changed, 54 insertions(+), 3 deletions(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [igt-dev] [RFC PATCH i-g-t v2 3/8] tests/core_hotunplug: Add unbind-unplug-rescan variant

2020-06-25 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-06-22 18:44:10)
> Check if this 3-step procedure exhibits any issues with device recover
> after unplug.  Such issues may indicate insufficient device hardware
> re-initialization performed by the device driver, or other kernel bugs
> outside the driver code.
> 
> v2: rebase on upstream
> 
> Signed-off-by: Janusz Krzysztofik 

After addressing comments from preceding patches:

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  tests/core_hotunplug.c | 40 ++--
>  1 file changed, 38 insertions(+), 2 deletions(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [igt-dev] [RFC PATCH i-g-t v2 2/8] tests/core_hotunplug: Use PCI device sysfs entry, not DRM

2020-06-25 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-06-22 18:44:09)
> Future subtests may want to access PCI attributes of the device after
> driver unbind.  Refactor prepare() helper.
> 
> v2: rebase on upstream
> 
> Signed-off-by: Janusz Krzysztofik 
> ---
>  tests/core_hotunplug.c | 68 +-
>  1 file changed, 40 insertions(+), 28 deletions(-)
> 
> diff --git a/tests/core_hotunplug.c b/tests/core_hotunplug.c
> index 826645b1f..35eba9b8a 100644
> --- a/tests/core_hotunplug.c
> +++ b/tests/core_hotunplug.c
> @@ -55,42 +55,54 @@ struct hotunplug {
> igt_kmsg(KMSG_DEBUG "%s: %s: %s\n", igt_test_name(), __func__, msg); \
>  })
>  
> -static void prepare_for_unbind(struct hotunplug *priv, char *buf, int buflen)
> +static inline int prepare_common(struct hotunplug *priv)
>  {
> -   int len;
> +   int fd_sysfs_drm;
> +
> +   local_debug("opening device");
> +   priv->fd.drm = __drm_open_driver(DRIVER_ANY);
> +   igt_assert(priv->fd.drm >= 0);
> +
> +   fd_sysfs_drm = igt_sysfs_open(priv->fd.drm);
> +   igt_assert(fd_sysfs_drm >= 0);
> +
> +   return fd_sysfs_drm;
> +}
> +
> +static inline void prepare_for_rebind(struct hotunplug *priv,
> + char *buf, int buflen)
> +{
> +   int fd_sysfs_drm, len;
>  
> igt_assert(buflen);
>  
> -   priv->fd.sysfs_drv = openat(priv->fd.sysfs_dev, "device/driver",
> -   O_DIRECTORY);
> -   igt_assert(priv->fd.sysfs_drv >= 0);
> +   fd_sysfs_drm = prepare_common(priv);
> +
> +   priv->fd.sysfs_drv = openat(fd_sysfs_drm, "device/driver", 
> O_DIRECTORY);
>  
> -   len = readlinkat(priv->fd.sysfs_dev, "device", buf, buflen - 1);
> +   len = readlinkat(fd_sysfs_drm, "device", buf, buflen - 1);
> buf[len] = '\0';
> priv->dev_bus_addr = strrchr(buf, '/');
> -   igt_assert(priv->dev_bus_addr++);
>  
> -   /* sysfs_dev no longer needed */
> -   close(priv->fd.sysfs_dev);
> +   close(fd_sysfs_drm);
> +
> +   igt_assert(priv->fd.sysfs_drv >= 0);
> +   igt_assert(priv->dev_bus_addr++);
>  }
>  
> -static inline void prepare(struct hotunplug *priv, char *buf, int buflen)
> +static inline void prepare_for_rescan(struct hotunplug *priv)
>  {
> -   local_debug("opening device");
> -   priv->fd.drm = __drm_open_driver(DRIVER_ANY);
> -   igt_assert(priv->fd.drm >= 0);
> +   int fd_sysfs_drm = prepare_common(priv);
>  
> -   priv->fd.sysfs_dev = igt_sysfs_open(priv->fd.drm);
> -   igt_assert(priv->fd.sysfs_dev >= 0);
> +   priv->fd.sysfs_dev = openat(fd_sysfs_drm, "device", O_DIRECTORY);
>  
> -   if (buf) {
> -   prepare_for_unbind(priv, buf, buflen);
> -   } else {
> -   /* prepare for bus rescan */
> -   priv->fd.sysfs_bus = openat(priv->fd.sysfs_dev,
> -   "device/subsystem", O_DIRECTORY);
> -   igt_assert(priv->fd.sysfs_bus >= 0);
> -   }
> +   priv->fd.sysfs_bus = openat(fd_sysfs_drm, "device/subsystem",
> +   O_DIRECTORY);
> +
> +   close(fd_sysfs_drm);
> +
> +   igt_assert(priv->fd.sysfs_dev >= 0);
> +   igt_assert(priv->fd.sysfs_bus >= 0);
>  }

I find the lifecycle of hotunplug.fd.sysfs_* difficult to follow now...
Would it be possible to keep the "prepare" step simpler and just open everything
everytime? (perhaps closing and opening new ones when called multiple times?)
Or do we need to have drv separate from bus/dev?

-Michał

>  
>  static const char *failure;
> @@ -124,7 +136,7 @@ static void device_unplug(int fd_sysfs_dev)
>  {
> failure = "Device unplug timeout!";
> igt_set_timeout(60, failure);
> -   igt_sysfs_set(fd_sysfs_dev, "device/remove", "1");
> +   igt_sysfs_set(fd_sysfs_dev, "remove", "1");
> igt_reset_timeout();
> failure = NULL;
>  
> @@ -185,7 +197,7 @@ static void unbind_rebind(void)
> struct hotunplug priv;
> char buf[PATH_MAX];
>  
> -   prepare(, buf, sizeof(buf));
> +   prepare_for_rebind(, buf, sizeof(buf));
>  
> local_debug("closing the device");
> close(priv.fd.drm);
> @@ -203,7 +215,7 @@ static void unplug_rescan(void)
>  {
> struct hotunplug priv;
>  
> -   prepare(, NULL, 0);
> +   prepare_for_rescan();
>  
> local_debug("closing the device");
> close(priv.fd.drm);
> @@ -222,7 +234,7 @@ static void hotunbind_lateclose(void)
> struct hotunplug priv;
> char buf[PATH_MAX];
>  
> -   prepare(, buf, sizeof(buf));
> +   prepare_for_rebind(, buf, sizeof(buf));
>  
> local_debug("hot unbinding the driver from the device");
> driver_unbind(priv.fd.sysfs_drv, priv.dev_bus_addr);
> @@ -240,7 +252,7 @@ static void hotunplug_lateclose(void)
>  {
> struct hotunplug priv;
>  
> -   prepare(, NULL, 0);
> +   prepare_for_rescan();
>  
>   

Re: [Intel-gfx] [RFC PATCH i-g-t v2 1/8] tests/core_hotunplug: Duplicate debug messages in dmesg

2020-06-25 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-06-22 18:44:08)
> The purpose of debug messages displayed by the test is to make
> identification of a subtest phase that fails more easy.  Since issues
> exhibited by the test are mostly reported to dmesg, print those debug
> messages to /dev/kmsg as well.

I'm not a fan of spamming dmesg from IGT and I'd prefer if you add this logging
to the kernel, but let's go over this case-by-case.

> v2: rebase on upstream
> 
> Signed-off-by: Janusz Krzysztofik 
> ---
>  tests/core_hotunplug.c | 38 ++
>  1 file changed, 22 insertions(+), 16 deletions(-)
> 
> diff --git a/tests/core_hotunplug.c b/tests/core_hotunplug.c
> index e03f3b945..826645b1f 100644
> --- a/tests/core_hotunplug.c
> +++ b/tests/core_hotunplug.c
> @@ -49,6 +49,12 @@ struct hotunplug {
>  
>  /* Helpers */
>  
> +#define local_debug(msg...) \
> +({  \
> +   igt_debug("%s: %s\n", __func__, msg);\
> +   igt_kmsg(KMSG_DEBUG "%s: %s: %s\n", igt_test_name(), __func__, msg); \
> +})
> +
>  static void prepare_for_unbind(struct hotunplug *priv, char *buf, int buflen)
>  {
> int len;
> @@ -68,9 +74,9 @@ static void prepare_for_unbind(struct hotunplug *priv, char 
> *buf, int buflen)
> close(priv->fd.sysfs_dev);
>  }
>  
> -static void prepare(struct hotunplug *priv, char *buf, int buflen)
> +static inline void prepare(struct hotunplug *priv, char *buf, int buflen)
>  {
> -   igt_debug("opening device\n");
> +   local_debug("opening device");

[  220.458370] [drm:drm_open] pid = 194, minor = 128
[  220.460062] [drm:i915_gem_open [i915]]

> priv->fd.drm = __drm_open_driver(DRIVER_ANY);
> igt_assert(priv->fd.drm >= 0);
>  
> @@ -137,14 +143,14 @@ static void bus_rescan(int fd_sysfs_bus)
> close(fd_sysfs_bus);
>  }
>  
> -static void healthcheck(void)
> +static inline void healthcheck(void)
>  {
> int fd_drm;
>  
> /* device name may have changed, rebuild IGT device list */
> igt_devices_scan(true);
>  
> -   igt_debug("reopening the device\n");
> +   local_debug("reopening the device");

Well, this is going to look the same as open, except closing it won't print
drm_lastclose.

[  293.957567] [drm:drm_release] open_count = 2
[  293.958805] [drm:drm_file_free.part.0] pid = 194, device = 0xe280, 
open_count = 2

> fd_drm = __drm_open_driver(DRIVER_ANY);
> igt_abort_on_f(fd_drm < 0, "Device reopen failure");
>  
> @@ -181,13 +187,13 @@ static void unbind_rebind(void)
>  
> prepare(, buf, sizeof(buf));
>  
> -   igt_debug("closing the device\n");
> +   local_debug("closing the device");

[  250.157568] [drm:drm_release] open_count = 1
[  250.158807] [drm:drm_file_free.part.0] pid = 194, device = 0xe280, 
open_count = 1
[  250.161183] [drm:drm_lastclose]
[  250.162312] [drm:drm_lastclose] driver lastclose completed

> close(priv.fd.drm);
>  
> -   igt_debug("unbinding the driver from the device\n");
> +   local_debug("unbinding the driver from the device");
> driver_unbind(priv.fd.sysfs_drv, priv.dev_bus_addr);

[ 1553.868235] bus: 'event_source': remove device i915__00_02.0

>  
> -   igt_debug("rebinding the driver to the device\n");
> +   local_debug("rebinding the driver to the device");
> driver_bind(priv.fd.sysfs_drv, priv.dev_bus_addr);

[ 1592.758219] bus: 'pci': driver_probe_device: matched device :00:02.0 
with driver i915
[ 1592.760543] bus: 'pci': really_probe: probing driver i915 with device 
:00:02.0
(...bunch of i915 logs...)
[  203.961656] driver: 'i915': driver_bound: bound to device ':00:02.0'
[  203.966421] bus: 'pci': really_probe: bound device :00:02.0 to driver 
i915

>  
> healthcheck();
> @@ -199,13 +205,13 @@ static void unplug_rescan(void)
>  
> prepare(, NULL, 0);
>  
> -   igt_debug("closing the device\n");
> +   local_debug("closing the device");
> close(priv.fd.drm);
>  
> -   igt_debug("unplugging the device\n");
> +   local_debug("unplugging the device");
> device_unplug(priv.fd.sysfs_dev);

[   60.664163] bus: 'pci': remove device :00:02.0

> -   igt_debug("recovering the device\n");
> +   local_debug("recovering the device");
> bus_rescan(priv.fd.sysfs_bus);

[   97.384479] bus: 'pci': add device :00:02.0

>  
> healthcheck();
> @@ -218,13 +224,13 @@ static void hotunbind_lateclose(void)
>  
> prepare(, buf, sizeof(buf));
>  
> -   igt_debug("hot unbinding the driver from the device\n");
> +   local_debug("hot unbinding the driver from the device");
> driver_unbind(priv.fd.sysfs_drv, priv.dev_bus_addr);
>  
> -   igt_debug("rebinding the driver to the device\n");
> +   local_debug("rebinding the driver to the device");
>   

Re: [Intel-gfx] [RFC PATCH 4/4] drm/i915: Move UC firmware cleanup from driver_release to _remove

2020-05-27 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-05-18 20:17:20)
> UC firmware is stored in a GEM object.  Clean it up on driver remove to
 ^ double whitespace
> avoid intel-iommu triggered kernel panic on late DMA unmapping or even
> an RPM related warning on object late removal in no IOMMU setups.

This is no longer the case after:
drm/i915/gem: Lazily acquire the device wakeref for freeing objects

Right?

> 
> <4> [93.335282] [ cut here ]
> <4> [93.335515] pm_runtime_get_sync() failed: -13
> <4> [93.336056] WARNING: CPU: 6 PID: 200 at 
> drivers/gpu/drm/i915/intel_runtime_pm.c:361 __intel_runtime_pm_get+0x4d/0x60 
> [i915]
> <4> [93.336104] Modules linked in: snd_hda_codec_hdmi mei_hdcp i915 
> x86_pkg_temp_thermal coretemp crct10dif_pclmul crc32_pclmul 
> ghash_clmulni_intel snd_hda_intel cdc_ether snd_intel_dspcfg usbnet 
> snd_hda_codec mii snd_hwdep snd_hda_core e1000e snd_pcm ptp pps_core mei_me 
> mei intel_lpss_pci prime_numbers
> <4> [93.336268] CPU: 6 PID: 200 Comm: kworker/u16:3 Tainted: G U  
>   5.7.0-rc4-CI-Trybot_6405+ #1
> <4> [93.336289] Hardware name: Intel Corporation Tiger Lake Client 
> Platform/TigerLake Y LPDDR4x T4 Crb, BIOS TGLSFWI1.R00.2457.A16.1912270059 
> 12/27/2019
> <4> [93.336811] Workqueue: i915 __i915_gem_free_work [i915]
> <4> [93.337296] RIP: 0010:__intel_runtime_pm_get+0x4d/0x60 [i915]
> <4> [93.337332] Code: ff ff 48 89 df 5b 5d e9 a1 fa ff ff 80 3d 4b 7a 2e 00 
> 00 75 e1 89 c6 48 c7 c7 a8 2d 40 a0 c6 05 39 7a 2e 00 01 e8 53 fc e9 e0 <0f> 
> 0b eb c8 0f 1f 44 00 00 66 2e 0f 1f 84 00 00 00 00 00 41 57 41
> <4> [93.337357] RSP: 0018:c9000144bdd8 EFLAGS: 00010282
> <4> [93.337384] RAX:  RBX: 88838ee5bc40 RCX: 
> 0001
> <4> [93.337409] RDX: 8001 RSI: 88839d264928 RDI: 
> 
> <4> [93.337440] RBP: 0001 R08: 88839d264928 R09: 
> 
> <4> [93.337467] R10:  R11:  R12: 
> 88838ee5bc40
> <4> [93.337493] R13: 0006 R14: 82769a30 R15: 
> 88839376bab0
> <4> [93.337515] FS:  () GS:8883a410() 
> knlGS:
> <4> [93.337542] CS:  0010 DS:  ES:  CR0: 80050033
> <4> [93.337563] CR2: 55bc19b16ff8 CR3: 0003a11c4005 CR4: 
> 00760ee0
> <4> [93.337583] PKRU: 5554
> <4> [93.337605] Call Trace:
> <4> [93.338148]  i915_gem_object_release_mmap+0x23/0x70 [i915]
> <4> [93.338665]  __i915_gem_free_objects.isra.21+0x10a/0x4b0 [i915]
> <4> [93.338741]  process_one_work+0x268/0x600
> <4> [93.338785]  ? __schedule+0x307/0x8d0
> <4> [93.338878]  worker_thread+0x37/0x380
> <4> [93.338929]  ? process_one_work+0x600/0x600
> <4> [93.338963]  kthread+0x140/0x160
> <4> [93.339006]  ? kthread_park+0x80/0x80
> <4> [93.339057]  ret_from_fork+0x24/0x50
> <4> [93.339181] irq event stamp: 204220
> <4> [93.339219] hardirqs last  enabled at (204219): [] 
> console_unlock+0x4cd/0x5a0
> <4> [93.339250] hardirqs last disabled at (204220): [] 
> trace_hardirqs_off_thunk+0x1a/0x1c
> <4> [93.339277] softirqs last  enabled at (204208): [] 
> __do_softirq+0x395/0x49e
> <4> [93.339307] softirqs last disabled at (204197): [] 
> irq_exit+0xba/0xc0
> <4> [93.339330] ---[ end trace f066187622b8c484 ]---
> 
> Signed-off-by: Janusz Krzysztofik 

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  drivers/gpu/drm/i915/i915_gem.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 87d3c4f5b6c6..f9d37c7e6d6f 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -1191,6 +1191,8 @@ void i915_gem_driver_remove(struct drm_i915_private 
> *dev_priv)
>  
> i915_gem_driver_remove__contexts(dev_priv);
>  
> +   intel_uc_cleanup_firmwares(_priv->gt.uc);
> +
> i915_gem_drain_freed_objects(dev_priv);
>  }
>  
> @@ -1202,7 +1204,6 @@ void i915_gem_driver_release(struct drm_i915_private 
> *dev_priv)
>  
> intel_wa_list_free(_priv->gt_wa_list);
>  
> -   intel_uc_cleanup_firmwares(_priv->gt.uc);
> i915_gem_cleanup_userptr(dev_priv);
>  
> i915_gem_drain_freed_objects(dev_priv);
> -- 
> 2.21.1
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [RFC PATCH 3/4] drm/i915: Move GGTT cleanup from driver_release to _remove

2020-05-27 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-05-18 20:17:19)
> GGTT including its scratch page is not cleaned up until driver release.
> Since DMA mappings still exist before scratch page cleanup, unmapping
> them on last device close after the driver has been already removed may
> be judged by intel-iommu code as a bug and result in kernel panic.
> 
> Since we abort requests and block user access to hardware on device
> removal, there seems not much sense in still keeping GGTT.  Clean it up
> on driver remove.  However, skip GGTT address space cleanup as its
> mutext may still be needed if there are objects to be freed.  That
> cleanup is always called on address space release after all.
> 
> [   81.290284] [ cut here ]
> [   81.291602] kernel BUG at drivers/iommu/intel-iommu.c:3591!
> [   81.293558] invalid opcode:  [#1] PREEMPT SMP
> [   81.294695] CPU: 0 PID: 207 Comm: core_hotunplug Tainted: G U  
>   5.4.17 #2
> [   81.296579] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007
> [   81.297959] RIP: 0010:intel_unmap+0x200/0x230
> [   81.299015] Code: 00 e8 e4 45 c5 ff 85 c0 74 09 80 3d 2b 84 c0 00 00 74 19 
> 65 ff 0d 78 9a b2 7e 0f 85 fa fe ff ff e8 95 57 b1 ff e9 f0 fe ff ff <0f> 0b 
> e8 19 4c c5 ff 85 c0 75 de 48 c7 c2 48 d2 e1 81 be 57 00 00
> [   81.303425] RSP: 0018:c913fda0 EFLAGS: 00010246
> [   81.304683] RAX:  RBX: 8882228dd0b0 RCX: 
> 
> [   81.306384] RDX: 1000 RSI: af801000 RDI: 
> 8882228dd0b0
> [   81.308086] RBP:  R08:  R09: 
> 
> [   81.309788] R10:  R11:  R12: 
> af801000
> [   81.311489] R13: 888223a0 R14: 1000 R15: 
> 888223a0a2e8
> [   81.313191] FS:  7f5408e3c940() GS:88822860() 
> knlGS:
> [   81.315116] CS:  0010 DS:  ES:  CR0: 80050033
> [   81.316495] CR2: 01fc0048 CR3: 00022464a000 CR4: 
> 06b0
> [   81.318196] Call Trace:
> [   81.318967]  cleanup_scratch_page+0x44/0x80 [i915]
> [   81.320281]  i915_ggtt_driver_release+0x15b/0x220 [i915]
> [   81.321717]  i915_driver_release+0x33/0x90 [i915]
> [   81.322856]  drm_release+0xbc/0xd0
> [   81.323691]  __fput+0xcd/0x260
> [   81.324447]  task_work_run+0x90/0xc0
> [   81.325323]  do_syscall_64+0x3da/0x560
> [   81.326240]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
> [   81.327457] RIP: 0033:0x7f54096ecba3
> [   81.328332] Code: 00 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 
> 00 00 00 00 64 8b 04 25 18 00 00 00 85 c0 75 14 b8 03 00 00 00 0f 05 <48> 3d 
> 00 f0 ff ff 77 45 c3 0f 1f 40 00 48 83 ec 18 89 7c 24 0c e8
> [   81.332741] RSP: 002b:7ffcc5165698 EFLAGS: 0246 ORIG_RAX: 
> 0003
> [   81.334546] RAX:  RBX:  RCX: 
> 7f54096ecba3
> [   81.336247] RDX: 005cc5d0 RSI: 0005 RDI: 
> 0004
> [   81.337949] RBP: 0003 R08: 005b8014 R09: 
> 0004
> [   81.339650] R10: 005cc650 R11: 0246 R12: 
> 004022f0
> [   81.341352] R13: 7ffcc5165850 R14:  R15: 
> 
> [   81.343059] Modules linked in: i915 mfd_core intel_gtt prime_numbers
> [   81.345015] ---[ end trace 010aae55e56f8998 ]---
> 
> Signed-off-by: Janusz Krzysztofik 
> 
> drm/i915: Defer GGTT vm address space fini to vm release

Hum?

> 
> Signed-off-by: Janusz Krzysztofik 
> ---
>  drivers/gpu/drm/i915/gt/intel_ggtt.c | 13 +
>  drivers/gpu/drm/i915/gt/intel_gtt.h  |  1 +
>  drivers/gpu/drm/i915/i915_drv.c  |  2 ++
>  3 files changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c 
> b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> index 66165b10256e..ff2b4f74149a 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> @@ -701,7 +701,6 @@ static void ggtt_cleanup_hw(struct i915_ggtt *ggtt)
> ggtt->vm.cleanup(>vm);
>  
> mutex_unlock(>vm.mutex);
> -   i915_address_space_fini(>vm);

Ok, so this was defered to release. Where are we going to drop the final ref?
And also - I can see that we have a:

GEM_BUG_ON(i915_is_ggtt(vm));

in i915_vm_release().
Which means that we probably don't drop the final ref and don't ever call
i915_address_space_fini for ggtt.

-Michał

>  
> arch_phys_wc_del(ggtt->mtrr);
>  
> @@ -709,6 +708,15 @@ static void ggtt_cleanup_hw(struct i915_ggtt *ggtt)
> io_mapping_fini(>iomap);
>  }
>  
> +void i915_ggtt_driver_remove(struct drm_i915_private *i915)
> +{
> +   struct i915_ggtt *ggtt = >ggtt;
> +
> +   fini_aliasing_ppgtt(ggtt);
> +
> +   ggtt_cleanup_hw(ggtt);
> +}
> +
>  /**
>   * i915_ggtt_driver_release - Clean up GGTT hardware initialization
>   * @i915: i915 device
> @@ -718,10 +726,7 @@ void i915_ggtt_driver_release(struct 

Re: [Intel-gfx] [RFC PATCH 2/4] drm/i915: Release GT resources on driver remove

2020-05-27 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-05-18 20:17:18)
> GT scratch page is now released and its DMA mappings revoked on driver
> release.  If a device is removed while its file descriptor is still
> open, the driver is not released until last device file descriptor
> closure.  In that case intel-iommu code may judge late DMA unmapping as
> a bug and kernel panic may occur.
> 
> Since DMA mapped address space may be no longer usable after device
> removal, release GT resources including scratch page as well as a
> reference to its address space on driver remove.  Implement that by
> just calling intel_gt_driver_release() on GT remove as that function
> has been already made safe to be called again on driver release even if
> already called before, e.g. on GEM initialization failure.

Do you mean:
if (vm) /* FIXME being called twice on error paths :( */
i915_vm_put(vm);

?

We're not fixing that... We're adding more :(
Unfortunately I don't have a clear answer on how to rework our init / cleanup to
be unplug friendly, and this fixes a bug, so...

Reviewed-by: Michał Winiarski 

-Michał


> 
> <4> [39.201062] [ cut here ]
> <2> [39.201074] kernel BUG at drivers/iommu/intel-iommu.c:3717!
> <4> [39.201154] invalid opcode:  [#1] PREEMPT SMP NOPTI
> <4> [39.201162] CPU: 6 PID: 7 Comm: kworker/u16:0 Tainted: G U  W 
> 5.7.0-rc5-CI-CI_DRM_8485+ #1
> <4> [39.201172] Hardware name: Intel Corporation Ice Lake Client 
> Platform/IceLake U DDR4 SODIMM PD RVP, BIOS ICLSFWR1.R00.3175.A00.1904261428 
> 04/26/2019
> <4> [39.201243] Workqueue: i915 __i915_gem_free_work [i915]
> <4> [39.201252] RIP: 0010:intel_unmap+0x1f5/0x230
> <4> [39.201260] Code: 01 e8 9f bc a9 ff 85 c0 74 09 80 3d df 60 09 01 00 74 
> 19 65 ff 0d 13 12 97 7e 0f 85 fc fe ff ff e8 82 b0 95 ff e9 f2 fe ff ff <0f> 
> 0b e8 d4 bd a9 ff 85 c0 75 de 48 c7 c2 10 84 2c 82 be 54 00 00
> <4> [39.201278] RSP: 0018:c90dbc98 EFLAGS: 00010246
> <4> [39.201285] RAX:  RBX:  RCX: 
> ea0021d3
> <4> [39.201293] RDX: 0005f000 RSI: fed0 RDI: 
> 89eec000
> <4> [39.201301] RBP: 89eec0b0 R08:  R09: 
> fffe
> <4> [39.201309] R10: 458139fc R11: f6c6d8b2 R12: 
> 0025
> <4> [39.201318] R13: fed0 R14: 0005f000 R15: 
> 0025
> <4> [39.201326] FS:  () GS:9010() 
> knlGS:
> <4> [39.201335] CS:  0010 DS:  ES:  CR0: 80050033
> <4> [39.201342] CR2: 560f1308e148 CR3: 000881972002 CR4: 
> 00760ee0
> <4> [39.201350] PKRU: 5554
> <4> [39.201355] Call Trace:
> <4> [39.201361]  intel_unmap_sg+0x7b/0x180
> <4> [39.201412]  shmem_put_pages+0x43/0x250 [i915]
> <4> [39.201472]  ? __i915_gem_object_unset_pages.part.12+0x11b/0x1d0 [i915]
> <4> [39.201531]  ? __i915_gem_object_unset_pages.part.12+0x133/0x1d0 [i915]
> <4> [39.201590]  __i915_gem_object_put_pages+0x81/0xc0 [i915]
> <4> [39.201646]  __i915_gem_free_objects.isra.21+0x1a7/0x4b0 [i915]
> <4> [39.201658]  process_one_work+0x268/0x600
> <4> [39.201666]  ? __schedule+0x307/0x8d0
> <4> [39.201675]  worker_thread+0x1d0/0x380
> <4> [39.201682]  ? process_one_work+0x600/0x600
> <4> [39.201689]  kthread+0x140/0x160
> <4> [39.201695]  ? kthread_park+0x80/0x80
> <4> [39.201703]  ret_from_fork+0x24/0x50
> <4> [39.201712] Modules linked in: snd_hda_codec_hdmi snd_hda_codec_realtek 
> snd_hda_codec_generic i915 mei_hdcp x86_pkg_temp_thermal coretemp 
> crct10dif_pclmul crc32_pclmul snd_hda_intel snd_intel_dspcfg snd_hda_codec 
> e1000e ax88179_178a usbnet snd_hwdep mii snd_hda_core ghash_clmulni_intel 
> snd_pcm ptp pps_core mei_me mei intel_lpss_pci prime_numbers
> <4> [39.201764] ---[ end trace f3ec1bae3de04509 ]---
> 
> Signed-off-by: Janusz Krzysztofik 
> ---
>  drivers/gpu/drm/i915/gt/intel_gt.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
> b/drivers/gpu/drm/i915/gt/intel_gt.c
> index f069551e412f..5771e80e85a6 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.c
> @@ -599,6 +599,8 @@ void intel_gt_driver_remove(struct intel_gt *gt)
> intel_uc_driver_remove(>uc);
>  
> intel_engines_release(gt);
> +
> +   intel_gt_driver_release(gt);
>  }
>  
>  void intel_gt_driver_unregister(struct intel_gt *gt)
> -- 
> 2.21.1
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [RFC PATCH 1/4] drm/i915: Drop user contexts on driver remove

2020-05-27 Thread Michał Winiarski
Quoting Janusz Krzysztofik (2020-05-18 20:17:17)
> Contexts associated with open device file descriptors together with
> their assigned address spaces are now closed on device file close.  On
> address space closure its associated DMA mappings are revoked.  If the
> device is removed while being open, subsequent attempts to revoke
> those mappings while closing the device file descriptor may may be
> judged by intel-iommu code as a bug and result in kernel panic.
> 
> Since user contexts become useless after the device is no longer
> available, drop them on device removal.
> 
> <4> [36.900985] [ cut here ]
> <2> [36.901005] kernel BUG at drivers/iommu/intel-iommu.c:3717!
> <4> [36.901105] invalid opcode:  [#1] PREEMPT SMP NOPTI
> <4> [36.901117] CPU: 0 PID: 39 Comm: kworker/u8:1 Tainted: G U  W 
> 5.7.0-rc5-CI-CI_DRM_8485+ #1
> <4> [36.901133] Hardware name: Intel Corporation Elkhart Lake Embedded 
> Platform/ElkhartLake LPDDR4x T3 CRB, BIOS EHLSFWI1.R00.1484.A00.1911290833 
> 11/29/2019
> <4> [36.901250] Workqueue: i915 __i915_vm_release [i915]
> <4> [36.901264] RIP: 0010:intel_unmap+0x1f5/0x230
> <4> [36.901274] Code: 01 e8 9f bc a9 ff 85 c0 74 09 80 3d df 60 09 01 00 74 
> 19 65 ff 0d 13 12 97 7e 0f 85 fc fe ff ff e8 82 b0 95 ff e9 f2 fe ff ff <0f> 
> 0b e8 d4 bd a9 ff 85 c0 75 de 48 c7 c2 10 84 2c 82 be 54 00 00
> <4> [36.901302] RSP: 0018:c91ebdc0 EFLAGS: 00010246
> <4> [36.901313] RAX:  RBX: 8882561dd000 RCX: 
> 
> <4> [36.901324] RDX: 1000 RSI: ffd9c000 RDI: 
> 888274c94000
> <4> [36.901336] RBP: 888274c940b0 R08:  R09: 
> 0001
> <4> [36.901348] R10: 0a25d812 R11: 112af2d4 R12: 
> 888252c70200
> <4> [36.901360] R13: ffd9c000 R14: 1000 R15: 
> 8882561dd010
> <4> [36.901372] FS:  () GS:88827800() 
> knlGS:
> <4> [36.901386] CS:  0010 DS:  ES:  CR0: 80050033
> <4> [36.901396] CR2: 7f06def54950 CR3: 000255844000 CR4: 
> 00340ef0
> <4> [36.901408] Call Trace:
> <4> [36.901418]  ? process_one_work+0x1de/0x600
> <4> [36.901494]  cleanup_page_dma+0x37/0x70 [i915]
> <4> [36.901573]  free_pd+0x9/0x20 [i915]
> <4> [36.901644]  gen8_ppgtt_cleanup+0x59/0xc0 [i915]
> <4> [36.901721]  __i915_vm_release+0x14/0x30 [i915]
> <4> [36.901733]  process_one_work+0x268/0x600
> <4> [36.901744]  ? __schedule+0x307/0x8d0
> <4> [36.901756]  worker_thread+0x37/0x380
> <4> [36.901766]  ? process_one_work+0x600/0x600
> <4> [36.901775]  kthread+0x140/0x160
> <4> [36.901783]  ? kthread_park+0x80/0x80
> <4> [36.901792]  ret_from_fork+0x24/0x50
> <4> [36.901804] Modules linked in: mei_hdcp i915 x86_pkg_temp_thermal 
> coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel ax88179_178a 
> usbnet mii mei_me mei prime_numbers intel_lpss_pci
> <4> [36.901857] ---[ end trace 52d1b4d81f8d1ea7 ]---
> 
> Signed-off-by: Janusz Krzysztofik 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_context.c | 38 +
>  drivers/gpu/drm/i915/gem/i915_gem_context.h |  1 +
>  drivers/gpu/drm/i915/i915_gem.c |  2 ++
>  3 files changed, 41 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index 900ea8b7fc8f..0096a69fbfd3 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -927,6 +927,44 @@ void i915_gem_driver_release__contexts(struct 
> drm_i915_private *i915)
> rcu_barrier(); /* and flush the left over RCU frees */
>  }
>  
> +void i915_gem_driver_remove__contexts(struct drm_i915_private *i915)
> +{
> +   struct i915_gem_context *ctx, *cn;
> +
> +   list_for_each_entry_safe(ctx, cn, >gem.contexts.list, link) {

You're not removing ctx from gem.contexts.list inside this loop.

> +   struct drm_i915_file_private *file_priv = ctx->file_priv;
> +   struct i915_gem_context *entry;
> +   unsigned long int id;
> +
> +   if (i915_gem_context_is_closed(ctx) || IS_ERR(file_priv))
> +   continue;
> +
> +   xa_for_each(_priv->context_xa, id, entry) {

We're iterating over contexts?
I thought we were already doing that by going over i915->gem.contexts.list.

> +   struct i915_address_space *vm;
> +   unsigned long int idx;
> +
> +   if (entry != ctx)
> +   continue;
> +
> +   xa_erase(_priv->context_xa, id);
> +
> +   if (id)
> +   break;

Ok... So we're exiting early for !default contexts?

> +
> +   xa_for_each(_priv->vm_xa, idx, vm) {
> +   xa_erase(_priv->vm_xa, idx);
> +   i915_vm_put(vm);
> +   }

[Intel-gfx] [PATCH 2/2] drm/i915/pmu: Avoid using globals for PMU events

2020-02-19 Thread Michał Winiarski
Attempting to bind / unbind module from devices where we have both
integrated and discreete GPU handled by i915, will cause us to try and
double free the global state, hitting null ptr deref in free_event_attributes.

Let's move it to i915_pmu.

Fixes: 05488673a4d4 ("drm/i915/pmu: Support multiple GPUs")
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Michal Wajdeczko 
Cc: Tvrtko Ursulin 
Reviewed-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_pmu.c | 41 ++---
 drivers/gpu/drm/i915/i915_pmu.h |  4 
 2 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index 12f4818c78b8..2c062534eac1 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -822,11 +822,6 @@ static ssize_t i915_pmu_event_show(struct device *dev,
return sprintf(buf, "config=0x%lx\n", eattr->val);
 }
 
-static struct attribute_group i915_pmu_events_attr_group = {
-   .name = "events",
-   /* Patch in attrs at runtime. */
-};
-
 static ssize_t
 i915_pmu_get_attr_cpumask(struct device *dev,
  struct device_attribute *attr,
@@ -846,13 +841,6 @@ static const struct attribute_group 
i915_pmu_cpumask_attr_group = {
.attrs = i915_cpumask_attrs,
 };
 
-static const struct attribute_group *i915_pmu_attr_groups[] = {
-   _pmu_format_attr_group,
-   _pmu_events_attr_group,
-   _pmu_cpumask_attr_group,
-   NULL
-};
-
 #define __event(__config, __name, __unit) \
 { \
.config = (__config), \
@@ -1026,16 +1014,16 @@ err:;
 
 static void free_event_attributes(struct i915_pmu *pmu)
 {
-   struct attribute **attr_iter = i915_pmu_events_attr_group.attrs;
+   struct attribute **attr_iter = pmu->events_attr_group.attrs;
 
for (; *attr_iter; attr_iter++)
kfree((*attr_iter)->name);
 
-   kfree(i915_pmu_events_attr_group.attrs);
+   kfree(pmu->events_attr_group.attrs);
kfree(pmu->i915_attr);
kfree(pmu->pmu_attr);
 
-   i915_pmu_events_attr_group.attrs = NULL;
+   pmu->events_attr_group.attrs = NULL;
pmu->i915_attr = NULL;
pmu->pmu_attr = NULL;
 }
@@ -1117,6 +1105,13 @@ static bool is_igp(struct drm_i915_private *i915)
 void i915_pmu_register(struct drm_i915_private *i915)
 {
struct i915_pmu *pmu = >pmu;
+   const struct attribute_group *attr_groups[] = {
+   _pmu_format_attr_group,
+   >events_attr_group,
+   _pmu_cpumask_attr_group,
+   NULL
+   };
+
int ret = -ENOMEM;
 
if (INTEL_GEN(i915) <= 2) {
@@ -1143,11 +1138,16 @@ void i915_pmu_register(struct drm_i915_private *i915)
if (!pmu->name)
goto err;
 
-   i915_pmu_events_attr_group.attrs = create_event_attributes(pmu);
-   if (!i915_pmu_events_attr_group.attrs)
+   pmu->events_attr_group.name = "events";
+   pmu->events_attr_group.attrs = create_event_attributes(pmu);
+   if (!pmu->events_attr_group.attrs)
goto err_name;
 
-   pmu->base.attr_groups   = i915_pmu_attr_groups;
+   pmu->base.attr_groups = kmemdup(attr_groups, sizeof(attr_groups),
+   GFP_KERNEL);
+   if (!pmu->base.attr_groups)
+   goto err_attr;
+
pmu->base.task_ctx_nr   = perf_invalid_context;
pmu->base.event_init= i915_pmu_event_init;
pmu->base.add   = i915_pmu_event_add;
@@ -1159,7 +1159,7 @@ void i915_pmu_register(struct drm_i915_private *i915)
 
ret = perf_pmu_register(>base, pmu->name, -1);
if (ret)
-   goto err_attr;
+   goto err_groups;
 
ret = i915_pmu_register_cpuhp_state(pmu);
if (ret)
@@ -1169,6 +1169,8 @@ void i915_pmu_register(struct drm_i915_private *i915)
 
 err_unreg:
perf_pmu_unregister(>base);
+err_groups:
+   kfree(pmu->base.attr_groups);
 err_attr:
pmu->base.event_init = NULL;
free_event_attributes(pmu);
@@ -1194,6 +1196,7 @@ void i915_pmu_unregister(struct drm_i915_private *i915)
 
perf_pmu_unregister(>base);
pmu->base.event_init = NULL;
+   kfree(pmu->base.attr_groups);
if (!is_igp(i915))
kfree(pmu->name);
free_event_attributes(pmu);
diff --git a/drivers/gpu/drm/i915/i915_pmu.h b/drivers/gpu/drm/i915/i915_pmu.h
index 207058391cec..f1d6cad0d7d5 100644
--- a/drivers/gpu/drm/i915/i915_pmu.h
+++ b/drivers/gpu/drm/i915/i915_pmu.h
@@ -107,6 +107,10 @@ struct i915_pmu {
 * @sleep_last: Last time GT parked for RC6 estimation.
 */
ktime_t sleep_last;
+   /**
+* @events_attr_group: Device events attribute group.
+*/
+   struct attribute_group events_attr_group;
/**
 * @i915_attr: M

[Intel-gfx] [PATCH 1/2] drm/i915/pmu: Avoid using globals for CPU hotplug state

2020-02-19 Thread Michał Winiarski
Attempting to bind / unbind module from devices where we have both
integrated and discreete GPU handled by i915 can lead to leaks and
warnings from cpuhp:
Error: Removing state XXX which has instances left.

Let's move the state to i915_pmu.

Fixes: 05488673a4d4 ("drm/i915/pmu: Support multiple GPUs")
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Michal Wajdeczko 
Cc: Tvrtko Ursulin 
Reviewed-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_pmu.c | 18 +-
 drivers/gpu/drm/i915/i915_pmu.h |  7 +--
 2 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index a3b61fb96226..12f4818c78b8 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -1042,7 +1042,7 @@ static void free_event_attributes(struct i915_pmu *pmu)
 
 static int i915_pmu_cpu_online(unsigned int cpu, struct hlist_node *node)
 {
-   struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), node);
+   struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
 
GEM_BUG_ON(!pmu->base.event_init);
 
@@ -1055,7 +1055,7 @@ static int i915_pmu_cpu_online(unsigned int cpu, struct 
hlist_node *node)
 
 static int i915_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
 {
-   struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), node);
+   struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
unsigned int target;
 
GEM_BUG_ON(!pmu->base.event_init);
@@ -1072,8 +1072,6 @@ static int i915_pmu_cpu_offline(unsigned int cpu, struct 
hlist_node *node)
return 0;
 }
 
-static enum cpuhp_state cpuhp_slot = CPUHP_INVALID;
-
 static int i915_pmu_register_cpuhp_state(struct i915_pmu *pmu)
 {
enum cpuhp_state slot;
@@ -1087,21 +1085,22 @@ static int i915_pmu_register_cpuhp_state(struct 
i915_pmu *pmu)
return ret;
 
slot = ret;
-   ret = cpuhp_state_add_instance(slot, >node);
+   ret = cpuhp_state_add_instance(slot, >cpuhp.node);
if (ret) {
cpuhp_remove_multi_state(slot);
return ret;
}
 
-   cpuhp_slot = slot;
+   pmu->cpuhp.slot = slot;
return 0;
 }
 
 static void i915_pmu_unregister_cpuhp_state(struct i915_pmu *pmu)
 {
-   WARN_ON(cpuhp_slot == CPUHP_INVALID);
-   WARN_ON(cpuhp_state_remove_instance(cpuhp_slot, >node));
-   cpuhp_remove_multi_state(cpuhp_slot);
+   WARN_ON(pmu->cpuhp.slot == CPUHP_INVALID);
+   WARN_ON(cpuhp_state_remove_instance(pmu->cpuhp.slot, >cpuhp.node));
+   cpuhp_remove_multi_state(pmu->cpuhp.slot);
+   pmu->cpuhp.slot = CPUHP_INVALID;
 }
 
 static bool is_igp(struct drm_i915_private *i915)
@@ -1128,6 +1127,7 @@ void i915_pmu_register(struct drm_i915_private *i915)
spin_lock_init(>lock);
hrtimer_init(>timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
pmu->timer.function = i915_sample;
+   pmu->cpuhp.slot = CPUHP_INVALID;
 
if (!is_igp(i915)) {
pmu->name = kasprintf(GFP_KERNEL,
diff --git a/drivers/gpu/drm/i915/i915_pmu.h b/drivers/gpu/drm/i915/i915_pmu.h
index 6c1647c5daf2..207058391cec 100644
--- a/drivers/gpu/drm/i915/i915_pmu.h
+++ b/drivers/gpu/drm/i915/i915_pmu.h
@@ -39,9 +39,12 @@ struct i915_pmu_sample {
 
 struct i915_pmu {
/**
-* @node: List node for CPU hotplug handling.
+* @cpuhp: Struct used for CPU hotplug handling.
 */
-   struct hlist_node node;
+   struct {
+   struct hlist_node node;
+   enum cpuhp_state slot;
+   } cpuhp;
/**
 * @base: PMU base.
 */
-- 
2.21.1

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


[Intel-gfx] [PATCH] drm/i915/pmu: Avoid using globals for per-device state

2020-02-19 Thread Michał Winiarski
Attempting to bind / unbind module from devices where we have both
integrated and discreete GPU handed by i915 may lead to interesting
results where we're keeping per-device state in per-module globals.

Fixes: 05488673a4d4 ("drm/i915/pmu: Support multiple GPUs")
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Michal Wajdeczko 
Cc: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_pmu.c | 56 ++---
 drivers/gpu/drm/i915/i915_pmu.h |  8 +
 2 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index a3b61fb96226..1b4fdcb9045d 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -822,11 +822,6 @@ static ssize_t i915_pmu_event_show(struct device *dev,
return sprintf(buf, "config=0x%lx\n", eattr->val);
 }
 
-static struct attribute_group i915_pmu_events_attr_group = {
-   .name = "events",
-   /* Patch in attrs at runtime. */
-};
-
 static ssize_t
 i915_pmu_get_attr_cpumask(struct device *dev,
  struct device_attribute *attr,
@@ -846,13 +841,6 @@ static const struct attribute_group 
i915_pmu_cpumask_attr_group = {
.attrs = i915_cpumask_attrs,
 };
 
-static const struct attribute_group *i915_pmu_attr_groups[] = {
-   _pmu_format_attr_group,
-   _pmu_events_attr_group,
-   _pmu_cpumask_attr_group,
-   NULL
-};
-
 #define __event(__config, __name, __unit) \
 { \
.config = (__config), \
@@ -1026,16 +1014,16 @@ err:;
 
 static void free_event_attributes(struct i915_pmu *pmu)
 {
-   struct attribute **attr_iter = i915_pmu_events_attr_group.attrs;
+   struct attribute **attr_iter = pmu->events_attr_group.attrs;
 
for (; *attr_iter; attr_iter++)
kfree((*attr_iter)->name);
 
-   kfree(i915_pmu_events_attr_group.attrs);
+   kfree(pmu->events_attr_group.attrs);
kfree(pmu->i915_attr);
kfree(pmu->pmu_attr);
 
-   i915_pmu_events_attr_group.attrs = NULL;
+   pmu->events_attr_group.attrs = NULL;
pmu->i915_attr = NULL;
pmu->pmu_attr = NULL;
 }
@@ -1072,8 +1060,6 @@ static int i915_pmu_cpu_offline(unsigned int cpu, struct 
hlist_node *node)
return 0;
 }
 
-static enum cpuhp_state cpuhp_slot = CPUHP_INVALID;
-
 static int i915_pmu_register_cpuhp_state(struct i915_pmu *pmu)
 {
enum cpuhp_state slot;
@@ -1093,15 +1079,16 @@ static int i915_pmu_register_cpuhp_state(struct 
i915_pmu *pmu)
return ret;
}
 
-   cpuhp_slot = slot;
+   pmu->cpuhp_slot = slot;
return 0;
 }
 
 static void i915_pmu_unregister_cpuhp_state(struct i915_pmu *pmu)
 {
-   WARN_ON(cpuhp_slot == CPUHP_INVALID);
-   WARN_ON(cpuhp_state_remove_instance(cpuhp_slot, >node));
-   cpuhp_remove_multi_state(cpuhp_slot);
+   WARN_ON(pmu->cpuhp_slot == CPUHP_INVALID);
+   WARN_ON(cpuhp_state_remove_instance(pmu->cpuhp_slot, >node));
+   cpuhp_remove_multi_state(pmu->cpuhp_slot);
+   pmu->cpuhp_slot = CPUHP_INVALID;
 }
 
 static bool is_igp(struct drm_i915_private *i915)
@@ -1118,6 +1105,13 @@ static bool is_igp(struct drm_i915_private *i915)
 void i915_pmu_register(struct drm_i915_private *i915)
 {
struct i915_pmu *pmu = >pmu;
+   const struct attribute_group *attr_groups[] = {
+   _pmu_format_attr_group,
+   >events_attr_group,
+   _pmu_cpumask_attr_group,
+   NULL
+   };
+
int ret = -ENOMEM;
 
if (INTEL_GEN(i915) <= 2) {
@@ -1128,6 +1122,7 @@ void i915_pmu_register(struct drm_i915_private *i915)
spin_lock_init(>lock);
hrtimer_init(>timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
pmu->timer.function = i915_sample;
+   pmu->cpuhp_slot = CPUHP_INVALID;
 
if (!is_igp(i915)) {
pmu->name = kasprintf(GFP_KERNEL,
@@ -1143,11 +1138,19 @@ void i915_pmu_register(struct drm_i915_private *i915)
if (!pmu->name)
goto err;
 
-   i915_pmu_events_attr_group.attrs = create_event_attributes(pmu);
-   if (!i915_pmu_events_attr_group.attrs)
+   pmu->events_attr_group.name = "events";
+   pmu->events_attr_group.attrs = create_event_attributes(pmu);
+   if (!pmu->events_attr_group.attrs)
goto err_name;
 
-   pmu->base.attr_groups   = i915_pmu_attr_groups;
+   pmu->base.attr_groups = kcalloc(ARRAY_SIZE(attr_groups),
+   sizeof(*attr_groups),
+   GFP_KERNEL);
+   if (!pmu->base.attr_groups)
+   goto err_attr;
+   memcpy(attr_groups, pmu->base.attr_groups,
+  ARRAY_SIZE(attr_groups) * sizeof(*attr_groups));
+
pmu->base.task_ctx_nr   = perf_invalid_context;
pmu->base.

Re: [Intel-gfx] [RFC PATCH i-g-t] tests/gem_userptr_blits: Refresh map-fixed-invalidate* subtests

2020-02-13 Thread Michał Winiarski
On Thu, Feb 13, 2020 at 01:46:41PM +0100, Janusz Krzysztofik wrote:
> map-fixed-invalidate* subtests utilize gem_set_tiling() which may fail,
> e.g. on hardware with no mappable aperture, due to missing fences.
> Skip those subtests if fences are not available.
> 
> Moreover, those subtests use GEM_MMAP_GTT IOCTL which may also fail,
> e.g. on hardware with no mappable aperture.  Use GEM_MMAP_OFFSET
> instead and iterate MMAP_OFFSET coherent types to find one that works.
> 
> Signed-off-by: Janusz Krzysztofik 
> Cc: Michał Winiarski 
> ---
> Hi Michał,
> 
> As you are the author of those subtests, let me ask you a few questions
> I'm not sure about:
> 1. How critical is the use of gem_set_tiling() to those subtests?  Can
>we just skip those operations if not supported?  If not, can you
>propose a replacement that should work on hardware with no mappable
>aperture?

It's a regression test, see:
e4b946bfe1e3 ("drm/i915: Fix userptr deadlock with aliased GTT mmappings")

The idea was to cause a deadlock by triggerring i915_gem_object_release_mmap
from set_tiling underneath struct_mutex, which would then cause invalidate on a
stale userptr (which would also attempt to acquire struct mutex - classic
recursive lock). Original trace which served as an example to write the IGT:

[23106.066196] [drm:i915_gem_open] 
[23279.022598] INFO: task test_api64:1359 blocked for more than 120 seconds.
[23279.032453]   Tainted: G U  4.1.0-rc7+ #16
[23279.039440] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this 
message.
[23279.049191] test_api64  D 880146837a18 12760  1359530 0x
[23279.058101]  880146837a18 8801468379d8 8101efcd 
880147e22e20
[23279.067372]  8800a34b8000 8801468379f8 880146838000 

[23279.076599]  8801459911b0 0246 8801459911a8 
880146837a38
[23279.085923] Call Trace:
[23279.089510]  [] ? native_sched_clock+0x2d/0x90
[23279.097223]  [] schedule+0x37/0x90
[23279.103662]  [] schedule_preempt_disabled+0xe/0x10
[23279.111665]  [] mutex_lock_nested+0x165/0x3d0
[23279.119287]  [] ? cancel_userptr+0x2c/0x150 [i915]
[23279.127376]  [] ? ftrace_graph_caller+0x78/0xa8
[23279.135204]  [] ? cancel_userptr+0x2c/0x150 [i915]
[23279.143329]  [] cancel_userptr+0x2c/0x150 [i915]
[23279.151263]  [] ftrace_graph_caller+0xa8/0xa8
[23279.158801]  [] 
i915_gem_userptr_mn_invalidate_range_start+0x141/0x200 [i915]
[23279.169559]  [] ? 
i915_gem_userptr_mn_invalidate_range_start+0x5/0x200 [i915]
[23279.180364]  [] ftrace_graph_caller+0xa8/0xa8
[23279.187919]  [] 
__mmu_notifier_invalidate_range_start+0x83/0xd0
[23279.197342]  [] ? 
__mmu_notifier_invalidate_range_start+0x5/0xd0
[23279.206804]  [] zap_page_range_single+0xf6/0x120
[23279.214727]  [] ? unmap_mapping_range+0x64/0x140
[23279.222515]  [] ? unmap_mapping_range+0x64/0x140
[23279.230489]  [] ? unmap_mapping_range+0x64/0x140
[23279.238442]  [] unmap_mapping_range+0x11a/0x140
[23279.246141]  [] ? i915_gem_release_mmap+0x5/0x20 [i915]
[23279.254753]  [] i915_gem_release_mmap.part.44+0x46/0x60 
[i915]
[23279.264002]  [] ? i915_gem_release_mmap+0x19/0x20 [i915]
[23279.272723]  [] ftrace_graph_caller+0xa8/0xa8
[23279.280239]  [] i915_gem_release_mmap+0x19/0x20 [i915]
[23279.288780]  [] ftrace_graph_caller+0xa8/0xa8
[23279.296323]  [] i915_gem_set_tiling+0x204/0x540 [i915]
[23279.304854]  [] ftrace_graph_caller+0xa8/0xa8
[23279.312559]  [] drm_ioctl+0x12f/0x620 [drm]
[23279.319986]  [] ? 
i915_gem_detect_bit_6_swizzle+0x200/0x200 [i915]
[23279.329744]  [] ? handle_mm_fault+0xe1e/0x1780
[23279.337380]  [] ? native_sched_clock+0x2d/0x90
[23279.345081]  [] ? sched_clock+0x9/0x10
[23279.352029]  [] ? local_clock+0x25/0x30
[23279.359059]  [] ? lock_release_holdtime.part.25+0xf/0x1f0
[23279.367914]  [] do_vfs_ioctl+0x2c6/0x4f0
[23279.375068]  [] ? up_read+0x23/0x40
[23279.381794]  [] ? __do_page_fault+0x1bc/0x450
[23279.389356]  [] SyS_ioctl+0x81/0xa0
[23279.396025]  [] system_call_fastpath+0x12/0x76
[23279.403823] 4 locks held by test_api64/1359:
[23279.409505]  #0:  (>struct_mutex){..}, at: [] 
i915_gem_set_tiling+0xf6/0x540 [i915]
[23279.421939]  #1:  (>i_mmap_rwsem){..}, at: [] 
unmap_mapping_range+0x64/0x140
[23279.434071]  #2:  (){..}, at: [] 
__mmu_notifier_invalidate_range_start+0x5/0xd0
[23279.446103]  #3:  (>struct_mutex){..}, at: [] 
cancel_userptr+0x2c/0x150 [i915]

Since then, i915 has changed a lot... (no more struct mutex), so it's hard to
immediately say whether there's still any deadlock potential there.

-Michał

> 2. Which of MMAP_OFFSET types should do the job if mappable aperture is
>not available?  Should any of them work, as I've assumed?  Is my
>approach of succeeding a subtest on first successful MMAP_OFFSET
>type correct?  Or should we examine all types?
> 
> Thanks,
> Janus

Re: [Intel-gfx] [PATCH i-g-t v2] i915/gem_ctx_isolation: Check nonpriv values are kept across switch

2019-09-30 Thread Michał Winiarski
On Fri, Sep 27, 2019 at 02:28:34PM +0100, Chris Wilson wrote:
> Verify that the values we store in our nonpriv context image registers
> are restored after a switch.
> 
> v2: Use explicit ordering to ensure we force the context switch back and
> forth in between the register writes and their read.
> 
> Signed-off-by: Chris Wilson 
> Cc: Michał Winiarski 

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  tests/i915/gem_ctx_isolation.c | 31 +++
>  1 file changed, 31 insertions(+)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH v2 6/6] drm/i915/execlists: Don't allocate scratch

2019-09-26 Thread Michał Winiarski
We're no longer using it on execlists platforms. There's no point in
allocating it.

v2: Move scratch init to legacy ring submission backend. (Chris)

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c  |  2 --
 drivers/gpu/drm/i915/gt/intel_gt.c | 17 +
 drivers/gpu/drm/i915/gt/intel_gt.h |  2 +-
 drivers/gpu/drm/i915/gt/intel_ringbuffer.c |  5 +
 drivers/gpu/drm/i915/i915_gem.c|  2 --
 5 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index f451d5076bde..a4e5aceff678 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -669,8 +669,6 @@ static int measure_breadcrumb_dw(struct intel_engine_cs 
*engine)
struct measure_breadcrumb *frame;
int dw = -ENOMEM;
 
-   GEM_BUG_ON(!engine->gt->scratch);
-
frame = kzalloc(sizeof(*frame), GFP_KERNEL);
if (!frame)
return -ENOMEM;
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index eef9bdae8ebb..e67a6cabc81d 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -322,13 +322,17 @@ void intel_gt_driver_register(struct intel_gt *gt)
intel_gpu_ips_init(gt->i915);
 }
 
-static int intel_gt_init_scratch(struct intel_gt *gt, unsigned int size)
+int intel_gt_init_scratch(struct intel_gt *gt, unsigned int size)
 {
struct drm_i915_private *i915 = gt->i915;
struct drm_i915_gem_object *obj;
struct i915_vma *vma;
int ret;
 
+   /* Created lazily - submission backend calls us at its init time */
+   if (gt->scratch)
+   return 0;
+
obj = i915_gem_object_create_stolen(i915, size);
if (!obj)
obj = i915_gem_object_create_internal(i915, size);
@@ -361,17 +365,6 @@ static void intel_gt_fini_scratch(struct intel_gt *gt)
i915_vma_unpin_and_release(>scratch, 0);
 }
 
-int intel_gt_init(struct intel_gt *gt)
-{
-   int err;
-
-   err = intel_gt_init_scratch(gt, IS_GEN(gt->i915, 2) ? SZ_256K : SZ_4K);
-   if (err)
-   return err;
-
-   return 0;
-}
-
 void intel_gt_driver_remove(struct intel_gt *gt)
 {
GEM_BUG_ON(gt->awake);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h 
b/drivers/gpu/drm/i915/gt/intel_gt.h
index e6ab0bff0efb..b9ed8ea3706e 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt.h
@@ -30,7 +30,7 @@ static inline struct intel_gt *huc_to_gt(struct intel_huc 
*huc)
 void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915);
 void intel_gt_init_hw_early(struct drm_i915_private *i915);
 int __must_check intel_gt_init_hw(struct intel_gt *gt);
-int intel_gt_init(struct intel_gt *gt);
+int intel_gt_init_scratch(struct intel_gt *gt, unsigned int size);
 void intel_gt_driver_register(struct intel_gt *gt);
 
 void intel_gt_driver_unregister(struct intel_gt *gt);
diff --git a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
index 0747b8c9f768..64d22239df8a 100644
--- a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
@@ -2315,6 +2315,11 @@ int intel_ring_submission_init(struct intel_engine_cs 
*engine)
struct intel_ring *ring;
int err;
 
+   err = intel_gt_init_scratch(engine->gt,
+   IS_GEN(engine->i915, 2) ? SZ_256K : SZ_4K);
+   if (err)
+   goto err;
+
timeline = intel_timeline_create(engine->gt, engine->status_page.vma);
if (IS_ERR(timeline)) {
err = PTR_ERR(timeline);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e2897a666225..09d387f4d46b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1337,8 +1337,6 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
goto err_unlock;
}
 
-   intel_gt_init(_priv->gt);
-
ret = intel_engines_setup(dev_priv);
if (ret) {
GEM_BUG_ON(ret == -EIO);
-- 
2.21.0

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

[Intel-gfx] [PATCH 6/6] drm/i915/execlists: Don't allocate scratch

2019-09-26 Thread Michał Winiarski
We're no longer using it on execlists platforms. There's no point in
allocating it.

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c | 2 --
 drivers/gpu/drm/i915/gt/intel_gt.c| 6 ++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index f451d5076bde..a4e5aceff678 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -669,8 +669,6 @@ static int measure_breadcrumb_dw(struct intel_engine_cs 
*engine)
struct measure_breadcrumb *frame;
int dw = -ENOMEM;
 
-   GEM_BUG_ON(!engine->gt->scratch);
-
frame = kzalloc(sizeof(*frame), GFP_KERNEL);
if (!frame)
return -ENOMEM;
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index eef9bdae8ebb..e135a66b7242 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -329,6 +329,9 @@ static int intel_gt_init_scratch(struct intel_gt *gt, 
unsigned int size)
struct i915_vma *vma;
int ret;
 
+   if (HAS_EXECLISTS(i915))
+   return 0;
+
obj = i915_gem_object_create_stolen(i915, size);
if (!obj)
obj = i915_gem_object_create_internal(i915, size);
@@ -358,6 +361,9 @@ static int intel_gt_init_scratch(struct intel_gt *gt, 
unsigned int size)
 
 static void intel_gt_fini_scratch(struct intel_gt *gt)
 {
+   if (HAS_EXECLISTS(gt->i915))
+   return;
+
i915_vma_unpin_and_release(>scratch, 0);
 }
 
-- 
2.21.0

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

[Intel-gfx] [PATCH 4/6] drm/i915: Add definitions for MI_MATH command

2019-09-26 Thread Michał Winiarski
We can use it in i915 for updating parts of unmasked registers from
within a batch. We're also adding Gen8+ versions of CS_GPR registers
(aka MI_MATH_REG in the coprocessor).

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/gt/intel_gpu_commands.h | 24 
 drivers/gpu/drm/i915/i915_reg.h  |  4 
 2 files changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h 
b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
index 9211b1ad401b..26c286bc9625 100644
--- a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
+++ b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
@@ -241,6 +241,30 @@
 #define   PIPE_CONTROL_DEPTH_CACHE_FLUSH   (1<<0)
 #define   PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
 
+#define MI_MATH(x) MI_INSTR(0x1A, (x)-1)
+#define MI_MATH_INSTR(opcode, op1, op2) (((opcode) << 20) | \
+((op1) << 10) | (op2))
+/* Opcodes for MI_MATH_INSTR */
+#define   MI_MATH_NOOP MI_MATH_INSTR(0x0, 0x0, 0x0)
+#define   MI_MATH_LOAD(op1, op2)   MI_MATH_INSTR(0x80, op1, op2)
+#define   MI_MATH_LOADINV(op1, op2)MI_MATH_INSTR(0x480, op1, op2)
+#define   MI_MATH_LOAD0(op1)   MI_MATH_INSTR(0x081, op1)
+#define   MI_MATH_LOAD1(op1)   MI_MATH_INSTR(0x481, op1)
+#define   MI_MATH_ADD  MI_MATH_INSTR(0x100, 0x0, 0x0)
+#define   MI_MATH_SUB  MI_MATH_INSTR(0x101, 0x0, 0x0)
+#define   MI_MATH_AND  MI_MATH_INSTR(0x102, 0x0, 0x0)
+#define   MI_MATH_OR   MI_MATH_INSTR(0x103, 0x0, 0x0)
+#define   MI_MATH_XOR  MI_MATH_INSTR(0x104, 0x0, 0x0)
+#define   MI_MATH_STORE(op1, op2)  MI_MATH_INSTR(0x180, op1, op2)
+#define   MI_MATH_STOREINV(op1, op2)   MI_MATH_INSTR(0x580, op1, op2)
+/* Registers used as operands in MI_MATH_INSTR */
+#define   MI_MATH_REG(x)   (x)
+#define   MI_MATH_REG_SRCA 0x20
+#define   MI_MATH_REG_SRCB 0x21
+#define   MI_MATH_REG_ACCU 0x31
+#define   MI_MATH_REG_ZF   0x32
+#define   MI_MATH_REG_CF   0x33
+
 /*
  * Commands used only by the command parser
  */
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e752de9470bd..fbedf89fc0bb 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2483,6 +2483,10 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
 #define   RING_WAIT(1 << 11) /* gen3+, PRBx_CTL */
 #define   RING_WAIT_SEMAPHORE  (1 << 10) /* gen6+ */
 
+/* There are 16 64-bit CS General Purpose Registers per-engine on Gen8+ */
+#define GEN8_RING_CS_GPR(base, n)  _MMIO(((base) + 0x600) + (n) * 8)
+#define GEN8_RING_CS_GPR_UDW(base, n)  _MMIO(((base) + 0x600) + (n) * 8 + 4)
+
 #define RING_FORCE_TO_NONPRIV(base, i) _MMIO(((base) + 0x4D0) + (i) * 4)
 #define   RING_FORCE_TO_NONPRIV_ACCESS_RW  (0 << 28)/* CFL+ & Gen11+ */
 #define   RING_FORCE_TO_NONPRIV_ACCESS_RD  (1 << 28)
-- 
2.21.0

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

[Intel-gfx] [PATCH 5/6] drm/i915: Don't use scratch in WA batch.

2019-09-26 Thread Michał Winiarski
We're currently doing one workaround where we're using scratch as a
temporary storage place, while we're overwriting the value of one
register with some known constant value in order to perform a
workaround.
While we could just do similar thing with CS_GPR register
and MI_LOAD_REGISTER_REG instead of scratch, since we would use CS_GPR
anyways, let's just drop the constant values and do the bitops using
MI_MATH.

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/intel_engine.h   | 53 
 drivers/gpu/drm/i915/gt/intel_gt_types.h |  3 --
 drivers/gpu/drm/i915/gt/intel_lrc.c  | 27 +++-
 3 files changed, 58 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h 
b/drivers/gpu/drm/i915/gt/intel_engine.h
index d3c6993f4f46..2dfe0b23af1d 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -400,6 +400,59 @@ gen8_emit_ggtt_write(u32 *cs, u32 value, u32 gtt_offset, 
u32 flags)
return cs;
 }
 
+/*
+ * We're using CS_GPR registers for the MI_MATH ops.
+ * Note that user contexts are free to use those registers, which means that we
+ * should only use this this function during context initialization, before
+ * context restore (WA batch) or inside i915-owned contexts.
+ */
+static inline u32 *
+gen8_emit_bitop_reg_mask(struct intel_engine_cs *engine,
+u32 *cs, u32 op, i915_reg_t reg, u32 mask)
+{
+   const u32 base = engine->mmio_base;
+
+   GEM_BUG_ON(op != MI_MATH_OR && op != MI_MATH_AND);
+
+   *cs++ = MI_LOAD_REGISTER_REG;
+   *cs++ = i915_mmio_reg_offset(reg);
+   *cs++ = i915_mmio_reg_offset(GEN8_RING_CS_GPR(base, 0));
+   *cs++ = MI_NOOP;
+
+   *cs++ = MI_LOAD_REGISTER_IMM(1);
+   *cs++ = i915_mmio_reg_offset(GEN8_RING_CS_GPR(base, 1));
+   *cs++ = mask;
+   *cs++ = MI_NOOP;
+
+   *cs++ = MI_MATH(4);
+   *cs++ = MI_MATH_LOAD(MI_MATH_REG_SRCA, MI_MATH_REG(0));
+   *cs++ = MI_MATH_LOAD(MI_MATH_REG_SRCB, MI_MATH_REG(1));
+   *cs++ = op;
+   *cs++ = MI_MATH_STORE(MI_MATH_REG(0), MI_MATH_REG_ACCU);
+   *cs++ = MI_NOOP;
+
+   *cs++ = MI_LOAD_REGISTER_REG;
+   *cs++ = i915_mmio_reg_offset(GEN8_RING_CS_GPR(base, 0));
+   *cs++ = i915_mmio_reg_offset(reg);
+   *cs++ = MI_NOOP;
+
+   return cs;
+}
+
+static inline u32 *
+gen8_emit_set_register(struct intel_engine_cs *engine,
+  u32 *cs, i915_reg_t reg, u32 mask)
+{
+   return gen8_emit_bitop_reg_mask(engine, cs, MI_MATH_OR, reg, mask);
+}
+
+static inline u32 *
+gen8_emit_clear_register(struct intel_engine_cs *engine,
+u32 *cs, i915_reg_t reg, u32 mask)
+{
+   return gen8_emit_bitop_reg_mask(engine, cs, MI_MATH_AND, reg, ~mask);
+}
+
 static inline void __intel_engine_reset(struct intel_engine_cs *engine,
bool stalled)
 {
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h 
b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index e64db4c13df6..d9f25ac520a8 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -92,9 +92,6 @@ enum intel_gt_scratch_field {
/* 8 bytes */
INTEL_GT_SCRATCH_FIELD_RENDER_FLUSH = 128,
 
-   /* 8 bytes */
-   INTEL_GT_SCRATCH_FIELD_COHERENTL3_WA = 256,
-
 };
 
 #endif /* __INTEL_GT_TYPES_H__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index fa385218ce92..089c17599ca4 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -2269,13 +2269,7 @@ static int execlists_request_alloc(struct i915_request 
*request)
  * PIPE_CONTROL instruction. This is required for the flush to happen correctly
  * but there is a slight complication as this is applied in WA batch where the
  * values are only initialized once so we cannot take register value at the
- * beginning and reuse it further; hence we save its value to memory, upload a
- * constant value with bit21 set and then we restore it back with the saved 
value.
- * To simplify the WA, a constant value is formed by using the default value
- * of this register. This shouldn't be a problem because we are only modifying
- * it for a short period and this batch in non-premptible. We can ofcourse
- * use additional instructions that read the actual value of the register
- * at that time and set our bit of interest but it makes the WA complicated.
+ * beginning and reuse it further;
  *
  * This WA is also required for Gen9 so extracting as a function avoids
  * code duplication.
@@ -2283,27 +2277,16 @@ static int execlists_request_alloc(struct i915_request 
*request)
 static u32 *
 gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, u32 *batch)
 {
-   /* NB no one else is allowed to scribble over scratch + 256! */
-   *batch++ = MI_STORE_REGISTER_MEM_GEN8 | MI_SRM_LRM

[Intel-gfx] [PATCH 1/6] drm/i915: Define explicit wedged on init reset state

2019-09-26 Thread Michał Winiarski
We're currently using scratch presence as a way of identifying that we
entered wedged state at driver initialization time.
Let's use a separate flag rather than rely on scratch.

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Mika Kuoppala 
---
 drivers/gpu/drm/i915/gt/intel_reset.c   | 11 ++-
 drivers/gpu/drm/i915/gt/intel_reset.h   |  9 +
 drivers/gpu/drm/i915/gt/intel_reset_types.h |  6 ++
 drivers/gpu/drm/i915/i915_gem.c |  2 +-
 4 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c 
b/drivers/gpu/drm/i915/gt/intel_reset.c
index ae68c3786f63..0f1534ac823f 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -811,7 +811,8 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
if (!test_bit(I915_WEDGED, >reset.flags))
return true;
 
-   if (!gt->scratch) /* Never full initialised, recovery impossible */
+   /* Never fullly initialised, recovery impossible */
+   if (test_bit(I915_WEDGED_ON_INIT, >reset.flags))
return false;
 
GEM_TRACE("start\n");
@@ -1279,6 +1280,14 @@ int intel_gt_terminally_wedged(struct intel_gt *gt)
return intel_gt_is_wedged(gt) ? -EIO : 0;
 }
 
+void intel_gt_set_wedged_on_init(struct intel_gt *gt)
+{
+   BUILD_BUG_ON(I915_RESET_ENGINE + I915_NUM_ENGINES >
+I915_WEDGED_ON_INIT);
+   intel_gt_set_wedged(gt);
+   set_bit(I915_WEDGED_ON_INIT, >reset.flags);
+}
+
 void intel_gt_init_reset(struct intel_gt *gt)
 {
init_waitqueue_head(>reset.queue);
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.h 
b/drivers/gpu/drm/i915/gt/intel_reset.h
index 52c00199e069..0b6ff1ee7f06 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.h
+++ b/drivers/gpu/drm/i915/gt/intel_reset.h
@@ -45,6 +45,12 @@ void intel_gt_set_wedged(struct intel_gt *gt);
 bool intel_gt_unset_wedged(struct intel_gt *gt);
 int intel_gt_terminally_wedged(struct intel_gt *gt);
 
+/*
+ * There's no unset_wedged_on_init paired with this one.
+ * Once we're wedged on init, there's no going back.
+ */
+void intel_gt_set_wedged_on_init(struct intel_gt *gt);
+
 int __intel_gt_reset(struct intel_gt *gt, intel_engine_mask_t engine_mask);
 
 int intel_reset_guc(struct intel_gt *gt);
@@ -68,6 +74,9 @@ void __intel_fini_wedge(struct intel_wedge_me *w);
 
 static inline bool __intel_reset_failed(const struct intel_reset *reset)
 {
+   GEM_BUG_ON(test_bit(I915_WEDGED_ON_INIT, >flags) ?
+  !test_bit(I915_WEDGED, >flags) : false);
+
return unlikely(test_bit(I915_WEDGED, >flags));
 }
 
diff --git a/drivers/gpu/drm/i915/gt/intel_reset_types.h 
b/drivers/gpu/drm/i915/gt/intel_reset_types.h
index 31968356e0c0..f43bc3a0fe4f 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_reset_types.h
@@ -29,11 +29,17 @@ struct intel_reset {
 * we set the #I915_WEDGED bit. Prior to command submission, e.g.
 * i915_request_alloc(), this bit is checked and the sequence
 * aborted (with -EIO reported to userspace) if set.
+*
+* #I915_WEDGED_ON_INIT - If we fail to initialize the GPU we can no
+* longer use the GPU - similar to #I915_WEDGED bit. The difference in
+* in the way we're handling "forced" unwedged (e.g. through debugfs),
+* which is not allowed in case we failed to initialize.
 */
unsigned long flags;
 #define I915_RESET_BACKOFF 0
 #define I915_RESET_MODESET 1
 #define I915_RESET_ENGINE  2
+#define I915_WEDGED_ON_INIT(BITS_PER_LONG - 2)
 #define I915_WEDGED(BITS_PER_LONG - 1)
 
struct mutex mutex; /* serialises wedging/unwedging */
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 2da9544fa9a4..e2897a666225 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1411,7 +1411,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
 err_gt:
mutex_unlock(_priv->drm.struct_mutex);
 
-   intel_gt_set_wedged(_priv->gt);
+   intel_gt_set_wedged_on_init(_priv->gt);
i915_gem_suspend(dev_priv);
i915_gem_suspend_late(dev_priv);
 
-- 
2.21.0

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

[Intel-gfx] [PATCH 2/6] drm/i915/execlists: Use per-process HWSP as scratch

2019-09-26 Thread Michał Winiarski
Some of our commands (MI_FLUSH_DW / PIPE_CONTROL) require a post-sync write
operation to be performed. Currently we're using dedicated VMA for
PIPE_CONTROL and global HWSP for MI_FLUSH_DW.
On execlists platforms, each of our contexts has an area that can be
used as scratch space. Let's use that instead.

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/intel_gt_types.h |  3 --
 drivers/gpu/drm/i915/gt/intel_lrc.c  | 45 +++-
 drivers/gpu/drm/i915/gt/intel_lrc.h  |  4 +++
 3 files changed, 17 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h 
b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index 3039cef64b11..e64db4c13df6 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -89,9 +89,6 @@ enum intel_gt_scratch_field {
/* 8 bytes */
INTEL_GT_SCRATCH_FIELD_DEFAULT = 0,
 
-   /* 8 bytes */
-   INTEL_GT_SCRATCH_FIELD_CLEAR_SLM_WA = 128,
-
/* 8 bytes */
INTEL_GT_SCRATCH_FIELD_RENDER_FLUSH = 128,
 
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index ab725a6ca0ac..fa385218ce92 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -2308,12 +2308,6 @@ gen8_emit_flush_coherentl3_wa(struct intel_engine_cs 
*engine, u32 *batch)
return batch;
 }
 
-static u32 slm_offset(struct intel_engine_cs *engine)
-{
-   return intel_gt_scratch_offset(engine->gt,
-  INTEL_GT_SCRATCH_FIELD_CLEAR_SLM_WA);
-}
-
 /*
  * Typically we only have one indirect_ctx and per_ctx batch buffer which are
  * initialized at the beginning and shared across all contexts but this field
@@ -2342,10 +2336,10 @@ static u32 *gen8_init_indirectctx_bb(struct 
intel_engine_cs *engine, u32 *batch)
/* Actual scratch location is at 128 bytes offset */
batch = gen8_emit_pipe_control(batch,
   PIPE_CONTROL_FLUSH_L3 |
-  PIPE_CONTROL_GLOBAL_GTT_IVB |
+  PIPE_CONTROL_STORE_DATA_INDEX |
   PIPE_CONTROL_CS_STALL |
   PIPE_CONTROL_QW_WRITE,
-  slm_offset(engine));
+  LRC_PPHWSP_SCRATCH_ADDR);
 
*batch++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
 
@@ -3052,7 +3046,7 @@ static int gen8_emit_flush(struct i915_request *request, 
u32 mode)
}
 
*cs++ = cmd;
-   *cs++ = I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT;
+   *cs++ = LRC_PPHWSP_SCRATCH_ADDR;
*cs++ = 0; /* upper addr */
*cs++ = 0; /* value */
intel_ring_advance(request, cs);
@@ -3063,10 +3057,6 @@ static int gen8_emit_flush(struct i915_request *request, 
u32 mode)
 static int gen8_emit_flush_render(struct i915_request *request,
  u32 mode)
 {
-   struct intel_engine_cs *engine = request->engine;
-   u32 scratch_addr =
-   intel_gt_scratch_offset(engine->gt,
-   INTEL_GT_SCRATCH_FIELD_RENDER_FLUSH);
bool vf_flush_wa = false, dc_flush_wa = false;
u32 *cs, flags = 0;
int len;
@@ -3088,7 +3078,7 @@ static int gen8_emit_flush_render(struct i915_request 
*request,
flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
flags |= PIPE_CONTROL_QW_WRITE;
-   flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
+   flags |= PIPE_CONTROL_STORE_DATA_INDEX;
 
/*
 * On GEN9: before VF_CACHE_INVALIDATE we need to emit a NULL
@@ -3121,7 +3111,7 @@ static int gen8_emit_flush_render(struct i915_request 
*request,
cs = gen8_emit_pipe_control(cs, PIPE_CONTROL_DC_FLUSH_ENABLE,
0);
 
-   cs = gen8_emit_pipe_control(cs, flags, scratch_addr);
+   cs = gen8_emit_pipe_control(cs, flags, LRC_PPHWSP_SCRATCH_ADDR);
 
if (dc_flush_wa)
cs = gen8_emit_pipe_control(cs, PIPE_CONTROL_CS_STALL, 0);
@@ -3134,11 +3124,6 @@ static int gen8_emit_flush_render(struct i915_request 
*request,
 static int gen11_emit_flush_render(struct i915_request *request,
   u32 mode)
 {
-   struct intel_engine_cs *engine = request->engine;
-   const u32 scratch_addr =
-   intel_gt_scratch_offset(engine->gt,
-   INTEL_GT_SCRATCH_FIELD_RENDER_FLUSH);
-
if (mode & EMIT_FLUSH) {
u32 *cs;
u32 flags = 0;
@@ -3151,13 +3136,13 @@ static int gen11_emit_flush_render(struct i915_request 
*request,
flags |= PIPE_CONTROL_DC_FLUSH_ENABLE;
  

[Intel-gfx] [PATCH 3/6] drm/i915: Adjust length of MI_LOAD_REGISTER_REG

2019-09-26 Thread Michał Winiarski
Default length value of MI_LOAD_REGISTER_REG is 1.
Also move it out of cmd-parser-only registers since we're going to use
it in i915.

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Jani Nikula 
---
 drivers/gpu/drm/i915/gt/intel_gpu_commands.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h 
b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
index f78b13d74e17..9211b1ad401b 100644
--- a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
+++ b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
@@ -152,6 +152,7 @@
 #define   MI_FLUSH_DW_USE_PPGTT(0<<2)
 #define MI_LOAD_REGISTER_MEM  MI_INSTR(0x29, 1)
 #define MI_LOAD_REGISTER_MEM_GEN8  MI_INSTR(0x29, 2)
+#define MI_LOAD_REGISTER_REGMI_INSTR(0x2A, 1)
 #define MI_BATCH_BUFFERMI_INSTR(0x30, 1)
 #define   MI_BATCH_NON_SECURE  (1)
 /* for snb/ivb/vlv this also means "batch in ppgtt" when ppgtt is enabled. */
@@ -256,7 +257,6 @@
 #define MI_CLFLUSH  MI_INSTR(0x27, 0)
 #define MI_REPORT_PERF_COUNTMI_INSTR(0x28, 0)
 #define   MI_REPORT_PERF_COUNT_GGTT (1<<0)
-#define MI_LOAD_REGISTER_REGMI_INSTR(0x2A, 0)
 #define MI_RS_STORE_DATA_IMMMI_INSTR(0x2B, 0)
 #define MI_LOAD_URB_MEM MI_INSTR(0x2C, 0)
 #define MI_STORE_URB_MEMMI_INSTR(0x2D, 0)
-- 
2.21.0

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

Re: [Intel-gfx] [PATCH 02/12] drm/i915/guc: simplify guc client

2019-07-10 Thread Michał Winiarski
On Tue, Jul 09, 2019 at 05:54:27PM -0700, Daniele Ceraolo Spurio wrote:
> We originally added support, in some cases partial, for different modes
> of operations via guc clients:
> 
> - proxy vs direct submission;
> - variable engine mask per-client.
> 
> We only ever used one flow (all submissions via a single proxy), so the
> other code paths haven't been exercised and are most likely
> non-functional. The guc firmware interface is also in the process of
> being updated to better fit the i915 flow and our client abstraction
> will need to change accordingly (or possibly go away entirely), so these
> old unused paths can be considered dead and removed.
> 
> Signed-off-by: Daniele Ceraolo Spurio 
> Cc: Chris Wilson 
> Cc: Michal Wajdeczko 
> Cc: Matthew Brost 
> Cc: John Harrison 
> Acked-by: Matthew Brost 

drm/i915/guc: simplify guc client
      ^ Sentence case

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  drivers/gpu/drm/i915/i915_debugfs.c |  3 +-
>  drivers/gpu/drm/i915/intel_guc_submission.c | 73 ++---
>  drivers/gpu/drm/i915/intel_guc_submission.h |  2 -
>  drivers/gpu/drm/i915/selftests/intel_guc.c  | 12 +---
>  4 files changed, 8 insertions(+), 82 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
> b/drivers/gpu/drm/i915/i915_debugfs.c
> index b4d195677877..dc65a6131a5b 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -2021,7 +2021,6 @@ static int i915_guc_stage_pool(struct seq_file *m, void 
> *data)
>   struct drm_i915_private *dev_priv = node_to_i915(m->private);
>   const struct intel_guc *guc = _priv->guc;
>   struct guc_stage_desc *desc = guc->stage_desc_pool_vaddr;
> - struct intel_guc_client *client = guc->execbuf_client;
>   intel_engine_mask_t tmp;
>   int index;
>  
> @@ -2051,7 +2050,7 @@ static int i915_guc_stage_pool(struct seq_file *m, void 
> *data)
>  desc->wq_addr, desc->wq_size);
>   seq_putc(m, '\n');
>  
> - for_each_engine_masked(engine, dev_priv, client->engines, tmp) {
> + for_each_engine(engine, dev_priv, tmp) {
>   u32 guc_engine_id = engine->guc_id;
>   struct guc_execlist_context *lrc =
>   >lrc[guc_engine_id];
> diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c 
> b/drivers/gpu/drm/i915/intel_guc_submission.c
> index 8520bb224175..30692f8289bd 100644
> --- a/drivers/gpu/drm/i915/intel_guc_submission.c
> +++ b/drivers/gpu/drm/i915/intel_guc_submission.c
> @@ -363,10 +363,7 @@ static void guc_stage_desc_pool_destroy(struct intel_guc 
> *guc)
>  static void guc_stage_desc_init(struct intel_guc_client *client)
>  {
>   struct intel_guc *guc = client->guc;
> - struct i915_gem_context *ctx = client->owner;
> - struct i915_gem_engines_iter it;
>   struct guc_stage_desc *desc;
> - struct intel_context *ce;
>   u32 gfx_addr;
>  
>   desc = __get_stage_desc(client);
> @@ -380,55 +377,6 @@ static void guc_stage_desc_init(struct intel_guc_client 
> *client)
>   desc->priority = client->priority;
>   desc->db_id = client->doorbell_id;
>  
> - for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
> - struct guc_execlist_context *lrc;
> -
> - if (!(ce->engine->mask & client->engines))
> - continue;
> -
> - /* TODO: We have a design issue to be solved here. Only when we
> -  * receive the first batch, we know which engine is used by the
> -  * user. But here GuC expects the lrc and ring to be pinned. It
> -  * is not an issue for default context, which is the only one
> -  * for now who owns a GuC client. But for future owner of GuC
> -  * client, need to make sure lrc is pinned prior to enter here.
> -  */
> - if (!ce->state)
> - break;  /* XXX: continue? */
> -
> - /*
> -  * XXX: When this is a GUC_STAGE_DESC_ATTR_KERNEL client (proxy
> -  * submission or, in other words, not using a direct submission
> -  * model) the KMD's LRCA is not used for any work submission.
> -  * Instead, the GuC uses the LRCA of the user mode context (see
> -  * guc_add_request below).
> -  */
> - lrc = >lrc[ce->engine->guc_id];
> - lrc->context_desc = lower_32_bits(ce->lrc_desc);
> -
> - /* The state page is after PPHWSP */
>

Re: [Intel-gfx] [PATCH 01/12] drm/i915/guc: Remove preemption support for current fw

2019-07-10 Thread Michał Winiarski
On Tue, Jul 09, 2019 at 05:54:26PM -0700, Daniele Ceraolo Spurio wrote:
> From: Chris Wilson 
> 
> Preemption via GuC submission is not being supported with its current
> legacy incarnation. The current FW does support a similar pre-emption
> flow via H2G, but it is class-based instead of being instance-based,
> which doesn't fit well with the i915 tracking. To fix this, the
> firmware is being updated to better support our needs with a new flow,
> so we can safely remove the old code.
> 
> v2 (Daniele): resurrect & rebase, reword commit message, remove
> preempt_context as well
> 
> Signed-off-by: Chris Wilson 
> Signed-off-by: Daniele Ceraolo Spurio 
> Cc: Chris Wilson 
> Cc: Michal Wajdeczko 
> Cc: Matthew Brost 
> Cc: John Harrison 
> Acked-by: Matthew Brost 

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  drivers/gpu/drm/i915/gem/i915_gem_context.c  |  17 --
>  drivers/gpu/drm/i915/gt/intel_engine_cs.c|  13 --
>  drivers/gpu/drm/i915/gt/intel_engine_types.h |   1 -
>  drivers/gpu/drm/i915/gt/intel_gt_pm.c|   4 -
>  drivers/gpu/drm/i915/i915_debugfs.c  |   5 -
>  drivers/gpu/drm/i915/i915_drv.h  |   2 -
>  drivers/gpu/drm/i915/intel_guc.c |  31 ---
>  drivers/gpu/drm/i915/intel_guc.h |   9 -
>  drivers/gpu/drm/i915/intel_guc_submission.c  | 231 +--
>  drivers/gpu/drm/i915/selftests/intel_guc.c   |  31 +--
>  10 files changed, 14 insertions(+), 330 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index e367dce2a696..078592912d97 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -644,18 +644,12 @@ static void init_contexts(struct drm_i915_private *i915)
>   init_llist_head(>contexts.free_list);
>  }
>  
> -static bool needs_preempt_context(struct drm_i915_private *i915)
> -{
> - return USES_GUC_SUBMISSION(i915);
> -}
> -
>  int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
>  {
>   struct i915_gem_context *ctx;
>  
>   /* Reassure ourselves we are only called once */
>   GEM_BUG_ON(dev_priv->kernel_context);
> - GEM_BUG_ON(dev_priv->preempt_context);
>  
>   init_contexts(dev_priv);
>  
> @@ -676,15 +670,6 @@ int i915_gem_contexts_init(struct drm_i915_private 
> *dev_priv)
>   GEM_BUG_ON(!atomic_read(>hw_id_pin_count));
>   dev_priv->kernel_context = ctx;
>  
> - /* highest priority; preempting task */
> - if (needs_preempt_context(dev_priv)) {
> - ctx = i915_gem_context_create_kernel(dev_priv, INT_MAX);
> - if (!IS_ERR(ctx))
> - dev_priv->preempt_context = ctx;
> - else
> - DRM_ERROR("Failed to create preempt context; disabling 
> preemption\n");
> - }
> -
>   DRM_DEBUG_DRIVER("%s context support initialized\n",
>DRIVER_CAPS(dev_priv)->has_logical_contexts ?
>"logical" : "fake");
> @@ -695,8 +680,6 @@ void i915_gem_contexts_fini(struct drm_i915_private *i915)
>  {
>   lockdep_assert_held(>drm.struct_mutex);
>  
> - if (i915->preempt_context)
> - destroy_kernel_context(>preempt_context);
>   destroy_kernel_context(>kernel_context);
>  
>   /* Must free all deferred contexts (via flush_workqueue) first */
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
> b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> index bdf279fa3b2e..76b5c068a26d 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> @@ -841,15 +841,6 @@ int intel_engine_init_common(struct intel_engine_cs 
> *engine)
>   if (ret)
>   return ret;
>  
> - /*
> -  * Similarly the preempt context must always be available so that
> -  * we can interrupt the engine at any time. However, as preemption
> -  * is optional, we allow it to fail.
> -  */
> - if (i915->preempt_context)
> - pin_context(i915->preempt_context, engine,
> - >preempt_context);
> -
>   ret = measure_breadcrumb_dw(engine);
>   if (ret < 0)
>   goto err_unpin;
> @@ -861,8 +852,6 @@ int intel_engine_init_common(struct intel_engine_cs 
> *engine)
>   return 0;
>  
>  err_unpin:
> - if (engine->preempt_context)
> - intel_context_unpin(engine->preempt_context);
>   intel_context_unpin(engine->kernel_context);
>   return ret;
>  }
> @@ -887,8 +

[Intel-gfx] [PATCH 1/2] Revert "drm/i915: Introduce private PAT management"

2019-07-02 Thread Michał Winiarski
This reverts commit 4395890a48551982549d222d1923e2833dac47cf.

It's been over a year since this was merged, and the actual users of
intel_ppat_get / intel_ppat_put never materialized.

Time to remove it!

v2: Unbreak suspend (Chris)
v3: Rebase, drop fixes tag to avoid confusion

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Zhi Wang 
---
 drivers/gpu/drm/i915/i915_drv.h |   2 -
 drivers/gpu/drm/i915/i915_gem_gtt.c | 279 +---
 drivers/gpu/drm/i915/i915_gem_gtt.h |  36 
 3 files changed, 42 insertions(+), 275 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 02dd9f9f3a89..09e09d26e67d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1489,8 +1489,6 @@ struct drm_i915_private {
DECLARE_HASHTABLE(mm_structs, 7);
struct mutex mm_lock;
 
-   struct intel_ppat ppat;
-
/* Kernel Modesetting */
 
struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index ff1d5008a256..30e14eac47ac 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3028,203 +3028,26 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, 
u64 size)
return 0;
 }
 
-static struct intel_ppat_entry *
-__alloc_ppat_entry(struct intel_ppat *ppat, unsigned int index, u8 value)
+static void cnl_setup_private_ppat(struct drm_i915_private *dev_priv)
 {
-   struct intel_ppat_entry *entry = >entries[index];
-
-   GEM_BUG_ON(index >= ppat->max_entries);
-   GEM_BUG_ON(test_bit(index, ppat->used));
-
-   entry->ppat = ppat;
-   entry->value = value;
-   kref_init(>ref);
-   set_bit(index, ppat->used);
-   set_bit(index, ppat->dirty);
-
-   return entry;
-}
-
-static void __free_ppat_entry(struct intel_ppat_entry *entry)
-{
-   struct intel_ppat *ppat = entry->ppat;
-   unsigned int index = entry - ppat->entries;
-
-   GEM_BUG_ON(index >= ppat->max_entries);
-   GEM_BUG_ON(!test_bit(index, ppat->used));
-
-   entry->value = ppat->clear_value;
-   clear_bit(index, ppat->used);
-   set_bit(index, ppat->dirty);
-}
-
-/**
- * intel_ppat_get - get a usable PPAT entry
- * @i915: i915 device instance
- * @value: the PPAT value required by the caller
- *
- * The function tries to search if there is an existing PPAT entry which
- * matches with the required value. If perfectly matched, the existing PPAT
- * entry will be used. If only partially matched, it will try to check if
- * there is any available PPAT index. If yes, it will allocate a new PPAT
- * index for the required entry and update the HW. If not, the partially
- * matched entry will be used.
- */
-const struct intel_ppat_entry *
-intel_ppat_get(struct drm_i915_private *i915, u8 value)
-{
-   struct intel_ppat *ppat = >ppat;
-   struct intel_ppat_entry *entry = NULL;
-   unsigned int scanned, best_score;
-   int i;
-
-   GEM_BUG_ON(!ppat->max_entries);
-
-   scanned = best_score = 0;
-   for_each_set_bit(i, ppat->used, ppat->max_entries) {
-   unsigned int score;
-
-   score = ppat->match(ppat->entries[i].value, value);
-   if (score > best_score) {
-   entry = >entries[i];
-   if (score == INTEL_PPAT_PERFECT_MATCH) {
-   kref_get(>ref);
-   return entry;
-   }
-   best_score = score;
-   }
-   scanned++;
-   }
-
-   if (scanned == ppat->max_entries) {
-   if (!entry)
-   return ERR_PTR(-ENOSPC);
-
-   kref_get(>ref);
-   return entry;
-   }
-
-   i = find_first_zero_bit(ppat->used, ppat->max_entries);
-   entry = __alloc_ppat_entry(ppat, i, value);
-   ppat->update_hw(i915);
-   return entry;
-}
-
-static void release_ppat(struct kref *kref)
-{
-   struct intel_ppat_entry *entry =
-   container_of(kref, struct intel_ppat_entry, ref);
-   struct drm_i915_private *i915 = entry->ppat->i915;
-
-   __free_ppat_entry(entry);
-   entry->ppat->update_hw(i915);
-}
-
-/**
- * intel_ppat_put - put back the PPAT entry got from intel_ppat_get()
- * @entry: an intel PPAT entry
- *
- * Put back the PPAT entry got from intel_ppat_get(). If the PPAT index of the
- * entry is dynamically allocated, its reference count will be decreased. Once
- * the reference count becomes into zero, the PPAT index becomes free again.
- */
-void intel_ppat_put(const struct intel_ppat_entry *entry)
-{
-   struct intel_ppat *ppat = entry->ppat;
-   unsigned int index = entry - ppat->entries;

[Intel-gfx] [PATCH 2/2] drm/i915/gtt: Don't check PPGTT presence on PPGTT-only platforms

2019-07-02 Thread Michał Winiarski
We missed one place where we check PPGTT-only platform for PPGTT
presence. Let's remove it.
While I'm here let's assert that this particular code is never called on
pre-gen8 platforms.

References: 4bdafb9ddfa4 ("drm/i915: Remove i915.enable_ppgtt override")
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 35 +
 1 file changed, 10 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 30e14eac47ac..9e76347e039e 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3047,31 +3047,14 @@ static void bdw_setup_private_ppat(struct 
drm_i915_private *dev_priv)
 {
u64 pat;
 
-   if (!HAS_PPGTT(dev_priv)) {
-   /* Spec: "For GGTT, there is NO pat_sel[2:0] from the entry,
-* so RTL will always use the value corresponding to
-* pat_sel = 000".
-* So let's disable cache for GGTT to avoid screen corruptions.
-* MOCS still can be used though.
-* - System agent ggtt writes (i.e. cpu gtt mmaps) already work
-* before this patch, i.e. the same uncached + snooping access
-* like on gen6/7 seems to be in effect.
-* - So this just fixes blitter/render access. Again it looks
-* like it's not just uncached access, but uncached + snooping.
-* So we can still hold onto all our assumptions wrt cpu
-* clflushing on LLC machines.
-*/
-   pat = GEN8_PPAT(0, GEN8_PPAT_UC);
-   } else {
-   pat = GEN8_PPAT(0, GEN8_PPAT_WB | GEN8_PPAT_LLC) |  /* for 
normal objects, no eLLC */
- GEN8_PPAT(1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC) |  /* for 
something pointing to ptes? */
- GEN8_PPAT(2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC) |  /* for 
scanout with eLLC */
- GEN8_PPAT(3, GEN8_PPAT_UC) |  /* 
Uncached objects, mostly for scanout */
- GEN8_PPAT(4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(0)) |
- GEN8_PPAT(5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(1)) |
- GEN8_PPAT(6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(2)) |
- GEN8_PPAT(7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(3));
-   }
+   pat = GEN8_PPAT(0, GEN8_PPAT_WB | GEN8_PPAT_LLC) |  /* for normal 
objects, no eLLC */
+ GEN8_PPAT(1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC) |  /* for 
something pointing to ptes? */
+ GEN8_PPAT(2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC) |  /* for scanout 
with eLLC */
+ GEN8_PPAT(3, GEN8_PPAT_UC) |  /* Uncached 
objects, mostly for scanout */
+ GEN8_PPAT(4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)) 
|
+ GEN8_PPAT(5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1)) 
|
+ GEN8_PPAT(6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)) 
|
+ GEN8_PPAT(7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3));
 
I915_WRITE(GEN8_PRIVATE_PAT_LO, lower_32_bits(pat));
I915_WRITE(GEN8_PRIVATE_PAT_HI, upper_32_bits(pat));
@@ -3123,6 +3106,8 @@ static void gen6_gmch_remove(struct i915_address_space 
*vm)
 
 static void setup_private_pat(struct drm_i915_private *dev_priv)
 {
+   GEM_BUG_ON(INTEL_GEN(dev_priv) < 8);
+
if (INTEL_GEN(dev_priv) >= 10)
cnl_setup_private_ppat(dev_priv);
else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
-- 
2.21.0

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

[Intel-gfx] [PATCH] drm/i915/guc: Check if reset is supported before attempting to reset GuC

2019-06-14 Thread Michał Winiarski
Let's trust both the user (i915.reset modparam) and device caps instead
of attempting to reset unconditionally.

Signed-off-by: Michał Winiarski 
Cc: Arkadiusz Hiler 
Cc: Michal Wajdeczko 
Cc: Stuart Summers 
Cc: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/intel_uc.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index a8e7f0ba7c3b..0752fb77b6fe 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -38,6 +38,11 @@ static int __intel_uc_reset_hw(struct drm_i915_private 
*dev_priv)
int ret;
u32 guc_status;
 
+   if (!intel_has_gpu_reset(dev_priv)) {
+   DRM_DEBUG_DRIVER("GPU reset disabled, skipping GuC reset\n");
+   return 0;
+   }
+
ret = intel_reset_guc(dev_priv);
if (ret) {
DRM_ERROR("Failed to reset GuC, ret = %d\n", ret);
-- 
2.21.0

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

Re: [Intel-gfx] [PATCH v4 17/22] drm/i915/guc: Correctly handle GuC interrupts on Gen11

2019-05-27 Thread Michał Winiarski
On Thu, May 23, 2019 at 11:30:44PM +, Michal Wajdeczko wrote:
> From: Oscar Mateo 
> 
> The GuC interrupts now get their own interrupt vector (instead of
> sharing a register with the PM interrupts) so handle appropriately.
> 
> v2: (Chris)
> v3: rebased (Michal)
> Bspec: 19820

Bspec: 19820, 19840, 19841, 20176

> 
> Signed-off-by: Oscar Mateo 
> Signed-off-by: Michal Wajdeczko 
> Cc: Tvrtko Ursulin 
> Cc: Daniele Ceraolo Spurio 
> Cc: Joonas Lahtinen 
> ---
>  drivers/gpu/drm/i915/i915_drv.h  |  6 ++-
>  drivers/gpu/drm/i915/i915_irq.c  | 58 +++-
>  drivers/gpu/drm/i915/i915_irq.h  |  3 ++
>  drivers/gpu/drm/i915/i915_reg.h  |  1 +
>  drivers/gpu/drm/i915/intel_guc.c |  3 ++
>  drivers/gpu/drm/i915/intel_guc_reg.h | 18 +
>  6 files changed, 86 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 311e19154672..6bd7a9347071 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1570,7 +1570,11 @@ struct drm_i915_private {
>   u32 pm_imr;
>   u32 pm_ier;
>   u32 pm_rps_events;
> - u32 pm_guc_events;
> + union {
> + /* RPS and GuC share a register pre-Gen11 */
> + u32 pm_guc_events;
> + u32 guc_events;
> + };
>   u32 pipestat_irq_mask[I915_MAX_PIPES];
>  
>   struct i915_hotplug hotplug;
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 607709a8c229..52345772f84c 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -624,6 +624,41 @@ void gen9_disable_guc_interrupts(struct drm_i915_private 
> *dev_priv)
>   gen9_reset_guc_interrupts(dev_priv);
>  }
>  
> +void gen11_reset_guc_interrupts(struct drm_i915_private *i915)
> +{
> + spin_lock_irq(>irq_lock);
> + gen11_reset_one_iir(i915, 0, GEN11_GUC);
> + spin_unlock_irq(>irq_lock);
> +}
> +
> +void gen11_enable_guc_interrupts(struct drm_i915_private *dev_priv)
> +{
> + spin_lock_irq(_priv->irq_lock);
> + if (!dev_priv->guc.interrupts.enabled) {
> + u32 guc_events = dev_priv->guc_events << 16;

#define the GuC enable/mask shift somewhere (also, adding a comment stating that
GuC is sharing this register with SG, and we currently don't care about
SG interrupts wouldn't hurt)

With that
Reviewed-by: Michał Winiarski 

-Michał

> +
> + WARN_ON_ONCE(gen11_reset_one_iir(dev_priv, 0, GEN11_GUC));
> + I915_WRITE(GEN11_GUC_SG_INTR_ENABLE, guc_events);
> + I915_WRITE(GEN11_GUC_SG_INTR_MASK, ~guc_events);
> + dev_priv->guc.interrupts.enabled = true;
> + }
> + spin_unlock_irq(_priv->irq_lock);
> +}
> +
> +void gen11_disable_guc_interrupts(struct drm_i915_private *dev_priv)
> +{
> + spin_lock_irq(_priv->irq_lock);
> + dev_priv->guc.interrupts.enabled = false;
> +
> + I915_WRITE(GEN11_GUC_SG_INTR_MASK, ~0);
> + I915_WRITE(GEN11_GUC_SG_INTR_ENABLE, 0);
> +
> + spin_unlock_irq(_priv->irq_lock);
> + synchronize_irq(dev_priv->drm.irq);
> +
> + gen11_reset_guc_interrupts(dev_priv);
> +}
> +
>  /**
>   * bdw_update_port_irq - update DE port interrupt
>   * @dev_priv: driver private
> @@ -1893,6 +1928,12 @@ static void gen9_guc_irq_handler(struct 
> drm_i915_private *dev_priv, u32 gt_iir)
>   intel_guc_to_host_event_handler(_priv->guc);
>  }
>  
> +static void gen11_guc_irq_handler(struct drm_i915_private *i915, u16 iir)
> +{
> + if (iir & GEN11_GUC_INTR_GUC2HOST)
> + intel_guc_to_host_event_handler(>guc);
> +}
> +
>  static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv)
>  {
>   enum pipe pipe;
> @@ -3015,6 +3056,9 @@ static void
>  gen11_other_irq_handler(struct drm_i915_private * const i915,
>   const u8 instance, const u16 iir)
>  {
> + if (instance == OTHER_GUC_INSTANCE)
> + return gen11_guc_irq_handler(i915, iir);
> +
>   if (instance == OTHER_GTPM_INSTANCE)
>   return gen11_rps_irq_handler(i915, iir);
>  
> @@ -3545,6 +3589,8 @@ static void gen11_gt_irq_reset(struct drm_i915_private 
> *dev_priv)
>  
>   I915_WRITE(GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0);
>   I915_WRITE(GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
> + I915_WRITE(GEN11_GUC_SG_INTR_ENABLE, 0);
> + I915_WRITE(GEN11_GUC_SG_INTR_MASK,  ~0);
>  }
>  
>  static void gen11_irq_reset(struct drm_device *dev)
> @@ -4200,6 +4246,10 @@ static void gen11_gt_irq_postinstall(struct 
> drm

[Intel-gfx] [PATCH v2] drm/i915: Update size upon return from GEM_CREATE

2019-03-26 Thread Michał Winiarski
Since GEM_CREATE is trying to outsmart the user by rounding up unaligned
objects, we used to update the size returned to userspace.
This update seems to have been lost throughout the history.

v2: Use round_up(), reorder locals (Chris)

References: ff72145badb8 ("drm: dumb scanout create/mmap for intel/radeon (v3)")
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Janusz Krzysztofik 
Cc: Joonas Lahtinen 
Reviewed-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_gem.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f6cdd5fb9deb..e506e43cfade 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -622,14 +622,15 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
 static int
 i915_gem_create(struct drm_file *file,
struct drm_i915_private *dev_priv,
-   u64 size,
+   u64 *size_p,
u32 *handle_p)
 {
struct drm_i915_gem_object *obj;
-   int ret;
u32 handle;
+   u64 size;
+   int ret;
 
-   size = roundup(size, PAGE_SIZE);
+   size = round_up(*size_p, PAGE_SIZE);
if (size == 0)
return -EINVAL;
 
@@ -645,6 +646,7 @@ i915_gem_create(struct drm_file *file,
return ret;
 
*handle_p = handle;
+   *size_p = obj->base.size;
return 0;
 }
 
@@ -657,7 +659,7 @@ i915_gem_dumb_create(struct drm_file *file,
args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64);
args->size = args->pitch * args->height;
return i915_gem_create(file, to_i915(dev),
-  args->size, >handle);
+  >size, >handle);
 }
 
 static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj)
@@ -682,7 +684,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
i915_gem_flush_free_objects(dev_priv);
 
return i915_gem_create(file, dev_priv,
-  args->size, >handle);
+  >size, >handle);
 }
 
 static inline enum fb_op_origin
-- 
2.20.1

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

[Intel-gfx] [PATCH] drm/i915: Update size upon return from GEM_CREATE

2019-03-26 Thread Michał Winiarski
Since GEM_CREATE is trying to outsmart the user by rounding up unaligned
objects, we used to update the size returned to userspace.
This update seems to have been lost throughout the history.

References: ff72145badb8 ("drm: dumb scanout create/mmap for intel/radeon (v3)")
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Janusz Krzysztofik 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/i915_gem.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f6cdd5fb9deb..77b82cb81a6c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -622,14 +622,15 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
 static int
 i915_gem_create(struct drm_file *file,
struct drm_i915_private *dev_priv,
-   u64 size,
+   u64 *size_p,
u32 *handle_p)
 {
struct drm_i915_gem_object *obj;
int ret;
+   u64 size;
u32 handle;
 
-   size = roundup(size, PAGE_SIZE);
+   size = roundup(*size_p, PAGE_SIZE);
if (size == 0)
return -EINVAL;
 
@@ -645,6 +646,8 @@ i915_gem_create(struct drm_file *file,
return ret;
 
*handle_p = handle;
+   *size_p = obj->base.size;
+
return 0;
 }
 
@@ -657,7 +660,7 @@ i915_gem_dumb_create(struct drm_file *file,
args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64);
args->size = args->pitch * args->height;
return i915_gem_create(file, to_i915(dev),
-  args->size, >handle);
+  >size, >handle);
 }
 
 static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj)
@@ -682,7 +685,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
i915_gem_flush_free_objects(dev_priv);
 
return i915_gem_create(file, dev_priv,
-  args->size, >handle);
+  >size, >handle);
 }
 
 static inline enum fb_op_origin
-- 
2.20.1

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

[Intel-gfx] [PATCH v2] Revert "drm/i915: Introduce private PAT management"

2019-03-25 Thread Michał Winiarski
This reverts commit 4395890a48551982549d222d1923e2833dac47cf.

It's been over a year since this was merged, and the actual users of
intel_ppat_get / intel_ppat_put never materialized.

Time to remove it!

v2: Unbreak suspend (Chris)

Fixes: 4395890a4855 ("drm/i915: Introduce private PAT management")
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Zhi Wang 
Reviewed-by: Chris Wilson 
---
 drivers/gpu/drm/i915/i915_drv.h |   2 -
 drivers/gpu/drm/i915/i915_gem_gtt.c | 279 +---
 drivers/gpu/drm/i915/i915_gem_gtt.h |  36 
 3 files changed, 42 insertions(+), 275 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fefcb39aefc4..d29a3f23f80f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1656,8 +1656,6 @@ struct drm_i915_private {
DECLARE_HASHTABLE(mm_structs, 7);
struct mutex mm_lock;
 
-   struct intel_ppat ppat;
-
/* Kernel Modesetting */
 
struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index b9e0e3a00223..34e87697116b 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2881,203 +2881,26 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, 
u64 size)
return 0;
 }
 
-static struct intel_ppat_entry *
-__alloc_ppat_entry(struct intel_ppat *ppat, unsigned int index, u8 value)
+static void cnl_setup_private_ppat(struct drm_i915_private *dev_priv)
 {
-   struct intel_ppat_entry *entry = >entries[index];
-
-   GEM_BUG_ON(index >= ppat->max_entries);
-   GEM_BUG_ON(test_bit(index, ppat->used));
-
-   entry->ppat = ppat;
-   entry->value = value;
-   kref_init(>ref);
-   set_bit(index, ppat->used);
-   set_bit(index, ppat->dirty);
-
-   return entry;
-}
-
-static void __free_ppat_entry(struct intel_ppat_entry *entry)
-{
-   struct intel_ppat *ppat = entry->ppat;
-   unsigned int index = entry - ppat->entries;
-
-   GEM_BUG_ON(index >= ppat->max_entries);
-   GEM_BUG_ON(!test_bit(index, ppat->used));
-
-   entry->value = ppat->clear_value;
-   clear_bit(index, ppat->used);
-   set_bit(index, ppat->dirty);
-}
-
-/**
- * intel_ppat_get - get a usable PPAT entry
- * @i915: i915 device instance
- * @value: the PPAT value required by the caller
- *
- * The function tries to search if there is an existing PPAT entry which
- * matches with the required value. If perfectly matched, the existing PPAT
- * entry will be used. If only partially matched, it will try to check if
- * there is any available PPAT index. If yes, it will allocate a new PPAT
- * index for the required entry and update the HW. If not, the partially
- * matched entry will be used.
- */
-const struct intel_ppat_entry *
-intel_ppat_get(struct drm_i915_private *i915, u8 value)
-{
-   struct intel_ppat *ppat = >ppat;
-   struct intel_ppat_entry *entry = NULL;
-   unsigned int scanned, best_score;
-   int i;
-
-   GEM_BUG_ON(!ppat->max_entries);
-
-   scanned = best_score = 0;
-   for_each_set_bit(i, ppat->used, ppat->max_entries) {
-   unsigned int score;
-
-   score = ppat->match(ppat->entries[i].value, value);
-   if (score > best_score) {
-   entry = >entries[i];
-   if (score == INTEL_PPAT_PERFECT_MATCH) {
-   kref_get(>ref);
-   return entry;
-   }
-   best_score = score;
-   }
-   scanned++;
-   }
-
-   if (scanned == ppat->max_entries) {
-   if (!entry)
-   return ERR_PTR(-ENOSPC);
-
-   kref_get(>ref);
-   return entry;
-   }
-
-   i = find_first_zero_bit(ppat->used, ppat->max_entries);
-   entry = __alloc_ppat_entry(ppat, i, value);
-   ppat->update_hw(i915);
-   return entry;
-}
-
-static void release_ppat(struct kref *kref)
-{
-   struct intel_ppat_entry *entry =
-   container_of(kref, struct intel_ppat_entry, ref);
-   struct drm_i915_private *i915 = entry->ppat->i915;
-
-   __free_ppat_entry(entry);
-   entry->ppat->update_hw(i915);
-}
-
-/**
- * intel_ppat_put - put back the PPAT entry got from intel_ppat_get()
- * @entry: an intel PPAT entry
- *
- * Put back the PPAT entry got from intel_ppat_get(). If the PPAT index of the
- * entry is dynamically allocated, its reference count will be decreased. Once
- * the reference count becomes into zero, the PPAT index becomes free again.
- */
-void intel_ppat_put(const struct intel_ppat_entry *entry)
-{
-   struct intel_ppat *ppat = entry-&

Re: [Intel-gfx] [PATCH] Revert "drm/i915: Introduce private PAT management"

2019-03-25 Thread Michał Winiarski
On Sun, Mar 24, 2019 at 01:47:08PM +, Chris Wilson wrote:
> Quoting Michał Winiarski (2019-03-22 16:20:37)
> >  static int gen8_gmch_probe(struct i915_ggtt *ggtt)
> > @@ -3517,14 +3327,6 @@ void i915_gem_restore_gtt_mappings(struct 
> > drm_i915_private *dev_priv)
> > i915_ggtt_invalidate(dev_priv);
> >  
> > mutex_unlock(>vm.mutex);
> > -
> > -   if (INTEL_GEN(dev_priv) >= 8) {
> > -   struct intel_ppat *ppat = _priv->ppat;
> > -
> > -   bitmap_set(ppat->dirty, 0, ppat->max_entries);
> > -   dev_priv->ppat.update_hw(dev_priv);
> 
> Missed on the first pass, do we need to keep the restore, i.e. call
> setup_private_pat() again?

Yeah, we do, fortunately CI caught it.

Sending v2.

-Michał

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

[Intel-gfx] [PATCH] Revert "drm/i915: Introduce private PAT management"

2019-03-22 Thread Michał Winiarski
This reverts commit 4395890a48551982549d222d1923e2833dac47cf.

It's been over a year since this was merged, and the actual users of
intel_ppat_get / intel_ppat_put never materialized.

Time to remove it!

Fixes: 4395890a4855 ("drm/i915: Introduce private PAT management")
Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Zhi Wang 
---
 drivers/gpu/drm/i915/i915_drv.h |   2 -
 drivers/gpu/drm/i915/i915_gem_gtt.c | 278 
 drivers/gpu/drm/i915/i915_gem_gtt.h |  36 
 3 files changed, 40 insertions(+), 276 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fefcb39aefc4..d29a3f23f80f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1656,8 +1656,6 @@ struct drm_i915_private {
DECLARE_HASHTABLE(mm_structs, 7);
struct mutex mm_lock;
 
-   struct intel_ppat ppat;
-
/* Kernel Modesetting */
 
struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index b9e0e3a00223..c773fa65b4c6 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2881,203 +2881,26 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, 
u64 size)
return 0;
 }
 
-static struct intel_ppat_entry *
-__alloc_ppat_entry(struct intel_ppat *ppat, unsigned int index, u8 value)
+static void cnl_setup_private_ppat(struct drm_i915_private *dev_priv)
 {
-   struct intel_ppat_entry *entry = >entries[index];
-
-   GEM_BUG_ON(index >= ppat->max_entries);
-   GEM_BUG_ON(test_bit(index, ppat->used));
-
-   entry->ppat = ppat;
-   entry->value = value;
-   kref_init(>ref);
-   set_bit(index, ppat->used);
-   set_bit(index, ppat->dirty);
-
-   return entry;
-}
-
-static void __free_ppat_entry(struct intel_ppat_entry *entry)
-{
-   struct intel_ppat *ppat = entry->ppat;
-   unsigned int index = entry - ppat->entries;
-
-   GEM_BUG_ON(index >= ppat->max_entries);
-   GEM_BUG_ON(!test_bit(index, ppat->used));
-
-   entry->value = ppat->clear_value;
-   clear_bit(index, ppat->used);
-   set_bit(index, ppat->dirty);
-}
-
-/**
- * intel_ppat_get - get a usable PPAT entry
- * @i915: i915 device instance
- * @value: the PPAT value required by the caller
- *
- * The function tries to search if there is an existing PPAT entry which
- * matches with the required value. If perfectly matched, the existing PPAT
- * entry will be used. If only partially matched, it will try to check if
- * there is any available PPAT index. If yes, it will allocate a new PPAT
- * index for the required entry and update the HW. If not, the partially
- * matched entry will be used.
- */
-const struct intel_ppat_entry *
-intel_ppat_get(struct drm_i915_private *i915, u8 value)
-{
-   struct intel_ppat *ppat = >ppat;
-   struct intel_ppat_entry *entry = NULL;
-   unsigned int scanned, best_score;
-   int i;
-
-   GEM_BUG_ON(!ppat->max_entries);
-
-   scanned = best_score = 0;
-   for_each_set_bit(i, ppat->used, ppat->max_entries) {
-   unsigned int score;
-
-   score = ppat->match(ppat->entries[i].value, value);
-   if (score > best_score) {
-   entry = >entries[i];
-   if (score == INTEL_PPAT_PERFECT_MATCH) {
-   kref_get(>ref);
-   return entry;
-   }
-   best_score = score;
-   }
-   scanned++;
-   }
-
-   if (scanned == ppat->max_entries) {
-   if (!entry)
-   return ERR_PTR(-ENOSPC);
-
-   kref_get(>ref);
-   return entry;
-   }
-
-   i = find_first_zero_bit(ppat->used, ppat->max_entries);
-   entry = __alloc_ppat_entry(ppat, i, value);
-   ppat->update_hw(i915);
-   return entry;
-}
-
-static void release_ppat(struct kref *kref)
-{
-   struct intel_ppat_entry *entry =
-   container_of(kref, struct intel_ppat_entry, ref);
-   struct drm_i915_private *i915 = entry->ppat->i915;
-
-   __free_ppat_entry(entry);
-   entry->ppat->update_hw(i915);
-}
-
-/**
- * intel_ppat_put - put back the PPAT entry got from intel_ppat_get()
- * @entry: an intel PPAT entry
- *
- * Put back the PPAT entry got from intel_ppat_get(). If the PPAT index of the
- * entry is dynamically allocated, its reference count will be decreased. Once
- * the reference count becomes into zero, the PPAT index becomes free again.
- */
-void intel_ppat_put(const struct intel_ppat_entry *entry)
-{
-   struct intel_ppat *ppat = entry->ppat;
-   unsigned int index = entry - ppat->

[Intel-gfx] [PATCH] drm/i915/selftests: Upgrade printing test/subtest name to pr_info

2019-03-05 Thread Michał Winiarski
We're using pr_debug for things that we don't really want to see in the
CI log, but we may find useful during test development.
Let's upgrade the test name printer - we do want to see those in CI log.

Signed-off-by: Michał Winiarski 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/selftests/i915_selftest.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_selftest.c 
b/drivers/gpu/drm/i915/selftests/i915_selftest.c
index 10ef0e636a24..b18eaefef798 100644
--- a/drivers/gpu/drm/i915/selftests/i915_selftest.c
+++ b/drivers/gpu/drm/i915/selftests/i915_selftest.c
@@ -133,7 +133,7 @@ static int __run_selftests(const char *name,
if (signal_pending(current))
return -EINTR;
 
-   pr_debug(DRIVER_NAME ": Running %s\n", st->name);
+   pr_info(DRIVER_NAME ": Running %s\n", st->name);
if (data)
err = st->live(data);
else
@@ -255,7 +255,7 @@ int __i915_subtests(const char *caller,
if (!apply_subtest_filter(caller, st->name))
continue;
 
-   pr_debug(DRIVER_NAME ": Running %s/%s\n", caller, st->name);
+   pr_info(DRIVER_NAME ": Running %s/%s\n", caller, st->name);
GEM_TRACE("Running %s/%s\n", caller, st->name);
 
err = st->func(data);
-- 
2.20.1

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

[Intel-gfx] [PATCH 1/2] drm/i915/icl: Default to Thread Group preemption for compute workloads

2019-03-05 Thread Michał Winiarski
We assumed that the default preemption granularity is fine for ICL.
Unfortunately, it turns out that some drivers don't support mid-thread
preemption for compute workloads.
If a workload that doesn't support mid-thread preemption gets mid-thread
preempted, we're going to observe a GPU hang.
While I'm here, let's also update the "workaround" naming.

Signed-off-by: Michał Winiarski 
Cc: Anuj Phogat 
Cc: Joonas Lahtinen 
Cc: Matt Roper 
Cc: Rafael Antognolli 
Tested-by: Anuj Phogat 
Reviewed-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/intel_workarounds.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_workarounds.c 
b/drivers/gpu/drm/i915/intel_workarounds.c
index 89b4007d5200..2fba33509f4e 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -555,6 +555,11 @@ static void icl_ctx_workarounds_init(struct 
intel_engine_cs *engine)
   GEN10_CACHE_MODE_SS,
   0, /* write-only, so skip validation */
   _MASKED_BIT_ENABLE(FLOAT_BLEND_OPTIMIZATION_ENABLE));
+
+   /* WaDisableGPGPUMidThreadPreemption:icl */
+   WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1,
+   GEN9_PREEMPT_GPGPU_LEVEL_MASK,
+   GEN9_PREEMPT_GPGPU_THREAD_GROUP_LEVEL);
 }
 
 void intel_engine_init_ctx_wa(struct intel_engine_cs *engine)
@@ -1162,8 +1167,8 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct 
i915_wa_list *wal)
GEN7_DISABLE_SAMPLER_PREFETCH);
}
 
-   if (IS_GEN(i915, 9) || IS_CANNONLAKE(i915)) {
-   /* 
WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,cnl */
+   if (IS_GEN_RANGE(i915, 9, 11)) {
+   /* 
FtrPerCtxtPreemptionGranularityControl:skl,bxt,kbl,cfl,cnl,icl */
wa_masked_en(wal,
 GEN7_FF_SLICE_CS_CHICKEN1,
 GEN9_FFSC_PERCTX_PREEMPT_CTRL);
-- 
2.20.1

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

[Intel-gfx] [PATCH 2/2] drm/i915/icl: Apply WaEnablePreemptionGranularityControlByUMD

2019-03-05 Thread Michał Winiarski
There are still some cases where userspace needs to change the
preemption granularity for compute workloads. Let's whitelist the
per-ctx granularity control register to allow it.

Signed-off-by: Michał Winiarski 
Cc: Anuj Phogat 
Cc: Joonas Lahtinen 
Cc: Matt Roper 
Cc: Rafael Antognolli 
Cc: Chris Wilson 
---
 drivers/gpu/drm/i915/intel_workarounds.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_workarounds.c 
b/drivers/gpu/drm/i915/intel_workarounds.c
index 2fba33509f4e..582f554e53f4 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -1053,6 +1053,9 @@ static void icl_whitelist_build(struct i915_wa_list *w)
 
/* WaAllowUMDToModifySamplerMode:icl */
whitelist_reg(w, GEN10_SAMPLER_MODE);
+
+   /* WaEnablePreemptionGranularityControlByUMD:icl */
+   whitelist_reg(w, GEN8_CS_CHICKEN1);
 }
 
 void intel_engine_init_whitelist(struct intel_engine_cs *engine)
-- 
2.20.1

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

Re: [Intel-gfx] [PATCH 06/38] drm/i915/selftests: Check that whitelisted registers are accessible

2019-03-01 Thread Michał Winiarski
On Fri, Mar 01, 2019 at 02:03:32PM +, Chris Wilson wrote:
> There is no point in whitelisting a register that the user then cannot
> write to, so check the register exists before merging such patches.
> 
> v2: Mark SLICE_COMMON_ECO_CHICKEN1 [731c] as write-only
> 
> Signed-off-by: Chris Wilson 
> Cc: Dale B Stimson 
> Cc: Michał Winiarski 
> ---
>  .../drm/i915/selftests/intel_workarounds.c| 376 ++
>  1 file changed, 376 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/selftests/intel_workarounds.c 
> b/drivers/gpu/drm/i915/selftests/intel_workarounds.c
> index e6ffc8ac22dc..33b3ced83fde 100644
> --- a/drivers/gpu/drm/i915/selftests/intel_workarounds.c
> +++ b/drivers/gpu/drm/i915/selftests/intel_workarounds.c
> @@ -12,6 +12,14 @@
>  #include "igt_spinner.h"
>  #include "igt_wedge_me.h"
>  #include "mock_context.h"
> +#include "mock_drm.h"
> +
> +static const struct wo_register {
> + enum intel_platform platform;
> + u32 reg;
> +} wo_registers[] = {
> + { INTEL_GEMINILAKE, 0x731c }
> +};
>  
>  #define REF_NAME_MAX (INTEL_ENGINE_CS_MAX_NAME + 4)
>  struct wa_lists {
> @@ -331,6 +339,373 @@ static int check_whitelist_across_reset(struct 
> intel_engine_cs *engine,
>   return err;
>  }
>  
> +static struct i915_vma *create_scratch(struct i915_gem_context *ctx)
> +{
> + struct drm_i915_gem_object *obj;
> + struct i915_vma *vma;
> + void *ptr;
> + int err;
> +
> + obj = i915_gem_object_create_internal(ctx->i915, PAGE_SIZE);
> + if (IS_ERR(obj))
> + return ERR_CAST(obj);
> +
> + i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);

Check return value.

> +
> + ptr = i915_gem_object_pin_map(obj, I915_MAP_WB);
> + if (IS_ERR(ptr)) {
> + err = PTR_ERR(ptr);
> + goto err_obj;
> + }
> + memset(ptr, 0xc5, PAGE_SIZE);
> + i915_gem_object_unpin_map(obj);
> +
> + vma = i915_vma_instance(obj, >ppgtt->vm, NULL);
> + if (IS_ERR(vma)) {
> + err = PTR_ERR(vma);
> + goto err_obj;
> + }
> +
> + err = i915_vma_pin(vma, 0, 0, PIN_USER);
> + if (err)
> + goto err_obj;
> +
> + err = i915_gem_object_set_to_cpu_domain(obj, false);
> + if (err)
> + goto err_obj;
> +
> + return vma;
> +
> +err_obj:
> + i915_gem_object_put(obj);
> + return ERR_PTR(err);
> +}
> +

[SNIP]

> +static int check_dirty_whitelist(struct i915_gem_context *ctx,
> +  struct intel_engine_cs *engine)
> +{
> + const u32 values[] = {
> + 0x,
> + 0x01010101,
> + 0x10100101,
> + 0x03030303,
> + 0x30300303,
> + 0x05050505,
> + 0x50500505,
> + 0x0f0f0f0f,
> + 0xf00ff00f,
> + 0x10101010,
> + 0xf0f01010,
> + 0x30303030,
> + 0xa0a03030,
> + 0x50505050,
> + 0xc0c05050,
> + 0xf0f0f0f0,
> + 0x,
> + 0x,
> + 0x,
> + 0x,
> + 0x00ff00ff,
> + 0xffff,
> + 0x00ff,
> + 0x,
> + };
> + struct i915_vma *scratch;
> + struct i915_vma *batch;
> + int err = 0, i, v;
> + u32 *cs;
> +
> + scratch = create_scratch(ctx);
> + if (IS_ERR(scratch))
> + return PTR_ERR(scratch);
> +
> + batch = create_batch(ctx);
> + if (IS_ERR(batch)) {
> + err = PTR_ERR(batch);
> + goto out_scratch;
> + }
> +
> + for (i = 0; i < engine->whitelist.count; i++) {
> + u32 reg = i915_mmio_reg_offset(engine->whitelist.list[i].reg);
> + u64 addr = scratch->node.start;
> + struct i915_request *rq;
> + u32 srm, lrm, rsvd;
> + u32 expect;
> + int idx;
> +
> + if (wo_register(engine, reg))
> + continue;
> +
> + srm = MI_STORE_REGISTER_MEM;
> + lrm = MI_LOAD_REGISTER_MEM;
> + if (INTEL_GEN(ctx->i915) >= 8)
> + lrm++, srm++;
> +
> + pr_debug("%s: Writing garbage to %x {srm=0x%08x, lrm=0x%08x}\n",
> +  engine->name, reg, srm, lrm);

Why are we printing opcodes (srm/lrm)?

> +
> + cs = i915_gem_object_pin_map(batch->obj, I915_MAP_WC);
> + if (I

[Intel-gfx] [PATCH 1/2] drm/i915/icl: Default to Thread Group preemption for compute workloads

2019-02-27 Thread Michał Winiarski
We assumed that the default preemption granularity is fine for ICL.
Unfortunately, it turns out that some drivers don't support mid-thread
preemption for compute workloads.
If a workload that doesn't support mid-thread preemption gets mid-thread
preempted, we're going to observe a GPU hang.
While I'm here, let's also update the "workaround" naming.

Signed-off-by: Michał Winiarski 
Cc: Anuj Phogat 
Cc: Joonas Lahtinen 
Cc: Matt Roper 
Cc: Rafael Antognolli 
---
 drivers/gpu/drm/i915/intel_workarounds.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_workarounds.c 
b/drivers/gpu/drm/i915/intel_workarounds.c
index 743cf5b00155..a19e1c0052a7 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -555,6 +555,11 @@ static void icl_ctx_workarounds_init(struct 
intel_engine_cs *engine)
   GEN10_CACHE_MODE_SS,
   0, /* write-only, so skip validation */
   _MASKED_BIT_ENABLE(FLOAT_BLEND_OPTIMIZATION_ENABLE));
+
+   /* WaDisableGPGPUMidThreadPreemption:icl */
+   WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1,
+   GEN9_PREEMPT_GPGPU_LEVEL_MASK,
+   GEN9_PREEMPT_GPGPU_THREAD_GROUP_LEVEL);
 }
 
 void intel_engine_init_ctx_wa(struct intel_engine_cs *engine)
@@ -1170,8 +1175,8 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct 
i915_wa_list *wal)
GEN7_DISABLE_SAMPLER_PREFETCH);
}
 
-   if (IS_GEN(i915, 9) || IS_CANNONLAKE(i915)) {
-   /* 
WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,cnl */
+   if (IS_GEN_RANGE(i915, 9, 11)) {
+   /* 
FtrPerCtxtPreemptionGranularityControl:skl,bxt,kbl,cfl,cnl,icl */
wa_masked_en(wal,
 GEN7_FF_SLICE_CS_CHICKEN1,
 GEN9_FFSC_PERCTX_PREEMPT_CTRL);
-- 
2.20.1

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

[Intel-gfx] [PATCH 2/2] drm/i915/icl: Apply WaEnablePreemptionGranularityControlByUMD

2019-02-27 Thread Michał Winiarski
There are still some cases where userspace needs to change the
preemption granularity for compute workloads. Let's whitelist the
per-ctx granularity control register to allow it.

Signed-off-by: Michał Winiarski 
Cc: Anuj Phogat 
Cc: Joonas Lahtinen 
Cc: Matt Roper 
Cc: Rafael Antognolli 
---
 drivers/gpu/drm/i915/intel_workarounds.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_workarounds.c 
b/drivers/gpu/drm/i915/intel_workarounds.c
index a19e1c0052a7..1aa167415096 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -1057,6 +1057,9 @@ static void icl_whitelist_build(struct i915_wa_list *w)
 
/* WaAllowUMDToModifySamplerMode:icl */
whitelist_reg(w, GEN10_SAMPLER_MODE);
+
+   /* WaEnablePreemptionGranularityControlByUMD:icl */
+   whitelist_reg(w, GEN8_CS_CHICKEN1);
 }
 
 void intel_engine_init_whitelist(struct intel_engine_cs *engine)
-- 
2.20.1

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

Re: [Intel-gfx] [igt-dev] [PATCH i-g-t 3/4] tests/gem_media_vme: Simple test to exercise the VME block

2019-01-10 Thread Michał Winiarski
On Tue, Jan 08, 2019 at 03:13:02PM +, Tvrtko Ursulin wrote:
> From: Tony Ye 
> 
> Simple test which exercises the VME fixed function block.
> 
> v2: (Tvrtko Ursulin)
>  * Small cleanups like copyright date, tabs, remove unused bits.
> 
> v3: (Tony Ye)
>  * Added curbe data entry for dst surface.
>  * Read the dst surface after the VME kernel being executed.
> 
> v4: (Tony Ye)
>  * Added the media_vme.gxa kernel source code and compile instructions.
> 
> v5: (Tvrtko Ursulin)
>  * Added hang detector.
> 
> v6: (Tvrtko Ursulin)
>  * Replace gem_read with gem_sync. (Chris Wilson)
> 
> Signed-off-by: Tony Ye 
> Signed-off-by: Tvrtko Ursulin 
> Cc: Tony Ye 
> Reviewed-by: Joonas Lahtinen 
> ---
>  lib/gpu_cmds.c  | 136 
>  lib/gpu_cmds.h  |  20 ++-
>  lib/i915/shaders/media/README_media_vme.txt |  65 ++
>  lib/i915/shaders/media/media_vme.gxa|  51 
>  lib/intel_batchbuffer.c |   9 ++
>  lib/intel_batchbuffer.h |   7 +
>  lib/media_fill.c| 110 
>  lib/media_fill.h|   6 +
>  lib/surfaceformat.h |   2 +
>  tests/Makefile.sources  |   3 +
>  tests/i915/gem_media_vme.c  | 117 +
>  tests/meson.build   |   1 +
>  12 files changed, 525 insertions(+), 2 deletions(-)
>  create mode 100755 lib/i915/shaders/media/README_media_vme.txt
>  create mode 100755 lib/i915/shaders/media/media_vme.gxa
>  create mode 100644 tests/i915/gem_media_vme.c
> 
> diff --git a/lib/i915/shaders/media/README_media_vme.txt 
> b/lib/i915/shaders/media/README_media_vme.txt
> new file mode 100755
> index ..2470fdd89825
> --- /dev/null
> +++ b/lib/i915/shaders/media/README_media_vme.txt
> @@ -0,0 +1,65 @@
> +Step1: Building IGA (Intel Graphics Assembler)
> +
> +
> +1. Download or clone IGC (Intel Graphics Compiler)
> +
> +   https://github.com/intel/intel-graphics-compiler.git
> +
> +2. Chdir into 'intel-graphics-compiler' (or any other workspace folder of 
> choice)
> +
> +   It should read the following folder strucutre:
> +
> +   workspace
> +  |- visa
> +  |- IGC
> +  |- inc
> +  |- 3d
> +  |- skuwa
> +
> +3. Chdir into IGA sub-component
> +
> +   cd visa/iga
> +
> +4. Create build directory
> +
> +mkdir build
> +
> +5. Change into build directory
> +
> +cd build
> +
> +6. Run cmake
> +
> +   cmake ../
> +
> +7. Run make to build IGA project
> +
> +   make
> +
> +8. Get the output executable "iga64" in IGAExe folder
> +
> +   usage: ./iga64 OPTIONS ARGS
> +   where OPTIONS:
> + -h --help shows help on an option
> + -d --disassemble  disassembles the input file
> + -a --assemble assembles the input file
> + -n --numeric-labels   use numeric labels
> + -p --platformDEVICE   specifies the platform (e.g. "GEN9")
> + -o --output  FILE specifies the output file
> +
> +   EXAMPLES:
> +   ./iga64  file.gxa  -p=11 -a  -o file.krn
> +
> +Step2: Building ASM code
> +
> +1. Command line to convert asm code to binary:
> +
> +   iga64 media_vme.gxa -p=11 -a -o media_vme.krn
> +
> +2. Pad 128 bytes zeros to the kernel:
> +
> +   dd if=/dev/zero bs=1 count=128 >> media_vme.krn

Why we're padding it with 128B zeroes?
We don't seem to do that for any other shaders.

Could you modify this instruction to use lib/i915/shaders/converter.py and
rather than adding yet another README, update lib/i915/shaders/README instead?

-Michał

> +
> +3. Generate hexdump:
> +
> +   hexdump -v  -e '4/4 "0x%08x " "\n"' media_vme.krn > media_vme.hex
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915/icl: Apply WaEnablePreemptionGranularityControlByUMD

2019-01-09 Thread Michał Winiarski
On Mon, Jan 07, 2019 at 11:19:31AM -0800, Matt Roper wrote:
> On Mon, Jan 07, 2019 at 01:23:50PM +0100, Michał Winiarski wrote:
> > On Mon, Jan 07, 2019 at 01:01:16PM +0200, Joonas Lahtinen wrote:
> > > Quoting José Roberto de Souza (2019-01-04 19:37:00)
> > > > According to Workaround database ICL also needs
> > > > WaEnablePreemptionGranularityControlByUMD, to allow userspace to do
> > > > fine-granularity preemptions per-context.
> > > 
> > > I must wonder where is the userspace component that needs this, and why
> > > it hasn't been noticed earlier?
> > > 
> > > Or is this one more of the cases when no userspace actually uses the
> > > register?
> > 
> > It's used:
> > https://gitlab.freedesktop.org/mesa/mesa/blob/master/src/mesa/drivers/dri/i965/brw_state_upload.c#L64
> > 
> > -Michał
> 
> Wasn't this just an artificial i915-only workaround that was added to
> prevent breakage of pre-preemption UMD's?  Initial gen9 driver releases
> didn't support preemption, so when preemption support did get added to
> i915, the kernel had to force object-level off by default at context
> creation to avoid breaking old userspace that didn't build batch buffers
> with all the necessary preemption workarounds.  This CS_CHICKEN1
> register was then exposed to userspace so that newer, preemption-aware
> userspace could opt back in if it properly supported preemption.

It wasn't just old userspace vs preeemption-aware userspace.
Even the preemption-aware userspace needs to downgrade its preemption
granularity as a WA, see:
https://gitlab.freedesktop.org/mesa/mesa/blob/master/src/mesa/drivers/dri/i965/brw_draw.c#L876

> For gen11, there shouldn't be any "old" userspace around that doesn't
> support preemption, so shouldn't the kernel just leave object-level
> preemption enabled by default (meaning there's no need to expose this
> register to userspace to allow it to explicitly opt-in)?

Agreed, as a bonus we don't allow anyone to explicity opt-out - which is
great, as long as everything works reliably.

-Michał

> 
> Matt
> 
> > 
> > > Regards, Joonas
> > > 
> > > > 
> > > > BSpec: 11348
> > > > Cc: Oscar Mateo 
> > > > Cc: Radhakrishna Sripada 
> > > > Signed-off-by: José Roberto de Souza 
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_workarounds.c | 9 ++---
> > > >  1 file changed, 6 insertions(+), 3 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/intel_workarounds.c 
> > > > b/drivers/gpu/drm/i915/intel_workarounds.c
> > > > index 480c53a2ecb5..bbc5a66faa07 100644
> > > > --- a/drivers/gpu/drm/i915/intel_workarounds.c
> > > > +++ b/drivers/gpu/drm/i915/intel_workarounds.c
> > > > @@ -1014,7 +1014,7 @@ static void gen9_whitelist_build(struct 
> > > > i915_wa_list *w)
> > > > /* 
> > > > WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */
> > > > whitelist_reg(w, GEN9_CTX_PREEMPT_REG);
> > > >  
> > > > -   /* 
> > > > WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */
> > > > +   /* 
> > > > WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl,icl] */
> > > > whitelist_reg(w, GEN8_CS_CHICKEN1);
> > > >  
> > > > /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */
> > > > @@ -1068,6 +1068,9 @@ static void icl_whitelist_build(struct 
> > > > i915_wa_list *w)
> > > >  
> > > > /* WaAllowUMDToModifySamplerMode:icl */
> > > > whitelist_reg(w, GEN10_SAMPLER_MODE);
> > > > +
> > > > +   /* WaEnablePreemptionGranularityControlByUMD:icl */
> > > > +   whitelist_reg(w, GEN8_CS_CHICKEN1);
> > > >  }
> > > >  
> > > >  void intel_engine_init_whitelist(struct intel_engine_cs *engine)
> > > > @@ -1186,8 +1189,8 @@ static void rcs_engine_wa_init(struct 
> > > > intel_engine_cs *engine)
> > > > GEN7_DISABLE_SAMPLER_PREFETCH);
> > > > }
> > > >  
> > > > -   if (IS_GEN(i915, 9) || IS_CANNONLAKE(i915)) {
> > > > -   /* 
> > > > WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,cnl */
> > > > +   if (IS_GEN_RANGE(i915, 9, 11)) {
> > > > +   /* 
> > > > WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,cnl,icl */
> > &g

Re: [Intel-gfx] [igt-dev] [PATCH i-g-t] tests/gem_shrink: Exercise OOM and other routes to shrinking in reasonable time

2019-01-07 Thread Michał Winiarski
On Fri, Jan 04, 2019 at 03:37:09PM +, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin 
> 
> A set of subtests which exercises different paths to our shrinker code
> (including the OOM killer) in predictable and reasonable time budget.
> 
> Signed-off-by: Tvrtko Ursulin 
> ---
>  lib/igt_core.c|  19 ++
>  lib/igt_core.h|   1 +
>  tests/i915/gem_shrink.c   | 399 ++
>  tests/intel-ci/blacklist.txt  |   1 +
>  tests/intel-ci/fast-feedback.testlist |   3 +
>  5 files changed, 423 insertions(+)

[snip]

> diff --git a/tests/i915/gem_shrink.c b/tests/i915/gem_shrink.c
> index c8e05814ee70..7c002de0ef1f 100644
> --- a/tests/i915/gem_shrink.c
> +++ b/tests/i915/gem_shrink.c
> @@ -26,6 +26,10 @@
>   *
>   * Exercise the shrinker by overallocating GEM objects
>   */
> +#include 
> +#include 
> +#include 
> +#include 
>  
>  #include "igt.h"
>  #include "igt_gt.h"
> @@ -366,6 +370,376 @@ static void reclaim(unsigned engine, int timeout)
>   close(fd);
>  }
>  
> +static unsigned long get_meminfo(const char *info, const char *tag)
> +{
> + const char *str;
> + unsigned long val;
> +
> + str = strstr(info, tag);
> + if (str && sscanf(str + strlen(tag), " %lu", ) == 1)
> + return val >> 10;
> +
> + igt_warn("Unrecognised /proc/meminfo field: '%s'\n", tag);
> + return 0;
> +}
> +
> +static unsigned long get_avail_ram_mb(void)
> +{
> + int fd;
> + int ret;
> + char buf[4096];
> + unsigned long ram;
> +
> + fd = open("/proc/meminfo", O_RDONLY);
> + igt_assert_fd(fd);
> +
> + ret = read(fd, buf, sizeof(buf));
> + igt_assert(ret >= 0);
> +
> + close(fd);
> +
> + ram = get_meminfo(buf, "MemAvailable:");
> + ram += get_meminfo(buf, "Buffers:");
> + ram += get_meminfo(buf, "Cached:");
> + ram += get_meminfo(buf, "SwapCached:");
> +
> + return ram;
> +}

What's wrong with ones from intel_os.c?

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


Re: [Intel-gfx] [PATCH] drm/i915/icl: Apply WaEnablePreemptionGranularityControlByUMD

2019-01-07 Thread Michał Winiarski
On Mon, Jan 07, 2019 at 01:01:16PM +0200, Joonas Lahtinen wrote:
> Quoting José Roberto de Souza (2019-01-04 19:37:00)
> > According to Workaround database ICL also needs
> > WaEnablePreemptionGranularityControlByUMD, to allow userspace to do
> > fine-granularity preemptions per-context.
> 
> I must wonder where is the userspace component that needs this, and why
> it hasn't been noticed earlier?
> 
> Or is this one more of the cases when no userspace actually uses the
> register?

It's used:
https://gitlab.freedesktop.org/mesa/mesa/blob/master/src/mesa/drivers/dri/i965/brw_state_upload.c#L64

-Michał

> Regards, Joonas
> 
> > 
> > BSpec: 11348
> > Cc: Oscar Mateo 
> > Cc: Radhakrishna Sripada 
> > Signed-off-by: José Roberto de Souza 
> > ---
> >  drivers/gpu/drm/i915/intel_workarounds.c | 9 ++---
> >  1 file changed, 6 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_workarounds.c 
> > b/drivers/gpu/drm/i915/intel_workarounds.c
> > index 480c53a2ecb5..bbc5a66faa07 100644
> > --- a/drivers/gpu/drm/i915/intel_workarounds.c
> > +++ b/drivers/gpu/drm/i915/intel_workarounds.c
> > @@ -1014,7 +1014,7 @@ static void gen9_whitelist_build(struct i915_wa_list 
> > *w)
> > /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */
> > whitelist_reg(w, GEN9_CTX_PREEMPT_REG);
> >  
> > -   /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] 
> > */
> > +   /* 
> > WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl,icl] */
> > whitelist_reg(w, GEN8_CS_CHICKEN1);
> >  
> > /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */
> > @@ -1068,6 +1068,9 @@ static void icl_whitelist_build(struct i915_wa_list 
> > *w)
> >  
> > /* WaAllowUMDToModifySamplerMode:icl */
> > whitelist_reg(w, GEN10_SAMPLER_MODE);
> > +
> > +   /* WaEnablePreemptionGranularityControlByUMD:icl */
> > +   whitelist_reg(w, GEN8_CS_CHICKEN1);
> >  }
> >  
> >  void intel_engine_init_whitelist(struct intel_engine_cs *engine)
> > @@ -1186,8 +1189,8 @@ static void rcs_engine_wa_init(struct intel_engine_cs 
> > *engine)
> > GEN7_DISABLE_SAMPLER_PREFETCH);
> > }
> >  
> > -   if (IS_GEN(i915, 9) || IS_CANNONLAKE(i915)) {
> > -   /* 
> > WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,cnl */
> > +   if (IS_GEN_RANGE(i915, 9, 11)) {
> > +   /* 
> > WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,cnl,icl */
> > wa_masked_en(wal,
> >  GEN7_FF_SLICE_CS_CHICKEN1,
> >  GEN9_FFSC_PERCTX_PREEMPT_CTRL);
> > -- 
> > 2.20.1
> > 
> > ___
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915/huc: Normalize HuC status returned by I915_PARAM_HAS_HUC

2018-10-16 Thread Michał Winiarski
On Tue, Oct 16, 2018 at 11:34:14AM +, Michal Wajdeczko wrote:
> In response for I915_PARAM_HAS_HUC we are returning value that
> indicates if HuC firmware was loaded and verified. However, our
> previously used positive value was based on specific register bit
> which is about to change on future platform. Let's normalize our
> return values to 0 and 1 before clients will start to use Gen9 value.
> 
> Signed-off-by: Michal Wajdeczko 
> Cc: Michal Winiarski 
> Cc: Joonas Lahtinen 
> Cc: Haihao Xiang 

It's "tweaking" the ABI, but hopefully we can avoid breaking anything.

intel-vaapi-driver is doing !!(getparam) and media-driver is being optimistic
(i.e. assuming that HuC is present without any checks).

I don't know of any other components using this, and as you've mentioned in the
commit message - HuC is still under unsafe param, so:

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  drivers/gpu/drm/i915/intel_huc.c | 9 +
>  1 file changed, 5 insertions(+), 4 deletions(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915/guc: Restore preempt-context across S3/S4

2018-09-20 Thread Michał Winiarski
On Wed, Sep 19, 2018 at 09:54:32PM +0100, Chris Wilson wrote:
> Stolen memory is lost across S4 (hibernate) or S3-RST as it is a portion
> of ordinary volatile RAM. As we allocate our rings from stolen, this may
> include the rings used for our preempt context and their breadcrumb
> instructions. In order to allow preemption following hibernation and
> loss of stolen memory, we therefore need to repopulate the instructions
> inside the lost ring upon resume. To handle both module load and resume,
> we simply defer constructing the ring to first use.
> 
> Testcase: igt/drv_selftest/live_gem
> Signed-off-by: Chris Wilson 
> Cc: Michał Winiarski 
> Cc: Michal Wajdeczko 

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  drivers/gpu/drm/i915/intel_guc_submission.c | 80 +++--
>  1 file changed, 27 insertions(+), 53 deletions(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/3] drm/i915: Protect guc_fini_wq() against module load abort

2018-07-26 Thread Michał Winiarski
On Thu, Jul 26, 2018 at 09:50:31AM +0100, Chris Wilson wrote:
> Prevent
> [  397.873143] general protection fault:  [#1] PREEMPT SMP PTI
> [  397.873154] CPU: 4 PID: 4799 Comm: drv_module_relo Tainted: G U
> 4.18.0-rc6-CI-CI_DRM_4534+ #1
> [  397.873162] Hardware name: Micro-Star International Co., Ltd. 
> MS-7B54/Z370M MORTAR (MS-7B54), BIOS 1.10 12/28/2017
> [  397.873175] RIP: 0010:__lock_acquire+0xf6/0x1b50
> [  397.873179] Code: 85 c0 4c 8b 9d 40 ff ff ff 8b 8d 38 ff ff ff 44 8b 8d 30 
> ff ff ff 4c 8b 85 28 ff ff ff 44 8b 95 24 ff ff ff 0f 84 54 03 00 00  ff 
> 80 38 01 00 00 8b 15 45 8c 59 02 45 8b bc 24 70 08 00 00 85
> [  397.873240] RSP: 0018:c9497b40 EFLAGS: 00010002
> [  397.873246] RAX: 6b6b6b6b6b6b6b6b RBX: 0001 RCX: 
> 
> [  397.873252] RDX: 0046 RSI:  RDI: 
> 
> [  397.873258] RBP: c9497c20 R08: 810a25e9 R09: 
> 
> [  397.873264] R10:  R11: 880255c63c28 R12: 
> 8801093b2840
> [  397.873270] R13: 0001 R14: 0001 R15: 
> 0246
> [  397.873277] FS:  7faf88d71980() GS:88026630() 
> knlGS:
> [  397.873284] CS:  0010 DS:  ES:  CR0: 80050033
> [  397.873289] CR2: 55d866c9ca10 CR3: 00025472e006 CR4: 
> 003606e0
> [  397.873295] DR0:  DR1:  DR2: 
> 
> [  397.873301] DR3:  DR6: fffe0ff0 DR7: 
> 0400
> [  397.873308] Call Trace:
> [  397.873318]  ? lock_acquire+0xa6/0x210
> [  397.873323]  lock_acquire+0xa6/0x210
> [  397.873331]  ? drain_workqueue+0x19/0x180
> [  397.873339]  __mutex_lock+0x89/0x980
> [  397.873346]  ? drain_workqueue+0x19/0x180
> [  397.873352]  ? _raw_spin_unlock_irqrestore+0x4c/0x60
> [  397.873359]  ? trace_hardirqs_on_caller+0xe0/0x1b0
> [  397.873365]  ? drain_workqueue+0x19/0x180
> [  397.873373]  ? debug_object_active_state+0x127/0x150
> [  397.873381]  ? drain_workqueue+0x19/0x180
> [  397.873387]  drain_workqueue+0x19/0x180
> [  397.873395]  destroy_workqueue+0x12/0x1f0
> [  397.873476]  intel_guc_fini_misc+0x36/0x90 [i915]
> [  397.873540]  i915_gem_fini+0x91/0x100 [i915]
> [  397.873588]  i915_driver_unload+0xd2/0x110 [i915]
> [  397.873638]  i915_pci_remove+0x19/0x30 [i915]
> [  397.873646]  pci_device_remove+0x36/0xb0
> [  397.873653]  device_release_driver_internal+0x185/0x250
> [  397.873660]  driver_detach+0x35/0x70
> [  397.873668]  bus_remove_driver+0x53/0xd0
> [  397.873675]  pci_unregister_driver+0x25/0xa0
> [  397.873683]  __se_sys_delete_module+0x162/0x210
> [  397.873691]  ? do_syscall_64+0xd/0x190
> [  397.873697]  do_syscall_64+0x55/0x190
> [  397.873704]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
> [  397.873710] RIP: 0033:0x7faf884231b7
> [  397.873714] Code: 73 01 c3 48 8b 0d d1 8c 2c 00 f7 d8 64 89 01 48 83 c8 ff 
> c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 b0 00 00 00 0f 05 <48> 3d 
> 01 f0 ff ff 73 01 c3 48 8b 0d a1 8c 2c 00 f7 d8 64 89 01 48
> [  397.873775] RSP: 002b:7ffda4e98cf8 EFLAGS: 0206 ORIG_RAX: 
> 00b0
> [  397.873784] RAX: ffda RBX:  RCX: 
> 7faf884231b7
> [  397.873790] RDX:  RSI: 0800 RDI: 
> 55fbb18f1bd8
> [  397.873796] RBP: 55fbb18f1b70 R08: 55fbb18f1bdc R09: 
> 7ffda4e98d38
> [  397.873802] R10: 7ffda4e97cf4 R11: 0206 R12: 
> 55fbb0d32470
> [  397.873808] R13: 7ffda4e992e0 R14:  R15: 
> 0000
> 
> v2: It's use-after-free; not a NULL pointer.
> 
> Testcase: igt/drv_module_reload/basic-reload-inject
> Signed-off-by: Chris Wilson 
> Cc: Michał Winiarski 
> Cc: Michal Wajdeczko 

Whole series:

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  drivers/gpu/drm/i915/intel_guc.c | 12 +++-
>  1 file changed, 7 insertions(+), 5 deletions(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Pull unpin map into vma release

2018-07-24 Thread Michał Winiarski
On Sat, Jul 21, 2018 at 01:50:37PM +0100, Chris Wilson wrote:
> A reasonably common operation is to pin the map of the vma alongside the
> vma itself for the lifetime of the vma, and so release both pin at the
> same time as destroying the vma. It is common enough to pull into the
> release function, making that central function more attractive to a
> couple of other callsites.
> 
> The continual ulterior motive is to sweep over errors on module load
> aborting...
> 
> Testcase: igt/drv_module_reload/basic-reload-inject
> Signed-off-by: Chris Wilson 
> Cc: Michał Winiarski 
> Cc: Michal Wajdeczko 

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  drivers/gpu/drm/i915/i915_perf.c| 10 --
>  drivers/gpu/drm/i915/i915_vma.c |  5 -
>  drivers/gpu/drm/i915/i915_vma.h |  3 ++-
>  drivers/gpu/drm/i915/intel_engine_cs.c  | 18 +++---
>  drivers/gpu/drm/i915/intel_guc.c|  5 ++---
>  drivers/gpu/drm/i915/intel_guc_ads.c|  2 +-
>  drivers/gpu/drm/i915/intel_guc_ct.c |  7 ++-
>  drivers/gpu/drm/i915/intel_guc_log.c|  2 +-
>  drivers/gpu/drm/i915/intel_guc_submission.c | 10 --
>  drivers/gpu/drm/i915/intel_lrc.c|  2 +-
>  10 files changed, 24 insertions(+), 40 deletions(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 1/5] drm/i915/guc: Avoid wasting memory on incorrect GuC pin bias

2018-07-20 Thread Michał Winiarski
On Fri, Jul 20, 2018 at 03:33:51PM +0200, Jakub Bartmiński wrote:
> It would appear that the calculated GuC pin bias was larger than it
> should be, as the GuC address space does NOT contain the "HW contexts RSVD"
> part of the WOPCM. Thus, the GuC pin bias is simply the GuC WOPCM size.
> 
> Signed-off-by: Jakub Bartmiński 
> Cc: Chris Wilson 
> Cc: Michał Winiarski 
> Cc: Michal Wajdeczko 

Cc: Jackie Li 

Matches what I was able to read on GuC view of GGTT.

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  drivers/gpu/drm/i915/intel_guc.c | 50 ++--
>  1 file changed, 22 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_guc.c 
> b/drivers/gpu/drm/i915/intel_guc.c
> index e12bd259df17..17753952933e 100644
> --- a/drivers/gpu/drm/i915/intel_guc.c
> +++ b/drivers/gpu/drm/i915/intel_guc.c
> @@ -582,50 +582,44 @@ int intel_guc_resume(struct intel_guc *guc)
>   *
>   * ::
>   *
> - * +==> ++ <== GUC_GGTT_TOP
> - * ^||
> - * |||
> - * ||DRAM|
> - * ||   Memory   |
> - * |||
> - *GuC   ||
> - *  Address  +> ++ <== WOPCM Top
> - *   Space   ^  |   HW contexts RSVD |
> - * | |  |WOPCM   |
> - * | | +==> ++ <== GuC WOPCM Top
> - * |GuC^||
> - * |GGTT   |||
> - * |Pin   GuC   |GuC |
> - * |Bias WOPCM  |   WOPCM|
> - * | |Size  ||
> - * | | |||
> - * v v v||
> - * +=+=+==> ++ <== GuC WOPCM Base
> - *  |   Non-GuC WOPCM|
> - *  |   (HuC/Reserved)   |
> - *  ++ <== WOPCM Base
> + * +> ++ <== GUC_GGTT_TOP
> + * ^  ||
> + * |  ||
> + * |  |DRAM|
> + * |  |   Memory   |
> + * |  ||
> + *GuC ||
> + *  Address+> ++ <== GuC WOPCM Top
> + *   Space ^  ||
> + * |   |  ||
> + * |  GuC |GuC |
> + * | WOPCM|   WOPCM|
> + * |  Size||
> + * |   |  ||
> + * v   v  ||
> + * +===+> ++ <== GuC WOPCM Base
>   *
>   * The lower part of GuC Address Space [0, ggtt_pin_bias) is mapped to WOPCM
>   * while upper part of GuC Address Space [ggtt_pin_bias, GUC_GGTT_TOP) is 
> mapped
> - * to DRAM. The value of the GuC ggtt_pin_bias is determined by WOPCM size 
> and
> - * actual GuC WOPCM size.
> + * to DRAM. The value of the GuC ggtt_pin_bias is the GuC WOPCM size.
>   */
>  
>  /**
>   * guc_init_ggtt_pin_bias() - Initialize the GuC ggtt_pin_bias value.
>   * @guc: intel_guc structure.
>   *
> - * This function will calculate and initialize the ggtt_pin_bias value based 
> on
> - * overall WOPCM size and GuC WOPCM size.
> + * This function will calculate and initialize the ggtt_pin_bias value
> + * based on the GuC WOPCM size.
>   */
>  static void guc_init_ggtt_pin_bias(struct intel_guc *guc)
>  {
>   struct drm_i915_private *i915 = guc_to_i915(guc);
>  
>   GEM_BUG_ON(!i915->wopcm.size);
> - GEM_BUG_ON(i915->wopcm.size < i915->wopcm.guc.base);
> + GEM_BUG_ON(range_overflows(i915->wopcm.guc.base, i915->wopcm.guc.size,
> +i915->wopcm.size));
>  
> - guc->ggtt_pin_bias = i915->wopcm.size - i915->wopcm.guc.base;
> + guc->ggtt_pin_bias = i915->wopcm.guc.size;
>  }
>  
>  /**
> -- 
> 2.17.1
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Suppress assertion for i915_ggtt_disable_guc

2018-07-20 Thread Michał Winiarski
On Fri, Jul 20, 2018 at 10:51:44AM +0100, Chris Wilson wrote:
> Another step in the drv_module_reload fault-injection saga, is that we
> try to disable the guc twice. Probably. It's a little unclear exactly
> what is going on in the unload sequence that catches us out, so for the
> time being suppress the assertion to get the test re-enabled.
> 
> Testcase: igt/drv_module_reload/basic-reload-inject
> Signed-off-by: Chris Wilson 
> Cc: Michał Winiarski 
> Cc: Michal Wajdeczko 

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index cff0e6430994..1b476423bfab 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3654,6 +3654,10 @@ void i915_ggtt_enable_guc(struct drm_i915_private 
> *i915)
>  
>  void i915_ggtt_disable_guc(struct drm_i915_private *i915)
>  {
> + /* XXX Temporary pardon for error unload */
> + if (i915->ggtt.invalidate == gen6_ggtt_invalidate)
> + return;
> +
>   /* We should only be called after i915_ggtt_enable_guc() */
>   GEM_BUG_ON(i915->ggtt.invalidate != guc_ggtt_invalidate);
>  
> -- 
> 2.18.0
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH i-g-t] lib: Move trash_bos to their only user

2018-07-19 Thread Michał Winiarski
On Wed, Jul 18, 2018 at 11:56:27AM +0100, Chris Wilson wrote:
> Only pm_rpm still uses the igt_trash_aperture() and so we can remove it
> from the lib and in the process convert it over from the legacy
> libdrm_intel.
> 
> Signed-off-by: Chris Wilson 
> Cc: Michał Winiarski 

I'm not sure what the test is testing exactly, but since it's a straight forward
conversion from libdrm_intel with no functional changes:

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  lib/igt_aux.c  | 57 --
>  lib/igt_aux.h  | 10 +
>  tests/pm_rpm.c | 31 ++-
>  3 files changed, 22 insertions(+), 76 deletions(-)
> 
> diff --git a/lib/igt_aux.c b/lib/igt_aux.c
> index d9dbf7ced..1250d5c5f 100644
> --- a/lib/igt_aux.c
> +++ b/lib/igt_aux.c
> @@ -682,63 +682,6 @@ void igt_print_activity(void)
>   igt_interactive_info(".");
>  }
>  
> -/* mappable aperture trasher helper */
> -drm_intel_bo **trash_bos;
> -int num_trash_bos;
> -
> -/**
> - * igt_init_aperture_trashers:
> - * @bufmgr: libdrm buffer manager
> - *
> - * Initialize the aperture trasher using @bufmgr, which can then be run with
> - * igt_trash_aperture().
> - */
> -void igt_init_aperture_trashers(drm_intel_bufmgr *bufmgr)
> -{
> - int i;
> -
> - num_trash_bos = gem_mappable_aperture_size() / (1024*1024);
> -
> - trash_bos = malloc(num_trash_bos * sizeof(drm_intel_bo *));
> - igt_assert(trash_bos);
> -
> - for (i = 0; i < num_trash_bos; i++)
> - trash_bos[i] = drm_intel_bo_alloc(bufmgr, "trash bo", 
> 1024*1024, 4096);
> -}
> -
> -/**
> - * igt_trash_aperture:
> - *
> - * Trash the aperture by walking a set of GTT memory mapped objects.
> - */
> -void igt_trash_aperture(void)
> -{
> - int i;
> - uint8_t *gtt_ptr;
> -
> - for (i = 0; i < num_trash_bos; i++) {
> - drm_intel_gem_bo_map_gtt(trash_bos[i]);
> - gtt_ptr = trash_bos[i]->virtual;
> - *gtt_ptr = 0;
> - drm_intel_gem_bo_unmap_gtt(trash_bos[i]);
> - }
> -}
> -
> -/**
> - * igt_cleanup_aperture_trashers:
> - *
> - * Clean up all aperture trasher state set up with 
> igt_init_aperture_trashers().
> - */
> -void igt_cleanup_aperture_trashers(void)
> -{
> - int i;
> -
> - for (i = 0; i < num_trash_bos; i++)
> - drm_intel_bo_unreference(trash_bos[i]);
> -
> - free(trash_bos);
> -}
> -
>  static int autoresume_delay;
>  
>  static const char *suspend_state_name[] = {
> diff --git a/lib/igt_aux.h b/lib/igt_aux.h
> index 639a90778..ef89faa9b 100644
> --- a/lib/igt_aux.h
> +++ b/lib/igt_aux.h
> @@ -28,16 +28,13 @@
>  #ifndef IGT_AUX_H
>  #define IGT_AUX_H
>  
> -#include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include 
>  
> -extern drm_intel_bo **trash_bos;
> -extern int num_trash_bos;
> -
>  /* signal interrupt helpers */
>  #define gettid() syscall(__NR_gettid)
>  #define sigev_notify_thread_id _sigev_un._tid
> @@ -122,11 +119,6 @@ bool igt_check_boolean_env_var(const char *env_var, bool 
> default_value);
>  
>  bool igt_aub_dump_enabled(void);
>  
> -/* helpers based upon the libdrm buffer manager */
> -void igt_init_aperture_trashers(drm_intel_bufmgr *bufmgr);
> -void igt_trash_aperture(void);
> -void igt_cleanup_aperture_trashers(void);
> -
>  /* suspend/hibernate and auto-resume system */
>  
>  /**
> diff --git a/tests/pm_rpm.c b/tests/pm_rpm.c
> index 1f2647be1..4268bb19a 100644
> --- a/tests/pm_rpm.c
> +++ b/tests/pm_rpm.c
> @@ -1295,25 +1295,36 @@ static void gem_idle_subtest(void)
>  
>  static void gem_evict_pwrite_subtest(void)
>  {
> - static drm_intel_bufmgr *bufmgr;
> + struct {
> + uint32_t handle;
> + uint32_t *ptr;
> + } *trash_bos;
> + unsigned int num_trash_bos, n;
>   uint32_t buf;
> - int i;
>  
> - bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
> - igt_assert(bufmgr);
> - igt_init_aperture_trashers(bufmgr);
> + num_trash_bos = gem_mappable_aperture_size() / (1024*1024) + 1;
> + trash_bos = malloc(num_trash_bos * sizeof(*trash_bos));
> + igt_assert(trash_bos);
>  
> - igt_trash_aperture();
> + for (n = 0; n < num_trash_bos; n++) {
> + trash_bos[n].handle = gem_create(drm_fd, 1024*1024);
> + trash_bos[n].ptr = gem_mmap__gtt(drm_fd, trash_bos[n].handle,
> +  1024*1024, PROT_WRITE);
> + *trash_bos[n].ptr = 0;
> + }
>  
>

Re: [Intel-gfx] [PATCH] drm/i915/guc: Keep guc submission permanently engaged

2018-07-19 Thread Michał Winiarski
On Tue, Jul 17, 2018 at 09:29:32PM +0100, Chris Wilson wrote:
> We make a decision at module load whether to use the GuC backend or not,
> but lose that setup across set-wedge. Currently, the guc doesn't
> override the engine->set_default_submission hook letting execlists sneak
> back in temporarily on unwedging leading to an unbalanced park/unpark.
> 
> v2: Remove comment about switching back temporarily to execlists on
> guc_submission_disable(). We currently only call disable on shutdown,
> and plan to also call disable before suspend and reset, in which case we
> will either restore guc submission or mark the driver as wedged, making
> the reset back to execlists pointless.
> v3: Move reset.prepare across
> 
> Testcase: igt/drv_module_reload/basic-reload-inject
> Testcase: igt/gem_eio
> Signed-off-by: Chris Wilson 
> Cc: Michał Winiarski 
> Cc: Michal Wajdeczko 

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  drivers/gpu/drm/i915/intel_guc_submission.c | 41 ++---
>  drivers/gpu/drm/i915/intel_lrc.c|  4 +-
>  drivers/gpu/drm/i915/intel_lrc.h|  2 +
>  3 files changed, 31 insertions(+), 16 deletions(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [igt-dev] [PATCH i-g-t] igt: Force eviction of test bo directly

2018-07-18 Thread Michał Winiarski
On Fri, Jul 13, 2018 at 10:54:40AM +0100, Chris Wilson wrote:
> Currently we indirectly try to evict the test buffers by mmaping enough
> bo that should fill the aperture. However, this assumes that the kernel
> is trying to fill the aperture and does not use random replacement
> (which it does) or use small partials to avoid mmaping the whole object
> (which it does). Rather than assume, use the debugfs interface to force
> the eviction of the bound objects.
> 
> Signed-off-by: Chris Wilson 

Reviewed-by: Michał Winiarski 

-Michał

> ---
>  tests/gem_caching.c| 9 +
>  tests/gem_partial_pwrite_pread.c   | 9 +
>  tests/gem_tiled_partial_pwrite_pread.c | 9 +
>  3 files changed, 3 insertions(+), 24 deletions(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/2] drm/i915: Stop lying about the WOPCM size

2018-07-17 Thread Michał Winiarski
On Tue, Jul 17, 2018 at 03:52:41PM +0200, Michał Winiarski wrote:
> On Tue, Jul 17, 2018 at 03:53:19PM +0300, Ville Syrjala wrote:
> > From: Ville Syrjälä 
> > 
> > Most plattforms don't have a fixed 1MiB WOPCM so stop saying that they
> > do.
> > 
> > Also toss in a FIXME about actually using the WOPCM size we probed from
> > the hardware instead of assuming the fixed 1MiB size.
> > 
> > Cc: Jackie Li 
> > Signed-off-by: Ville Syrjälä 
> > ---
> >  drivers/gpu/drm/i915/intel_wopcm.c | 9 -
> >  1 file changed, 8 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_wopcm.c 
> > b/drivers/gpu/drm/i915/intel_wopcm.c
> > index 74bf76f3fddc..75c7a2b0c869 100644
> > --- a/drivers/gpu/drm/i915/intel_wopcm.c
> > +++ b/drivers/gpu/drm/i915/intel_wopcm.c
> > @@ -71,6 +71,12 @@
> >   */
> >  void intel_wopcm_init_early(struct intel_wopcm *wopcm)
> >  {
> > +   struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
> > +
> > +   if (!HAS_GUC(i915))
> > +   return;
> 
> Single use dev_priv, drop the local?
> 
> > +
> > +   /* FIXME use the size we actually probed from the hardware */
> > wopcm->size = GEN9_WOPCM_SIZE;
> 
> I don't think that's exposed to us in any way.
> I'd drop the FIXME - with that:

Ok - I was wrong, keep the fixme.

> 
> Reviewed-by: Michał Winiarski 
> 
> -Michał
> 
> >  
> > DRM_DEBUG_DRIVER("WOPCM size: %uKiB\n", wopcm->size / 1024);
> > @@ -163,7 +169,8 @@ int intel_wopcm_init(struct intel_wopcm *wopcm)
> > u32 guc_wopcm_rsvd;
> > int err;
> >  
> > -   GEM_BUG_ON(!wopcm->size);
> > +   if (!wopcm->size)
> > +   return 0;

But I'd also go with HAS_GUC and keep the BUG_ON as Michał suggested.

-Michał

> >  
> > if (guc_fw_size >= wopcm->size) {
> > DRM_ERROR("GuC FW (%uKiB) is too big to fit in WOPCM.",
> > -- 
> > 2.16.4
> > 
> > ___
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/2] drm/i915: Stop lying about the WOPCM size

2018-07-17 Thread Michał Winiarski
On Tue, Jul 17, 2018 at 03:53:19PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Most plattforms don't have a fixed 1MiB WOPCM so stop saying that they
> do.
> 
> Also toss in a FIXME about actually using the WOPCM size we probed from
> the hardware instead of assuming the fixed 1MiB size.
> 
> Cc: Jackie Li 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_wopcm.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_wopcm.c 
> b/drivers/gpu/drm/i915/intel_wopcm.c
> index 74bf76f3fddc..75c7a2b0c869 100644
> --- a/drivers/gpu/drm/i915/intel_wopcm.c
> +++ b/drivers/gpu/drm/i915/intel_wopcm.c
> @@ -71,6 +71,12 @@
>   */
>  void intel_wopcm_init_early(struct intel_wopcm *wopcm)
>  {
> + struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
> +
> + if (!HAS_GUC(i915))
> + return;

Single use dev_priv, drop the local?

> +
> + /* FIXME use the size we actually probed from the hardware */
>   wopcm->size = GEN9_WOPCM_SIZE;

I don't think that's exposed to us in any way.
I'd drop the FIXME - with that:

Reviewed-by: Michał Winiarski 

-Michał

>  
>   DRM_DEBUG_DRIVER("WOPCM size: %uKiB\n", wopcm->size / 1024);
> @@ -163,7 +169,8 @@ int intel_wopcm_init(struct intel_wopcm *wopcm)
>   u32 guc_wopcm_rsvd;
>   int err;
>  
> - GEM_BUG_ON(!wopcm->size);
> + if (!wopcm->size)
> + return 0;
>  
>   if (guc_fw_size >= wopcm->size) {
>   DRM_ERROR("GuC FW (%uKiB) is too big to fit in WOPCM.",
> -- 
> 2.16.4
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915/kvmgt: Fix compilation error

2018-07-12 Thread Michał Winiarski
gvt_pin_guest_page extracted some of the gvt_dma_map_page functionality:
commit 79e542f5af79 ("drm/i915/kvmgt: Support setting dma map for huge pages")

And yet, part of it was reintroduced in:
commit 39b4cbadb9a9 ("drm/i915/kvmgt: Check the pfn got from vfio_pin_pages")

Causing kvmgt part to no longer build. Let's remove it.

Reported-by: Tomasz Lis 
Signed-off-by: Michał Winiarski 
Cc: Changbin Du 
Cc: Zhenyu Wang 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 718ab307a500..4d2f53ae9f0f 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -185,12 +185,6 @@ static int gvt_dma_map_page(struct intel_vgpu *vgpu, 
unsigned long gfn,
if (ret)
return ret;
 
-   if (!pfn_valid(pfn)) {
-   gvt_vgpu_err("pfn 0x%lx is not mem backed\n", pfn);
-   vfio_unpin_pages(mdev_dev(vgpu->vdev.mdev), , 1);
-   return -EINVAL;
-   }
-
/* Setup DMA mapping. */
*dma_addr = dma_map_page(dev, page, 0, size, PCI_DMA_BIDIRECTIONAL);
ret = dma_mapping_error(dev, *dma_addr);
-- 
2.17.1

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


  1   2   3   4   5   6   7   >