All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: intel-gfx@lists.freedesktop.org
Cc: Ben Widawsky <ben@bwidawsk.net>
Subject: Re: [PATCH 4/4] drm/i915: ILK + VT-d workaround
Date: Sat, 15 Oct 2011 23:09:28 +0100	[thread overview]
Message-ID: <d08817$1s0vfm@azsmga001.ch.intel.com> (raw)
In-Reply-To: <1318711636-30109-5-git-send-email-ben@bwidawsk.net>

On Sat, 15 Oct 2011 13:47:16 -0700, Ben Widawsky <ben@bwidawsk.net> wrote:
> Idle the GPU before doing any unmaps. We know if VT-d is in use through
> an exported variable from iommu code.
> 
> This should avoid a known HW issue.
> 
> Signed-off-by: Ben Widawsky <ben@bwidawsk.net>

Just one minor comment below, but
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>

> ---
>  drivers/char/agp/intel-gtt.c        |   28 ++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_drv.h     |    2 +-
>  drivers/gpu/drm/i915/i915_gem.c     |    4 +++-
>  drivers/gpu/drm/i915/i915_gem_gtt.c |   19 ++++++++++++++++++-
>  include/drm/intel-gtt.h             |    2 ++
>  5 files changed, 52 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
> index 8515101..80a7ed0 100644
> --- a/drivers/char/agp/intel-gtt.c
> +++ b/drivers/char/agp/intel-gtt.c
> @@ -923,6 +923,9 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
>  {
>  	int ret = -EINVAL;
>  
> +	if (intel_private.base.do_idle_maps)
> +		return -ENODEV;
> +
>  	if (intel_private.clear_fake_agp) {
>  		int start = intel_private.base.stolen_size / PAGE_SIZE;
>  		int end = intel_private.base.gtt_mappable_entries;
> @@ -985,6 +988,9 @@ static int intel_fake_agp_remove_entries(struct agp_memory *mem,
>  	if (mem->page_count == 0)
>  		return 0;
>  
> +	if (intel_private.base.do_idle_maps)
> +		return -ENODEV;
> +
>  	intel_gtt_clear_range(pg_start, mem->page_count);
>  
>  	if (intel_private.base.needs_dmar) {
> @@ -1177,6 +1183,25 @@ static void gen6_cleanup(void)
>  {
>  }
>  
> +/* Certain Gen5 chipsets require require idling the GPU before
> + * unmapping anything from the GTT when VT-d is enabled.
> + */
> +extern int intel_iommu_gfx_mapped;
> +static inline int needs_idle_maps(void)
> +{
> +	const unsigned short gpu_devid = intel_private.pcidev->device;
> +
> +	/* Query intel_iommu to see if we need the workaround. Presumably that
> +	 * was loaded first.
> +	 */
> +	if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB ||
> +	     gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
> +	     intel_iommu_gfx_mapped)
> +		return 1;
> +
> +	return 0;
> +}
> +
>  static int i9xx_setup(void)
>  {
>  	u32 reg_addr;
> @@ -1211,6 +1236,9 @@ static int i9xx_setup(void)
>  		intel_private.gtt_bus_addr = reg_addr + gtt_offset;
>  	}
>  
> +	if (needs_idle_maps());
> +		intel_private.base.do_idle_maps = 1;
> +
>  	intel_i9xx_setup_flush();
>  
>  	return 0;
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 15c0ca5..3aa8612 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1219,7 +1219,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev);
>  int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj);
>  void i915_gem_gtt_rebind_object(struct drm_i915_gem_object *obj,
>  				enum i915_cache_level cache_level);
> -void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj);
> +int i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj);

Make this a __must_check, if we forget to handle the error from unbind,
it will undoubtably lead to great confusion and an upset chip/kernel.
Admittedly today there is only callsite, but useful defence against
future callers making a mistake.
>  
>  /* i915_gem_evict.c */
>  int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size,
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index a925141..89d22eb 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2130,7 +2130,9 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
>  
>  	trace_i915_gem_object_unbind(obj);
>  
> -	i915_gem_gtt_unbind_object(obj);
> +	ret = i915_gem_gtt_unbind_object(obj);
> +	if (ret == -ERESTARTSYS)
> +		return ret;
>  	i915_gem_object_put_pages_gtt(obj);
>  
>  	list_del_init(&obj->gtt_list);
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 7a709cd..1df6395 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -49,6 +49,15 @@ static unsigned int cache_level_to_agp_type(struct drm_device *dev,
>  	}
>  }
>  
> +static bool do_idling(struct drm_i915_private *dev_priv)
> +{
> +	if (dev_priv->mm.gtt->do_idle_maps)
> +		if (i915_gpu_idle(dev_priv->dev))
> +			return false;
> +
> +	return true;
> +}
> +
>  void i915_gem_restore_gtt_mappings(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -115,8 +124,14 @@ void i915_gem_gtt_rebind_object(struct drm_i915_gem_object *obj,
>  				       agp_type);
>  }
>  
> -void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj)
> +int i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj)
>  {
> +	struct drm_device *dev = obj->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +	if (do_idling(dev_priv) == false)
> +		return -ERESTARTSYS;
> +
>  	intel_gtt_clear_range(obj->gtt_space->start >> PAGE_SHIFT,
>  			      obj->base.size >> PAGE_SHIFT);
>  
> @@ -124,4 +139,6 @@ void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj)
>  		intel_gtt_unmap_memory(obj->sg_list, obj->num_sg);
>  		obj->sg_list = NULL;
>  	}
> +
> +	return 0;
>  }
> diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h
> index 9e343c0..b174620 100644
> --- a/include/drm/intel-gtt.h
> +++ b/include/drm/intel-gtt.h
> @@ -13,6 +13,8 @@ const struct intel_gtt {
>  	unsigned int gtt_mappable_entries;
>  	/* Whether i915 needs to use the dmar apis or not. */
>  	unsigned int needs_dmar : 1;
> +	/* Whether we idle the gpu before mapping/unmapping */
> +	unsigned int do_idle_maps : 1;
>  } *intel_gtt_get(void);
>  
>  void intel_gtt_chipset_flush(void);
> -- 
> 1.7.7
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Chris Wilson, Intel Open Source Technology Centre

  parent reply	other threads:[~2011-10-15 22:09 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-15 20:47 [PATCH v4 0/4] ILK VT-d fix Ben Widawsky
2011-10-15 20:47 ` [PATCH 1/4] intel-iommu: Workaround IOTLB hang on Ironlake GPU Ben Widawsky
2011-10-15 20:47 ` [PATCH 2/4] intel-iommu: Export a flag indicating that the IOMMU is used for iGFX Ben Widawsky
2011-10-15 20:47 ` [PATCH 3/4] drm/i915: Remove early exit on i915_gpu_idle Ben Widawsky
2011-10-15 20:59   ` Daniel Vetter
2011-10-15 22:10   ` Chris Wilson
2011-10-15 20:47 ` [PATCH 4/4] drm/i915: ILK + VT-d workaround Ben Widawsky
2011-10-15 21:15   ` Daniel Vetter
2011-10-15 22:09   ` Chris Wilson [this message]
     [not found] ` <1319443974.13738.85.camel@shinybook.infradead.org>
2011-10-24 15:37   ` [PATCH v4 0/4] ILK VT-d fix Keith Packard
  -- strict thread matches above, loose matches on Subject: below --
2011-10-17 22:51 [PATCH 0/4] v5: ILK vt-d fix, more like v3 now Ben Widawsky
2011-10-17 22:51 ` [PATCH 4/4] drm/i915: ILK + VT-d workaround Ben Widawsky
2011-10-18  7:24   ` Paul Menzel
2011-10-18 15:06     ` Ben Widawsky
2011-10-18  7:35   ` Daniel Vetter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='d08817$1s0vfm@azsmga001.ch.intel.com' \
    --to=chris@chris-wilson.co.uk \
    --cc=ben@bwidawsk.net \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.