From d3a713f2c96580c22716707f2cdad2f5f8d0913f Mon Sep 17 00:00:00 2001 From: Luiz Amaral Date: Fri, 22 Nov 2024 15:26:05 +0100 Subject: [PATCH] Repin all possible vCPUs, not just ones in use When trying to increse the amount of vCPUs in a VM, we were greeted with a cgroup error: ``` virCgroupSetValueRaw:502 : Unable to write to '/sys/fs/cgroup/machine.slice/.../vcpu6/cpuset.cpus': Numerical result out of range ``` It turns out that when live repinning the VM on the new hypervisor, we were iterating only over the amount of vCPUs assigned to the VM (for example, 0 to 5) instead of the max amount of vCPUs assignable (coming from props.max_cpus). Now we iterate over the max amount of vCPUs assignable and pin them to the local hypervisor topology. --- igvm/kvm.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/igvm/kvm.py b/igvm/kvm.py index 80fe6f32..26d2f4ae 100644 --- a/igvm/kvm.py +++ b/igvm/kvm.py @@ -174,15 +174,17 @@ def set_vcpus(hypervisor, vm, domain, num_cpu): def _live_repin_cpus(domain, props, max_phys_cpus): """Adjusts NUMA pinning of all VCPUs.""" num_nodes = props.num_nodes - for vcpu, mask in enumerate(domain.vcpuPinInfo()): - mask = list(mask) - # Set interleaving NUMA pinning for each VCPU up to the maximum + max_vcpus = props.max_cpus + # We used to iterate over the output of domain.vcpuPinInfo() here but + # it only showed the pinning for the current CPUs, not the maximum. + # It ended up that when migrating VMs from a host with more CPUs to a host + # with less CPUs, the VM couldn't have the amount of vCPUs increased, as the + # pinning still had the old (higher) amount of CPUs. + for vcpu in range(max_vcpus): + mask = [] + # Set interleaving NUMA pinning for each vCPU up to the maximum for pcpu in range(0, max_phys_cpus): - mask[pcpu] = (pcpu % num_nodes == vcpu % num_nodes) - # And disable all above the threshold - # (Useful when migrating to a host with less CPUs) - for pcpu in range(max_phys_cpus, len(mask)): - mask[pcpu] = False + mask.append(pcpu % num_nodes == vcpu % num_nodes) domain.pinVcpu(vcpu, tuple(mask))