The current clang thin-lto build often produces lots of symbols with
suffix. The following is a partial list of such function call symbols:
...
ethnl_module_fw_flash_ntf.llvm.7631589765585346066
__nf_conntrack_alloc.llvm.6438426151906658917
tcp_can_early_drop.llvm.11937612064648250727
tcp_print_conntrack.llvm.11937612064648250727
...
In my particular build with current bpf-next, the number of '*.llvm.<hash>'
function calls is 1212. As the side effect of cross-file inlining,
some static variables may be promoted with '*.llvm.<hash>' as well.
In my same setup, the number of variables with such suffixes is 9.
Such symbols make kernel live patching difficult since
- a minor code change will change the hash and then the '*.llvm.<hash>'
symbol becomes another one with a different hash. Sometimes, maybe
the suffix is gone.
- a previous source-level symbol may become a one with suffix after live
patching code.
In [1], Song Liu suggested to reduce the number of '*.llvm.<hash>' functions
to make live patch easier. In respond of this, I implemented this
in llvm ([2]). The same thin-lto build with [2] only has two symbols with
suffix:
m_stop.llvm.14460341347352036579
m_next.llvm.14460341347352036579
This should make live patch much easier.
To support suffix symbol reduction, two lld flags are necessary to enable
this feature in kernel:
- Flag '--lto-whole-program-visibility' is needed as it ensures that all
non-assembly files are available in the same thin-lto lld, which is true
for kernel.
- Flag '-mllvm -always-rename-promoted-locals=false' is needed to enable
suffix reduction. Currently in llvm [1], only process mode is supported.
There is another distributed mode (across different processes or even
different machines) which is not supported yet ([2]). The kernel uses
process mode so it should work.
The assembly files may have some global functions/data which may potentially
conflict with thin-lto global symbols after the above two flags. But such
assembly
global symbols are limited and tend to be uniquely named for its context.
Hence the conflict with globals in non-assembly codes is rare. If indeed the
conflict happens, we can rename either of them to avoid conflicts.
Nathan Chancellor suggested the following under thin-lto:
KBUILD_LDFLAGS += $(call ld-option,--lto-whole-program-visibility -mllvm
-always-rename-promoted-locals=false)
The '-mllvm -always-rename-promoted-locals=false' flag is only available for
llvm23.
So for llvm22 or earlier, the above KBUILD_LDFLAGS will ignore those two flags.
For llvm23 and later, two flags will be added to KBUILD_LDFLAGS.
[1] https://lpc.events/event/19/contributions/2212
[2] https://github.com/llvm/llvm-project/pull/178587
Signed-off-by: Yonghong Song <[email protected]>
---
Makefile | 1 +
1 file changed, 1 insertion(+)
Changelog:
v1 -> v2:
- v1:
https://lore.kernel.org/linux-kbuild/[email protected]/
- Removed the new config option and use ld-option to check whether new flags
will be used or not.
diff --git a/Makefile b/Makefile
index e944c6e71e81..e4385af16985 100644
--- a/Makefile
+++ b/Makefile
@@ -1034,6 +1034,7 @@ endif
ifdef CONFIG_LTO_CLANG
ifdef CONFIG_LTO_CLANG_THIN
CC_FLAGS_LTO := -flto=thin -fsplit-lto-unit
+KBUILD_LDFLAGS += $(call ld-option,--lto-whole-program-visibility -mllvm
-always-rename-promoted-locals=false)
else
CC_FLAGS_LTO := -flto
endif
--
2.47.3