[Intel-gfx] [PATCH 06/66] drm/i915: Conditionally use guard page based on PPGTT

Jesse Barnes jbarnes at virtuousgeek.org
Fri Jun 28 19:57:25 CEST 2013


On Thu, 27 Jun 2013 16:30:07 -0700
Ben Widawsky <ben at bwidawsk.net> wrote:

> The PPGTT PDEs serve as the guard page (as long as they remain at the
> top) so we don't need yet another guard page. Note that there is a
> potential issue if the aliasing PPGTT (and later, the default context)
> relinquish this part of the GGTT. We should be able to assert that won't
> happen however.
> 
> While there, add some comments for the setup_global_gtt function which
> started getting complicated.
> 
> The reason I've opted not to leave out the guard_page argument is that
> in order to support dri1, we call the setup function, and I didn't like
> to have to clear the guard page in more than 1 location.
> 
> Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
> ---
>  drivers/gpu/drm/i915/i915_drv.h     |  3 ++-
>  drivers/gpu/drm/i915/i915_gem.c     |  4 ++--
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 27 ++++++++++++++++++++++-----
>  3 files changed, 26 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index b709712..c677d6c 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1852,7 +1852,8 @@ void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj);
>  void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj);
>  void i915_gem_init_global_gtt(struct drm_device *dev);
>  void i915_gem_setup_global_gtt(struct drm_device *dev, unsigned long start,
> -			       unsigned long mappable_end, unsigned long end);
> +			       unsigned long mappable_end, unsigned long end,
> +			       unsigned long guard_size);
>  int i915_gem_gtt_init(struct drm_device *dev);
>  static inline void i915_gem_chipset_flush(struct drm_device *dev)
>  {
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 6806bb9..629e047 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -158,8 +158,8 @@ i915_gem_init_ioctl(struct drm_device *dev, void *data,
>  
>  	mutex_lock(&dev->struct_mutex);
>  	i915_gem_setup_global_gtt(dev, args->gtt_start, args->gtt_end,
> -				  args->gtt_end);
> -	dev_priv->gtt.mappable_end = args->gtt_end;
> +				  args->gtt_end, PAGE_SIZE);
> +	dev_priv->gtt.mappable_end = args->gtt_end - PAGE_SIZE;
>  	mutex_unlock(&dev->struct_mutex);
>  
>  	return 0;
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 0fce8d0..fb30d65 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -613,10 +613,23 @@ static void i915_gtt_color_adjust(struct drm_mm_node *node,
>  			*end -= 4096;
>  	}
>  }
> +
> +/**
> + * i915_gem_setup_global_gtt() setup an allocator for the global GTT with the
> + * given parameters and initialize all PTEs to point to the scratch page.
> + *
> + * @dev
> + * @start - first offset of managed GGTT space
> + * @mappable_end - Last offset of the aperture mapped region
> + * @end - Last offset that can be accessed by the allocator
> + * @guard_size - Size to initialize to scratch after end. (Currently only used
> + *		 for prefetching case)
> + */
>  void i915_gem_setup_global_gtt(struct drm_device *dev,
>  			       unsigned long start,
>  			       unsigned long mappable_end,
> -			       unsigned long end)
> +			       unsigned long end,
> +			       unsigned long guard_size)
>  {
>  	/* Let GEM Manage all of the aperture.
>  	 *
> @@ -634,8 +647,11 @@ void i915_gem_setup_global_gtt(struct drm_device *dev,
>  
>  	BUG_ON(mappable_end > end);
>  
> +	if (WARN_ON(guard_size & ~PAGE_MASK))
> +		guard_size = round_up(guard_size, PAGE_SIZE);
> +
>  	/* Subtract the guard page ... */
> -	drm_mm_init(&dev_priv->mm.gtt_space, start, end - start - PAGE_SIZE);
> +	drm_mm_init(&dev_priv->mm.gtt_space, start, end - start - guard_size);
>  	if (!HAS_LLC(dev))
>  		dev_priv->mm.gtt_space.color_adjust = i915_gtt_color_adjust;
>  
> @@ -665,7 +681,8 @@ void i915_gem_setup_global_gtt(struct drm_device *dev,
>  	}
>  
>  	/* And finally clear the reserved guard page */
> -	dev_priv->gtt.gtt_clear_range(dev, end / PAGE_SIZE - 1, 1);
> +	dev_priv->gtt.gtt_clear_range(dev, (end - guard_size) / PAGE_SIZE,
> +				      guard_size / PAGE_SIZE);
>  }
>  
>  static bool
> @@ -700,7 +717,7 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
>  			gtt_size -= GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE;
>  		}
>  
> -		i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size);
> +		i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size, 0);
>  
>  		ret = i915_gem_init_aliasing_ppgtt(dev);
>  		if (!ret)
> @@ -710,7 +727,7 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
>  		drm_mm_takedown(&dev_priv->mm.gtt_space);
>  		gtt_size += GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE;
>  	}
> -	i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size);
> +	i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size, PAGE_SIZE);
>  }
>  
>  static int setup_scratch_page(struct drm_device *dev)

Just a nitpick that can be changed with a follow on patch if others
agree: I'd rather see the WARN_ON made a BUG_ON when checking that the
guard_size is a multiple of PAGE_SIZE (which, incidentally, is the
wrong value to use, but that's also for another cleanup).

Reviewed-by: Jesse Barnes <jbarnes at virtuousgeek.org>

-- 
Jesse Barnes, Intel Open Source Technology Center



More information about the Intel-gfx mailing list