From fec9fa4f6c34234f764fc11ddd370a0aa75eb4c4 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 6 Sep 2016 16:06:35 +0100 Subject: [PATCH] Add NUMA topology support libvirt has supported specification of a guest NUMA topology since 0.9.8. This functionality can be used for basic validation of some NUMA-dependent features during development. Add basic configuration support, by allowing the user to specify how many NUMA nodes the instance may have. The following options are added: * numa_nodes - Defaults to none For additional information on specifying NUMA nodes with Libvirt, see: * https://libvirt.org/formatdomain.html#elementsCPU --- README.md | 1 + lib/vagrant-libvirt/action/create_domain.rb | 1 + lib/vagrant-libvirt/config.rb | 26 ++++++++++++++++++++ lib/vagrant-libvirt/templates/domain.xml.erb | 8 ++++++ 4 files changed, 36 insertions(+) diff --git a/README.md b/README.md index 6a5f4d4..471400f 100644 --- a/README.md +++ b/README.md @@ -237,6 +237,7 @@ end * `cpu_fallback` - Whether to allow libvirt to fall back to a CPU model close to the specified model if features in the guest CPU are not supported on the host. Defaults to 'allow' if not set. Allowed values: `allow`, `forbid`. +* `numa_nodes` - Number of NUMA nodes on guest. Must be a factor of `cpu`. * `loader` - Sets path to custom UEFI loader. * `volume_cache` - Controls the cache mechanism. Possible values are "default", "none", "writethrough", "writeback", "directsync" and "unsafe". [See diff --git a/lib/vagrant-libvirt/action/create_domain.rb b/lib/vagrant-libvirt/action/create_domain.rb index 0b1fe88..520af57 100644 --- a/lib/vagrant-libvirt/action/create_domain.rb +++ b/lib/vagrant-libvirt/action/create_domain.rb @@ -37,6 +37,7 @@ module VagrantPlugins @cpu_mode = config.cpu_mode @cpu_model = config.cpu_model @cpu_fallback = config.cpu_fallback + @numa_nodes = config.numa_nodes @loader = config.loader @machine_type = config.machine_type @machine_arch = config.machine_arch diff --git a/lib/vagrant-libvirt/config.rb b/lib/vagrant-libvirt/config.rb index 09c1e29..9c472aa 100644 --- a/lib/vagrant-libvirt/config.rb +++ b/lib/vagrant-libvirt/config.rb @@ -62,6 +62,7 @@ module VagrantPlugins attr_accessor :cpu_model attr_accessor :cpu_fallback attr_accessor :cpu_features + attr_accessor :numa_nodes attr_accessor :loader attr_accessor :boot_order attr_accessor :machine_type @@ -143,6 +144,7 @@ module VagrantPlugins @cpu_model = UNSET_VALUE @cpu_fallback = UNSET_VALUE @cpu_features = UNSET_VALUE + @numa_nodes = UNSET_VALUE @loader = UNSET_VALUE @machine_type = UNSET_VALUE @machine_arch = UNSET_VALUE @@ -232,6 +234,29 @@ module VagrantPlugins raise 'Only four cdroms may be attached at a time' end + def _generate_numa + if @cpus % @numa_nodes != 0 + raise 'NUMA nodes must be a factor of CPUs' + end + + numa = [] + + (1..@numa_nodes).each do |node| + numa_cpu_start = (@cpus / @numa_nodes) * (node - 1) + numa_cpu_end = (@cpus / @numa_nodes) * node - 1 + numa_cpu = Array(numa_cpu_start..numa_cpu_end).join(',') + numa_mem = @memory / @numa_nodes + + numa.push({ + id: node, + cpu: numa_cpu, + mem: numa_mem + }) + end + + @numa_nodes = numa + end + def cpu_feature(options={}) if options[:name].nil? || options[:policy].nil? raise 'CPU Feature name AND policy must be specified' @@ -457,6 +482,7 @@ module VagrantPlugins @cpu_model = 'qemu64' if @cpu_model == UNSET_VALUE @cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE @cpu_features = [] if @cpu_features == UNSET_VALUE + @numa_nodes = _generate_numa() if @numa_nodes != UNSET_VALUE @loader = nil if @loader == UNSET_VALUE @machine_type = nil if @machine_type == UNSET_VALUE @machine_arch = nil if @machine_arch == UNSET_VALUE diff --git a/lib/vagrant-libvirt/templates/domain.xml.erb b/lib/vagrant-libvirt/templates/domain.xml.erb index d35a595..5bb5a94 100644 --- a/lib/vagrant-libvirt/templates/domain.xml.erb +++ b/lib/vagrant-libvirt/templates/domain.xml.erb @@ -15,6 +15,14 @@ <% @cpu_features.each do |cpu_feature| %> <% end %> + <% else %> + <% if @numa_nodes %> + + <% @numa_nodes.each do |node| %> + + <% end %> + + <% end %> <% end %>