* [PATCH] drm/edid: reduce update_display_info() stack usage
@ 2026-10-13 20:51 Arnd Bergmann
2026-10-19 13:28 ` Jani Nikula
0 siblings, 1 reply; 3+ messages in thread
From: Arnd Bergmann @ 2026-10-13 20:51 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter
Cc: Arnd Bergmann, Mario Limonciello (AMD),
Chenyu Chen, Jani Nikula, Alex Deucher, Harry Wentland,
dri-devel, linux-kernel
From: Arnd Bergmann <arnd@arndb.de>
The drm_parse_cea_ext() calls into nine individual parser functions
based on the data format. If all of those get inlined and KASAN_STACK
is enabled, this can explode the combined stack usage beyond a
reasonable amount:
drivers/gpu/drm/drm_edid.c: In function 'update_display_info':
drivers/gpu/drm/drm_edid.c:7040:1: error: the frame size of 1888 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
7040 | }
| ^
Mark all of the individual parser functions as noinline_for_stack
to avoid this and keep their stack frames separate. This reduces
the stack usage for update_display_info/drm_parse_cea_ext to
a more manageable 744 bytes, while each parser only adds at most
200 bytes on top.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 3148038747b6..913a8bbe8894 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5341,8 +5341,9 @@ static int edid_hfeeodb_extension_block_count(const struct edid *edid)
* etc). For example, if the bit 0 in bitmap is set, first mode in VDB can
* support YCBCR420 output too.
*/
-static void parse_cta_y420cmdb(struct drm_connector *connector,
- const struct cea_db *db, u64 *y420cmdb_map)
+static noinline_for_stack void
+parse_cta_y420cmdb(struct drm_connector *connector, const struct cea_db *db,
+ u64 *y420cmdb_map)
{
struct drm_display_info *info = &connector->display_info;
int i, map_len = cea_db_payload_len(db) - 1;
@@ -5515,7 +5516,7 @@ static uint8_t hdr_metadata_type(const u8 *edid_ext)
BIT(HDMI_STATIC_METADATA_TYPE1);
}
-static void
+static noinline_for_stack void
drm_parse_hdr_metadata_block(struct drm_connector *connector, const u8 *db)
{
struct hdr_static_metadata *hdr_metadata =
@@ -6070,7 +6071,8 @@ drm_default_rgb_quant_range(const struct drm_display_mode *mode)
EXPORT_SYMBOL(drm_default_rgb_quant_range);
/* CTA-861 Video Data Block (CTA VDB) */
-static void parse_cta_vdb(struct drm_connector *connector, const struct cea_db *db)
+static noinline_for_stack void
+parse_cta_vdb(struct drm_connector *connector, const struct cea_db *db)
{
struct drm_display_info *info = &connector->display_info;
int i, vic_index, len = cea_db_payload_len(db);
@@ -6136,8 +6138,8 @@ static bool cta_vdb_has_vic(const struct drm_connector *connector, u8 vic)
}
/* CTA-861-H YCbCr 4:2:0 Video Data Block (CTA Y420VDB) */
-static void parse_cta_y420vdb(struct drm_connector *connector,
- const struct cea_db *db)
+static noinline_for_stack void
+parse_cta_y420vdb(struct drm_connector *connector, const struct cea_db *db)
{
struct drm_display_info *info = &connector->display_info;
struct drm_hdmi_info *hdmi = &info->hdmi;
@@ -6155,7 +6157,8 @@ static void parse_cta_y420vdb(struct drm_connector *connector,
}
}
-static void drm_parse_vcdb(struct drm_connector *connector, const u8 *db)
+static noinline_for_stack void
+drm_parse_vcdb(struct drm_connector *connector, const u8 *db)
{
struct drm_display_info *info = &connector->display_info;
@@ -6310,8 +6313,8 @@ static void drm_parse_dsc_info(struct drm_hdmi_dsc_cap *hdmi_dsc,
}
/* Sink Capability Data Structure */
-static void drm_parse_hdmi_forum_scds(struct drm_connector *connector,
- const u8 *hf_scds)
+static noinline_for_stack void
+drm_parse_hdmi_forum_scds(struct drm_connector *connector, const u8 *hf_scds)
{
struct drm_display_info *info = &connector->display_info;
struct drm_hdmi_info *hdmi = &info->hdmi;
@@ -6451,7 +6454,7 @@ static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
}
/* HDMI Vendor-Specific Data Block (HDMI VSDB, H14b-VSDB) */
-static void
+static noinline_for_stack void
drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db)
{
struct drm_display_info *info = &connector->display_info;
@@ -6486,8 +6489,8 @@ drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db)
* See EDID extension for head-mounted and specialized monitors, specified at:
* https://docs.microsoft.com/en-us/windows-hardware/drivers/display/specialized-monitors-edid-extension
*/
-static void drm_parse_microsoft_vsdb(struct drm_connector *connector,
- const u8 *db)
+static noinline_for_stack void
+drm_parse_microsoft_vsdb(struct drm_connector *connector, const u8 *db)
{
struct drm_display_info *info = &connector->display_info;
u8 version = db[4];
@@ -6558,8 +6561,8 @@ static void drm_parse_amd_vsdb_v3(struct drm_display_info *info,
info->amd_vsdb.max_frame_rate = max_frame_rate;
}
-static void drm_parse_amd_vsdb(struct drm_connector *connector,
- const struct cea_db *db)
+static noinline_for_stack void
+drm_parse_amd_vsdb(struct drm_connector *connector, const struct cea_db *db)
{
struct drm_display_info *info = &connector->display_info;
const u8 *data = cea_db_data(db);
--
2.53.0
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] drm/edid: reduce update_display_info() stack usage
2026-10-13 20:51 [PATCH] drm/edid: reduce update_display_info() stack usage Arnd Bergmann
@ 2026-10-19 13:28 ` Jani Nikula
2026-10-19 16:15 ` Arnd Bergmann
0 siblings, 1 reply; 3+ messages in thread
From: Jani Nikula @ 2026-10-19 13:28 UTC (permalink / raw)
To: Arnd Bergmann, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: Arnd Bergmann, Mario Limonciello (AMD),
Chenyu Chen, Alex Deucher, Harry Wentland, dri-devel,
linux-kernel
On Tue, 13 Oct 2026, Arnd Bergmann <arnd@kernel.org> wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> The drm_parse_cea_ext() calls into nine individual parser functions
> based on the data format. If all of those get inlined and KASAN_STACK
> is enabled, this can explode the combined stack usage beyond a
> reasonable amount:
>
> drivers/gpu/drm/drm_edid.c: In function 'update_display_info':
> drivers/gpu/drm/drm_edid.c:7040:1: error: the frame size of 1888 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
> 7040 | }
> | ^
>
> Mark all of the individual parser functions as noinline_for_stack
> to avoid this and keep their stack frames separate. This reduces
> the stack usage for update_display_info/drm_parse_cea_ext to
> a more manageable 744 bytes, while each parser only adds at most
> 200 bytes on top.
Is there really no way to tell the compiler to not do silly things in a
more generic way?
BR,
Jani.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++++--------------
> 1 file changed, 17 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 3148038747b6..913a8bbe8894 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -5341,8 +5341,9 @@ static int edid_hfeeodb_extension_block_count(const struct edid *edid)
> * etc). For example, if the bit 0 in bitmap is set, first mode in VDB can
> * support YCBCR420 output too.
> */
> -static void parse_cta_y420cmdb(struct drm_connector *connector,
> - const struct cea_db *db, u64 *y420cmdb_map)
> +static noinline_for_stack void
> +parse_cta_y420cmdb(struct drm_connector *connector, const struct cea_db *db,
> + u64 *y420cmdb_map)
> {
> struct drm_display_info *info = &connector->display_info;
> int i, map_len = cea_db_payload_len(db) - 1;
> @@ -5515,7 +5516,7 @@ static uint8_t hdr_metadata_type(const u8 *edid_ext)
> BIT(HDMI_STATIC_METADATA_TYPE1);
> }
>
> -static void
> +static noinline_for_stack void
> drm_parse_hdr_metadata_block(struct drm_connector *connector, const u8 *db)
> {
> struct hdr_static_metadata *hdr_metadata =
> @@ -6070,7 +6071,8 @@ drm_default_rgb_quant_range(const struct drm_display_mode *mode)
> EXPORT_SYMBOL(drm_default_rgb_quant_range);
>
> /* CTA-861 Video Data Block (CTA VDB) */
> -static void parse_cta_vdb(struct drm_connector *connector, const struct cea_db *db)
> +static noinline_for_stack void
> +parse_cta_vdb(struct drm_connector *connector, const struct cea_db *db)
> {
> struct drm_display_info *info = &connector->display_info;
> int i, vic_index, len = cea_db_payload_len(db);
> @@ -6136,8 +6138,8 @@ static bool cta_vdb_has_vic(const struct drm_connector *connector, u8 vic)
> }
>
> /* CTA-861-H YCbCr 4:2:0 Video Data Block (CTA Y420VDB) */
> -static void parse_cta_y420vdb(struct drm_connector *connector,
> - const struct cea_db *db)
> +static noinline_for_stack void
> +parse_cta_y420vdb(struct drm_connector *connector, const struct cea_db *db)
> {
> struct drm_display_info *info = &connector->display_info;
> struct drm_hdmi_info *hdmi = &info->hdmi;
> @@ -6155,7 +6157,8 @@ static void parse_cta_y420vdb(struct drm_connector *connector,
> }
> }
>
> -static void drm_parse_vcdb(struct drm_connector *connector, const u8 *db)
> +static noinline_for_stack void
> +drm_parse_vcdb(struct drm_connector *connector, const u8 *db)
> {
> struct drm_display_info *info = &connector->display_info;
>
> @@ -6310,8 +6313,8 @@ static void drm_parse_dsc_info(struct drm_hdmi_dsc_cap *hdmi_dsc,
> }
>
> /* Sink Capability Data Structure */
> -static void drm_parse_hdmi_forum_scds(struct drm_connector *connector,
> - const u8 *hf_scds)
> +static noinline_for_stack void
> +drm_parse_hdmi_forum_scds(struct drm_connector *connector, const u8 *hf_scds)
> {
> struct drm_display_info *info = &connector->display_info;
> struct drm_hdmi_info *hdmi = &info->hdmi;
> @@ -6451,7 +6454,7 @@ static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
> }
>
> /* HDMI Vendor-Specific Data Block (HDMI VSDB, H14b-VSDB) */
> -static void
> +static noinline_for_stack void
> drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db)
> {
> struct drm_display_info *info = &connector->display_info;
> @@ -6486,8 +6489,8 @@ drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db)
> * See EDID extension for head-mounted and specialized monitors, specified at:
> * https://docs.microsoft.com/en-us/windows-hardware/drivers/display/specialized-monitors-edid-extension
> */
> -static void drm_parse_microsoft_vsdb(struct drm_connector *connector,
> - const u8 *db)
> +static noinline_for_stack void
> +drm_parse_microsoft_vsdb(struct drm_connector *connector, const u8 *db)
> {
> struct drm_display_info *info = &connector->display_info;
> u8 version = db[4];
> @@ -6558,8 +6561,8 @@ static void drm_parse_amd_vsdb_v3(struct drm_display_info *info,
> info->amd_vsdb.max_frame_rate = max_frame_rate;
> }
>
> -static void drm_parse_amd_vsdb(struct drm_connector *connector,
> - const struct cea_db *db)
> +static noinline_for_stack void
> +drm_parse_amd_vsdb(struct drm_connector *connector, const struct cea_db *db)
> {
> struct drm_display_info *info = &connector->display_info;
> const u8 *data = cea_db_data(db);
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] drm/edid: reduce update_display_info() stack usage
2026-10-19 13:28 ` Jani Nikula
@ 2026-10-19 16:15 ` Arnd Bergmann
0 siblings, 0 replies; 3+ messages in thread
From: Arnd Bergmann @ 2026-10-19 16:15 UTC (permalink / raw)
To: Jani Nikula, Arnd Bergmann, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Dave Airlie, Simona Vetter
Cc: Mario Limonciello (AMD),
Chenyu Chen, Alex Deucher, Harry Wentland, dri-devel,
linux-kernel
On Mon, Oct 19, 2026, at 15:28, Jani Nikula wrote:
> On Tue, 13 Oct 2026, Arnd Bergmann <arnd@kernel.org> wrote:
>> From: Arnd Bergmann <arnd@arndb.de>
>>
>> The drm_parse_cea_ext() calls into nine individual parser functions
>> based on the data format. If all of those get inlined and KASAN_STACK
>> is enabled, this can explode the combined stack usage beyond a
>> reasonable amount:
>>
>> drivers/gpu/drm/drm_edid.c: In function 'update_display_info':
>> drivers/gpu/drm/drm_edid.c:7040:1: error: the frame size of 1888 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
>> 7040 | }
>> | ^
>>
>> Mark all of the individual parser functions as noinline_for_stack
>> to avoid this and keep their stack frames separate. This reduces
>> the stack usage for update_display_info/drm_parse_cea_ext to
>> a more manageable 744 bytes, while each parser only adds at most
>> 200 bytes on top.
>
> Is there really no way to tell the compiler to not do silly things in a
> more generic way?
The problem is really the sanitizers here, which turn off the
optimizations that gcc relies on for its normal behavior and
which cause additional register pressure for the inserted function
calls.
Arnd
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-19 16:16 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-13 20:51 [PATCH] drm/edid: reduce update_display_info() stack usage Arnd Bergmann
2026-10-19 13:28 ` Jani Nikula
2026-10-19 16:15 ` Arnd Bergmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®