[Intel-gfx] [PATCH 3/6] drm/i915: Propagating correct error codes to the userspace
Chris Wilson
chris at chris-wilson.co.uk
Thu Oct 8 03:49:48 PDT 2015
On Thu, Oct 08, 2015 at 11:54:26AM +0530, ankitprasad.r.sharma at intel.com wrote:
> From: Ankitprasad Sharma <ankitprasad.r.sharma at intel.com>
>
> Propagating correct error codes to userspace by using ERR_PTR and
> PTR_ERR macros for stolen memory based object allocation. We generally
> return -ENOMEM to the user whenever there is a failure in object
> allocation. This patch helps user to identify the correct reason for the
> failure and not just -ENOMEM each time.
>
> v2: Moved the patch up in the series, added error propagation for
> i915_gem_alloc_object too (Chris)
>
> Signed-off-by: Ankitprasad Sharma <ankitprasad.r.sharma at intel.com>
> ---
> drivers/gpu/drm/i915/i915_gem.c | 15 +++++-----
> drivers/gpu/drm/i915/i915_gem_batch_pool.c | 4 +--
> drivers/gpu/drm/i915/i915_gem_context.c | 4 +--
> drivers/gpu/drm/i915/i915_gem_render_state.c | 4 +--
> drivers/gpu/drm/i915/i915_gem_stolen.c | 43 ++++++++++++++++------------
> drivers/gpu/drm/i915/i915_guc_submission.c | 4 +--
> drivers/gpu/drm/i915/intel_display.c | 2 +-
> drivers/gpu/drm/i915/intel_fbdev.c | 6 ++--
> drivers/gpu/drm/i915/intel_lrc.c | 8 +++---
> drivers/gpu/drm/i915/intel_overlay.c | 4 +--
> drivers/gpu/drm/i915/intel_pm.c | 2 +-
> drivers/gpu/drm/i915/intel_ringbuffer.c | 20 ++++++-------
> 12 files changed, 61 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index d3f4321..54f7df1 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -4273,14 +4273,15 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
> struct drm_i915_gem_object *obj;
> struct address_space *mapping;
> gfp_t mask;
> + int ret = 0;
Pointless initialisation.
>
> obj = i915_gem_object_alloc(dev);
> if (obj == NULL)
> - return NULL;
> + return ERR_PTR(-ENOMEM);
>
> - if (drm_gem_object_init(dev, &obj->base, size) != 0) {
> + if ((ret = drm_gem_object_init(dev, &obj->base, size)) != 0) {
> i915_gem_object_free(obj);
> - return NULL;
> + return ERR_PTR(ret);
> }
>
> mask = GFP_HIGHUSER | __GFP_RECLAIMABLE;
> diff --git a/drivers/gpu/drm/i915/i915_gem_batch_pool.c b/drivers/gpu/drm/i915/i915_gem_batch_pool.c
> index 7bf2f3f..d79caa2 100644
> --- a/drivers/gpu/drm/i915/i915_gem_batch_pool.c
> +++ b/drivers/gpu/drm/i915/i915_gem_batch_pool.c
> @@ -135,8 +135,8 @@ i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool,
> int ret;
>
> obj = i915_gem_alloc_object(pool->dev, size);
> - if (obj == NULL)
> - return ERR_PTR(-ENOMEM);
> + if (IS_ERR(obj))
> + return obj;
>
> ret = i915_gem_object_get_pages(obj);
> if (ret)
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index 74aa0c9..603600c 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -157,8 +157,8 @@ i915_gem_alloc_context_obj(struct drm_device *dev, size_t size)
> int ret;
>
> obj = i915_gem_alloc_object(dev, size);
> - if (obj == NULL)
> - return ERR_PTR(-ENOMEM);
> + if (IS_ERR(obj))
> + return obj;
>
> /*
> * Try to make the context utilize L3 as well as LLC.
> diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
> index 5026a62..50d010e 100644
> --- a/drivers/gpu/drm/i915/i915_gem_render_state.c
> +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
> @@ -58,8 +58,8 @@ static int render_state_init(struct render_state *so, struct drm_device *dev)
> return -EINVAL;
>
> so->obj = i915_gem_alloc_object(dev, 4096);
> - if (so->obj == NULL)
> - return -ENOMEM;
> + if (IS_ERR(so->obj))
> + return PTR_ERR(so->obj);
>
> ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0);
> if (ret)
> diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
> index 5ec2190..d3e6813 100644
> --- a/drivers/gpu/drm/i915/i915_gem_stolen.c
> +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
> @@ -406,6 +406,7 @@ i915_pages_create_for_stolen(struct drm_device *dev,
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct sg_table *st;
> struct scatterlist *sg;
> + int ret;
>
> DRM_DEBUG_DRIVER("offset=0x%x, size=%d\n", offset, size);
> BUG_ON(offset > dev_priv->gtt.stolen_size - size);
> @@ -417,11 +418,12 @@ i915_pages_create_for_stolen(struct drm_device *dev,
>
> st = kmalloc(sizeof(*st), GFP_KERNEL);
> if (st == NULL)
> - return NULL;
> + return ERR_PTR(-ENOMEM);
>
> - if (sg_alloc_table(st, 1, GFP_KERNEL)) {
> + ret = sg_alloc_table(st, 1, GFP_KERNEL);
> + if (ret) {
> kfree(st);
> - return NULL;
> + return ERR_PTR(ret);
> }
>
> sg = st->sgl;
> @@ -470,18 +472,21 @@ _i915_gem_object_create_stolen(struct drm_device *dev,
> struct drm_mm_node *stolen)
> {
> struct drm_i915_gem_object *obj;
> + int ret = 0;
>
> obj = i915_gem_object_alloc(dev);
> if (obj == NULL)
> - return NULL;
> + return ERR_PTR(-ENOMEM);
>
> drm_gem_private_object_init(dev, &obj->base, stolen->size);
> i915_gem_object_init(obj, &i915_gem_object_stolen_ops);
>
> obj->pages = i915_pages_create_for_stolen(dev,
> stolen->start, stolen->size);
> - if (obj->pages == NULL)
> + if (IS_ERR(obj->pages)) {
> + ret = PTR_ERR(obj->pages);
> goto cleanup;
> + }
>
> i915_gem_object_pin_pages(obj);
> obj->stolen = stolen;
> @@ -493,7 +498,7 @@ _i915_gem_object_create_stolen(struct drm_device *dev,
>
> cleanup:
> i915_gem_object_free(obj);
> - return NULL;
> + return ERR_PTR(ret);
> }
>
> struct drm_i915_gem_object *
> @@ -505,29 +510,29 @@ i915_gem_object_create_stolen(struct drm_device *dev, u64 size)
> int ret;
>
> if (!drm_mm_initialized(&dev_priv->mm.stolen))
> - return NULL;
> + return ERR_PTR(-ENODEV);
>
> DRM_DEBUG_KMS("creating stolen object: size=%llx\n", size);
> if (size == 0)
> - return NULL;
> + return ERR_PTR(-EINVAL);
>
> stolen = kzalloc(sizeof(*stolen), GFP_KERNEL);
> if (!stolen)
> - return NULL;
> + return ERR_PTR(-ENOMEM);
>
> ret = i915_gem_stolen_insert_node(dev_priv, stolen, size, 4096);
> if (ret) {
> kfree(stolen);
> - return NULL;
> + return ERR_PTR(ret);
> }
>
> obj = _i915_gem_object_create_stolen(dev, stolen);
> - if (obj)
> + if (!IS_ERR(obj))
> return obj;
>
> i915_gem_stolen_remove_node(dev_priv, stolen);
> kfree(stolen);
> - return NULL;
> + return obj;
> }
>
> struct drm_i915_gem_object *
> @@ -544,7 +549,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
> int ret;
>
> if (!drm_mm_initialized(&dev_priv->mm.stolen))
> - return NULL;
> + return ERR_PTR(-ENODEV);
>
> DRM_DEBUG_KMS("creating preallocated stolen object: stolen_offset=%x, gtt_offset=%x, size=%x\n",
> stolen_offset, gtt_offset, size);
> @@ -552,11 +557,11 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
> /* KISS and expect everything to be page-aligned */
> if (WARN_ON(size == 0) || WARN_ON(size & 4095) ||
> WARN_ON(stolen_offset & 4095))
> - return NULL;
> + return ERR_PTR(-EINVAL);
>
> stolen = kzalloc(sizeof(*stolen), GFP_KERNEL);
> if (!stolen)
> - return NULL;
> + return ERR_PTR(-ENOMEM);
>
> stolen->start = stolen_offset;
> stolen->size = size;
> @@ -566,15 +571,15 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
> if (ret) {
> DRM_DEBUG_KMS("failed to allocate stolen space\n");
> kfree(stolen);
> - return NULL;
> + return ERR_PTR(ret);
> }
>
> obj = _i915_gem_object_create_stolen(dev, stolen);
> - if (obj == NULL) {
> + if (IS_ERR(obj)) {
> DRM_DEBUG_KMS("failed to allocate stolen object\n");
> i915_gem_stolen_remove_node(dev_priv, stolen);
> kfree(stolen);
> - return NULL;
> + return obj;
> }
>
> /* Some objects just need physical mem from stolen space */
> @@ -612,5 +617,5 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
>
> err:
> drm_gem_object_unreference(&obj->base);
> - return NULL;
> + return ERR_PTR(ret);
> }
> diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
> index 792d0b9..3901698 100644
> --- a/drivers/gpu/drm/i915/i915_guc_submission.c
> +++ b/drivers/gpu/drm/i915/i915_guc_submission.c
> @@ -646,8 +646,8 @@ static struct drm_i915_gem_object *gem_allocate_guc_obj(struct drm_device *dev,
> struct drm_i915_gem_object *obj;
>
> obj = i915_gem_alloc_object(dev, size);
> - if (!obj)
> - return NULL;
> + if (IS_ERR(obj))
> + return obj;
Did you check the caller?
>
> if (i915_gem_object_get_pages(obj)) {
> drm_gem_object_unreference(&obj->base);
New error code return here.
The call to get_pages() is redundant anyway.
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 1847257..d08989a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2514,7 +2514,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
> base_aligned,
> base_aligned,
> size_aligned);
> - if (!obj)
> + if (IS_ERR(obj))
> return false;
>
> obj->tiling_mode = plane_config->tiling;
> diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
> index 6532912..67de958 100644
> --- a/drivers/gpu/drm/i915/intel_fbdev.c
> +++ b/drivers/gpu/drm/i915/intel_fbdev.c
> @@ -140,11 +140,11 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
> size = mode_cmd.pitches[0] * mode_cmd.height;
> size = PAGE_ALIGN(size);
> obj = i915_gem_object_create_stolen(dev, size);
> - if (obj == NULL)
> + if (IS_ERR(obj))
> obj = i915_gem_alloc_object(dev, size);
> - if (!obj) {
> + if (IS_ERR(obj)) {
> DRM_ERROR("failed to allocate framebuffer\n");
> - ret = -ENOMEM;
> + ret = PTR_ERR(obj);
> goto out;
> }
>
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 256167b..d9bd9a1 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -1377,9 +1377,9 @@ static int lrc_setup_wa_ctx_obj(struct intel_engine_cs *ring, u32 size)
> int ret;
>
> ring->wa_ctx.obj = i915_gem_alloc_object(ring->dev, PAGE_ALIGN(size));
> - if (!ring->wa_ctx.obj) {
> + if (IS_ERR(ring->wa_ctx.obj)) {
> DRM_DEBUG_DRIVER("alloc LRC WA ctx backing obj failed.\n");
> - return -ENOMEM;
> + return PTR_ERR(ring->wa_ctx.obj);
Safer not to store error objects inside structs - we have a habit of
using drm_gem_object_unreference() which will then explode.
> }
>
> ret = i915_gem_obj_ggtt_pin(ring->wa_ctx.obj, PAGE_SIZE, 0);
> @@ -2459,9 +2459,9 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx,
> context_size += PAGE_SIZE * LRC_PPHWSP_PN;
>
> ctx_obj = i915_gem_alloc_object(dev, context_size);
> - if (!ctx_obj) {
> + if (IS_ERR(ctx_obj)) {
> DRM_DEBUG_DRIVER("Alloc LRC backing obj failed.\n");
> - return -ENOMEM;
> + return PTR_ERR(ctx_obj);
> }
>
> ringbuf = intel_engine_create_ringbuffer(ring, 4 * PAGE_SIZE);
> diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
> index 4445426..bfb95a2 100644
> --- a/drivers/gpu/drm/i915/intel_overlay.c
> +++ b/drivers/gpu/drm/i915/intel_overlay.c
> @@ -1392,9 +1392,9 @@ void intel_setup_overlay(struct drm_device *dev)
> reg_bo = NULL;
> if (!OVERLAY_NEEDS_PHYSICAL(dev))
> reg_bo = i915_gem_object_create_stolen(dev, PAGE_SIZE);
> - if (reg_bo == NULL)
> + if (IS_ERR_OR_NULL(reg_bo))
> reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
> - if (reg_bo == NULL)
> + if (IS_ERR(reg_bo))
> goto out_free;
> overlay->reg_bo = reg_bo;
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index ab5ac5e..0d35d7f 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5387,7 +5387,7 @@ static void valleyview_setup_pctx(struct drm_device *dev)
> * memory, or any other relevant ranges.
> */
> pctx = i915_gem_object_create_stolen(dev, pctx_size);
> - if (!pctx) {
> + if (IS_ERR(pctx)) {
> DRM_DEBUG("not enough stolen space for PCTX, disabling\n");
> return;
> }
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 16a4ead..a928602 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -676,9 +676,9 @@ intel_init_pipe_control(struct intel_engine_cs *ring)
> WARN_ON(ring->scratch.obj);
>
> ring->scratch.obj = i915_gem_alloc_object(ring->dev, 4096);
> - if (ring->scratch.obj == NULL) {
> + if (IS_ERR(ring->scratch.obj)) {
> DRM_ERROR("Failed to allocate seqno page\n");
> - ret = -ENOMEM;
> + ret = PTR_ERR(ring->scratch.obj);
Beware the caller subsequently calling drm_gem_object_unreference on the
error pointer.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list