dracutdevs / dracut

dracut the event driven initramfs infrastructure
https://github.com/dracutdevs/dracut/wiki
GNU General Public License v2.0
600 stars 399 forks source link

perf(drm): group dracut_instmods calls #2577

Open aafeijoo-suse opened 10 months ago

aafeijoo-suse commented 10 months ago

This module loops over many bus devices, and calls dracut_instmods for each one. E.g., on a Lenovo Thinkpad laptop:

> for i in /sys/bus/{pci/devices,platform/devices,virtio/devices,soc/devices/soc?,vmbus/devices}/*/modalias; do [[ -e $i ]] && [[ -n $(< "$i") ]]  && echo $i; done | wc -l
79

Every call to dracut_instmods spawns a dracut-install process, which in the previous example means calling dracut-install 79 times using the same arguments.

If any call to dracut-install fails, dracut continues its execution (even the errors are not shown, because it's called with --silent). Therefore, let's take the contents of all the modalias files into an array and call dracut-install only once, adding also the -o argument, so if any of the modules cannot be installed, dracut-install does not stop.

Performance test

The following test patch was used to measure the improvement of this change:

diff --git a/dracut.sh b/dracut.sh
index 3b292910..a25a45ee 100755
--- a/dracut.sh
+++ b/dracut.sh
@@ -1916,10 +1916,20 @@ for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
     else
         module_install "$_d_mod" "$moddir"
         if [[ $no_kernel != yes ]]; then
+if [[ "$_d_mod" == "drm" ]]; then
+    echo "drm installkernel perf"
+    export -f module_installkernel instmods dracut_instmods strstr
+    export DRACUT_INSTALL hostonly
+    hyperfine --shell=bash --warmup 3 --runs 100 'derror() { echo "ERROR: $1"; } ; module_installkernel drm /usr/lib/dracut/modules.d/50drm' || {
+        dfatal "installkernel failed in module $_d_mod"
+        exit 1
+    }
+else
             module_installkernel "$_d_mod" "$moddir" || {
                 dfatal "installkernel failed in module $_d_mod"
                 exit 1
             }
+fi
         fi
     fi
     mods_to_load=${mods_to_load// $_d_mod /}

System:

Current code:

$ sudo dracut -f --stdlog 3 -H test1.img
drm installkernel perf
Benchmark 1: derror() { echo "ERROR: $1"; } ; module_installkernel drm /usr/lib/dracut/modules.d/50drm
  Time (mean ± σ):     245.5 ms ±  17.6 ms    [User: 203.9 ms, System: 48.0 ms]
  Range (min … max):   233.9 ms … 345.6 ms    100 runs

Code with patch applied:

$ sudo dracut -f --stdlog 3 -H test2.img
drm installkernel perf
Benchmark 1: derror() { echo "ERROR: $1"; } ; module_installkernel drm /usr/lib/dracut/modules.d/50drm
  Time (mean ± σ):      64.5 ms ±   0.8 ms    [User: 49.8 ms, System: 15.4 ms]
  Range (min … max):    62.6 ms …  67.9 ms    100 runs

It was also verified that the drm module with the new code installs the same kernel modules.

$ sudo dracut -f --stdlog 3 -H -o drm test0.img
dracut: dracut module 'plymouth' depends on 'drm', which can't be installed
$ sudo lsinitrd test0.img 2>&1 | awk '{ print $9 }' > test0.txt
$ sudo lsinitrd test1.img 2>&1 | awk '{ print $9 }' > test1.txt
$ sudo lsinitrd test2.img 2>&1 | awk '{ print $9 }' > test2.txt
$ diff test0.txt test1.txt | grep "\.ko"
> lib/modules/5.14.21-150400.24.55-default/kernel/drivers/acpi/button.ko.zst
> lib/modules/5.14.21-150400.24.55-default/kernel/drivers/gpu/drm/drm_kms_helper.ko.zst
> lib/modules/5.14.21-150400.24.55-default/kernel/drivers/gpu/drm/drm.ko.zst
> lib/modules/5.14.21-150400.24.55-default/kernel/drivers/gpu/drm/drm_ttm_helper.ko.zst
> lib/modules/5.14.21-150400.24.55-default/kernel/drivers/gpu/drm/i915/i915.ko.zst
> lib/modules/5.14.21-150400.24.55-default/kernel/drivers/gpu/drm/nouveau/nouveau.ko.zst
> lib/modules/5.14.21-150400.24.55-default/kernel/drivers/gpu/drm/ttm/ttm.ko.zst
> lib/modules/5.14.21-150400.24.55-default/kernel/drivers/i2c/algos/i2c-algo-bit.ko.zst
> lib/modules/5.14.21-150400.24.55-default/kernel/drivers/media/cec/core/cec.ko.zst
> lib/modules/5.14.21-150400.24.55-default/kernel/drivers/platform/x86/mxm-wmi.ko.zst
$ diff -s test1.txt test2.txt
Files test1.txt and test2.txt are identical

Checklist

stale[bot] commented 6 months ago

This issue is being marked as stale because it has not had any recent activity. It will be closed if no further activity occurs. If this is still an issue in the latest release of Dracut and you would like to keep it open please comment on this issue within the next 7 days. Thank you for your contributions.

stale[bot] commented 5 months ago

This issue is being marked as stale because it has not had any recent activity. It will be closed if no further activity occurs. If this is still an issue in the latest release of Dracut and you would like to keep it open please comment on this issue within the next 7 days. Thank you for your contributions.