Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Rename .data.once to .data..once to fix resetting WARN*_ONCE

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.once 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>

+9 -9
+1 -1
include/asm-generic/vmlinux.lds.h
··· 359 359 *(.data..shared_aligned) /* percpu related */ \ 360 360 *(.data..unlikely) \ 361 361 __start_once = .; \ 362 - *(.data.once) \ 362 + *(.data..once) \ 363 363 __end_once = .; \ 364 364 STRUCT_ALIGN(); \ 365 365 *(__tracepoints) \
+3 -3
include/linux/mmdebug.h
··· 46 46 } \ 47 47 } while (0) 48 48 #define VM_WARN_ON_ONCE_PAGE(cond, page) ({ \ 49 - static bool __section(".data.once") __warned; \ 49 + static bool __section(".data..once") __warned; \ 50 50 int __ret_warn_once = !!(cond); \ 51 51 \ 52 52 if (unlikely(__ret_warn_once && !__warned)) { \ ··· 66 66 unlikely(__ret_warn); \ 67 67 }) 68 68 #define VM_WARN_ON_ONCE_FOLIO(cond, folio) ({ \ 69 - static bool __section(".data.once") __warned; \ 69 + static bool __section(".data..once") __warned; \ 70 70 int __ret_warn_once = !!(cond); \ 71 71 \ 72 72 if (unlikely(__ret_warn_once && !__warned)) { \ ··· 77 77 unlikely(__ret_warn_once); \ 78 78 }) 79 79 #define VM_WARN_ON_ONCE_MM(cond, mm) ({ \ 80 - static bool __section(".data.once") __warned; \ 80 + static bool __section(".data..once") __warned; \ 81 81 int __ret_warn_once = !!(cond); \ 82 82 \ 83 83 if (unlikely(__ret_warn_once && !__warned)) { \
+2 -2
include/linux/once.h
··· 46 46 #define DO_ONCE(func, ...) \ 47 47 ({ \ 48 48 bool ___ret = false; \ 49 - static bool __section(".data.once") ___done = false; \ 49 + static bool __section(".data..once") ___done = false; \ 50 50 static DEFINE_STATIC_KEY_TRUE(___once_key); \ 51 51 if (static_branch_unlikely(&___once_key)) { \ 52 52 unsigned long ___flags; \ ··· 64 64 #define DO_ONCE_SLEEPABLE(func, ...) \ 65 65 ({ \ 66 66 bool ___ret = false; \ 67 - static bool __section(".data.once") ___done = false; \ 67 + static bool __section(".data..once") ___done = false; \ 68 68 static DEFINE_STATIC_KEY_TRUE(___once_key); \ 69 69 if (static_branch_unlikely(&___once_key)) { \ 70 70 ___ret = __do_once_sleepable_start(&___done); \
+1 -1
include/linux/once_lite.h
··· 12 12 13 13 #define __ONCE_LITE_IF(condition) \ 14 14 ({ \ 15 - static bool __section(".data.once") __already_done; \ 15 + static bool __section(".data..once") __already_done; \ 16 16 bool __ret_cond = !!(condition); \ 17 17 bool __ret_once = false; \ 18 18 \
+1 -1
include/net/net_debug.h
··· 27 27 28 28 #define netdev_level_once(level, dev, fmt, ...) \ 29 29 do { \ 30 - static bool __section(".data.once") __print_once; \ 30 + static bool __section(".data..once") __print_once; \ 31 31 \ 32 32 if (!__print_once) { \ 33 33 __print_once = true; \
+1 -1
mm/internal.h
··· 48 48 * when we specify __GFP_NOWARN. 49 49 */ 50 50 #define WARN_ON_ONCE_GFP(cond, gfp) ({ \ 51 - static bool __section(".data.once") __warned; \ 51 + static bool __section(".data..once") __warned; \ 52 52 int __ret_warn_once = !!(cond); \ 53 53 \ 54 54 if (unlikely(!(gfp & __GFP_NOWARN) && __ret_warn_once && !__warned)) { \