From 69cf814b34c68c98c803bbfb36c6b68537061661 Mon Sep 17 00:00:00 2001 From: Sandwich Date: Sat, 10 Oct 2026 02:29:34 +0200 Subject: [PATCH] fix: cpu-isolation hook restores prior allowedcpus instead of all cores --- scripts/libvirt-hook-cpu-isolation.sh | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/scripts/libvirt-hook-cpu-isolation.sh b/scripts/libvirt-hook-cpu-isolation.sh index 02a6083..54c06db 100755 --- a/scripts/libvirt-hook-cpu-isolation.sh +++ b/scripts/libvirt-hook-cpu-isolation.sh @@ -5,7 +5,8 @@ # # On start it reads the domain's own from the XML libvirt passes on # stdin, works out which host CPUs the guest occupies, and confines the systemd -# slices to the rest. On stop it hands everything back. +# slices to the rest. On stop it puts back what the slices had before, so a +# partition someone else set survives a guest's lifetime. # # Measured on a 16 vCPU guest pinned to one CCD of a 7950X: stalls over 10 us in # a 10 second window fell from ~100 to ~52, and CPU throughput rose about 2%. @@ -19,12 +20,7 @@ OPERATION="$2" ALL=$(cat /sys/devices/system/cpu/present) # not nproc: that honours this hook's own affinity NCPU=$(( ${ALL##*-} + 1 )) SLICES="system.slice user.slice init.scope" - -restore() { - for s in $SLICES; do - systemctl set-property --runtime -- "$s" AllowedCPUs="$ALL" 2>/dev/null - done -} +STATE="/run/vfio-native/cpu-isolation/$DOMAIN" # each slice's AllowedCPUs before we confined it case "$OPERATION" in prepare) @@ -62,6 +58,10 @@ PY ) [ -n "$HOST" ] || exit 0 # nothing left for the host, or it failed + mkdir -p "${STATE%/*}" + [ -f "$STATE" ] || for s in $SLICES; do + printf '%s=%s\n' "$s" "$(systemctl show -p AllowedCPUs --value -- "$s")" + done > "$STATE" for s in $SLICES; do systemctl set-property --runtime -- "$s" AllowedCPUs="$HOST" 2>/dev/null done @@ -69,8 +69,12 @@ PY ;; release|stopped) - restore - logger -t libvirt-cpu-isolation "$DOMAIN $OPERATION: host slices restored to $ALL" + [ -f "$STATE" ] || exit 0 # this hook confined nothing for the domain + while IFS='=' read -r s cpus; do + systemctl set-property --runtime -- "$s" AllowedCPUs="$cpus" 2>/dev/null + done < "$STATE" + logger -t libvirt-cpu-isolation "$DOMAIN $OPERATION: host slices restored to $(tr '\n' ' ' < "$STATE")" + rm -f "$STATE" ;; *) # Deliberately does nothing. An earlier version called virsh here to check