[PATCH 06/10] drm/vkms: flush crc workers earlier in commit flow

Daniel Vetter daniel.vetter at ffwll.ch
Thu Jun 6 22:27:47 UTC 2019


Currently we flush pending crc workers very late in the commit flow,
when we destry all the old crtc states. Unfortunately at that point
the framebuffers are already unpinned (and our vaddr possible gone),
so this isn't good. Also, the plane_states we need might also already
be cleaned up, since cleanup order of state structures isn't well
defined.

Fix this by waiting for all crc workers of the old state to complete
before we start any of the cleanup work.

Note that this is not yet race-free, because the hrtimer and crc
worker look at the wrong state pointers, but that will be fixed in
subsequent patches.

Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
Cc: Rodrigo Siqueira <rodrigosiqueiramelo at gmail.com>
Cc: Haneen Mohammed <hamohammed.sa at gmail.com>
Cc: Daniel Vetter <daniel at ffwll.ch>
---
 drivers/gpu/drm/vkms/vkms_crtc.c |  2 +-
 drivers/gpu/drm/vkms/vkms_drv.c  | 10 ++++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index 55b16d545fe7..b6987d90805f 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -125,7 +125,7 @@ static void vkms_atomic_crtc_destroy_state(struct drm_crtc *crtc,
 	__drm_atomic_helper_crtc_destroy_state(state);
 
 	if (vkms_state) {
-		flush_work(&vkms_state->crc_work);
+		WARN_ON(work_pending(&vkms_state->crc_work));
 		kfree(vkms_state);
 	}
 }
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index f677ab1d0094..cc53ef88a331 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -62,6 +62,9 @@ static void vkms_release(struct drm_device *dev)
 static void vkms_atomic_commit_tail(struct drm_atomic_state *old_state)
 {
 	struct drm_device *dev = old_state->dev;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *old_crtc_state;
+	int i;
 
 	drm_atomic_helper_commit_modeset_disables(dev, old_state);
 
@@ -75,6 +78,13 @@ static void vkms_atomic_commit_tail(struct drm_atomic_state *old_state)
 
 	drm_atomic_helper_wait_for_vblanks(dev, old_state);
 
+	for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
+		struct vkms_crtc_state *vkms_state =
+			to_vkms_crtc_state(old_crtc_state);
+
+		flush_work(&vkms_state->crc_work);
+	}
+
 	drm_atomic_helper_cleanup_planes(dev, old_state);
 }
 
-- 
2.20.1



More information about the dri-devel mailing list