[PATCH 1/6] pgo: modules Expose module sections for clang PGO instumentation.

From: Jarmo Tiitto
Date: Fri May 28 2021 - 16:02:49 EST


This patch series enables reading PGO profile data for
modules. It also contains some changes to instrumentation
code to fixup flaws when profile data is serialized from loaded modules.

To be able to export clang PGO profile data from modules into user space
we need to expose __llvm_prf_xxx sections from loaded modules.
This data is used by pgo/instrument.c and pgo/fs_mod.c in following patches.

====
The patch is based on Sami Tolvanen's earlier code: [1]
Patch https://lore.kernel.org/linux-doc/20210407211704.367039-1-morbo@xxxxxxxxxx/
and kernel v5.13-rc3 was used as starting point for my changes.

Be kind, I'm an kernel newbie and this is my first git send-mail. :-)

[1] https://patchwork.kernel.org/project/linux-kbuild/patch/20210407211704.367039-1-morbo@xxxxxxxxxx/
====
Signed-off-by: Jarmo Tiitto <jarmo.tiitto@xxxxxxxxx>
---
include/linux/module.h | 12 +++++++++++-
kernel/module.c | 8 +++++++-
2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/include/linux/module.h b/include/linux/module.h
index 8100bb477d86..2aa1e1fe4afa 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -504,7 +504,6 @@ struct module {
/* Elf information */
struct klp_modinfo *klp_info;
#endif
-
#ifdef CONFIG_MODULE_UNLOAD
/* What modules depend on me? */
struct list_head source_list;
@@ -527,6 +526,17 @@ struct module {
struct error_injection_entry *ei_funcs;
unsigned int num_ei_funcs;
#endif
+#ifdef CONFIG_PGO_CLANG
+ /* Clang PGO llvm_prf_xxx sections */
+ void *prf_data; /* struct llvm_prf_data */
+ int prf_data_size;
+ u64 *prf_cnts;
+ int prf_cnts_num;
+ const char *prf_names;
+ int prf_names_num;
+ void *prf_vnds; /* struct llvm_prf_value_node */
+ int prf_vnds_size;
+#endif
} ____cacheline_aligned __randomize_layout;
#ifndef MODULE_ARCH_INIT
#define MODULE_ARCH_INIT {}
diff --git a/kernel/module.c b/kernel/module.c
index 7e78dfabca97..e49de3b95d87 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3342,7 +3342,13 @@ static int find_module_sections(struct module *mod, struct load_info *info)

info->debug = section_objs(info, "__dyndbg",
sizeof(*info->debug), &info->num_debug);
-
+#ifdef CONFIG_PGO_CLANG
+ /* Grab module sections for Clang PGO profiler to hook into */
+ mod->prf_data = section_objs(info, "__llvm_prf_data", 1, &mod->prf_data_size);
+ mod->prf_cnts = section_objs(info, "__llvm_prf_cnts", sizeof(u64), &mod->prf_cnts_num);
+ mod->prf_names = section_objs(info, "__llvm_prf_names", sizeof(char), &mod->prf_names_num);
+ mod->prf_vnds = section_objs(info, "__llvm_prf_vnds", 1, &mod->prf_vnds_size);
+#endif
return 0;
}

--
2.31.1