drm/radeon/kms: unpin fb in atombios crtc disable
authorIlija Hadzic <ilijahadzic@gmail.com>
Sun, 3 Nov 2013 03:00:19 +0000 (23:00 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 8 Nov 2013 17:33:36 +0000 (12:33 -0500)
When drm_helper_disable_unused_functions calls disable
function of the CRTC, it also sets the crtc->fb pointer
to NULL. This can later (when the mode on that CRTC is setup
again from user space) cause ***_do_set_base functions to
"think" that there is no old buffer and skip the unpinning
code. Consequently, the buffer that has been NULL-ified in
drm_helper_disable_unused_functions will never be unpinned
causing a leak in VRAM.

This patch plugs the leak by unpinning the frame buffer
in crtc_disable function.

Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/atombios_crtc.c

index 86d9ee08b13f8266e8a43e5c32a7a66f8e639aea..4ad156267381479fc80dface515e0d4474392348 100644 (file)
@@ -1910,6 +1910,21 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
        int i;
 
        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+       if (crtc->fb) {
+               int r;
+               struct radeon_framebuffer *radeon_fb;
+               struct radeon_bo *rbo;
+
+               radeon_fb = to_radeon_framebuffer(crtc->fb);
+               rbo = gem_to_radeon_bo(radeon_fb->obj);
+               r = radeon_bo_reserve(rbo, false);
+               if (unlikely(r))
+                       DRM_ERROR("failed to reserve rbo before unpin\n");
+               else {
+                       radeon_bo_unpin(rbo);
+                       radeon_bo_unreserve(rbo);
+               }
+       }
        /* disable the GRPH */
        if (ASIC_IS_DCE4(rdev))
                WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 0);