All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Vetter <daniel.vetter@ffwll.ch>
To: DRI Development <dri-devel@lists.freedesktop.org>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>,
	Thierry Reding <treding@nvidia.com>
Subject: [PATCH 1/2] drm: Simplify fb refcounting rules around ->update_plane
Date: Wed, 23 Apr 2014 10:30:04 +0200	[thread overview]
Message-ID: <1398241805-24564-1-git-send-email-daniel.vetter@ffwll.ch> (raw)
In-Reply-To: <CAKMK7uHWuO0=-B9YNYQx3JZ=BiadW-LnNJQhe8XM_DTbba3szA@mail.gmail.com>

The introduction of primary planes has apparently caused a bit of fb
refcounting fun for people. That makes it a good time to clean up the
arcane rules and slight differences between ->update_plane and
->set_config. The new rules are:

- The core holds a reference for both the new and the old fb (if
  they're non-NULL of course) while calling into the driver through
  either ->update_plane or ->set_config.

- Drivers may not clobber plane->fb if their callback fails. If they
  do that, they need to store a pointer to the old fb in it again.
  When calling into the driver plane->fb still points at the current
  (old) framebuffer.

- The core will update the plane->fb pointer on success. Drivers can
  do that themselves too, but aren't required to any more for the
  primary plane.

- The core will update fb refcounts for the plane->fb pointer,
  presuming the drivers hold up their end of the bargain.

v2: Remove now unused tmpfb (Thierry)

v3: Drop broken changes from drm_mode_setplane (Ville). Also polish
the commit message a bit.

v4: Also fix up the handling of ->disable_plane in
drm_plane_force_disable. The issue was that we didn't save plane->fb
over the ->disable_plane call. Just paranoia, nothing relies on this.

Cc: Thierry Reding <treding@nvidia.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/drm_crtc.c         | 13 +++++++------
 drivers/gpu/drm/drm_plane_helper.c | 16 ----------------
 2 files changed, 7 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d8b7099abece..f6633cb927bc 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1145,16 +1145,17 @@ EXPORT_SYMBOL(drm_plane_cleanup);
  */
 void drm_plane_force_disable(struct drm_plane *plane)
 {
+	struct drm_framebuffer *old_fb = plane->fb;
 	int ret;
 
-	if (!plane->fb)
+	if (!old_fb)
 		return;
 
 	ret = plane->funcs->disable_plane(plane);
 	if (ret)
 		DRM_ERROR("failed to disable plane with busy fb\n");
 	/* disconnect the plane from the fb and crtc: */
-	__drm_framebuffer_unreference(plane->fb);
+	__drm_framebuffer_unreference(old_fb);
 	plane->fb = NULL;
 	plane->crtc = NULL;
 }
@@ -2187,16 +2188,18 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
 	}
 
 	drm_modeset_lock_all(dev);
+	old_fb = plane->fb;
 	ret = plane->funcs->update_plane(plane, crtc, fb,
 					 plane_req->crtc_x, plane_req->crtc_y,
 					 plane_req->crtc_w, plane_req->crtc_h,
 					 plane_req->src_x, plane_req->src_y,
 					 plane_req->src_w, plane_req->src_h);
 	if (!ret) {
-		old_fb = plane->fb;
 		plane->crtc = crtc;
 		plane->fb = fb;
 		fb = NULL;
+	} else {
+		old_fb = NULL;
 	}
 	drm_modeset_unlock_all(dev);
 
@@ -2239,9 +2242,7 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
 	ret = crtc->funcs->set_config(set);
 	if (ret == 0) {
 		crtc->primary->crtc = crtc;
-
-		/* crtc->fb must be updated by ->set_config, enforces this. */
-		WARN_ON(fb != crtc->primary->fb);
+		crtc->primary->fb = fb;
 	}
 
 	list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index 9540ff9f97fe..b72736d5541d 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -124,7 +124,6 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
 		.y2 = crtc->mode.vdisplay,
 	};
 	struct drm_connector **connector_list;
-	struct drm_framebuffer *tmpfb;
 	int num_connectors, ret;
 
 	if (!crtc->enabled) {
@@ -177,22 +176,7 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
 	set.connectors = connector_list;
 	set.num_connectors = num_connectors;
 
-	/*
-	 * set_config() adjusts crtc->primary->fb; however the DRM setplane
-	 * code that called us expects to handle the framebuffer update and
-	 * reference counting; save and restore the current fb before
-	 * calling it.
-	 *
-	 * N.B., we call set_config() directly here rather than using
-	 * drm_mode_set_config_internal.  We're reprogramming the same
-	 * connectors that were already in use, so we shouldn't need the extra
-	 * cross-CRTC fb refcounting to accomodate stealing connectors.
-	 * drm_mode_setplane() already handles the basic refcounting for the
-	 * framebuffers involved in this operation.
-	 */
-	tmpfb = plane->fb;
 	ret = crtc->funcs->set_config(&set);
-	plane->fb = tmpfb;
 
 	kfree(connector_list);
 	return ret;
-- 
1.9.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2014-04-23  8:30 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-22  9:07 [PATCH] drm: Simplify fb refcounting rules around ->update_plane Daniel Vetter
2014-04-22  9:16 ` Thierry Reding
2014-04-22 10:06 ` Ville Syrjälä
2014-04-22 14:09   ` Daniel Vetter
2014-04-22 14:28     ` Ville Syrjälä
2014-04-22 14:37       ` Daniel Vetter
2014-04-22 14:19   ` Daniel Vetter
2014-04-23  1:08     ` Matt Roper
2014-04-23  6:36       ` Daniel Vetter
2014-04-23  6:41         ` Daniel Vetter
2014-04-23  8:30           ` Daniel Vetter [this message]
2014-04-23  8:30             ` [PATCH 2/2] drm: Handle ->disable_plane failures correctly Daniel Vetter
2014-04-23 14:47               ` Matt Roper
2014-04-23 14:45             ` [PATCH 1/2] drm: Simplify fb refcounting rules around ->update_plane Matt Roper
2014-04-23 15:25               ` Daniel Vetter
2014-04-23 15:37                 ` [PATCH] " Daniel Vetter
2014-04-23 15:59                   ` Matt Roper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1398241805-24564-1-git-send-email-daniel.vetter@ffwll.ch \
    --to=daniel.vetter@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=treding@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.