Skip to content

-Wframe-larger-than in sound/soc/intel/avs/path.c #1642

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nathanchance opened this issue May 16, 2022 · 7 comments
Closed

-Wframe-larger-than in sound/soc/intel/avs/path.c #1642

nathanchance opened this issue May 16, 2022 · 7 comments
Assignees
Labels
-Wframe-larger-than= [BUG] linux A bug that should be fixed in the mainline kernel. CONFIG_WERROR Has in an error with CONFIG_WERROR (all{mod,yes}config) (or emits a non-compiler warning) [FIXED][LINUX] 6.0 This bug was fixed in Linux 6.0 [Reported-by] KernelCI Reported-by: kernelci.org bot <[email protected]>

Comments

@nathanchance
Copy link
Member

Initially reported by KernelCI: https://lore.kernel.org/[email protected]/

On arm64 allmodconfig:

$ make -skj"$(nproc)" ARCH=arm64 LLVM=1 mrproper allmodconfig sound/soc/intel/avs/path.o
sound/soc/intel/avs/path.c:815:18: error: stack frame size (2176) exceeds limit (2048) in 'avs_path_create' [-Werror,-Wframe-larger-than]
struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
                 ^
1 error generated.

I don't see any particularly large objects on the stack with frame_larger_than.py, could just be an inlining issue?

frame_larger_than.py output
$ python3 ../../github/frame-larger-than/frame_larger_than.py
avs_path_create:
        0       const struct pi_entry           _entry
        8       const struct pi_entry*          _entry_ptr
        8       struct avs_path*                path
        8       struct avs_tplg_path*           variant
avs_path_create_unlocked:
        4       int                             ret
        8       struct avs_path*                path
        4       int                             ret
kzalloc:
kmalloc:
        4       unsigned int                    index
avs_path_init:
        8       struct avs_tplg_pipeline*       tppl
        8       void*                           __mptr
        8       struct avs_path_pipeline*       ppl
        8       void*                           __mptr
        8       struct avs_tplg_pipeline*       tppl
INIT_LIST_HEAD:
INIT_LIST_HEAD:
        8       struct avs_path_pipeline*       ppl
avs_path_pipeline_create:
        4       int                             i
        4       int                             ret
        8       struct avs_tplg_module*         tmod
        8       struct avs_path_pipeline*       ppl
        8       struct avs_tplg_pplcfg*         cfg
        8       void*                           __mptr
        8       struct avs_path_module*         mod
        8       void*                           __mptr
        8       struct avs_path_binding*        binding
        4       int                             i
        4       int                             ret
        8       struct avs_tplg_module*         tmod
kzalloc:
kmalloc:
        4       unsigned int                    index
INIT_LIST_HEAD:
INIT_LIST_HEAD:
INIT_LIST_HEAD:
        8       struct avs_path_module*         mod
avs_path_module_create:
        4       int                             module_id
        4       int                             ret
        8       struct avs_path_module*         mod
        4       int                             module_id
        4       int                             ret
        8       struct avs_path_module*         mod
kzalloc:
kmalloc:
        4       unsigned int                    index
INIT_LIST_HEAD:
avs_path_module_type_create:
        8       const guid_t*                   type
guid_equal:
memcmp:
        8       size_t                          q_size
        8       size_t                          p_size
        8       size_t                          q_size
        8       size_t                          p_size
guid_equal:
memcmp:
        8       size_t                          q_size
        8       size_t                          p_size
        8       size_t                          q_size
        8       size_t                          p_size
guid_equal:
memcmp:
        8       size_t                          q_size
        8       size_t                          p_size
        8       size_t                          q_size
        8       size_t                          p_size
avs_modbase_create:
        40      struct avs_modcfg_base          cfg
        8       struct avs_tplg_module*         t
        40      struct avs_modcfg_base          cfg
guid_equal:
memcmp:
        8       size_t                          q_size
        8       size_t                          p_size
        8       size_t                          q_size
        8       size_t                          p_size
avs_copier_create:
        4       int                             ret
        4       u32                             dma_type
        8       void*                           data
        8       size_t                          data_size
        8       size_t                          cfg_size
        4       union avs_connector_node_id     node_id
        8       struct nhlt_specific_cfg*       ep_blob
        8       struct avs_copier_cfg*          cfg
        8       struct nhlt_acpi_table*         nhlt
        8       struct avs_tplg_module*         t
        8       size_t                          __fortify_size
        4       int                             ret
        4       u32                             dma_type
        8       void*                           data
        8       size_t                          data_size
        8       size_t                          cfg_size
        4       union avs_connector_node_id     node_id
        8       struct nhlt_specific_cfg*       ep_blob
        8       struct avs_copier_cfg*          cfg
kzalloc:
kmalloc:
        4       unsigned int                    index
guid_equal:
memcmp:
        8       size_t                          q_size
        8       size_t                          p_size
        8       size_t                          q_size
        8       size_t                          p_size
avs_micsel_create:
        64      struct avs_micsel_cfg           cfg
        8       struct avs_tplg_module*         t
        64      struct avs_micsel_cfg           cfg
guid_equal:
memcmp:
        8       size_t                          q_size
        8       size_t                          p_size
        8       size_t                          q_size
        8       size_t                          p_size
avs_mux_create:
        88      struct avs_mux_cfg              cfg
        8       struct avs_tplg_module*         t
        88      struct avs_mux_cfg              cfg
guid_equal:
memcmp:
        8       size_t                          q_size
        8       size_t                          p_size
        8       size_t                          q_size
        8       size_t                          p_size
avs_updown_mix_create:
        84      struct avs_updown_mixer_cfg     cfg
        4       int                             i
        8       struct avs_tplg_module*         t
        84      struct avs_updown_mixer_cfg     cfg
        4       int                             i
guid_equal:
memcmp:
        8       size_t                          q_size
        8       size_t                          p_size
        8       size_t                          q_size
        8       size_t                          p_size
avs_src_create:
        44      struct avs_src_cfg              cfg
        8       struct avs_tplg_module*         t
        44      struct avs_src_cfg              cfg
guid_equal:
memcmp:
        8       size_t                          q_size
        8       size_t                          p_size
        8       size_t                          q_size
        8       size_t                          p_size
avs_aec_create:
        92      struct avs_aec_cfg              cfg
        8       struct avs_tplg_module*         t
        92      struct avs_aec_cfg              cfg
guid_equal:
memcmp:
        8       size_t                          q_size
        8       size_t                          p_size
        8       size_t                          q_size
        8       size_t                          p_size
avs_asrc_create:
        48      struct avs_asrc_cfg             cfg
        8       struct avs_tplg_module*         t
        48      struct avs_asrc_cfg             cfg
guid_equal:
memcmp:
        8       size_t                          q_size
        8       size_t                          p_size
        8       size_t                          q_size
        8       size_t                          p_size
avs_wov_create:
        44      struct avs_wov_cfg              cfg
        8       struct avs_tplg_module*         t
        44      struct avs_wov_cfg              cfg
guid_equal:
memcmp:
        8       size_t                          q_size
        8       size_t                          p_size
        8       size_t                          q_size
        8       size_t                          p_size
avs_modext_create:
        4       int                             i
        4       int                             ret
        8       size_t                          num_pins
        8       size_t                          cfg_size
        8       struct avs_tplg_module*         t
        8       struct avs_tplg_modcfg_ext*     tcfg
        8       struct avs_modcfg_ext*          cfg
        8       struct avs_tplg_pin_format*     tpin
        8       struct avs_pin_format*          pin
        4       int                             i
        4       int                             ret
        8       size_t                          num_pins
        8       size_t                          cfg_size
kzalloc:
kmalloc:
        4       unsigned int                    index
list_add_tail:
__list_add:
        8       struct avs_path_binding*        binding
avs_path_binding_create:
        8       struct avs_path_binding*        binding
kzalloc:
kmalloc:
        4       unsigned int                    index
INIT_LIST_HEAD:
list_add_tail:
__list_add:
list_add_tail:
__list_add:
spin_lock:
list_add_tail:
__list_add:
spin_unlock:
avs_path_arm:
        4       int                             ret
        8       struct avs_path_pipeline*       ppl
        8       struct avs_path_binding*        binding
        8       void*                           __mptr
        8       void*                           __mptr
        8       void*                           __mptr
        8       void*                           __mptr
        4       int                             ret
        8       struct avs_path_pipeline*       ppl
        8       struct avs_path_binding*        binding
avs_path_binding_arm:
        8       struct avs_path_module*         target_mod
        8       struct avs_path_module*         this_mod
        8       struct avs_path_pipeline*       target_ppl
        8       struct avs_path*                target_path
        8       struct avs_tplg_binding*        t
        8       struct avs_path_module*         target_mod
        8       struct avs_path_module*         this_mod
avs_path_find_module:
        8       struct avs_path_module*         mod
        8       void*                           __mptr
        8       void*                           __mptr
        8       struct avs_path_module*         mod
avs_path_find_path:
        8       struct avs_path*                path
        8       struct avs_tplg*                tplg
        8       struct avs_tplg_path_template*  pos
        8       struct avs_tplg_path_template*  template
        8       void*                           __mptr
        8       void*                           __mptr
        8       void*                           __mptr
        8       void*                           __mptr
        8       struct avs_path*                path
        8       struct avs_tplg*                tplg
        8       struct avs_tplg_path_template*  pos
        8       struct avs_tplg_path_template*  template
avs_path_find_tplg:
        8       struct avs_soc_component*       acomp
        8       void*                           __mptr
        8       void*                           __mptr
        8       struct avs_soc_component*       acomp
spin_lock:
avs_path_find_pipeline:
        8       struct avs_path_pipeline*       ppl
        8       void*                           __mptr
        8       void*                           __mptr
        8       struct avs_path_pipeline*       ppl
avs_path_find_module:
        8       struct avs_path_module*         mod
        8       void*                           __mptr
        8       void*                           __mptr
        8       struct avs_path_module*         mod
avs_path_pipeline_arm:
        8       struct avs_path_module*         mod
        8       void*                           __mptr
        4       int                             ret
        8       struct avs_path_module*         sink
        8       struct avs_path_module*         source
        8       void*                           __mptr
        8       void*                           __mptr
        8       void*                           __mptr
        8       struct avs_path_module*         mod
        4       int                             ret
        8       struct avs_path_module*         sink
        8       struct avs_path_module*         source

It seems like something might be going on with avs_path_module_type_create() based on that output?

@nathanchance nathanchance added -Wframe-larger-than= [BUG] linux-next This is an issue only seen in linux-next [Reported-by] KernelCI Reported-by: kernelci.org bot <[email protected]> labels May 16, 2022
@nathanchance nathanchance changed the title -Wframe-larger-than in sound/soc/intel/avs/path.o -Wframe-larger-than in sound/soc/intel/avs/path.c May 16, 2022
@nickdesaulniers
Copy link
Member

I wonder why memcmp has so many local variables? Also looks like there's tons of __mptr. Hmm...

@nathanchance
Copy link
Member Author

I see __mptr in container_of, which might be used in that file through includes (I don't see any references to container_of in the actual source file).

@nathanchance
Copy link
Member Author

I finally got around to looking into this further. It can be reproduced with this minimal set of configs on top of allnoconfig:

$ echo "CONFIG_COMPILE_TEST=y
CONFIG_FORTIFY_SOURCE=y
CONFIG_KASAN=y
CONFIG_PCI=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_INTEL_AVS=y" >allno.config

$ make -skj"$(nproc)" ARCH=arm64 KCONFIG_ALLCONFIG=1 LLVM=1 mrproper allnoconfig sound/soc/intel/avs/path.o
sound/soc/intel/avs/path.c:815:18: warning: stack frame size (2144) exceeds limit (2048) in 'avs_path_create' [-Wframe-larger-than]
struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
                 ^
1 warning generated.

I wonder why memcmp has so many local variables?

It is because of CONFIG_FORTIFY_SOURCE, which is critical for reproducing this issue. guid_equal() is just a wrapper around memcmp(), which is redefined in include/linux/fortify-string.h with p_size and q_size for compile time checking. guid_equal() is called several times in avs_path_module_type_create().

The __mptr comes from container_of, as I mentioned above, which is in turn called within list_for_each_entry() and list_for_each_entry_safe(), which are used frequently in sound/soc/intel/avs/path.c.

It seems like this is just caused by excessive inlining plus KASAN not reusing stack slots? I am leaning towards sending this diff, which drastically reduces the stack usage, as can be seen by adding CONFIG_FRAME_WARN=128 to the above set of configs, but I am not sure if that is a proper solution here; I'd appreciate input from others.

$ git diff
diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
index 3d46dd5e5bc4..ec2aa0001f91 100644
--- a/sound/soc/intel/avs/path.c
+++ b/sound/soc/intel/avs/path.c
@@ -449,7 +449,8 @@ static int avs_modext_create(struct avs_dev *adev, struct avs_path_module *mod)
        return ret;
 }

-static int avs_path_module_type_create(struct avs_dev *adev, struct avs_path_module *mod)
+static noinline_for_stack int avs_path_module_type_create(struct avs_dev *adev,
+                                                         struct avs_path_module *mod)
 {
        const guid_t *type = &mod->template->cfg_ext->type;

$ make -skj"$(nproc)" ARCH=arm64 KCONFIG_ALLCONFIG=1 LLVM=1 mrproper allnoconfig sound/soc/intel/avs/path.o
sound/soc/intel/avs/path.c:816:18: warning: stack frame size (192) exceeds limit (128) in 'avs_path_create' [-Wframe-larger-than]
struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
                 ^
sound/soc/intel/avs/path.c:874:5: warning: stack frame size (256) exceeds limit (128) in 'avs_path_bind' [-Wframe-larger-than]
int avs_path_bind(struct avs_path *path)
    ^
sound/soc/intel/avs/path.c:452:31: warning: stack frame size (352) exceeds limit (128) in 'avs_path_module_type_create' [-Wframe-larger-than]
static noinline_for_stack int avs_path_module_type_create(struct avs_dev *adev,
                              ^
sound/soc/intel/avs/path.c:344:12: warning: stack frame size (160) exceeds limit (128) in 'avs_mux_create' [-Wframe-larger-than]
static int avs_mux_create(struct avs_dev *adev, struct avs_path_module *mod)
           ^
sound/soc/intel/avs/path.c:267:12: warning: stack frame size (160) exceeds limit (128) in 'avs_updown_mix_create' [-Wframe-larger-than]
static int avs_updown_mix_create(struct avs_dev *adev, struct avs_path_module *mod)
           ^
sound/soc/intel/avs/path.c:325:12: warning: stack frame size (160) exceeds limit (128) in 'avs_aec_create' [-Wframe-larger-than]
static int avs_aec_create(struct avs_dev *adev, struct avs_path_module *mod)
           ^
6 warnings generated.

@nathanchance nathanchance added [BUG] linux A bug that should be fixed in the mainline kernel. CONFIG_WERROR Has in an error with CONFIG_WERROR (all{mod,yes}config) (or emits a non-compiler warning) and removed [BUG] linux-next This is an issue only seen in linux-next labels Jun 15, 2022
@nathanchance
Copy link
Member Author

I have sent the above diff for review: https://lore.kernel.org/[email protected]/

@nathanchance nathanchance self-assigned this Jul 20, 2022
@nathanchance nathanchance added the [PATCH] Submitted A patch has been submitted for review label Jul 20, 2022
intel-lab-lkp pushed a commit to intel-lab-lkp/linux that referenced this issue Jul 20, 2022
When building ARCH=arm64 allmodconfig with clang, there is a warning
about high stack usage in avs_path_create(), which breaks the build due
to CONFIG_WERROR=y:

  sound/soc/intel/avs/path.c:815:18: error: stack frame size (2176) exceeds limit (2048) in 'avs_path_create' [-Werror,-Wframe-larger-than]
  struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
                   ^
  1 error generated.

This warning is also visible with allmodconfig on other architectures.
The minimum set of configs that triggers this on top of ARCH=arm64
allnoconfig:

  CONFIG_COMPILE_TEST=y
  CONFIG_FORTIFY_SOURCE=y
  CONFIG_KASAN=y
  CONFIG_PCI=y
  CONFIG_SOUND=y
  CONFIG_SND=y
  CONFIG_SND_SOC=y
  CONFIG_SND_SOC_INTEL_AVS=y

When CONFIG_FORTIFY_SOURCE is enabled, memcmp() (called from
guid_equal()) becomes a wrapper to do compile time checking, which
interacts poorly with inlining plus CONFIG_KASAN=y.

With ARCH=arm64 allmodconfig + CONFIG_KASAN=n + CONFIG_FRAME_WARN=128,
the stack usage is much better:

  sound/soc/intel/avs/path.c:815:18: warning: stack frame size (624) exceeds limit (128) in 'avs_path_create' [-Wframe-larger-than]
  struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
                   ^
  sound/soc/intel/avs/path.c:873:5: warning: stack frame size (144) exceeds limit (128) in 'avs_path_bind' [-Wframe-larger-than]
  int avs_path_bind(struct avs_path *path)
      ^
  2 warnings generated.

To avoid this warning, mark avs_path_module_type_create() as
noinline_for_stack, which redistributes the stack usage across multiple
functions, regardless of CONFIG_KASAN.

With ARCH=arm64 allmodconfig + CONFIG_FRAME_WARN=128, the warnings show:

  avs_path_create():             192
  avs_path_bind():               272
  avs_path_module_type_create(): 416
  avs_mux_create():              160
  avs_updown_mix_create():       160
  avs_aec_create():              176
  avs_asrc_create():             144

With ARCH=arm64 allmodconfig + CONFIG_FRAME_WARN=128 + CONFIG_KASAN=n,
the warnings show:

  avs_path_create():             192
  avs_path_bind():               144
  avs_path_module_type_create(): 416
  avs_mux_create():              176
  avs_updown_mix_create():       176
  avs_src_create():              144
  avs_aec_create():              192
  avs_asrc_create():             144
  avs_wov_create():              144

Link: ClangBuiltLinux#1642
Signed-off-by: Nathan Chancellor <[email protected]>
intel-lab-lkp pushed a commit to intel-lab-lkp/linux that referenced this issue Jul 22, 2022
As reported by Nathan, when building avs driver using clang with:
  CONFIG_COMPILE_TEST=y
  CONFIG_FORTIFY_SOURCE=y
  CONFIG_KASAN=y
  CONFIG_PCI=y
  CONFIG_SOUND=y
  CONFIG_SND=y
  CONFIG_SND_SOC=y
  CONFIG_SND_SOC_INTEL_AVS=y

there are reports of too big stack use, like:
  sound/soc/intel/avs/path.c:815:18: error: stack frame size (2176) exceeds limit (2048) in 'avs_path_create' [-Werror,-Wframe-larger-than]
  struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
                   ^
  1 error generated.

This is apparently caused by inlining many calls to guid_equal which
inlines fortified memcpy, using 2 size_t variables.

Instead of hardcoding many calls to guid_equal, use lookup table with
one call, this improves stack usage.

Link: https://lore.kernel.org/alsa-devel/[email protected]/T/
Link: ClangBuiltLinux#1642
Signed-off-by: Amadeusz Sławiński <[email protected]>
Reported-by: Nathan Chancellor <[email protected]>
Build-tested-by: Nathan Chancellor <[email protected]>
@nathanchance
Copy link
Member Author

Alternative patch submitted: https://lore.kernel.org/[email protected]/

ammarfaizi2 pushed a commit to ammarfaizi2/linux-block that referenced this issue Jul 22, 2022
As reported by Nathan, when building avs driver using clang with:
  CONFIG_COMPILE_TEST=y
  CONFIG_FORTIFY_SOURCE=y
  CONFIG_KASAN=y
  CONFIG_PCI=y
  CONFIG_SOUND=y
  CONFIG_SND=y
  CONFIG_SND_SOC=y
  CONFIG_SND_SOC_INTEL_AVS=y

there are reports of too big stack use, like:
  sound/soc/intel/avs/path.c:815:18: error: stack frame size (2176) exceeds limit (2048) in 'avs_path_create' [-Werror,-Wframe-larger-than]
  struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
                   ^
  1 error generated.

This is apparently caused by inlining many calls to guid_equal which
inlines fortified memcpy, using 2 size_t variables.

Instead of hardcoding many calls to guid_equal, use lookup table with
one call, this improves stack usage.

Link: https://lore.kernel.org/alsa-devel/[email protected]/T/
Link: ClangBuiltLinux/linux#1642
Signed-off-by: Amadeusz Sławiński <[email protected]>
Reported-by: Nathan Chancellor <[email protected]>
Build-tested-by: Nathan Chancellor <[email protected]>
Reviewed-by: Cezary Rojewski <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Mark Brown <[email protected]>
@nathanchance
Copy link
Member Author

@nathanchance nathanchance added [PATCH] Accepted A submitted patch has been accepted upstream and removed [PATCH] Submitted A patch has been submitted for review labels Jul 22, 2022
@nathanchance
Copy link
Member Author

@nathanchance nathanchance added [FIXED][LINUX] 6.0 This bug was fixed in Linux 6.0 and removed [PATCH] Accepted A submitted patch has been accepted upstream labels Aug 15, 2022
ammarfaizi2 pushed a commit to ammarfaizi2/linux-fork that referenced this issue Aug 16, 2022
commit 1e74435 upstream.

As reported by Nathan, when building avs driver using clang with:
  CONFIG_COMPILE_TEST=y
  CONFIG_FORTIFY_SOURCE=y
  CONFIG_KASAN=y
  CONFIG_PCI=y
  CONFIG_SOUND=y
  CONFIG_SND=y
  CONFIG_SND_SOC=y
  CONFIG_SND_SOC_INTEL_AVS=y

there are reports of too big stack use, like:
  sound/soc/intel/avs/path.c:815:18: error: stack frame size (2176) exceeds limit (2048) in 'avs_path_create' [-Werror,-Wframe-larger-than]
  struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
                   ^
  1 error generated.

This is apparently caused by inlining many calls to guid_equal which
inlines fortified memcpy, using 2 size_t variables.

Instead of hardcoding many calls to guid_equal, use lookup table with
one call, this improves stack usage.

Link: https://lore.kernel.org/alsa-devel/[email protected]/T/
Link: ClangBuiltLinux#1642
Signed-off-by: Amadeusz Sławiński <[email protected]>
Reported-by: Nathan Chancellor <[email protected]>
Build-tested-by: Nathan Chancellor <[email protected]>
Reviewed-by: Cezary Rojewski <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Mark Brown <[email protected]>
Cc: Naresh Kamboju <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
ammarfaizi2 pushed a commit to ammarfaizi2/linux-fork that referenced this issue Aug 16, 2022
commit 1e74435 upstream.

As reported by Nathan, when building avs driver using clang with:
  CONFIG_COMPILE_TEST=y
  CONFIG_FORTIFY_SOURCE=y
  CONFIG_KASAN=y
  CONFIG_PCI=y
  CONFIG_SOUND=y
  CONFIG_SND=y
  CONFIG_SND_SOC=y
  CONFIG_SND_SOC_INTEL_AVS=y

there are reports of too big stack use, like:
  sound/soc/intel/avs/path.c:815:18: error: stack frame size (2176) exceeds limit (2048) in 'avs_path_create' [-Werror,-Wframe-larger-than]
  struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
                   ^
  1 error generated.

This is apparently caused by inlining many calls to guid_equal which
inlines fortified memcpy, using 2 size_t variables.

Instead of hardcoding many calls to guid_equal, use lookup table with
one call, this improves stack usage.

Link: https://lore.kernel.org/alsa-devel/[email protected]/T/
Link: ClangBuiltLinux#1642
Signed-off-by: Amadeusz Sławiński <[email protected]>
Reported-by: Nathan Chancellor <[email protected]>
Build-tested-by: Nathan Chancellor <[email protected]>
Reviewed-by: Cezary Rojewski <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Mark Brown <[email protected]>
Cc: Naresh Kamboju <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
ammarfaizi2 pushed a commit to ammarfaizi2/linux-block that referenced this issue Aug 17, 2022
commit 1e74435 upstream.

As reported by Nathan, when building avs driver using clang with:
  CONFIG_COMPILE_TEST=y
  CONFIG_FORTIFY_SOURCE=y
  CONFIG_KASAN=y
  CONFIG_PCI=y
  CONFIG_SOUND=y
  CONFIG_SND=y
  CONFIG_SND_SOC=y
  CONFIG_SND_SOC_INTEL_AVS=y

there are reports of too big stack use, like:
  sound/soc/intel/avs/path.c:815:18: error: stack frame size (2176) exceeds limit (2048) in 'avs_path_create' [-Werror,-Wframe-larger-than]
  struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
                   ^
  1 error generated.

This is apparently caused by inlining many calls to guid_equal which
inlines fortified memcpy, using 2 size_t variables.

Instead of hardcoding many calls to guid_equal, use lookup table with
one call, this improves stack usage.

Link: https://lore.kernel.org/alsa-devel/[email protected]/T/
Link: ClangBuiltLinux/linux#1642
Signed-off-by: Amadeusz Sławiński <[email protected]>
Reported-by: Nathan Chancellor <[email protected]>
Build-tested-by: Nathan Chancellor <[email protected]>
Reviewed-by: Cezary Rojewski <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Mark Brown <[email protected]>
Cc: Naresh Kamboju <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Whissi pushed a commit to Whissi/linux-stable that referenced this issue Aug 17, 2022
commit 1e74435 upstream.

As reported by Nathan, when building avs driver using clang with:
  CONFIG_COMPILE_TEST=y
  CONFIG_FORTIFY_SOURCE=y
  CONFIG_KASAN=y
  CONFIG_PCI=y
  CONFIG_SOUND=y
  CONFIG_SND=y
  CONFIG_SND_SOC=y
  CONFIG_SND_SOC_INTEL_AVS=y

there are reports of too big stack use, like:
  sound/soc/intel/avs/path.c:815:18: error: stack frame size (2176) exceeds limit (2048) in 'avs_path_create' [-Werror,-Wframe-larger-than]
  struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
                   ^
  1 error generated.

This is apparently caused by inlining many calls to guid_equal which
inlines fortified memcpy, using 2 size_t variables.

Instead of hardcoding many calls to guid_equal, use lookup table with
one call, this improves stack usage.

Link: https://lore.kernel.org/alsa-devel/[email protected]/T/
Link: ClangBuiltLinux/linux#1642
Signed-off-by: Amadeusz Sławiński <[email protected]>
Reported-by: Nathan Chancellor <[email protected]>
Build-tested-by: Nathan Chancellor <[email protected]>
Reviewed-by: Cezary Rojewski <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Mark Brown <[email protected]>
Cc: Naresh Kamboju <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
crojewsk-intel pushed a commit to projectceladon/linux-intel-lts2021 that referenced this issue Feb 27, 2023
As reported by Nathan, when building avs driver using clang with:
  CONFIG_COMPILE_TEST=y
  CONFIG_FORTIFY_SOURCE=y
  CONFIG_KASAN=y
  CONFIG_PCI=y
  CONFIG_SOUND=y
  CONFIG_SND=y
  CONFIG_SND_SOC=y
  CONFIG_SND_SOC_INTEL_AVS=y

there are reports of too big stack use, like:
  sound/soc/intel/avs/path.c:815:18: error: stack frame size (2176) exceeds limit (2048) in 'avs_path_create' [-Werror,-Wframe-larger-than]
  struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
                   ^
  1 error generated.

This is apparently caused by inlining many calls to guid_equal which
inlines fortified memcpy, using 2 size_t variables.

Instead of hardcoding many calls to guid_equal, use lookup table with
one call, this improves stack usage.

Link: https://lore.kernel.org/alsa-devel/[email protected]/T/
Link: ClangBuiltLinux/linux#1642
Signed-off-by: Amadeusz Sławiński <[email protected]>
Reported-by: Nathan Chancellor <[email protected]>
Build-tested-by: Nathan Chancellor <[email protected]>
Reviewed-by: Cezary Rojewski <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Mark Brown <[email protected]>
Change-Id: Idd81cf2a4c8a91009b7561008246144bc7b70584
(cherry picked from commit 1e744351bcb9c4cee81300de5a6097100d835386)
Signed-off-by: Cezary Rojewski <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
-Wframe-larger-than= [BUG] linux A bug that should be fixed in the mainline kernel. CONFIG_WERROR Has in an error with CONFIG_WERROR (all{mod,yes}config) (or emits a non-compiler warning) [FIXED][LINUX] 6.0 This bug was fixed in Linux 6.0 [Reported-by] KernelCI Reported-by: kernelci.org bot <[email protected]>
Projects
None yet
Development

No branches or pull requests

2 participants