Skip to content

Commit

Permalink
Merge tag 'drm-misc-fixes-2018-05-02' of git://anongit.freedesktop.or…
Browse files Browse the repository at this point in the history
…g/drm/drm-misc into drm-fixes

vc4: Fix bo refcounts during async commits (Boris)
vga-dac: Fix edid memory leak (Sean)

Cc: Boris Brezillon <boris.brezillon@bootlin.com>
Cc: Sean Paul <seanpaul@chromium.org>

* tag 'drm-misc-fixes-2018-05-02' of git://anongit.freedesktop.org/drm/drm-misc:
  drm/bridge: vga-dac: Fix edid memory leak
  drm/vc4: Make sure vc4_bo_{inc,dec}_usecnt() calls are balanced
  • Loading branch information
Dave Airlie committed May 3, 2018
2 parents 083faae + 49ceda9 commit 1e5fbc0
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
4 changes: 3 additions & 1 deletion drivers/gpu/drm/bridge/dumb-vga-dac.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ static int dumb_vga_get_modes(struct drm_connector *connector)
}

drm_mode_connector_update_edid_property(connector, edid);
return drm_add_edid_modes(connector, edid);
ret = drm_add_edid_modes(connector, edid);
kfree(edid);
return ret;

fallback:
/*
Expand Down
46 changes: 45 additions & 1 deletion drivers/gpu/drm/vc4/vc4_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,7 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void *data)
struct vc4_async_flip_state {
struct drm_crtc *crtc;
struct drm_framebuffer *fb;
struct drm_framebuffer *old_fb;
struct drm_pending_vblank_event *event;

struct vc4_seqno_cb cb;
Expand Down Expand Up @@ -789,6 +790,23 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb)

drm_crtc_vblank_put(crtc);
drm_framebuffer_put(flip_state->fb);

/* Decrement the BO usecnt in order to keep the inc/dec calls balanced
* when the planes are updated through the async update path.
* FIXME: we should move to generic async-page-flip when it's
* available, so that we can get rid of this hand-made cleanup_fb()
* logic.
*/
if (flip_state->old_fb) {
struct drm_gem_cma_object *cma_bo;
struct vc4_bo *bo;

cma_bo = drm_fb_cma_get_gem_obj(flip_state->old_fb, 0);
bo = to_vc4_bo(&cma_bo->base);
vc4_bo_dec_usecnt(bo);
drm_framebuffer_put(flip_state->old_fb);
}

kfree(flip_state);

up(&vc4->async_modeset);
Expand All @@ -813,9 +831,22 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
struct vc4_bo *bo = to_vc4_bo(&cma_bo->base);

/* Increment the BO usecnt here, so that we never end up with an
* unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the
* plane is later updated through the non-async path.
* FIXME: we should move to generic async-page-flip when it's
* available, so that we can get rid of this hand-made prepare_fb()
* logic.
*/
ret = vc4_bo_inc_usecnt(bo);
if (ret)
return ret;

flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL);
if (!flip_state)
if (!flip_state) {
vc4_bo_dec_usecnt(bo);
return -ENOMEM;
}

drm_framebuffer_get(fb);
flip_state->fb = fb;
Expand All @@ -826,10 +857,23 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
ret = down_interruptible(&vc4->async_modeset);
if (ret) {
drm_framebuffer_put(fb);
vc4_bo_dec_usecnt(bo);
kfree(flip_state);
return ret;
}

/* Save the current FB before it's replaced by the new one in
* drm_atomic_set_fb_for_plane(). We'll need the old FB in
* vc4_async_page_flip_complete() to decrement the BO usecnt and keep
* it consistent.
* FIXME: we should move to generic async-page-flip when it's
* available, so that we can get rid of this hand-made cleanup_fb()
* logic.
*/
flip_state->old_fb = plane->state->fb;
if (flip_state->old_fb)
drm_framebuffer_get(flip_state->old_fb);

WARN_ON(drm_crtc_vblank_get(crtc) != 0);

/* Immediately update the plane's legacy fb pointer, so that later
Expand Down

0 comments on commit 1e5fbc0

Please sign in to comment.