media: v4l2-tpg: reduce stack usage for kasan builds

tpg_fill_plane_buffer() is a rather complex function. While there is
nothing wrong with it per se, I have run into corner cases with clang-22
on s390 using KASAN that makes it run out of registers and blow the
stack warning limit from excessive spills:

drivers/media/common/v4l2-tpg/v4l2-tpg-core.c:2629:6: error: stack frame size (1560) exceeds limit (1536)
      in 'tpg_fill_plane_buffer' [-Werror,-Wframe-larger-than]
 2629 | void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,

Forcing the two largest callees out of line completely avoids the problem
and prevents all the register spills, with the stack usage for each function
going down to a few bytes for the local variables.

Arguably this is a problem caused by clang rather than the code, but
a noinline_for_stack annotation is an easy workaround.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
Arnd Bergmann
2026-06-18 16:32:47 +02:00
committed by Hans Verkuil
parent 627a121c15
commit c49cdaafa4

View File

@@ -2346,9 +2346,11 @@ static void tpg_fill_params_extras(const struct tpg_data *tpg,
(params->is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
}
static void tpg_fill_plane_extras(const struct tpg_data *tpg,
const struct tpg_draw_params *params,
unsigned p, unsigned h, u8 *vbuf)
/* noinline to work around clang KASAN issues */
static noinline_for_stack void
tpg_fill_plane_extras(const struct tpg_data *tpg,
const struct tpg_draw_params *params,
unsigned p, unsigned h, u8 *vbuf)
{
unsigned twopixsize = params->twopixsize;
unsigned img_width = params->img_width;
@@ -2483,9 +2485,9 @@ static void tpg_fill_plane_extras(const struct tpg_data *tpg,
}
}
static void tpg_fill_plane_pattern(const struct tpg_data *tpg,
const struct tpg_draw_params *params,
unsigned p, unsigned h, u8 *vbuf)
static noinline_for_stack void
tpg_fill_plane_pattern(const struct tpg_data *tpg, const struct tpg_draw_params *params,
unsigned p, unsigned h, u8 *vbuf)
{
unsigned twopixsize = params->twopixsize;
unsigned img_width = params->img_width;