diff mbox series

[2/2] Rename .data.once to .data..once to fix resetting WARN*_ONCE

Message ID 20241106161445.189399-2-masahiroy@kernel.org (mailing list archive)
State New
Delegated to: Netdev Maintainers
Headers show
Series None | expand

Commit Message

Masahiro Yamada Nov. 6, 2024, 4:14 p.m. UTC
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(-)

Comments

Masahiro Yamada Nov. 6, 2024, 4:39 p.m. UTC | #1
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 mbox series

Patch

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)) { \