[PATCH] drm/radeon: deal with errors from framebuffer init path.

Alex Deucher alexdeucher at gmail.com
Tue Mar 6 05:33:31 PST 2012


On Tue, Mar 6, 2012 at 5:48 AM, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> We've been seeing a very occasional oops on a 32-bit rn50 platform running EL6
> kernels at boot. It seems to be due to one of these functions failing and
> us then accessing a NULL-300 pointer.
>
> This should prevent the oops and give some info in the logs as to what is going on.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  drivers/gpu/drm/radeon/radeon_display.c |   18 +++++++++++++++---
>  drivers/gpu/drm/radeon/radeon_fb.c      |   11 ++++++++++-
>  drivers/gpu/drm/radeon/radeon_mode.h    |    2 +-
>  3 files changed, 26 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
> index 8c49fef..3d31433 100644
> --- a/drivers/gpu/drm/radeon/radeon_display.c
> +++ b/drivers/gpu/drm/radeon/radeon_display.c
> @@ -1078,15 +1078,21 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = {
>        .create_handle = radeon_user_framebuffer_create_handle,
>  };
>
> -void
> +int
>  radeon_framebuffer_init(struct drm_device *dev,
>                        struct radeon_framebuffer *rfb,
>                        struct drm_mode_fb_cmd2 *mode_cmd,
>                        struct drm_gem_object *obj)
>  {
> +       int ret;
>        rfb->obj = obj;
> -       drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
> +       ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
> +       if (ret) {
> +               rfb->obj = NULL;
> +               return ret;
> +       }
>        drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
> +       return 0;
>  }
>
>  static struct drm_framebuffer *
> @@ -1096,6 +1102,7 @@ radeon_user_framebuffer_create(struct drm_device *dev,
>  {
>        struct drm_gem_object *obj;
>        struct radeon_framebuffer *radeon_fb;
> +       int ret;
>
>        obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
>        if (obj ==  NULL) {
> @@ -1108,7 +1115,12 @@ radeon_user_framebuffer_create(struct drm_device *dev,
>        if (radeon_fb == NULL)
>                return ERR_PTR(-ENOMEM);
>
> -       radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
> +       ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
> +       if (ret) {
> +               kfree(radeon_fb);
> +               drm_gem_object_unreference_unlocked(obj);
> +               return NULL;
> +       }
>
>        return &radeon_fb->base;
>  }
> diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
> index cf2bf35..195471c 100644
> --- a/drivers/gpu/drm/radeon/radeon_fb.c
> +++ b/drivers/gpu/drm/radeon/radeon_fb.c
> @@ -209,6 +209,11 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
>                                                          sizes->surface_depth);
>
>        ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj);
> +       if (ret) {
> +               DRM_ERROR("failed to create fbcon object %d\n", ret);
> +               return ret;
> +       }
> +
>        rbo = gem_to_radeon_bo(gobj);
>
>        /* okay we have an object now allocate the framebuffer */
> @@ -220,7 +225,11 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
>
>        info->par = rfbdev;
>
> -       radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
> +       ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
> +       if (ret) {
> +               DRM_ERROR("failed to initalise framebuffer %d\n", ret);
> +               goto out_unref;
> +       }
>
>        fb = &rfbdev->rfb.base;
>
> diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
> index 4330e32..8a85598 100644
> --- a/drivers/gpu/drm/radeon/radeon_mode.h
> +++ b/drivers/gpu/drm/radeon/radeon_mode.h
> @@ -649,7 +649,7 @@ extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
>                                     u16 blue, int regno);
>  extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
>                                     u16 *blue, int regno);
> -void radeon_framebuffer_init(struct drm_device *dev,
> +int radeon_framebuffer_init(struct drm_device *dev,
>                             struct radeon_framebuffer *rfb,
>                             struct drm_mode_fb_cmd2 *mode_cmd,
>                             struct drm_gem_object *obj);
> --
> 1.7.7.6
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list