Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e5fbc0b authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-fixes-2018-05-02' of git://anongit.freedesktop.org/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
parents 083faae1 49ceda9d
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -56,7 +56,9 @@ static int dumb_vga_get_modes(struct drm_connector *connector)
	}
	}


	drm_mode_connector_update_edid_property(connector, edid);
	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:
fallback:
	/*
	/*
+45 −1
Original line number Original line Diff line number Diff line
@@ -760,6 +760,7 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void *data)
struct vc4_async_flip_state {
struct vc4_async_flip_state {
	struct drm_crtc *crtc;
	struct drm_crtc *crtc;
	struct drm_framebuffer *fb;
	struct drm_framebuffer *fb;
	struct drm_framebuffer *old_fb;
	struct drm_pending_vblank_event *event;
	struct drm_pending_vblank_event *event;


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


	drm_crtc_vblank_put(crtc);
	drm_crtc_vblank_put(crtc);
	drm_framebuffer_put(flip_state->fb);
	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);
	kfree(flip_state);


	up(&vc4->async_modeset);
	up(&vc4->async_modeset);
@@ -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 drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
	struct vc4_bo *bo = to_vc4_bo(&cma_bo->base);
	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);
	flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL);
	if (!flip_state)
	if (!flip_state) {
		vc4_bo_dec_usecnt(bo);
		return -ENOMEM;
		return -ENOMEM;
	}


	drm_framebuffer_get(fb);
	drm_framebuffer_get(fb);
	flip_state->fb = fb;
	flip_state->fb = fb;
@@ -826,10 +857,23 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
	ret = down_interruptible(&vc4->async_modeset);
	ret = down_interruptible(&vc4->async_modeset);
	if (ret) {
	if (ret) {
		drm_framebuffer_put(fb);
		drm_framebuffer_put(fb);
		vc4_bo_dec_usecnt(bo);
		kfree(flip_state);
		kfree(flip_state);
		return ret;
		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);
	WARN_ON(drm_crtc_vblank_get(crtc) != 0);


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