[RFC PATCH 1/5] pgo: Expose module sections for clang PGO instumentation.

From: Jarmo Tiitto
Date: Fri Jun 11 2021 - 23:36:46 EST


Expose module sections for clang PGO:
In find_module_sections() add code to grab pointer and size
of __llvm_prf_{data,cnts,names,vnds} sections.

This data is used by pgo/instrument.c and pgo/fs.c
in following patches together with explicitly exposed
vmlinux's core __llvm_prf_xxx sections.

Signed-off-by: Jarmo Tiitto <jarmo.tiitto@xxxxxxxxx>
---
the reason of disabling profiling for module.c
is that instrumented kernel changes struct module layout,
and thus invalidates profile data collected from module.c
when optimized kernel it built.

More over the profile data from kernel/module.c
is probably not needed either way.
---
include/linux/module.h | 15 +++++++++++++++
kernel/Makefile | 6 ++++++
kernel/module.c | 7 +++++++
3 files changed, 28 insertions(+)

diff --git a/include/linux/module.h b/include/linux/module.h
index 8100bb477d86..7f557016e879 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -492,6 +492,21 @@ struct module {
unsigned long *kprobe_blacklist;
unsigned int num_kprobe_blacklist;
#endif
+#ifdef CONFIG_PGO_CLANG
+ /*
+ * Keep in sync with the PGO_CLANG_DATA sections
+ * in include/asm-generic/vmlinux.lds.h
+ * The prf_xxx_size is the section size in bytes.
+ */
+ void *prf_data; /* struct llvm_prf_data */
+ int prf_data_size;
+ void *prf_cnts;
+ int prf_cnts_size;
+ const void *prf_names;
+ int prf_names_size;
+ void *prf_vnds; /* struct llvm_prf_value_node */
+ int prf_vnds_size;
+#endif
#ifdef CONFIG_HAVE_STATIC_CALL_INLINE
int num_static_call_sites;
struct static_call_site *static_call_sites;
diff --git a/kernel/Makefile b/kernel/Makefile
index 6deef4effbdb..8657d67b771c 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -44,6 +44,12 @@ CFLAGS_kcov.o := $(call cc-option, -fno-conserve-stack) -fno-stack-protector
# Don't instrument error handlers
CFLAGS_REMOVE_cfi.o := $(CC_FLAGS_CFI)

+# Don't profile module.c:
+# CLANG_PGO changes the layout of struct module
+# for instrumented kernel so the profile data
+# will mismatch on final build.
+PGO_PROFILE_module.o := n
+
obj-y += sched/
obj-y += locking/
obj-y += power/
diff --git a/kernel/module.c b/kernel/module.c
index b5dd92e35b02..a2f65c247c41 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3329,6 +3329,13 @@ static int find_module_sections(struct module *mod, struct load_info *info)
sizeof(*mod->static_call_sites),
&mod->num_static_call_sites);
#endif
+#ifdef CONFIG_PGO_CLANG
+ mod->prf_data = section_objs(info, "__llvm_prf_data", 1, &mod->prf_data_size);
+ mod->prf_cnts = section_objs(info, "__llvm_prf_cnts", 1, &mod->prf_cnts_size);
+ mod->prf_names = section_objs(info, "__llvm_prf_names", 1, &mod->prf_names_size);
+ mod->prf_vnds = section_objs(info, "__llvm_prf_vnds", 1, &mod->prf_vnds_size);
+#endif
+
mod->extable = section_objs(info, "__ex_table",
sizeof(*mod->extable), &mod->num_exentries);


base-commit: 0039303120c0065f3952698597e0c9916b76ebd5
--
2.32.0