kernel-srpm-macros/find-requires.ksyms

189 lines
6.7 KiB
Plaintext
Raw Normal View History

#! /bin/bash
#
# This script is called during external module building to create dependencies
# both upon the RHEL kernel, and on additional external modules. Symbols that
# cannot be reconciled against those provided by the kernel are assumed to be
# provided by an external module and "ksym" replaces th regular "kernel" dep.
IFS=$'\n'
export LC_ALL=C
# Prevent elfutils from trying to download debuginfos
unset DEBUGINFOD_URLS
# Extract all of the symbols provided by this module.
all_provides() {
for module in "$@"; do
tmpfile=""
if [ "x${module%.ko}" = "x${module}" ]; then
tmpfile=$(mktemp -t ${0##*/}.XXXXXX.ko)
proc_bin=
case "${module##*.}" in
zst)
proc_bin=zstd
;;
xz)
proc_bin=xz
;;
bz2)
proc_bin=bzip2
;;
gz)
proc_bin=gzip
;;
esac
[ -n "$proc_bin" ] || continue
"$proc_bin" -d -c - < "$module" > "$tmpfile" || continue
module="$tmpfile"
fi
find-provides.ksyms, find-requires.ksyms: unify symbol parsing Since the immediate symbols can be retrieved for "objdump -t" output as well, it makes some sence to use it as the sole data source and handle both vaiants inside the awk script. This simplification comes at some runtime cost for the simpler case of the immediate symbols, though, and overall it is about 5% faster in the relative symbols case and about the same 5% slower in the absolute symbols case, with the latter not as important moving forward, probably: $ for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ./find-provides.ksyms.old > /dev/null 3.98s user 3.04s system 129% cpu 5.411 total new: ./find-provides.ksyms.new > /dev/null 3.78s user 3.06s system 132% cpu 5.181 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 6.18s user 4.00s system 124% cpu 8.161 total new: ./find-provides.ksyms.new > /dev/null 6.57s user 4.84s system 132% cpu 8.644 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ./find-provides.ksyms.old > /dev/null 4.70s user 2.94s system 126% cpu 6.061 total new: ./find-provides.ksyms.new > /dev/null 4.37s user 3.03s system 127% cpu 5.793 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 6.66s user 4.35s system 123% cpu 8.884 total new: ./find-provides.ksyms.new > /dev/null 7.07s user 5.00s system 130% cpu 9.218 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ./find-provides.ksyms.old > /dev/null 3.81s user 2.62s system 128% cpu 5.018 total new: ./find-provides.ksyms.new > /dev/null 3.55s user 2.56s system 128% cpu 4.743 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 13.79s user 8.59s system 125% cpu 17.817 total new: ./find-provides.ksyms.new > /dev/null 13.18s user 8.78s system 127% cpu 17.247 total * find-provides.ksyms: Do not perform an intial "nm | awk" run in an attempt to capture absolute symbols, just parse "objdump -t" output and handle both absolute and relative symbols in the awk script based on the section name. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-06-01 09:20:50 +00:00
objdump -t "$module" \
find-provides.ksyms, find-requires.ksyms: avoid calling nm twice Instead of running the nm output through grep and then running it through awk again, run it directly through awk, and bail of immediately if a non-absolute symbol is found. Also, while we're here, avoid executing the indirect parsing code if no __crc_* symbols are present at all, which shaves around 8-18% off of the run time: % for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo old:; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo new:; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.10s user 4.52s system 150% cpu 6.412 total new: ../find-provides.ksyms.new > /dev/null 4.41s user 3.48s system 136% cpu 5.764 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 7.80s user 6.19s system 143% cpu 9.740 total new: ../find-provides.ksyms.new > /dev/null 6.07s user 3.97s system 124% cpu 8.066 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.87s user 4.35s system 143% cpu 7.113 total new: ../find-provides.ksyms.new > /dev/null 5.12s user 3.56s system 132% cpu 6.533 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 8.44s user 6.78s system 144% cpu 10.535 total new: ../find-provides.ksyms.new > /dev/null 6.55s user 4.17s system 123% cpu 8.666 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.04s user 3.95s system 145% cpu 6.166 total new: ../find-provides.ksyms.new > /dev/null 4.64s user 3.17s system 136% cpu 5.719 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 8.49s user 5.54s system 139% cpu 10.043 total new: ../find-provides.ksyms.new > /dev/null 7.41s user 4.31s system 129% cpu 9.046 total * find-provides.ksyms: Rewrite the "if nm | grep -q; then nm | awk" with straight "nm | awk", update the awk script to return the exit code accordingly, execute indirect symbol parsing only if inderect __crc_* symbols are present. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-23 13:02:19 +00:00
| awk \
find-provides.ksyms, find-requires.ksyms: unify symbol parsing Since the immediate symbols can be retrieved for "objdump -t" output as well, it makes some sence to use it as the sole data source and handle both vaiants inside the awk script. This simplification comes at some runtime cost for the simpler case of the immediate symbols, though, and overall it is about 5% faster in the relative symbols case and about the same 5% slower in the absolute symbols case, with the latter not as important moving forward, probably: $ for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ./find-provides.ksyms.old > /dev/null 3.98s user 3.04s system 129% cpu 5.411 total new: ./find-provides.ksyms.new > /dev/null 3.78s user 3.06s system 132% cpu 5.181 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 6.18s user 4.00s system 124% cpu 8.161 total new: ./find-provides.ksyms.new > /dev/null 6.57s user 4.84s system 132% cpu 8.644 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ./find-provides.ksyms.old > /dev/null 4.70s user 2.94s system 126% cpu 6.061 total new: ./find-provides.ksyms.new > /dev/null 4.37s user 3.03s system 127% cpu 5.793 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 6.66s user 4.35s system 123% cpu 8.884 total new: ./find-provides.ksyms.new > /dev/null 7.07s user 5.00s system 130% cpu 9.218 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ./find-provides.ksyms.old > /dev/null 3.81s user 2.62s system 128% cpu 5.018 total new: ./find-provides.ksyms.new > /dev/null 3.55s user 2.56s system 128% cpu 4.743 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 13.79s user 8.59s system 125% cpu 17.817 total new: ./find-provides.ksyms.new > /dev/null 13.18s user 8.78s system 127% cpu 17.247 total * find-provides.ksyms: Do not perform an intial "nm | awk" run in an attempt to capture absolute symbols, just parse "objdump -t" output and handle both absolute and relative symbols in the awk script based on the section name. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-06-01 09:20:50 +00:00
-v 'dep_pfx='"$dep_pfx" \
-v 'module='"$module" \
--non-decimal-data \
'BEGIN { revbytes = 0 }
find-provides.ksyms, find-requires.ksyms: avoid calling nm twice Instead of running the nm output through grep and then running it through awk again, run it directly through awk, and bail of immediately if a non-absolute symbol is found. Also, while we're here, avoid executing the indirect parsing code if no __crc_* symbols are present at all, which shaves around 8-18% off of the run time: % for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo old:; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo new:; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.10s user 4.52s system 150% cpu 6.412 total new: ../find-provides.ksyms.new > /dev/null 4.41s user 3.48s system 136% cpu 5.764 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 7.80s user 6.19s system 143% cpu 9.740 total new: ../find-provides.ksyms.new > /dev/null 6.07s user 3.97s system 124% cpu 8.066 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.87s user 4.35s system 143% cpu 7.113 total new: ../find-provides.ksyms.new > /dev/null 5.12s user 3.56s system 132% cpu 6.533 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 8.44s user 6.78s system 144% cpu 10.535 total new: ../find-provides.ksyms.new > /dev/null 6.55s user 4.17s system 123% cpu 8.666 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.04s user 3.95s system 145% cpu 6.166 total new: ../find-provides.ksyms.new > /dev/null 4.64s user 3.17s system 136% cpu 5.719 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 8.49s user 5.54s system 139% cpu 10.043 total new: ../find-provides.ksyms.new > /dev/null 7.41s user 4.31s system 129% cpu 9.046 total * find-provides.ksyms: Rewrite the "if nm | grep -q; then nm | awk" with straight "nm | awk", update the awk script to return the exit code accordingly, execute indirect symbol parsing only if inderect __crc_* symbols are present. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-23 13:02:19 +00:00
find-provides.ksyms, find-requires.ksyms: unify symbol parsing Since the immediate symbols can be retrieved for "objdump -t" output as well, it makes some sence to use it as the sole data source and handle both vaiants inside the awk script. This simplification comes at some runtime cost for the simpler case of the immediate symbols, though, and overall it is about 5% faster in the relative symbols case and about the same 5% slower in the absolute symbols case, with the latter not as important moving forward, probably: $ for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ./find-provides.ksyms.old > /dev/null 3.98s user 3.04s system 129% cpu 5.411 total new: ./find-provides.ksyms.new > /dev/null 3.78s user 3.06s system 132% cpu 5.181 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 6.18s user 4.00s system 124% cpu 8.161 total new: ./find-provides.ksyms.new > /dev/null 6.57s user 4.84s system 132% cpu 8.644 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ./find-provides.ksyms.old > /dev/null 4.70s user 2.94s system 126% cpu 6.061 total new: ./find-provides.ksyms.new > /dev/null 4.37s user 3.03s system 127% cpu 5.793 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 6.66s user 4.35s system 123% cpu 8.884 total new: ./find-provides.ksyms.new > /dev/null 7.07s user 5.00s system 130% cpu 9.218 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ./find-provides.ksyms.old > /dev/null 3.81s user 2.62s system 128% cpu 5.018 total new: ./find-provides.ksyms.new > /dev/null 3.55s user 2.56s system 128% cpu 4.743 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 13.79s user 8.59s system 125% cpu 17.817 total new: ./find-provides.ksyms.new > /dev/null 13.18s user 8.78s system 127% cpu 17.247 total * find-provides.ksyms: Do not perform an intial "nm | awk" run in an attempt to capture absolute symbols, just parse "objdump -t" output and handle both absolute and relative symbols in the awk script based on the section name. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-06-01 09:20:50 +00:00
function check_endianness( t) {
if (revbytes) return revbytes;
find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing Linux commit v5.19-rc1~139^2~2 ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS") has broken the assumption aobut the placement of non-absolute CRC symbols in .rodata (and also affects the architectures that used to have these symbols as absolute); rewrite the parsing by utilising "objdump -t" output to figure out the section(s) where the __crc_* symbols are stored and process it instead of the hard-coded ".rodata" section. The change also speeds up the processing a bit, around 33% on synthetic tests: $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.old > /dev/null 2> /dev/null' sh -c 10.36s user 5.58s system 137% cpu 11.613 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.new > /dev/null 2> /dev/null' sh -c 7.82s user 4.59s system 142% cpu 8.686 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.old" \; > /dev/null 2> /dev/null' sh -c 11.85s user 6.76s system 129% cpu 14.318 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.new" \; > /dev/null 2> /dev/null' sh -c 8.91s user 5.51s system 135% cpu 10.647 total * find-provides.ksyms: Process "objdump -t" output to get the list of sections where __crc_* symbol contents are placed; retrieve each one with "readelf -R" and supply it to an awk script that cuts the required part of it for each __crc_* symbol in that section. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com> Resolves: #2135047
2023-02-05 00:26:01 +00:00
find-provides.ksyms, find-requires.ksyms: unify symbol parsing Since the immediate symbols can be retrieved for "objdump -t" output as well, it makes some sence to use it as the sole data source and handle both vaiants inside the awk script. This simplification comes at some runtime cost for the simpler case of the immediate symbols, though, and overall it is about 5% faster in the relative symbols case and about the same 5% slower in the absolute symbols case, with the latter not as important moving forward, probably: $ for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ./find-provides.ksyms.old > /dev/null 3.98s user 3.04s system 129% cpu 5.411 total new: ./find-provides.ksyms.new > /dev/null 3.78s user 3.06s system 132% cpu 5.181 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 6.18s user 4.00s system 124% cpu 8.161 total new: ./find-provides.ksyms.new > /dev/null 6.57s user 4.84s system 132% cpu 8.644 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ./find-provides.ksyms.old > /dev/null 4.70s user 2.94s system 126% cpu 6.061 total new: ./find-provides.ksyms.new > /dev/null 4.37s user 3.03s system 127% cpu 5.793 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 6.66s user 4.35s system 123% cpu 8.884 total new: ./find-provides.ksyms.new > /dev/null 7.07s user 5.00s system 130% cpu 9.218 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ./find-provides.ksyms.old > /dev/null 3.81s user 2.62s system 128% cpu 5.018 total new: ./find-provides.ksyms.new > /dev/null 3.55s user 2.56s system 128% cpu 4.743 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 13.79s user 8.59s system 125% cpu 17.817 total new: ./find-provides.ksyms.new > /dev/null 13.18s user 8.78s system 127% cpu 17.247 total * find-provides.ksyms: Do not perform an intial "nm | awk" run in an attempt to capture absolute symbols, just parse "objdump -t" output and handle both absolute and relative symbols in the awk script based on the section name. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-06-01 09:20:50 +00:00
revbytes = -1;
while (("readelf -h \"" module "\"" | getline t) > 0) {
if (match(t, /^ Data: *2\047s complement, little endian$/)) {
revbytes = 1;
break;
find-provides.ksyms, find-requires.ksyms: do section data parsing inside awk Previous approach with passing the section contents as a command line option proven to be error-prone, as it hits the command line option size limit on some kmods. Move the reading and processing of the section contents inside the awk script itself; it also saves a bit (around 3—4%) of time on the kernels with indirect __crc_* symbols: $ for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ./find-provides.ksyms.old > /dev/null 5.38s user 4.66s system 150% cpu 6.693 total new: ./find-provides.ksyms.new > /dev/null 5.20s user 4.52s system 149% cpu 6.484 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 7.85s user 6.34s system 143% cpu 9.864 total new: ./find-provides.ksyms.new > /dev/null 7.75s user 6.32s system 143% cpu 9.809 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ./find-provides.ksyms.old > /dev/null 6.19s user 4.68s system 144% cpu 7.506 total new: ./find-provides.ksyms.new > /dev/null 5.93s user 4.46s system 143% cpu 7.219 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 8.47s user 6.71s system 144% cpu 10.523 total new: ./find-provides.ksyms.new > /dev/null 8.44s user 6.59s system 144% cpu 10.435 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ./find-provides.ksyms.old > /dev/null 5.21s user 4.09s system 145% cpu 6.383 total new: ./find-provides.ksyms.new > /dev/null 5.04s user 3.85s system 145% cpu 6.120 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 8.68s user 5.77s system 139% cpu 10.326 total new: ./find-provides.ksyms.new > /dev/null 8.47s user 5.57s system 139% cpu 10.067 total * find-provides.ksyms: Add assign to revbytes the result of endianness chack test instead of the code snippet; do not generate SECTDATA variable; do not pass SECTDATA to the awk script; pass module and revbytes to the awk script; retrieve the section data into the sectdata variable and perform the byte re-shuffling in accordance to the revbytes value in the BEGIN section of the awk script. * find-requires.ksyms (all_provides): Likewise. Fixes: cd7e9e8a2fc2 "find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing" Resolves: #2135901 References: https://bugzilla.redhat.com/show_bug.cgi?id=2178935 Co-Authored-by: Denys Vlasenko <dvlasenk@redhat.com> Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-22 15:53:44 +00:00
}
find-provides.ksyms, find-requires.ksyms: avoid iterating over sections Since the section retrieval code is implemented inside the awk script now, the next step is to eliminate external iteration over the section list and just retrieve the required sections inside awk on demand. This allows calling (and processing the output of) objdump -t just once, which saves around 8-12% of time on kernels that store modversions as non-absolute symbols: $ for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ../find-provides.ksyms.old > /dev/null 4.41s user 3.46s system 136% cpu 5.756 total new: ../find-provides.ksyms.new > /dev/null 3.90s user 2.94s system 129% cpu 5.279 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 6.04s user 3.88s system 124% cpu 7.993 total new: ../find-provides.ksyms.new > /dev/null 6.08s user 3.91s system 124% cpu 8.012 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.09s user 3.51s system 133% cpu 6.452 total new: ../find-provides.ksyms.new > /dev/null 4.65s user 2.89s system 126% cpu 5.949 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 6.52s user 4.14s system 123% cpu 8.638 total new: ../find-provides.ksyms.new > /dev/null 6.64s user 4.12s system 123% cpu 8.690 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ../find-provides.ksyms.old > /dev/null 4.45s user 3.29s system 136% cpu 5.661 total new: ../find-provides.ksyms.new > /dev/null 3.84s user 2.54s system 127% cpu 4.980 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 7.34s user 4.33s system 129% cpu 9.019 total new: ../find-provides.ksyms.new > /dev/null 6.67s user 3.51s system 122% cpu 8.278 total * find-provides.ksyms: Remove "objdump -t" section loop, do not supply sectname to the awk script, treat sectdata as an array keyed on section name, convert section retrieval to a function with a section name as an argument, call it if a section name is not present in sectdata. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-23 14:17:39 +00:00
}
find-provides.ksyms, find-requires.ksyms: unify symbol parsing Since the immediate symbols can be retrieved for "objdump -t" output as well, it makes some sence to use it as the sole data source and handle both vaiants inside the awk script. This simplification comes at some runtime cost for the simpler case of the immediate symbols, though, and overall it is about 5% faster in the relative symbols case and about the same 5% slower in the absolute symbols case, with the latter not as important moving forward, probably: $ for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ./find-provides.ksyms.old > /dev/null 3.98s user 3.04s system 129% cpu 5.411 total new: ./find-provides.ksyms.new > /dev/null 3.78s user 3.06s system 132% cpu 5.181 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 6.18s user 4.00s system 124% cpu 8.161 total new: ./find-provides.ksyms.new > /dev/null 6.57s user 4.84s system 132% cpu 8.644 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ./find-provides.ksyms.old > /dev/null 4.70s user 2.94s system 126% cpu 6.061 total new: ./find-provides.ksyms.new > /dev/null 4.37s user 3.03s system 127% cpu 5.793 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 6.66s user 4.35s system 123% cpu 8.884 total new: ./find-provides.ksyms.new > /dev/null 7.07s user 5.00s system 130% cpu 9.218 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ./find-provides.ksyms.old > /dev/null 3.81s user 2.62s system 128% cpu 5.018 total new: ./find-provides.ksyms.new > /dev/null 3.55s user 2.56s system 128% cpu 4.743 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 13.79s user 8.59s system 125% cpu 17.817 total new: ./find-provides.ksyms.new > /dev/null 13.18s user 8.78s system 127% cpu 17.247 total * find-provides.ksyms: Do not perform an intial "nm | awk" run in an attempt to capture absolute symbols, just parse "objdump -t" output and handle both absolute and relative symbols in the awk script based on the section name. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-06-01 09:20:50 +00:00
return revbytes;
}
function readsect(name, a, t) {
a = "";
while (("readelf -R \"" name "\" \"" module "\"" | getline t) > 0) {
if (match(t, /^ 0x[0-9a-f]{8}/))
a = a substr(t, 14, 8) substr(t, 23, 8) substr(t, 32, 8) substr(t, 41, 8);
}
if (revbytes) { a = gensub(/(..)(..)(..)(..)/, "\\4\\3\\2\\1", "g", a); }
sectdata[name] = a;
}
match($0, /^([0-9a-f]+) [gl]...... (.*) [0-9a-f]+ __crc_(.*)$/, a) {
if (a[2] == "*ABS*") {
printf("%s(%s) = 0x%08x\n", dep_pfx, a[3], strtonum("0x" a[1]));
} else {
find-provides.ksyms, find-requires.ksyms: avoid iterating over sections Since the section retrieval code is implemented inside the awk script now, the next step is to eliminate external iteration over the section list and just retrieve the required sections inside awk on demand. This allows calling (and processing the output of) objdump -t just once, which saves around 8-12% of time on kernels that store modversions as non-absolute symbols: $ for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ../find-provides.ksyms.old > /dev/null 4.41s user 3.46s system 136% cpu 5.756 total new: ../find-provides.ksyms.new > /dev/null 3.90s user 2.94s system 129% cpu 5.279 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 6.04s user 3.88s system 124% cpu 7.993 total new: ../find-provides.ksyms.new > /dev/null 6.08s user 3.91s system 124% cpu 8.012 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.09s user 3.51s system 133% cpu 6.452 total new: ../find-provides.ksyms.new > /dev/null 4.65s user 2.89s system 126% cpu 5.949 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 6.52s user 4.14s system 123% cpu 8.638 total new: ../find-provides.ksyms.new > /dev/null 6.64s user 4.12s system 123% cpu 8.690 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ../find-provides.ksyms.old > /dev/null 4.45s user 3.29s system 136% cpu 5.661 total new: ../find-provides.ksyms.new > /dev/null 3.84s user 2.54s system 127% cpu 4.980 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 7.34s user 4.33s system 129% cpu 9.019 total new: ../find-provides.ksyms.new > /dev/null 6.67s user 3.51s system 122% cpu 8.278 total * find-provides.ksyms: Remove "objdump -t" section loop, do not supply sectname to the awk script, treat sectdata as an array keyed on section name, convert section retrieval to a function with a section name as an argument, call it if a section name is not present in sectdata. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-23 14:17:39 +00:00
if (!(a[2] in sectdata)) { readsect(a[2]) }
printf("%s(%s) = 0x%08s\n", dep_pfx, a[3], substr(sectdata[a[2]], (strtonum("0x" a[1]) * 2) + 1, 8))
find-provides.ksyms, find-requires.ksyms: unify symbol parsing Since the immediate symbols can be retrieved for "objdump -t" output as well, it makes some sence to use it as the sole data source and handle both vaiants inside the awk script. This simplification comes at some runtime cost for the simpler case of the immediate symbols, though, and overall it is about 5% faster in the relative symbols case and about the same 5% slower in the absolute symbols case, with the latter not as important moving forward, probably: $ for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ./find-provides.ksyms.old > /dev/null 3.98s user 3.04s system 129% cpu 5.411 total new: ./find-provides.ksyms.new > /dev/null 3.78s user 3.06s system 132% cpu 5.181 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 6.18s user 4.00s system 124% cpu 8.161 total new: ./find-provides.ksyms.new > /dev/null 6.57s user 4.84s system 132% cpu 8.644 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ./find-provides.ksyms.old > /dev/null 4.70s user 2.94s system 126% cpu 6.061 total new: ./find-provides.ksyms.new > /dev/null 4.37s user 3.03s system 127% cpu 5.793 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 6.66s user 4.35s system 123% cpu 8.884 total new: ./find-provides.ksyms.new > /dev/null 7.07s user 5.00s system 130% cpu 9.218 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ./find-provides.ksyms.old > /dev/null 3.81s user 2.62s system 128% cpu 5.018 total new: ./find-provides.ksyms.new > /dev/null 3.55s user 2.56s system 128% cpu 4.743 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 13.79s user 8.59s system 125% cpu 17.817 total new: ./find-provides.ksyms.new > /dev/null 13.18s user 8.78s system 127% cpu 17.247 total * find-provides.ksyms: Do not perform an intial "nm | awk" run in an attempt to capture absolute symbols, just parse "objdump -t" output and handle both absolute and relative symbols in the awk script based on the section name. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-06-01 09:20:50 +00:00
}
}'
[ -z "$tmpfile" ] || rm -f -- "$tmpfile"
done \
| sort -k1,1 -u
}
# Extract all of the requirements of this module.
all_requires() {
for module in "$@"; do
set -- $(/sbin/modinfo -F vermagic "$module" | sed -e 's: .*::' -e q)
/sbin/modprobe --dump-modversions "$module" \
| awk --non-decimal-data '
BEGIN { FS = "\t" ; OFS = "\t" }
{printf("%s:0x%08x\n", $2, $1)}' \
| sed -r -e 's:$:\t'"$1"':'
done \
| sort -k1,1 -u
}
# Filter out requirements fulfilled by the module itself.
mod_requires() {
join -t $'\t' -j 1 -v 1 \
<(all_requires "$@") \
<(all_provides "$@") \
| sort -k1,1 -u
}
if ! [ -e /sbin/modinfo -a -e /sbin/modprobe ]; then
cat > /dev/null
exit 0
fi
check_kabi() {
arch=$(uname -m)
kabi_file="/lib/modules/kabi-current/kabi_stablelist_$arch"
# If not installed, output a warning and return (continue)
if [ ! -f "$kabi_file" ]; then
echo "" >&2
echo "********************************************************************************" >&2
echo "*********************** KERNEL ABI COMPATIBILITY WARNING ***********************" >&2
echo "********************************************************************************" >&2
echo "The kernel ABI reference files (provided by "kabi-stablelists") were not found." >&2
echo "No compatibility check was performed. Please install the kABI reference files" >&2
echo "and rebuild if you would like to verify compatibility with kernel ABI." >&2
echo "" >&2
return
fi
unset non_kabi
for symbol in "$@"; do
if ! egrep "^[[:space:]]$symbol\$" $kabi_file >/dev/null; then
non_kabi=("${non_kabi[@]}" "$symbol")
fi
done
if [ ${#non_kabi[@]} -gt 0 ]; then
echo "" >&2
echo "********************************************************************************" >&2
echo "*********************** KERNEL ABI COMPATIBILITY WARNING ***********************" >&2
echo "********************************************************************************" >&2
echo "The following kernel symbols are not guaranteed to remain compatible with" >&2
echo "future kernel updates to this RHEL release:" >&2
echo "" >&2
for symbol in "${non_kabi[@]}"; do
printf "\t$symbol\n" >&2
done
echo "" >&2
echo "Red Hat recommends that you consider using only official kernel ABI symbols" >&2
echo "where possible. Requests for additions to the kernel ABI can be filed with" >&2
echo "your partner or customer representative (component: driver-update-program)." >&2
echo "" >&2
fi
}
modules=($(grep -E '/lib/modules/.+\.ko(\.gz|\.bz2|\.xz|\.zst)?$') "$@")
if [ ${#modules[@]} -gt 0 ]; then
kernel=$(/sbin/modinfo -F vermagic "${modules[0]}" | sed -e 's: .*::' -e q)
# get all that kernel provides
symvers=$(mktemp -t ${0##*/}.XXXXX)
cat /usr/src/kernels/$kernel/Module.symvers | awk '
BEGIN { FS = "\t" ; OFS = "\t" }
{ print $2 ":" $1 }
' \
| sed -r -e 's:$:\t'"$kernel"':' \
| sort -k1,1 -u > $symvers
# Symbols matching with the kernel get a "kernel" dependency
mod_req=$(mktemp -t mod_req.XXXXX)
mod_requires "${modules[@]}" > "$mod_req"
join -t $'\t' -j 1 $symvers "$mod_req" | sort -u \
| awk 'BEGIN { FS = "[\t:]" ; OFS = "\t" } { print "kernel(" $1 ") = " $2 }'
# Symbols from elsewhere get a "ksym" dependency
join -t $'\t' -j 1 -v 2 $symvers "$mod_req" | sort -u \
| awk 'BEGIN { FS = "[\t:]" ; OFS = "\t" } { print "ksym(" $1 ") = " $2 }'
os_id=$(sed -nr '/^ID[[:space:]]*=/{ s/ID[[:space:]]*=[[:space:]]*//; s/^"(.*)"$/\1/; p }' /etc/os-release)
if [ "rhel" = "$os_id" ]; then
# Check kABI if the kabi-stablelists package is installed
# Do this last so we can try to output this error at the end
kabi_check_symbols=($(join -t $'\t' -j 1 $symvers "$mod_req" | sort -u \
| awk 'BEGIN { FS = "[\t:]" ; OFS = "\t" } { print $1 }'))
check_kabi "${kabi_check_symbols[@]}"
fi
fi