[PATCH v7.2-rc6] drm/amd/display: fix usage of DC_FPU_{BEGIN, END} with PREEMPT_RT

Bert Karwatzki <[email protected]> Fri, 7 Aug 2026 14:49:42 +0200
Newsgroups org.freedesktop.lists.amd-gfx,dev.linux.lists.linux-rt-devel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-next,org.kernel.vger.stable
Message-ID <[email protected]>
On PREEMPT_RT kernels kvzalloc_obj() can sleep because spin_lock is
converted to rt_mutex. dc_create_plane_state() can be called while
inside an FPU-guarded region, resuling in "scheduling while atomic"
errors on PREEMPT_RT kernels.
 Fix this by calling kvzalloc_obj() with DC_RUN_WITH_PREEMPTION_ENABLED().
Also fix the error path in dc_create_stream_for_sink().

Fixes: 3539437f354b ("drm/amd/display: Move FPU Guards From DML To DC - Part 1")
Link: https://lore.kernel.org/lkml/[email protected]/
Signed-off-by: Bert Karwatzki <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/core/dc_stream.c  | 5 +++--
 drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 7666cdc78f4e..a5a304a3f802 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -233,8 +233,9 @@ struct dc_stream_state *dc_create_stream_for_sink(
 
 fail:
 	if (stream) {
-		kfree(stream->update_scratch);
-		kfree(stream);
+		if (stream->update_scratch)
+			DC_RUN_WITH_PREEMPTION_ENABLED(kfree(stream->update_scratch));
+		DC_RUN_WITH_PREEMPTION_ENABLED(kfree(stream));
 	}
 
 	return NULL;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
index 72845fc788f3..04982673ffbc 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
@@ -33,6 +33,7 @@
 #include "dpp.h"
 
 #include "dc_plane_priv.h"
+#include "dc_fpu.h"
 
 /*******************************************************************************
  * Private functions
@@ -86,8 +87,8 @@ uint8_t  dc_plane_get_pipe_mask(struct dc_state *dc_state, const struct dc_plane
  ******************************************************************************/
 struct dc_plane_state *dc_create_plane_state(const struct dc *dc)
 {
-	struct dc_plane_state *plane_state = kvzalloc_obj(*plane_state,
-							  GFP_ATOMIC);
+	struct dc_plane_state *plane_state;
+	DC_RUN_WITH_PREEMPTION_ENABLED(plane_state = kvzalloc_obj(*plane_state, GFP_ATOMIC));
 
 	if (NULL == plane_state)
 		return NULL;
-- 
2.55.0

Fix for stable with the old error handling in
dc_create_stream_for_sink() and compile fix form arm64/clang.

Bert Karwatzki