[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