[Intel-gfx] [PATCH] drm/i915: Disable kmem_caches when KASAN is enabled

Mika Kuoppala mika.kuoppala at linux.intel.com
Wed Mar 15 09:46:24 UTC 2017


Chris Wilson <chris at chris-wilson.co.uk> writes:

> kasan is very good at detecting use-after-free. However, our requests
> are allocated from a rcu-typesafe slab that is important for performance
> but makes kasan less effective. When enabling kasan we are intentionally
> looking for memory errors, disable the use of our caches to improve the
> likelihood of kasan spotting a bug.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/Kconfig.debug      | 13 +++++++++++++
>  drivers/gpu/drm/i915/i915_gem.c         | 11 +++++++++--
>  drivers/gpu/drm/i915/i915_gem_request.c | 25 ++++++++++++++++++++-----
>  drivers/gpu/drm/i915/i915_vma.c         | 15 ++++++++++++---
>  4 files changed, 54 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug
> index e091809a9a9e..bd8e90e4dfb9 100644
> --- a/drivers/gpu/drm/i915/Kconfig.debug
> +++ b/drivers/gpu/drm/i915/Kconfig.debug
> @@ -48,6 +48,19 @@ config DRM_I915_DEBUG_GEM
>  
>            If in doubt, say "N".
>  
> +config DRM_I915_DEBUG_KASAN
> +        bool "Insert extra checks when using KASAN"
> +        default n
> +        depends on DRM_I915_WERROR
> +        depends on KASAN
> +        help
> +	  Turns off use of kmem_caches to improve KASAN error detection,
> +          and inserts extra santiy checks.

s/santiy/sanity.

Would i915.kmem_cache=0/1 be too costly?

The name could also be DEBUG_NO_KMEM_CACHE
-Mika

> +
> +          Recommended for driver developers only.
> +
> +          If in doubt, say "N".
> +
>  config DRM_I915_SW_FENCE_DEBUG_OBJECTS
>          bool "Enable additional driver debugging for fence objects"
>          depends on DRM_I915
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 202bb850f260..0195468531f7 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -639,13 +639,20 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
>  
>  void *i915_gem_object_alloc(struct drm_i915_private *dev_priv)
>  {
> -	return kmem_cache_zalloc(dev_priv->objects, GFP_KERNEL);
> +	if (IS_ENABLED(CONFIG_DRM_I915_KASAN))
> +		return kzalloc(kmem_cache_size(dev_priv->objects), GFP_KERNEL);
> +	else
> +		return kmem_cache_zalloc(dev_priv->objects, GFP_KERNEL);
>  }
>  
>  void i915_gem_object_free(struct drm_i915_gem_object *obj)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
> -	kmem_cache_free(dev_priv->objects, obj);
> +
> +	if (IS_ENABLED(CONFIG_DRM_I915_KASAN))
> +		kfree(obj);
> +	else
> +		kmem_cache_free(dev_priv->objects, obj);
>  }
>  
>  static int
> diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
> index 1e1d9f2072cd..715760aa5aa1 100644
> --- a/drivers/gpu/drm/i915/i915_gem_request.c
> +++ b/drivers/gpu/drm/i915/i915_gem_request.c
> @@ -73,7 +73,10 @@ static void i915_fence_release(struct dma_fence *fence)
>  	 */
>  	i915_sw_fence_fini(&req->submit);
>  
> -	kmem_cache_free(req->i915->requests, req);
> +	if (IS_ENABLED(CONFIG_KASAN))
> +		dma_fence_free(fence);
> +	else
> +		kmem_cache_free(req->i915->requests, req);
>  }
>  
>  const struct dma_fence_ops i915_fence_ops = {
> @@ -105,14 +108,20 @@ i915_gem_request_remove_from_client(struct drm_i915_gem_request *request)
>  static struct i915_dependency *
>  i915_dependency_alloc(struct drm_i915_private *i915)
>  {
> -	return kmem_cache_alloc(i915->dependencies, GFP_KERNEL);
> +	if (IS_ENABLED(CONFIG_DRM_I915_KASAN))
> +		return kmalloc(kmem_cache_size(i915->dependencies), GFP_KERNEL);
> +	else
> +		return kmem_cache_alloc(i915->dependencies, GFP_KERNEL);
>  }
>  
>  static void
>  i915_dependency_free(struct drm_i915_private *i915,
>  		     struct i915_dependency *dep)
>  {
> -	kmem_cache_free(i915->dependencies, dep);
> +	if (IS_ENABLED(CONFIG_DRM_I915_KASAN))
> +		kfree(dep);
> +	else
> +		kmem_cache_free(i915->dependencies, dep);
>  }
>  
>  static void
> @@ -571,7 +580,10 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
>  	 *
>  	 * Do not use kmem_cache_zalloc() here!
>  	 */
> -	req = kmem_cache_alloc(dev_priv->requests, GFP_KERNEL);
> +	if (IS_ENABLED(CONFIG_DRM_I915_KASAN))
> +		req = kmalloc(sizeof(*req), GFP_KERNEL);
> +	else
> +		req = kmem_cache_alloc(dev_priv->requests, GFP_KERNEL);
>  	if (!req) {
>  		ret = -ENOMEM;
>  		goto err_unreserve;
> @@ -634,7 +646,10 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
>  	GEM_BUG_ON(!list_empty(&req->priotree.signalers_list));
>  	GEM_BUG_ON(!list_empty(&req->priotree.waiters_list));
>  
> -	kmem_cache_free(dev_priv->requests, req);
> +	if (IS_ENABLED(CONFIG_DRM_I915_KASAN))
> +		kfree(req);
> +	else
> +		kmem_cache_free(dev_priv->requests, req);
>  err_unreserve:
>  	unreserve_seqno(engine);
>  err_unpin:
> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> index 1aba47024656..684d529f6b91 100644
> --- a/drivers/gpu/drm/i915/i915_vma.c
> +++ b/drivers/gpu/drm/i915/i915_vma.c
> @@ -81,7 +81,10 @@ vma_create(struct drm_i915_gem_object *obj,
>  	/* The aliasing_ppgtt should never be used directly! */
>  	GEM_BUG_ON(vm == &vm->i915->mm.aliasing_ppgtt->base);
>  
> -	vma = kmem_cache_zalloc(vm->i915->vmas, GFP_KERNEL);
> +	if (IS_ENABLED(CONFIG_DRM_I915_KASAN))
> +		vma = kzalloc(kmem_cache_size(vm->i915->vmas), GFP_KERNEL);
> +	else
> +		vma = kmem_cache_zalloc(vm->i915->vmas, GFP_KERNEL);
>  	if (vma == NULL)
>  		return ERR_PTR(-ENOMEM);
>  
> @@ -159,7 +162,10 @@ vma_create(struct drm_i915_gem_object *obj,
>  	return vma;
>  
>  err_vma:
> -	kmem_cache_free(vm->i915->vmas, vma);
> +	if (IS_ENABLED(CONFIG_DRM_I915_KASAN))
> +		kfree(vma);
> +	else
> +		kmem_cache_free(vm->i915->vmas, vma);
>  	return ERR_PTR(-E2BIG);
>  }
>  
> @@ -588,7 +594,10 @@ void i915_vma_destroy(struct i915_vma *vma)
>  	if (!i915_vma_is_ggtt(vma))
>  		i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
>  
> -	kmem_cache_free(to_i915(vma->obj->base.dev)->vmas, vma);
> +	if (IS_ENABLED(CONFIG_DRM_I915_KASAN))
> +		kfree(vma);
> +	else
> +		kmem_cache_free(to_i915(vma->obj->base.dev)->vmas, vma);
>  }
>  
>  void i915_vma_close(struct i915_vma *vma)
> -- 
> 2.11.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


More information about the Intel-gfx mailing list