Message ID | 20241106161445.189399-2-masahiroy@kernel.org (mailing list archive) |
---|---|
State | New |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | None | expand |
On Thu, Nov 7, 2024 at 1:15 AM Masahiro Yamada <masahiroy@kernel.org> wrote: > > Commit b1fca27d384e ("kernel debug: support resetting WARN*_ONCE") > added support for clearing the state of once warnings. However, > it is not functional when CONFIG_LD_DEAD_CODE_DATA_ELIMINATION or > CONFIG_LTO_CLANG is enabled, because .data.unlikely matches the This is a copy-paste error. s/.data.unlikely/.data.once/ > .data.[0-9a-zA-Z_]* pattern in the DATA_MAIN macro. > > Commit cb87481ee89d ("kbuild: linker script do not match C names unless > LD_DEAD_CODE_DATA_ELIMINATION is configured") was introduced to suppress > the issue for the default CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=n case, > providing a minimal fix for stable backporting. We were aware this did > not address the issue for CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y. The > plan was to apply correct fixes and then revert cb87481ee89d. [1] > > Seven years have passed since then, yet the #ifdef workaround remains in > place. Meanwhile, commit b1fca27d384e introduced the .data.once section, > and commit dc5723b02e52 ("kbuild: add support for Clang LTO") extended > the #ifdef. > > Using a ".." separator in the section name fixes the issue for > CONFIG_LD_DEAD_CODE_DATA_ELIMINATION and CONFIG_LTO_CLANG. > > [1]: https://lore.kernel.org/linux-kbuild/CAK7LNASck6BfdLnESxXUeECYL26yUDm0cwRZuM4gmaWUkxjL5g@mail.gmail.com/ > > Fixes: b1fca27d384e ("kernel debug: support resetting WARN*_ONCE") > Fixes: dc5723b02e52 ("kbuild: add support for Clang LTO") > Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> > --- > > include/asm-generic/vmlinux.lds.h | 2 +- > include/linux/mmdebug.h | 6 +++--- > include/linux/once.h | 4 ++-- > include/linux/once_lite.h | 2 +- > include/net/net_debug.h | 2 +- > mm/internal.h | 2 +- > 6 files changed, 9 insertions(+), 9 deletions(-) > > diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h > index 3c9dc1fd094d..54504013c749 100644 > --- a/include/asm-generic/vmlinux.lds.h > +++ b/include/asm-generic/vmlinux.lds.h > @@ -359,7 +359,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) > *(.data..shared_aligned) /* percpu related */ \ > *(.data..unlikely) \ > __start_once = .; \ > - *(.data.once) \ > + *(.data..once) \ > __end_once = .; \ > STRUCT_ALIGN(); \ > *(__tracepoints) \ > diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h > index 39a7714605a7..d7cb1e5ecbda 100644 > --- a/include/linux/mmdebug.h > +++ b/include/linux/mmdebug.h > @@ -46,7 +46,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi); > } \ > } while (0) > #define VM_WARN_ON_ONCE_PAGE(cond, page) ({ \ > - static bool __section(".data.once") __warned; \ > + static bool __section(".data..once") __warned; \ > int __ret_warn_once = !!(cond); \ > \ > if (unlikely(__ret_warn_once && !__warned)) { \ > @@ -66,7 +66,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi); > unlikely(__ret_warn); \ > }) > #define VM_WARN_ON_ONCE_FOLIO(cond, folio) ({ \ > - static bool __section(".data.once") __warned; \ > + static bool __section(".data..once") __warned; \ > int __ret_warn_once = !!(cond); \ > \ > if (unlikely(__ret_warn_once && !__warned)) { \ > @@ -77,7 +77,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi); > unlikely(__ret_warn_once); \ > }) > #define VM_WARN_ON_ONCE_MM(cond, mm) ({ \ > - static bool __section(".data.once") __warned; \ > + static bool __section(".data..once") __warned; \ > int __ret_warn_once = !!(cond); \ > \ > if (unlikely(__ret_warn_once && !__warned)) { \ > diff --git a/include/linux/once.h b/include/linux/once.h > index bc714d414448..30346fcdc799 100644 > --- a/include/linux/once.h > +++ b/include/linux/once.h > @@ -46,7 +46,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key, > #define DO_ONCE(func, ...) \ > ({ \ > bool ___ret = false; \ > - static bool __section(".data.once") ___done = false; \ > + static bool __section(".data..once") ___done = false; \ > static DEFINE_STATIC_KEY_TRUE(___once_key); \ > if (static_branch_unlikely(&___once_key)) { \ > unsigned long ___flags; \ > @@ -64,7 +64,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key, > #define DO_ONCE_SLEEPABLE(func, ...) \ > ({ \ > bool ___ret = false; \ > - static bool __section(".data.once") ___done = false; \ > + static bool __section(".data..once") ___done = false; \ > static DEFINE_STATIC_KEY_TRUE(___once_key); \ > if (static_branch_unlikely(&___once_key)) { \ > ___ret = __do_once_sleepable_start(&___done); \ > diff --git a/include/linux/once_lite.h b/include/linux/once_lite.h > index b7bce4983638..27de7bc32a06 100644 > --- a/include/linux/once_lite.h > +++ b/include/linux/once_lite.h > @@ -12,7 +12,7 @@ > > #define __ONCE_LITE_IF(condition) \ > ({ \ > - static bool __section(".data.once") __already_done; \ > + static bool __section(".data..once") __already_done; \ > bool __ret_cond = !!(condition); \ > bool __ret_once = false; \ > \ > diff --git a/include/net/net_debug.h b/include/net/net_debug.h > index 1e74684cbbdb..4a79204c8d30 100644 > --- a/include/net/net_debug.h > +++ b/include/net/net_debug.h > @@ -27,7 +27,7 @@ void netdev_info(const struct net_device *dev, const char *format, ...); > > #define netdev_level_once(level, dev, fmt, ...) \ > do { \ > - static bool __section(".data.once") __print_once; \ > + static bool __section(".data..once") __print_once; \ > \ > if (!__print_once) { \ > __print_once = true; \ > diff --git a/mm/internal.h b/mm/internal.h > index 93083bbeeefa..a23f7b11b760 100644 > --- a/mm/internal.h > +++ b/mm/internal.h > @@ -48,7 +48,7 @@ struct folio_batch; > * when we specify __GFP_NOWARN. > */ > #define WARN_ON_ONCE_GFP(cond, gfp) ({ \ > - static bool __section(".data.once") __warned; \ > + static bool __section(".data..once") __warned; \ > int __ret_warn_once = !!(cond); \ > \ > if (unlikely(!(gfp & __GFP_NOWARN) && __ret_warn_once && !__warned)) { \ > -- > 2.43.0 >
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 3c9dc1fd094d..54504013c749 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -359,7 +359,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) *(.data..shared_aligned) /* percpu related */ \ *(.data..unlikely) \ __start_once = .; \ - *(.data.once) \ + *(.data..once) \ __end_once = .; \ STRUCT_ALIGN(); \ *(__tracepoints) \ diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h index 39a7714605a7..d7cb1e5ecbda 100644 --- a/include/linux/mmdebug.h +++ b/include/linux/mmdebug.h @@ -46,7 +46,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi); } \ } while (0) #define VM_WARN_ON_ONCE_PAGE(cond, page) ({ \ - static bool __section(".data.once") __warned; \ + static bool __section(".data..once") __warned; \ int __ret_warn_once = !!(cond); \ \ if (unlikely(__ret_warn_once && !__warned)) { \ @@ -66,7 +66,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi); unlikely(__ret_warn); \ }) #define VM_WARN_ON_ONCE_FOLIO(cond, folio) ({ \ - static bool __section(".data.once") __warned; \ + static bool __section(".data..once") __warned; \ int __ret_warn_once = !!(cond); \ \ if (unlikely(__ret_warn_once && !__warned)) { \ @@ -77,7 +77,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi); unlikely(__ret_warn_once); \ }) #define VM_WARN_ON_ONCE_MM(cond, mm) ({ \ - static bool __section(".data.once") __warned; \ + static bool __section(".data..once") __warned; \ int __ret_warn_once = !!(cond); \ \ if (unlikely(__ret_warn_once && !__warned)) { \ diff --git a/include/linux/once.h b/include/linux/once.h index bc714d414448..30346fcdc799 100644 --- a/include/linux/once.h +++ b/include/linux/once.h @@ -46,7 +46,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key, #define DO_ONCE(func, ...) \ ({ \ bool ___ret = false; \ - static bool __section(".data.once") ___done = false; \ + static bool __section(".data..once") ___done = false; \ static DEFINE_STATIC_KEY_TRUE(___once_key); \ if (static_branch_unlikely(&___once_key)) { \ unsigned long ___flags; \ @@ -64,7 +64,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key, #define DO_ONCE_SLEEPABLE(func, ...) \ ({ \ bool ___ret = false; \ - static bool __section(".data.once") ___done = false; \ + static bool __section(".data..once") ___done = false; \ static DEFINE_STATIC_KEY_TRUE(___once_key); \ if (static_branch_unlikely(&___once_key)) { \ ___ret = __do_once_sleepable_start(&___done); \ diff --git a/include/linux/once_lite.h b/include/linux/once_lite.h index b7bce4983638..27de7bc32a06 100644 --- a/include/linux/once_lite.h +++ b/include/linux/once_lite.h @@ -12,7 +12,7 @@ #define __ONCE_LITE_IF(condition) \ ({ \ - static bool __section(".data.once") __already_done; \ + static bool __section(".data..once") __already_done; \ bool __ret_cond = !!(condition); \ bool __ret_once = false; \ \ diff --git a/include/net/net_debug.h b/include/net/net_debug.h index 1e74684cbbdb..4a79204c8d30 100644 --- a/include/net/net_debug.h +++ b/include/net/net_debug.h @@ -27,7 +27,7 @@ void netdev_info(const struct net_device *dev, const char *format, ...); #define netdev_level_once(level, dev, fmt, ...) \ do { \ - static bool __section(".data.once") __print_once; \ + static bool __section(".data..once") __print_once; \ \ if (!__print_once) { \ __print_once = true; \ diff --git a/mm/internal.h b/mm/internal.h index 93083bbeeefa..a23f7b11b760 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -48,7 +48,7 @@ struct folio_batch; * when we specify __GFP_NOWARN. */ #define WARN_ON_ONCE_GFP(cond, gfp) ({ \ - static bool __section(".data.once") __warned; \ + static bool __section(".data..once") __warned; \ int __ret_warn_once = !!(cond); \ \ if (unlikely(!(gfp & __GFP_NOWARN) && __ret_warn_once && !__warned)) { \
Commit b1fca27d384e ("kernel debug: support resetting WARN*_ONCE") added support for clearing the state of once warnings. However, it is not functional when CONFIG_LD_DEAD_CODE_DATA_ELIMINATION or CONFIG_LTO_CLANG is enabled, because .data.unlikely matches the .data.[0-9a-zA-Z_]* pattern in the DATA_MAIN macro. Commit cb87481ee89d ("kbuild: linker script do not match C names unless LD_DEAD_CODE_DATA_ELIMINATION is configured") was introduced to suppress the issue for the default CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=n case, providing a minimal fix for stable backporting. We were aware this did not address the issue for CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y. The plan was to apply correct fixes and then revert cb87481ee89d. [1] Seven years have passed since then, yet the #ifdef workaround remains in place. Meanwhile, commit b1fca27d384e introduced the .data.once section, and commit dc5723b02e52 ("kbuild: add support for Clang LTO") extended the #ifdef. Using a ".." separator in the section name fixes the issue for CONFIG_LD_DEAD_CODE_DATA_ELIMINATION and CONFIG_LTO_CLANG. [1]: https://lore.kernel.org/linux-kbuild/CAK7LNASck6BfdLnESxXUeECYL26yUDm0cwRZuM4gmaWUkxjL5g@mail.gmail.com/ Fixes: b1fca27d384e ("kernel debug: support resetting WARN*_ONCE") Fixes: dc5723b02e52 ("kbuild: add support for Clang LTO") Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- include/asm-generic/vmlinux.lds.h | 2 +- include/linux/mmdebug.h | 6 +++--- include/linux/once.h | 4 ++-- include/linux/once_lite.h | 2 +- include/net/net_debug.h | 2 +- mm/internal.h | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-)