Re: [PATCH] drm/amd/display: fix usage of DC_FPU_{BEGIN,END} with PREEMPT_RT
From: Mikhail Gavrilov
Date: Sat Aug 01 2026 - 06:18:40 EST
On Sat, Aug 1, 2026 at 12:17 PM Bert Karwatzki <spasswolf@xxxxxx> wrote:
>
> 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/20260723123449.6494-1-spasswolf@xxxxxx/
>
> Signed-off-by: Bert Karwatzki <spasswolf@xxxxxx>
> ---
> drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 2 +-
> drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 4 ++--
> 2 files changed, 3 insertions(+), 3 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 cdcf140bc1bb..accad9e20e88 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
> @@ -229,7 +229,7 @@ struct dc_stream_state *dc_create_stream_for_sink(
>
> fail:
> if (stream)
> - kfree(stream);
> + 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 88e825a6582c..d5c6427796b6 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
> @@ -85,8 +85,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));
This hunk breaks the build when CONFIG_DRM_AMD_DC_FP=n.
dc_surface.c gets DC_RUN_WITH_PREEMPTION_ENABLED only indirectly, via
dc.h -> dc_types.h -> os_types.h, and there the include is guarded:
#if defined(CONFIG_DRM_AMD_DC_FP)
#include "amdgpu_dm/dc_fpu.h"
#endif
With DC_FP=n nothing defines the macro in that file. dc_stream.c is not
affected because it includes dc_fpu.h directly.
This is not only exotic architectures: DRM_AMD_DC has
select DRM_AMD_DC_FP if ARCH_HAS_KERNEL_FPU_SUPPORT && \
!(CC_IS_CLANG && (ARM64 || LOONGARCH || RISCV))
so an arm64 clang build is enough. On amd-staging-drm-next with your
patch applied:
$ make LLVM=1 ARCH=arm64 allmodconfig
$ make LLVM=1 ARCH=arm64 drivers/gpu/drm/amd/amdgpu/
dc_surface.c:89:2: error: call to undeclared function
'DC_RUN_WITH_PREEMPTION_ENABLED'; ISO C99 and later do not support
implicit function declarations [-Wimplicit-function-declaration]
89 | DC_RUN_WITH_PREEMPTION_ENABLED(plane_state =
kvzalloc_obj(*plane_state, GFP_ATOMIC));
A plain x86_64 build (DC_FP=y) is clean, which is presumably why it did
not show up for you.
Adding
#include "dc_fpu.h"
to dc_surface.c fixes it, and matches what dc_stream.c already does.
Please do not copy the local fallback that sits below that include in
dc_stream.c:
#if !defined(DC_RUN_WITH_PREEMPTION_ENABLED)
#define DC_RUN_WITH_PREEMPTION_ENABLED(code) code
#endif
It is dead code there - dc_fpu.h defines the macro in every branch - and
in a new file it would compile cleanly while quietly doing nothing.
One unrelated note: you kept Cc: stable # v7.1, but this version is
rebased onto next-20260729, where the update_scratch allocation is gone
from dc_create_stream_for_sink(). It does not apply to current mainline
either, so older trees will need a separate backport - worth saying so
in the commit message.
With the include added I can give this a Tested-by on dcn32 (RX 7900
XTX), which exercises the DML1 phantom-plane path rather than the dml21
one you hit.
--
Best Regards,
Mikhail Gavrilov.