On Tue, Oct 25, 2016 at 06:58:02PM +0300, ville.syrj...@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrj...@linux.intel.com>
> 
> Due to the plane->index not getting readjusted in drm_plane_cleanup(),
> we can't continue initialization of some plane/crtc init fails.
> Well, we sort of could I suppose if we left all initialized planes on
> the list, but that would expose those planes to userspace as well.
> 
> But for crtcs the situation is even worse since we assume that
> pipe==crtc index occasionally, so we can't really deal with a partially
> initialize set of crtcs.
> 
> So seems safest to just abort the entire thing if anything goes wrong.
> All the failure paths here are kmalloc()s anyway, so it seems unlikely
> we'd get very far if these start failing.
> 
> Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>

Some bikeshedding in this patch, but I like it. For patches 1-3:

Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch>
> ---
>  drivers/gpu/drm/i915/i915_drv.c      |   4 +-
>  drivers/gpu/drm/i915/i915_drv.h      |   2 +-
>  drivers/gpu/drm/i915/intel_display.c | 101 
> ++++++++++++++++++++++-------------
>  drivers/gpu/drm/i915/intel_drv.h     |   3 +-
>  drivers/gpu/drm/i915/intel_sprite.c  |   8 +--
>  5 files changed, 75 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index af3559d34328..0e393b5a988a 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -592,7 +592,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
>  
>       /* Important: The output setup functions called by modeset_init need
>        * working irqs for e.g. gmbus and dp aux transfers. */
> -     intel_modeset_init(dev);
> +     ret = intel_modeset_init(dev);
> +     if (ret)
> +             goto cleanup_irq;
>  
>       intel_guc_init(dev);
>  
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 7a621c74254e..a9308aeb2f1f 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3700,7 +3700,7 @@ void intel_device_info_dump(struct drm_i915_private 
> *dev_priv);
>  
>  /* modesetting */
>  extern void intel_modeset_init_hw(struct drm_device *dev);
> -extern void intel_modeset_init(struct drm_device *dev);
> +extern int intel_modeset_init(struct drm_device *dev);
>  extern void intel_modeset_gem_init(struct drm_device *dev);
>  extern void intel_modeset_cleanup(struct drm_device *dev);
>  extern int intel_connector_register(struct drm_connector *);
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 244a0f59d8f7..d5a49d12dc88 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -14975,9 +14975,6 @@ static void intel_finish_crtc_commit(struct drm_crtc 
> *crtc,
>   */
>  void intel_plane_destroy(struct drm_plane *plane)
>  {
> -     if (!plane)
> -             return;
> -
>       drm_plane_cleanup(plane);
>       kfree(to_intel_plane(plane));
>  }
> @@ -14991,11 +14988,10 @@ const struct drm_plane_funcs intel_plane_funcs = {
>       .atomic_set_property = intel_plane_atomic_set_property,
>       .atomic_duplicate_state = intel_plane_duplicate_state,
>       .atomic_destroy_state = intel_plane_destroy_state,
> -
>  };
>  
> -static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
> -                                                 int pipe)
> +static struct intel_plane *
> +intel_primary_plane_create(struct drm_device *dev, enum pipe pipe)
>  {
>       struct drm_i915_private *dev_priv = to_i915(dev);
>       struct intel_plane *primary = NULL;
> @@ -15006,12 +15002,17 @@ static struct drm_plane 
> *intel_primary_plane_create(struct drm_device *dev,
>       int ret;
>  
>       primary = kzalloc(sizeof(*primary), GFP_KERNEL);
> -     if (!primary)
> +     if (!primary) {
> +             ret = -ENOMEM;
>               goto fail;
> +     }
>  
>       state = intel_create_plane_state(&primary->base);
> -     if (!state)
> +     if (!state) {
> +             ret = -ENOMEM;
>               goto fail;
> +     }
> +
>       primary->base.state = &state->base;
>  
>       primary->can_scale = false;
> @@ -15092,13 +15093,13 @@ static struct drm_plane 
> *intel_primary_plane_create(struct drm_device *dev,
>  
>       drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs);
>  
> -     return &primary->base;
> +     return primary;
>  
>  fail:
>       kfree(state);
>       kfree(primary);
>  
> -     return NULL;
> +     return ERR_PTR(ret);
>  }
>  
>  static int
> @@ -15194,8 +15195,8 @@ intel_update_cursor_plane(struct drm_plane *plane,
>       intel_crtc_update_cursor(crtc, state);
>  }
>  
> -static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
> -                                                int pipe)
> +static struct intel_plane *
> +intel_cursor_plane_create(struct drm_device *dev, enum pipe pipe)
>  {
>       struct drm_i915_private *dev_priv = to_i915(dev);
>       struct intel_plane *cursor = NULL;
> @@ -15203,12 +15204,17 @@ static struct drm_plane 
> *intel_cursor_plane_create(struct drm_device *dev,
>       int ret;
>  
>       cursor = kzalloc(sizeof(*cursor), GFP_KERNEL);
> -     if (!cursor)
> +     if (!cursor) {
> +             ret = -ENOMEM;
>               goto fail;
> +     }
>  
>       state = intel_create_plane_state(&cursor->base);
> -     if (!state)
> +     if (!state) {
> +             ret = -ENOMEM;
>               goto fail;
> +     }
> +
>       cursor->base.state = &state->base;
>  
>       cursor->can_scale = false;
> @@ -15240,13 +15246,13 @@ static struct drm_plane 
> *intel_cursor_plane_create(struct drm_device *dev,
>  
>       drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
>  
> -     return &cursor->base;
> +     return cursor;
>  
>  fail:
>       kfree(state);
>       kfree(cursor);
>  
> -     return NULL;
> +     return ERR_PTR(ret);
>  }
>  
>  static void skl_init_scalers(struct drm_device *dev, struct intel_crtc 
> *intel_crtc,
> @@ -15265,22 +15271,24 @@ static void skl_init_scalers(struct drm_device 
> *dev, struct intel_crtc *intel_cr
>       scaler_state->scaler_id = -1;
>  }
>  
> -static void intel_crtc_init(struct drm_device *dev, int pipe)
> +static int intel_crtc_init(struct drm_device *dev, enum pipe pipe)
>  {
>       struct drm_i915_private *dev_priv = to_i915(dev);
>       struct intel_crtc *intel_crtc;
>       struct intel_crtc_state *crtc_state = NULL;
> -     struct drm_plane *primary = NULL;
> -     struct drm_plane *cursor = NULL;
> +     struct intel_plane *primary = NULL;
> +     struct intel_plane *cursor = NULL;
>       int sprite, ret;
>  
>       intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL);
> -     if (intel_crtc == NULL)
> -             return;
> +     if (!intel_crtc)
> +             return -ENOMEM;
>  
>       crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
> -     if (!crtc_state)
> +     if (!crtc_state) {
> +             ret = -ENOMEM;
>               goto fail;
> +     }
>       intel_crtc->config = crtc_state;
>       intel_crtc->base.state = &crtc_state->base;
>       crtc_state->base.crtc = &intel_crtc->base;
> @@ -15296,22 +15304,30 @@ static void intel_crtc_init(struct drm_device *dev, 
> int pipe)
>       }
>  
>       primary = intel_primary_plane_create(dev, pipe);
> -     if (!primary)
> +     if (IS_ERR(primary)) {
> +             ret = PTR_ERR(primary);
>               goto fail;
> +     }
>  
>       for_each_sprite(dev_priv, pipe, sprite) {
> -             ret = intel_plane_init(dev, pipe, sprite);
> -             if (ret)
> -                     DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n",
> -                                   pipe_name(pipe), sprite_name(pipe, 
> sprite), ret);
> +             struct intel_plane *plane;
> +
> +             plane = intel_sprite_plane_create(dev, pipe, sprite);
> +             if (!plane) {
> +                     ret = PTR_ERR(plane);
> +                     goto fail;
> +             }
>       }
>  
>       cursor = intel_cursor_plane_create(dev, pipe);
> -     if (!cursor)
> +     if (!cursor) {
> +             ret = PTR_ERR(cursor);
>               goto fail;
> +     }
>  
> -     ret = drm_crtc_init_with_planes(dev, &intel_crtc->base, primary,
> -                                     cursor, &intel_crtc_funcs,
> +     ret = drm_crtc_init_with_planes(dev, &intel_crtc->base,
> +                                     &primary->base, &cursor->base,
> +                                     &intel_crtc_funcs,
>                                       "pipe %c", pipe_name(pipe));
>       if (ret)
>               goto fail;
> @@ -15343,13 +15359,18 @@ static void intel_crtc_init(struct drm_device *dev, 
> int pipe)
>       intel_color_init(&intel_crtc->base);
>  
>       WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe);
> -     return;
> +
> +     return 0;
>  
>  fail:
> -     intel_plane_destroy(primary);
> -     intel_plane_destroy(cursor);
> +     /*
> +      * drm_mode_config_cleanup() will free up any
> +      * crtcs/planes already initialized.
> +      */
>       kfree(crtc_state);
>       kfree(intel_crtc);
> +
> +     return ret;
>  }
>  
>  enum pipe intel_get_pipe_from_connector(struct intel_connector *connector)
> @@ -16426,7 +16447,7 @@ static void sanitize_watermarks(struct drm_device 
> *dev)
>       drm_modeset_acquire_fini(&ctx);
>  }
>  
> -void intel_modeset_init(struct drm_device *dev)
> +int intel_modeset_init(struct drm_device *dev)
>  {
>       struct drm_i915_private *dev_priv = to_i915(dev);
>       struct i915_ggtt *ggtt = &dev_priv->ggtt;
> @@ -16450,7 +16471,7 @@ void intel_modeset_init(struct drm_device *dev)
>       intel_init_pm(dev);
>  
>       if (INTEL_INFO(dev)->num_pipes == 0)
> -             return;
> +             return 0;
>  
>       /*
>        * There may be no VBT; and if the BIOS enabled SSC we can
> @@ -16499,7 +16520,13 @@ void intel_modeset_init(struct drm_device *dev)
>                     INTEL_INFO(dev)->num_pipes > 1 ? "s" : "");
>  
>       for_each_pipe(dev_priv, pipe) {
> -             intel_crtc_init(dev, pipe);
> +             int ret;
> +
> +             ret = intel_crtc_init(dev, pipe);
> +             if (ret) {
> +                     drm_mode_config_cleanup(dev);
> +                     return ret;
> +             }
>       }
>  
>       intel_update_czclk(dev_priv);
> @@ -16547,6 +16574,8 @@ void intel_modeset_init(struct drm_device *dev)
>        * since the watermark calculation done here will use pstate->fb.
>        */
>       sanitize_watermarks(dev);
> +
> +     return 0;
>  }
>  
>  static void intel_enable_pipe_a(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index 7dda79df55d0..4fd7d74fd6dc 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1779,7 +1779,8 @@ bool intel_sdvo_init(struct drm_device *dev,
>  /* intel_sprite.c */
>  int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
>                            int usecs);
> -int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
> +struct intel_plane *intel_sprite_plane_create(struct drm_device *dev,
> +                                           enum pipe pipe, int plane);
>  int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
>                             struct drm_file *file_priv);
>  void intel_pipe_update_start(struct intel_crtc *crtc);
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
> b/drivers/gpu/drm/i915/intel_sprite.c
> index ae1e3d47951b..41ae7f562eec 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1042,8 +1042,8 @@ static uint32_t skl_plane_formats[] = {
>       DRM_FORMAT_VYUY,
>  };
>  
> -int
> -intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
> +struct intel_plane *
> +intel_sprite_plane_create(struct drm_device *dev, enum pipe pipe, int plane)
>  {
>       struct drm_i915_private *dev_priv = to_i915(dev);
>       struct intel_plane *intel_plane = NULL;
> @@ -1160,11 +1160,11 @@ intel_plane_init(struct drm_device *dev, enum pipe 
> pipe, int plane)
>  
>       drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
>  
> -     return 0;
> +     return intel_plane;
>  
>  fail:
>       kfree(state);
>       kfree(intel_plane);
>  
> -     return ret;
> +     return ERR_PTR(ret);
>  }
> -- 
> 2.7.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to