[Intel-gfx] [PATCH 136/190] drm/i915: Move ioremap_wc tracking onto VMA

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Thu Feb 11 13:20:46 UTC 2016



On 11/01/16 10:45, Chris Wilson wrote:
> By tracking the iomapping on the VMA itself, we can share that area
> between multiple users. Also by only revoking the iomapping upon
> unbinding from the mappable portion of the GGTT, we can keep that iomap
> across multiple invocations (e.g. execlists context pinning).

Between the lines and from some IRC discussion it seems the goal of this 
is to fix an address space memory leak with fbcon?

But I don't know fbdev so can't find who would do the unpin on the VMA 
to allow unbind to eventually unmap it?

Regards,

Tvrtko

> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_gem.c     |  5 +++++
>   drivers/gpu/drm/i915/i915_gem_gtt.c | 33 +++++++++++++++++++++++++++++++++
>   drivers/gpu/drm/i915/i915_gem_gtt.h |  4 ++++
>   drivers/gpu/drm/i915/intel_fbdev.c  |  8 +++-----
>   4 files changed, 45 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 0c4e8e1aeeff..5bb21b20c36a 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2699,6 +2699,11 @@ int i915_vma_unbind(struct i915_vma *vma)
>   		if (ret)
>   			return ret;
>
> +		if (vma->iomap) {
> +			iounmap(vma->iomap);
> +			vma->iomap = NULL;
> +		}
> +
>   		vma->map_and_fenceable = false;
>   	}
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index b8af904ad12c..3fcf2fd73453 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3575,3 +3575,36 @@ int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
>
>   	return 0;
>   }
> +
> +void *i915_vma_iomap(struct drm_i915_private *dev_priv,
> +		     struct i915_vma *vma)
> +{
> +	if (WARN_ON(!vma->map_and_fenceable))
> +		return ERR_PTR(-ENODEV);
> +
> +	GEM_BUG_ON(!vma->is_ggtt);
> +	GEM_BUG_ON((vma->bound & GLOBAL_BIND) == 0);
> +
> +	if (vma->iomap == NULL) {
> +		u32 base = dev_priv->gtt.mappable_base + vma->node.start;
> +		void *ptr;
> +
> +		ptr = ioremap_wc(base, vma->size);
> +		if (ptr == NULL) {
> +			int ret;
> +
> +			/* Too many areas already allocated? */
> +			ret = i915_gem_evict_vm(vma->vm, true);
> +			if (ret)
> +				return ERR_PTR(ret);
> +
> +			ptr = ioremap_wc(base, vma->size);
> +			if (ptr == NULL)
> +				return ERR_PTR(-ENOMEM);
> +		}
> +
> +		vma->iomap = ptr;
> +	}
> +
> +	return vma->iomap;
> +}
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index 6b0f557982d5..0e0570e13a68 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -181,6 +181,7 @@ struct i915_vma {
>   	struct drm_mm_node node;
>   	struct drm_i915_gem_object *obj;
>   	struct i915_address_space *vm;
> +	void *iomap;
>   	u64 size;
>
>   	struct i915_gem_active last_read[I915_NUM_RINGS];
> @@ -579,4 +580,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev);
>
>   int __must_check i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj);
>   void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj);
> +
> +void *i915_vma_iomap(struct drm_i915_private *dev_priv,
> +		     struct i915_vma *vma);
>   #endif
> diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
> index 7decbca25dbb..8e7c341951fd 100644
> --- a/drivers/gpu/drm/i915/intel_fbdev.c
> +++ b/drivers/gpu/drm/i915/intel_fbdev.c
> @@ -248,12 +248,10 @@ static int intelfb_create(struct drm_fb_helper *helper,
>   	info->fix.smem_start = dev->mode_config.fb_base + vma->node.start;
>   	info->fix.smem_len = vma->node.size;
>
> -	info->screen_base =
> -		ioremap_wc(dev_priv->gtt.mappable_base + vma->node.start,
> -			   vma->node.size);
> -	if (!info->screen_base) {
> +	info->screen_base = i915_vma_iomap(dev_priv, vma);
> +	if (IS_ERR(info->screen_base)) {
>   		DRM_ERROR("Failed to remap framebuffer into virtual memory\n");
> -		ret = -ENOSPC;
> +		ret = PTR_ERR(info->screen_base);
>   		goto out_destroy_fbi;
>   	}
>   	info->screen_size = vma->node.size;
>


More information about the Intel-gfx mailing list