Proxmox uses qemu which doesn’t implement CPU pinning by itself. If you want to limit a guest VM’s operations to specific CPU cores on the host you need to use taskset. It was a bit confusing to figure out but fortunately I found this gist by ayufan which handles it beautifully.
Save the following into taskset.sh and edit VMID to the ID of the VM you wish to pin CPUs to. Make sure you have the “expect” package installed.
#!/bin/bash
set -eo pipefail
VMID=200
cpu_tasks() {
expect <<EOF | sed -n 's/^.* CPU .*thread_id=\(.*\)$/\1/p' | tr -d '\r' || true
spawn qm monitor $VMID
expect ">"
send "info cpus\r"
expect ">"
EOF
}
VCPUS=($(cpu_tasks))
VCPU_COUNT="${#VCPUS[@]}"
if [[ $VCPU_COUNT -eq 0 ]]; then
echo "* No VCPUS for VM$VMID"
exit 1
fi
echo "* Detected ${#VCPUS[@]} assigned to VM$VMID..."
echo "* Resetting cpu shield..."
for CPU_INDEX in "${!VCPUS[@]}"
do
CPU_TASK="${VCPUS[$CPU_INDEX]}"
echo "* Assigning $CPU_INDEX to $CPU_TASK..."
taskset -pc "$CPU_INDEX" "$CPU_TASK"
done
Update 9/29/18: Fixed missing done at the end. Also if you want to offset which cores this script uses, you can do so by modifying the $CPU_INDEX variable to do a bit of math, like so:
taskset -pc "$[CPU_INDEX+16]"
The above adds 16 to each process ID, so instead of staring on thread 0 it starts on thread 16.
Missing done at the end
Thanks for pointing that out! I’ve updated the post to add it.