drm: Add consistency check for page-flipping
authorThierry Reding <thierry.reding@avionic-design.de>
Wed, 13 Feb 2013 15:08:33 +0000 (16:08 +0100)
committerThierry Reding <thierry.reding@avionic-design.de>
Fri, 22 Feb 2013 07:21:07 +0000 (08:21 +0100)
Driver implementations of the drm_crtc's .page_flip() function are
required to update the crtc->fb field on success to reflect that the new
framebuffer is now in use. This is important to keep reference counting
on the framebuffers balanced.

While at it, document this requirement to keep others from falling into
the same trap.

Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Documentation/DocBook/drm.tmpl
drivers/gpu/drm/drm_crtc.c

index 51e1904ac4c723b738c6aba7c094d67188eafaea..a6428ddfcfc2cd468139e16c7ed687b21b9d9736 100644 (file)
@@ -1160,6 +1160,12 @@ int max_width, max_height;</synopsis>
             without waiting for rendering or page flip to complete and must block
             any new rendering to the frame buffer until the page flip completes.
           </para>
+          <para>
+            If a page flip can be successfully scheduled the driver must set the
+            <code>drm_crtc-&lt;fb</code> field to the new framebuffer pointed to
+            by <code>fb</code>. This is important so that the reference counting
+            on framebuffers stays balanced.
+          </para>
           <para>
             If a page flip is already pending, the
             <methodname>page_flip</methodname> operation must return
index 781aef524b3bd7f850341ca98f218f67e35d2df9..3bdf2a650d9c4c4ec8f65d1c8f0e1ebd3bcc507e 100644 (file)
@@ -3792,6 +3792,13 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
                /* Keep the old fb, don't unref it. */
                old_fb = NULL;
        } else {
+               /*
+                * Warn if the driver hasn't properly updated the crtc->fb
+                * field to reflect that the new framebuffer is now used.
+                * Failing to do so will screw with the reference counting
+                * on framebuffers.
+                */
+               WARN_ON(crtc->fb != fb);
                /* Unref only the old framebuffer. */
                fb = NULL;
        }