ad57ea
From 3b4c6c6acfd781f34ce6318b1a80a800dd5c11ad Mon Sep 17 00:00:00 2001
ad57ea
From: Song Liu <songliubraving@fb.com>
ad57ea
Date: Wed, 13 Oct 2021 00:10:20 -0700
ad57ea
Subject: [PATCH 1/2] create-diff-object: compare section name with
ad57ea
 kpatch_section_function_name
ad57ea
ad57ea
Profile-Guided Optimization (PGO) uses profiling data to help the compiler
ad57ea
to evaluate the properties of a function, and thus adds different prefixes
ad57ea
to the section/function. For example, with -ffunction-sections, the
ad57ea
compiler will prefix some sectiones with .text.unlikely. However, if a
ad57ea
function changes from the version in the profiling data, the compiler may
ad57ea
ignore the profiling data. This often happens to the patched function
ad57ea
when kpatch-build builds the patch. As a result, the original function
ad57ea
and the patch function may have different prefix, i.e., one of them has
ad57ea
.text, the other has .text.unlikely.
ad57ea
ad57ea
To correlate these functions properly, use kpatch_section_function_name()
ad57ea
in kpatch_correlate_sections() to find matching sections.
ad57ea
ad57ea
Signed-off-by: Song Liu <songliubraving@fb.com>
ad57ea
---
ad57ea
 kpatch-build/create-diff-object.c | 7 +++++--
ad57ea
 1 file changed, 5 insertions(+), 2 deletions(-)
ad57ea
ad57ea
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
ad57ea
index 6a4848a2..c3b37dc3 100644
ad57ea
--- a/kpatch-build/create-diff-object.c
ad57ea
+++ b/kpatch-build/create-diff-object.c
ad57ea
@@ -957,6 +957,8 @@ static void kpatch_correlate_section(struct section *sec_orig,
ad57ea
 		kpatch_correlate_symbol(sec_orig->sym, sec_patched->sym);
ad57ea
 }
ad57ea
 
ad57ea
+static char *kpatch_section_function_name(struct section *sec);
ad57ea
+
ad57ea
 static void kpatch_correlate_sections(struct list_head *seclist_orig,
ad57ea
 		struct list_head *seclist_patched)
ad57ea
 {
ad57ea
@@ -966,8 +968,9 @@ static void kpatch_correlate_sections(struct list_head *seclist_orig,
ad57ea
 		if (sec_orig->twin)
ad57ea
 			continue;
ad57ea
 		list_for_each_entry(sec_patched, seclist_patched, list) {
ad57ea
-			if (kpatch_mangled_strcmp(sec_orig->name, sec_patched->name) ||
ad57ea
-			    sec_patched->twin)
ad57ea
+			if (sec_patched->twin ||
ad57ea
+			    kpatch_mangled_strcmp(kpatch_section_function_name(sec_orig),
ad57ea
+						  kpatch_section_function_name(sec_patched)))
ad57ea
 				continue;
ad57ea
 
ad57ea
 			if (is_special_static(is_rela_section(sec_orig) ?
ad57ea
ad57ea
From 6d93e41500959170ca222cd17362a5dcfe2945f6 Mon Sep 17 00:00:00 2001
ad57ea
From: Song Liu <songliubraving@fb.com>
ad57ea
Date: Wed, 13 Oct 2021 01:03:55 -0700
ad57ea
Subject: [PATCH 2/2] kpatch-build: add support for clang pgo
ad57ea
ad57ea
For clang with Profile-Guided Optimization (PGO), profile data is needed
ad57ea
to compile the livepatch properly. Add option -p|--profile-data, which
ad57ea
specifies the profile data file. This option is only valid with
ad57ea
CONFIG_CC_IS_CLANG and CONFIG_PGO_CLANG.
ad57ea
ad57ea
Signed-off-by: Song Liu <songliubraving@fb.com>
ad57ea
---
ad57ea
 kpatch-build/kpatch-build | 22 +++++++++++++++++++++-
ad57ea
 1 file changed, 21 insertions(+), 1 deletion(-)
ad57ea
ad57ea
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
ad57ea
index 3a9902e5..d8bee557 100755
ad57ea
--- a/kpatch-build/kpatch-build
ad57ea
+++ b/kpatch-build/kpatch-build
ad57ea
@@ -538,9 +538,10 @@ usage() {
ad57ea
 	echo "		--skip-cleanup          Skip post-build cleanup" >&2
ad57ea
 	echo "		--skip-compiler-check   Skip compiler version matching check" >&2
ad57ea
 	echo "		                        (not recommended)" >&2
ad57ea
+	echo "		-p, --profile-data      specify profile data for PGO (clang only)" >&2
ad57ea
 }
ad57ea
 
ad57ea
-options="$(getopt -o ha:r:s:c:v:j:t:n:o:de:R -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,oot-module:,debug,skip-gcc-check,skip-compiler-check,skip-cleanup,non-replace" -- "$@")" || die "getopt failed"
ad57ea
+options="$(getopt -o ha:r:s:c:v:j:t:n:o:de:Rp: -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,oot-module:,debug,skip-gcc-check,skip-compiler-check,skip-cleanup,non-replace,profile-data" -- "$@")" || die "getopt failed"
ad57ea
 
ad57ea
 eval set -- "$options"
ad57ea
 
ad57ea
@@ -617,6 +618,10 @@ while [[ $# -gt 0 ]]; do
ad57ea
 		echo "WARNING: Skipping compiler version matching check (not recommended)"
ad57ea
 		SKIPCOMPILERCHECK=1
ad57ea
 		;;
ad57ea
+	-p|--profile-data)
ad57ea
+		PROFILE_DATA="$(readlink -f "$2")"
ad57ea
+		shift
ad57ea
+		;;
ad57ea
 	*)
ad57ea
 		[[ "$1" = "--" ]] && shift && continue
ad57ea
 		[[ ! -f "$1" ]] && die "patch file '$1' not found"
ad57ea
@@ -835,6 +840,7 @@ CONFIG_JUMP_LABEL=0
ad57ea
 CONFIG_MODVERSIONS=0
ad57ea
 CONFIG_CC_IS_CLANG=0
ad57ea
 CONFIG_LD_IS_LLD=0
ad57ea
+CONFIG_PGO_CLANG=0
ad57ea
 
ad57ea
 if grep -q "CONFIG_LIVEPATCH=y" "$CONFIGFILE" && (kernel_is_rhel || kernel_version_gte 4.9.0); then
ad57ea
 
ad57ea
@@ -869,6 +875,7 @@ grep -q "CONFIG_JUMP_LABEL=y"   "$CONFIGFILE" && CONFIG_JUMP_LABEL=1
ad57ea
 grep -q "CONFIG_MODVERSIONS=y"  "$CONFIGFILE" && CONFIG_MODVERSIONS=1
ad57ea
 grep -q "CONFIG_CC_IS_CLANG=y"  "$CONFIGFILE" && CONFIG_CC_IS_CLANG=1
ad57ea
 grep -q "CONFIG_LD_IS_LLD=y"    "$CONFIGFILE" && CONFIG_LD_IS_LLD=1
ad57ea
+grep -q "CONFIG_PGO_CLANG=y"    "$CONFIGFILE" && CONFIG_PGO_CLANG=1
ad57ea
 
ad57ea
 # unsupported kernel option checking
ad57ea
 grep -q "CONFIG_DEBUG_INFO_SPLIT=y" "$CONFIGFILE" && die "kernel option 'CONFIG_DEBUG_INFO_SPLIT' not supported"
ad57ea
@@ -891,6 +898,16 @@ fi
ad57ea
 
ad57ea
 if [[ "$CONFIG_CC_IS_CLANG" -eq 1 ]]; then
ad57ea
 	echo "WARNING: Clang support is experimental"
ad57ea
+	if [[ -z "$PROFILE_DATA" ]] && [[ "$CONFIG_PGO_CLANG" -eq 1 ]]; then
ad57ea
+		die "Please specify profile-data for CONFIG_PGO_CLANG"
ad57ea
+	fi
ad57ea
+	if [[ -n "$PROFILE_DATA" ]] && [[ "$CONFIG_PGO_CLANG" -eq 0 ]]; then
ad57ea
+		echo "WARNING profile-data specified w/o CONFIG_PGO_CLANG, ignore it"
ad57ea
+	fi
ad57ea
+else
ad57ea
+	if [[ -n "$PROFILE_DATA" ]]; then
ad57ea
+		die "Only supports profile-data with Clang"
ad57ea
+	fi
ad57ea
 fi
ad57ea
 
ad57ea
 if [[ "$SKIPCOMPILERCHECK" -eq 0 ]]; then
ad57ea
@@ -937,6 +954,9 @@ declare -a MAKEVARS
ad57ea
 if [ "$CONFIG_CC_IS_CLANG" -eq 1 ]; then
ad57ea
 	MAKEVARS+=("CC=${KPATCH_CC_PREFIX}clang")
ad57ea
 	MAKEVARS+=("HOSTCC=clang")
ad57ea
+	if [[ "$CONFIG_PGO_CLANG" -eq 1 ]]; then
ad57ea
+		MAKEVARS+=("CFLAGS_PGO_CLANG=-fprofile-use=$PROFILE_DATA")
ad57ea
+	fi
ad57ea
 else
ad57ea
 	MAKEVARS+=("CC=${KPATCH_CC_PREFIX}gcc")
ad57ea
 fi