Re: [PATCH] drm/amd/display: fix usage of DC_FPU_{BEGIN, END} with PREEMPT_RT
Mikhail Gavrilov <[email protected]> Sat, 1 Aug 2026 15:17:04 +0500
| 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 | <CABXGCsMFa25HyOdcSX8QR8_=58=uJT+HMVhyus=rOFHBML25=w@mail.gmail.com> |
On Sat, Aug 1, 2026 at 12:17=E2=80=AFPM Bert Karwatzki <[email protected]> w= rote: > > 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 - P= art 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 | 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/gp= u/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/g= pu/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_sta= te, const struct dc_plane > ***********************************************************************= *******/ > struct dc_plane_state *dc_create_plane_state(const struct dc *dc) > { > - struct dc_plane_state *plane_state =3D kvzalloc_obj(*plane_state, > - GFP_ATOMIC); > + struct dc_plane_state *plane_state; > + DC_RUN_WITH_PREEMPTION_ENABLED(plane_state =3D kvzalloc_obj(*plan= e_state, GFP_ATOMIC)); This hunk breaks the build when CONFIG_DRM_AMD_DC_FP=3Dn. 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=3Dn 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=3D1 ARCH=3Darm64 allmodconfig $ make LLVM=3D1 ARCH=3Darm64 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 =3D kvzalloc_obj(*plane_state, GFP_ATOMIC)); A plain x86_64 build (DC_FP=3Dy) 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. --=20 Best Regards, Mikhail Gavrilov.