Re: gma500: remove double free in psbfb_create

From: Patrik Jakobsson
Date: Fri Sep 20 2013 - 17:46:31 EST


On Fri, Sep 20, 2013 at 3:56 PM, Dave Jones <davej@xxxxxxxxxx> wrote:
> This code appears to be calling psb_gtt_free_range twice with the same args.
> (The second call didn't appear in the diff output, it's right after the mutex_unlock)
>
> Spotted with Coverity, not tested due to lack of hardware.
>
> Signed-off-by: Dave Jones <davej@xxxxxxxxxxxxxxxxx>
>
> diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
> index 01dd7d2..d35ffc4 100644
> --- a/drivers/gpu/drm/gma500/framebuffer.c
> +++ b/drivers/gpu/drm/gma500/framebuffer.c
> @@ -479,9 +479,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,
> mutex_unlock(&dev->struct_mutex);
> return 0;
> out_unref:
> - if (backing->stolen)
> - psb_gtt_free_range(dev, backing);
> - else
> + if (!backing->stolen)
> drm_gem_object_unreference(&backing->gem);
> out_err1:
> mutex_unlock(&dev->struct_mutex);

Hi Dave, thanks for the patch.

This part of the code is a ref count disaster and probably needs to be
reworked anyways. It would be nice to always let drm_gem_object_unreference()
do the final cleanup call to psb_gtt_free_range() but stolen memory is treated
as an exception in some cases. Also we don't seem to take down the framebuffer
correctly on failure after drm_framebuffer_init() which seems scary.
psb_framebuffer_init() calls drm_framebuffer_init() which clearly states that
we need to be done with the setup and stop failing at this point.

Also, we always get a stolen memory backed object (we're even lowering the
depth to make sure we get one) so the drm_gem_object_unreference() is a NOP.

Anyways, your patch looks good but I would like to look at this some more since
it seems broken anyways.

Patrik
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/