diff --git a/docs/configuration.markdown b/docs/configuration.markdown index 05cfd59..98a9d2e 100644 --- a/docs/configuration.markdown +++ b/docs/configuration.markdown @@ -105,7 +105,6 @@ end * `cpus` - Number of virtual cpus. Defaults to 1 if not set. * `cpuset` - Physical cpus to which the vcpus can be pinned. For more details see [documentation](https://libvirt.org/formatdomain.html#elementsCPUAllocation). * `cputopology` - Number of CPU sockets, cores and threads running per core. All fields of `:sockets`, `:cores` and `:threads` are mandatory, `cpus` domain option must be present and must be equal to total count of **sockets * cores * threads**. For more details see [documentation](https://libvirt.org/formatdomain.html#elementsCPU). -* `nodeset` - Physical NUMA nodes where virtual memory can be pinned. For more details see [documentation](https://libvirt.org/formatdomain.html#elementsNUMATuning). ```ruby Vagrant.configure("2") do |config| @@ -117,6 +116,18 @@ end end ``` +* `cpuaffinitiy` - Mapping of vCPUs to host CPUs. [See `vcpupin`](https://libvirt.org/formatdomain.html#cpu-tuning). + + ```ruby + Vagrant.configure("2") do |config| + config.vm.provider :libvirt do |libvirt| + libvirt.cpus = 4 + libvirt.cpuaffinitiy 0 => '0-4,^3', 1 => '5', 2 => '6,7' + end + end + ``` + +* `nodeset` - Physical NUMA nodes where virtual memory can be pinned. For more details see [documentation](https://libvirt.org/formatdomain.html#elementsNUMATuning). * `nested` - [Enable nested virtualization](https://docs.fedoraproject.org/en-US/quick-docs/using-nested-virtualization-in-kvm/). Default is false. * `cpu_mode` - [CPU emulation mode](https://libvirt.org/formatdomain.html#elementsCPU). Defaults to diff --git a/lib/vagrant-libvirt/action/create_domain.rb b/lib/vagrant-libvirt/action/create_domain.rb index b4d0029..0ea41c8 100644 --- a/lib/vagrant-libvirt/action/create_domain.rb +++ b/lib/vagrant-libvirt/action/create_domain.rb @@ -32,6 +32,7 @@ module VagrantPlugins @cpuset = config.cpuset @cpu_features = config.cpu_features @cpu_topology = config.cpu_topology + @cpu_affinity = config.cpu_affinity @nodeset = config.nodeset @features = config.features @features_hyperv = config.features_hyperv @@ -206,13 +207,16 @@ module VagrantPlugins env[:ui].info(" -- Domain type: #{@domain_type}") env[:ui].info(" -- Cpus: #{@cpus}") unless @cpuset.nil? - env[:ui].info(" -- Cpuset: #{@cpuset}") + env[:ui].info(" -- Cpuset: #{@cpuset}") end if not @cpu_topology.empty? - env[:ui].info(" -- CPU topology: sockets=#{@cpu_topology[:sockets]}, cores=#{@cpu_topology[:cores]}, threads=#{@cpu_topology[:threads]}") + env[:ui].info(" -- CPU topology: sockets=#{@cpu_topology[:sockets]}, cores=#{@cpu_topology[:cores]}, threads=#{@cpu_topology[:threads]}") + end + @cpu_affinity.each do |vcpu, cpuset| + env[:ui].info(" -- CPU affinity: vcpu #{vcpu} => cpuset #{cpuset}") end @cpu_features.each do |cpu_feature| - env[:ui].info(" -- CPU Feature: name=#{cpu_feature[:name]}, policy=#{cpu_feature[:policy]}") + env[:ui].info(" -- CPU feature: name=#{cpu_feature[:name]}, policy=#{cpu_feature[:policy]}") end @features.each do |feature| env[:ui].info(" -- Feature: #{feature}") diff --git a/lib/vagrant-libvirt/config.rb b/lib/vagrant-libvirt/config.rb index 8d482d3..d069527 100644 --- a/lib/vagrant-libvirt/config.rb +++ b/lib/vagrant-libvirt/config.rb @@ -86,6 +86,7 @@ module VagrantPlugins attr_accessor :cpu_fallback attr_accessor :cpu_features attr_accessor :cpu_topology + attr_accessor :cpu_affinity attr_accessor :shares attr_accessor :features attr_accessor :features_hyperv @@ -248,6 +249,7 @@ module VagrantPlugins @cpu_fallback = UNSET_VALUE @cpu_features = UNSET_VALUE @cpu_topology = UNSET_VALUE + @cpu_affinity = UNSET_VALUE @shares = UNSET_VALUE @features = UNSET_VALUE @features_hyperv = UNSET_VALUE @@ -469,6 +471,16 @@ module VagrantPlugins @cpu_topology[:threads] = options[:threads] end + def cpuaffinitiy(affinity = {}) + if @cpu_affinity == UNSET_VALUE + @cpu_affinity = {} + end + + affinity.each do |vcpu, cpuset| + @cpu_affinity[vcpu] = cpuset + end + end + def memorybacking(option, config = {}) case option when :source @@ -866,6 +878,7 @@ module VagrantPlugins @cpu_model end @cpu_topology = {} if @cpu_topology == UNSET_VALUE + @cpu_affinity = {} if @cpu_affinity == UNSET_VALUE @cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE @cpu_features = [] if @cpu_features == UNSET_VALUE @shares = nil if @shares == UNSET_VALUE diff --git a/lib/vagrant-libvirt/templates/domain.xml.erb b/lib/vagrant-libvirt/templates/domain.xml.erb index afd68b1..d3e02da 100644 --- a/lib/vagrant-libvirt/templates/domain.xml.erb +++ b/lib/vagrant-libvirt/templates/domain.xml.erb @@ -44,9 +44,14 @@ <%- end -%> <%- end%> -<%- if @shares -%> +<%- if !@cpu_affinity.empty? || @shares -%> + <%- @cpu_affinity.each do |vcpu, cpuset| -%> + + <%- end -%> + <%- if @shares -%> <%= @shares %> + <%- end -%> <%- end -%> diff --git a/spec/unit/templates/domain_all_settings.xml b/spec/unit/templates/domain_all_settings.xml index 5bd7aa3..b9c29b7 100644 --- a/spec/unit/templates/domain_all_settings.xml +++ b/spec/unit/templates/domain_all_settings.xml @@ -14,6 +14,7 @@ + 1024 diff --git a/spec/unit/templates/domain_spec.rb b/spec/unit/templates/domain_spec.rb index 1c8ee8a..8b8f64c 100644 --- a/spec/unit/templates/domain_spec.rb +++ b/spec/unit/templates/domain_spec.rb @@ -67,6 +67,7 @@ describe 'templates/domain' do domain.clock_timer(name: 't2', track: 'b', tickpolicy: 'c', frequency: 'd', mode: 'e', present: 'yes') domain.hyperv_feature(name: 'spinlocks', state: 'on', retries: '4096') domain.cputopology(sockets: '1', cores: '3', threads: '2') + domain.cpuaffinitiy(0 => '0') domain.machine_type = 'pc-compatible' domain.machine_arch = 'x86_64' domain.loader = '/efi/loader'