]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
drm: writeback: Fix leak of writeback job
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Thu, 21 Feb 2019 00:51:37 +0000 (02:51 +0200)
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Mon, 18 Mar 2019 15:24:32 +0000 (17:24 +0200)
Writeback jobs are allocated when the WRITEBACK_FB_ID is set, and
deleted when the jobs complete. This results in both a memory leak of
the job and a leak of the framebuffer if the atomic commit returns
before the job is queued for processing, for instance if the atomic
check fails or if the commit runs in test-only mode.

Fix this by implementing the drm_writeback_cleanup_job() function and
calling it from __drm_atomic_helper_connector_destroy_state(). As
writeback jobs are removed from the state when they're queued for
processing, any job left in the state when the state gets destroyed
needs to be cleaned up.

The existing declaration of the drm_writeback_cleanup_job() function
without an implementation hints that this problem was considered, but
never addressed.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Brian Starkey <brian.starkey@arm.com>
Acked-by: Liviu Dudau <liviu.dudau@arm.com>
drivers/gpu/drm/drm_atomic_state_helper.c
drivers/gpu/drm/drm_writeback.c

index 4985384e51f6e5cc7308efc670d08a05e92ff4ec..59ffb6b9c74537d00cf70a753c605b30e83ddc5b 100644 (file)
@@ -30,6 +30,7 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_device.h>
+#include <drm/drm_writeback.h>
 
 #include <linux/slab.h>
 #include <linux/dma-fence.h>
@@ -412,6 +413,9 @@ __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
 
        if (state->commit)
                drm_crtc_commit_put(state->commit);
+
+       if (state->writeback_job)
+               drm_writeback_cleanup_job(state->writeback_job);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
 
index 338b993d7c9fb86ec532a18502bca911a0da7679..1b497d3530b58ed6ec6e2e39da883058c2148d12 100644 (file)
@@ -273,6 +273,15 @@ void drm_writeback_queue_job(struct drm_writeback_connector *wb_connector,
 }
 EXPORT_SYMBOL(drm_writeback_queue_job);
 
+void drm_writeback_cleanup_job(struct drm_writeback_job *job)
+{
+       if (job->fb)
+               drm_framebuffer_put(job->fb);
+
+       kfree(job);
+}
+EXPORT_SYMBOL(drm_writeback_cleanup_job);
+
 /*
  * @cleanup_work: deferred cleanup of a writeback job
  *
@@ -285,10 +294,9 @@ static void cleanup_work(struct work_struct *work)
        struct drm_writeback_job *job = container_of(work,
                                                     struct drm_writeback_job,
                                                     cleanup_work);
-       drm_framebuffer_put(job->fb);
-       kfree(job);
-}
 
+       drm_writeback_cleanup_job(job);
+}
 
 /**
  * drm_writeback_signal_completion - Signal the completion of a writeback job