From ad57eae9f0c25996cd7f92bbd765bea9911a666a Mon Sep 17 00:00:00 2001 From: Davide Cavalca Date: Oct 13 2021 21:37:54 +0000 Subject: Backport PR#1231 for clang PGO support --- diff --git a/SOURCES/1231.patch b/SOURCES/1231.patch new file mode 100644 index 0000000..ae061ab --- /dev/null +++ b/SOURCES/1231.patch @@ -0,0 +1,135 @@ +From 3b4c6c6acfd781f34ce6318b1a80a800dd5c11ad Mon Sep 17 00:00:00 2001 +From: Song Liu +Date: Wed, 13 Oct 2021 00:10:20 -0700 +Subject: [PATCH 1/2] create-diff-object: compare section name with + kpatch_section_function_name + +Profile-Guided Optimization (PGO) uses profiling data to help the compiler +to evaluate the properties of a function, and thus adds different prefixes +to the section/function. For example, with -ffunction-sections, the +compiler will prefix some sectiones with .text.unlikely. However, if a +function changes from the version in the profiling data, the compiler may +ignore the profiling data. This often happens to the patched function +when kpatch-build builds the patch. As a result, the original function +and the patch function may have different prefix, i.e., one of them has +.text, the other has .text.unlikely. + +To correlate these functions properly, use kpatch_section_function_name() +in kpatch_correlate_sections() to find matching sections. + +Signed-off-by: Song Liu +--- + kpatch-build/create-diff-object.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c +index 6a4848a2..c3b37dc3 100644 +--- a/kpatch-build/create-diff-object.c ++++ b/kpatch-build/create-diff-object.c +@@ -957,6 +957,8 @@ static void kpatch_correlate_section(struct section *sec_orig, + kpatch_correlate_symbol(sec_orig->sym, sec_patched->sym); + } + ++static char *kpatch_section_function_name(struct section *sec); ++ + static void kpatch_correlate_sections(struct list_head *seclist_orig, + struct list_head *seclist_patched) + { +@@ -966,8 +968,9 @@ static void kpatch_correlate_sections(struct list_head *seclist_orig, + if (sec_orig->twin) + continue; + list_for_each_entry(sec_patched, seclist_patched, list) { +- if (kpatch_mangled_strcmp(sec_orig->name, sec_patched->name) || +- sec_patched->twin) ++ if (sec_patched->twin || ++ kpatch_mangled_strcmp(kpatch_section_function_name(sec_orig), ++ kpatch_section_function_name(sec_patched))) + continue; + + if (is_special_static(is_rela_section(sec_orig) ? + +From 6d93e41500959170ca222cd17362a5dcfe2945f6 Mon Sep 17 00:00:00 2001 +From: Song Liu +Date: Wed, 13 Oct 2021 01:03:55 -0700 +Subject: [PATCH 2/2] kpatch-build: add support for clang pgo + +For clang with Profile-Guided Optimization (PGO), profile data is needed +to compile the livepatch properly. Add option -p|--profile-data, which +specifies the profile data file. This option is only valid with +CONFIG_CC_IS_CLANG and CONFIG_PGO_CLANG. + +Signed-off-by: Song Liu +--- + kpatch-build/kpatch-build | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build +index 3a9902e5..d8bee557 100755 +--- a/kpatch-build/kpatch-build ++++ b/kpatch-build/kpatch-build +@@ -538,9 +538,10 @@ usage() { + echo " --skip-cleanup Skip post-build cleanup" >&2 + echo " --skip-compiler-check Skip compiler version matching check" >&2 + echo " (not recommended)" >&2 ++ echo " -p, --profile-data specify profile data for PGO (clang only)" >&2 + } + +-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" ++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" + + eval set -- "$options" + +@@ -617,6 +618,10 @@ while [[ $# -gt 0 ]]; do + echo "WARNING: Skipping compiler version matching check (not recommended)" + SKIPCOMPILERCHECK=1 + ;; ++ -p|--profile-data) ++ PROFILE_DATA="$(readlink -f "$2")" ++ shift ++ ;; + *) + [[ "$1" = "--" ]] && shift && continue + [[ ! -f "$1" ]] && die "patch file '$1' not found" +@@ -835,6 +840,7 @@ CONFIG_JUMP_LABEL=0 + CONFIG_MODVERSIONS=0 + CONFIG_CC_IS_CLANG=0 + CONFIG_LD_IS_LLD=0 ++CONFIG_PGO_CLANG=0 + + if grep -q "CONFIG_LIVEPATCH=y" "$CONFIGFILE" && (kernel_is_rhel || kernel_version_gte 4.9.0); then + +@@ -869,6 +875,7 @@ grep -q "CONFIG_JUMP_LABEL=y" "$CONFIGFILE" && CONFIG_JUMP_LABEL=1 + grep -q "CONFIG_MODVERSIONS=y" "$CONFIGFILE" && CONFIG_MODVERSIONS=1 + grep -q "CONFIG_CC_IS_CLANG=y" "$CONFIGFILE" && CONFIG_CC_IS_CLANG=1 + grep -q "CONFIG_LD_IS_LLD=y" "$CONFIGFILE" && CONFIG_LD_IS_LLD=1 ++grep -q "CONFIG_PGO_CLANG=y" "$CONFIGFILE" && CONFIG_PGO_CLANG=1 + + # unsupported kernel option checking + grep -q "CONFIG_DEBUG_INFO_SPLIT=y" "$CONFIGFILE" && die "kernel option 'CONFIG_DEBUG_INFO_SPLIT' not supported" +@@ -891,6 +898,16 @@ fi + + if [[ "$CONFIG_CC_IS_CLANG" -eq 1 ]]; then + echo "WARNING: Clang support is experimental" ++ if [[ -z "$PROFILE_DATA" ]] && [[ "$CONFIG_PGO_CLANG" -eq 1 ]]; then ++ die "Please specify profile-data for CONFIG_PGO_CLANG" ++ fi ++ if [[ -n "$PROFILE_DATA" ]] && [[ "$CONFIG_PGO_CLANG" -eq 0 ]]; then ++ echo "WARNING profile-data specified w/o CONFIG_PGO_CLANG, ignore it" ++ fi ++else ++ if [[ -n "$PROFILE_DATA" ]]; then ++ die "Only supports profile-data with Clang" ++ fi + fi + + if [[ "$SKIPCOMPILERCHECK" -eq 0 ]]; then +@@ -937,6 +954,9 @@ declare -a MAKEVARS + if [ "$CONFIG_CC_IS_CLANG" -eq 1 ]; then + MAKEVARS+=("CC=${KPATCH_CC_PREFIX}clang") + MAKEVARS+=("HOSTCC=clang") ++ if [[ "$CONFIG_PGO_CLANG" -eq 1 ]]; then ++ MAKEVARS+=("CFLAGS_PGO_CLANG=-fprofile-use=$PROFILE_DATA") ++ fi + else + MAKEVARS+=("CC=${KPATCH_CC_PREFIX}gcc") + fi diff --git a/SPECS/kpatch.spec b/SPECS/kpatch.spec index 9109e87..3f91cac 100644 --- a/SPECS/kpatch.spec +++ b/SPECS/kpatch.spec @@ -2,7 +2,7 @@ Name: kpatch Version: 0.9.4 -Release: 1.6%{?dist} +Release: 1.7%{?dist} Summary: Dynamic kernel patch manager Group: System Environment/Kernel @@ -15,6 +15,9 @@ Source1: kpatch-dnf-v%{kpatch_dnf_ver}.tar.gz Patch0: 0001-contrib-disable-upstart-kpatch.conf-install.patch Patch1: 0002-kpatch-clarify-unload-unsupport.patch +# Upstream backports +Patch100: https://github.com/dynup/kpatch/pull/1231.patch + # kpatch-dnf backports Patch200: 0200-Makefile-set-install-permission-modes.patch @@ -58,6 +61,7 @@ kpatch-build is a tool to build patches for kpatch. %setup -q %patch0 -p1 %patch1 -p1 +%patch100 -p1 %setup -D -T -a 1 cd kpatch-dnf-%{kpatch_dnf_ver} @@ -98,6 +102,9 @@ echo -e "\t$ dnf kpatch auto" %{_mandir}/man1/kpatch-build.1* %changelog +* Wed Oct 13 2021 Davide Cavalca - 0.9.4-1.7 +- Backport PR#1231 for clang PGO support + * Fri Aug 27 2021 Davide Cavalca - 0.9.4-1.6 - Add Obsoletes to properly replace kpatch with kpatch-runtime on upgrades