diff mbox series

[4/6] drm/i915: do not destroy plane state if cursor unpin worker is scheduled

Message ID 20240205043147.3632165-5-chaitanya.kumar.borah@intel.com (mailing list archive)
State New, archived
Headers show
Series Cursor Fault Fixes | expand

Commit Message

Chaitanya Kumar Borah Feb. 5, 2024, 4:31 a.m. UTC
The plane destroy hook can be called asynchronously even when vblank
worker responsible for unpinning the cursor fb is scheduled. Since
the vblank worker destroys the plane state, do not destroy the plane
state if it is scheduled.

Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c | 19 +++++++++++++++++++
 .../gpu/drm/i915/display/intel_atomic_plane.h |  2 ++
 drivers/gpu/drm/i915/display/intel_cursor.c   |  2 +-
 3 files changed, 22 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 06c5d8262443..a585e4aca309 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -136,6 +136,25 @@  intel_plane_destroy_state(struct drm_plane *plane,
 {
 	struct intel_plane_state *plane_state = to_intel_plane_state(state);
 
+	/* Do not proceed if vblank unpin worker is yet to be executed */
+	if (plane_state->unpin_work.vblank)
+		return;
+
+	drm_WARN_ON(plane->dev, plane_state->ggtt_vma);
+	drm_WARN_ON(plane->dev, plane_state->dpt_vma);
+
+	__drm_atomic_helper_plane_destroy_state(&plane_state->uapi);
+	if (plane_state->hw.fb)
+		drm_framebuffer_put(plane_state->hw.fb);
+	kfree(plane_state);
+}
+
+void
+intel_cursor_destroy_state(struct drm_plane *plane,
+			   struct drm_plane_state *state)
+{
+	struct intel_plane_state *plane_state = to_intel_plane_state(state);
+
 	drm_WARN_ON(plane->dev, plane_state->ggtt_vma);
 	drm_WARN_ON(plane->dev, plane_state->dpt_vma);
 
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index 5a897cf6fa02..1e165b709a80 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -45,6 +45,8 @@  void intel_plane_free(struct intel_plane *plane);
 struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane);
 void intel_plane_destroy_state(struct drm_plane *plane,
 			       struct drm_plane_state *state);
+void intel_cursor_destroy_state(struct drm_plane *plane,
+				struct drm_plane_state *state);
 void intel_crtc_planes_update_noarm(struct intel_atomic_state *state,
 				    struct intel_crtc *crtc);
 void intel_crtc_planes_update_arm(struct intel_atomic_state *state,
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index dbb26a212800..32f9bb753331 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -662,7 +662,7 @@  void intel_cursor_unpin_work(struct kthread_work *base)
 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
 
 	intel_plane_unpin_fb(plane_state);
-	intel_plane_destroy_state(&plane->base, &plane_state->uapi);
+	intel_cursor_destroy_state(&plane->base, &plane_state->uapi);
 }
 
 static int