Remove NSM from emul thread tests
A continuation of [1] in which we are trying to reduce the dependency on
NovaServiceManager when interacting with cpu_dedicated_set and
cpu_shared_set.
This commit introduces two new configuration options:
* whitebox_hardware.dedicated_cpus_per_numa
* whitebox_hardware.shared_cpus_per_numa
These options describe the number of pCPUs alloacted to either shared or
dedicated sets for a given compute host. We are making the assumption
that although the pCPUs allocated to their respective sets may be
different on each compute host, the number of pCPUs allocated are the
same.
Commit also removes NSM from three of the four base emulator thread
testcases and reduces some of the complexity originally present in the
tests. Since vcpu_pin_set and cpu_dedicated_set are no longer
directly modified in the test, their respective child tests have been
removed leaving just the parent to covering scenarios based on the
deployment.
[1] cca33388c2
Change-Id: I57243d49de0d1715fecaa6496a92fc2c576c448a
This commit is contained in:
parent
0276f52886
commit
7385e1bc55
@ -86,7 +86,7 @@
|
||||
vars:
|
||||
# NOTE(artom) We can't have this on the parent job, otherwise the two
|
||||
# -cpupinnig jobs will inherit it as well.
|
||||
tempest_exclude_regex: test_live_migrate_and_reboot|test_shared_pinned_and_unpinned_guest
|
||||
tempest_exclude_regex: 'test_live_migrate_and_reboot|test_shared_pinned_and_unpinned_guest|^whitebox_tempest_plugin.api.compute.test_cpu_pinning.EmulatorThreadTest'
|
||||
|
||||
- job:
|
||||
name: whitebox-devstack-multinode-cpupinning
|
||||
@ -95,7 +95,7 @@
|
||||
Runs the CPU pinning tests on single-NUMA, non-SMT, nested virt VMs. Uses
|
||||
[compute]cpu_dedicated_set to configure host CPUs for pinning.
|
||||
vars:
|
||||
tempest_test_regex: test_live_migrate_and_reboot|test_shared_pinned_and_unpinned_guest
|
||||
tempest_test_regex: 'test_live_migrate_and_reboot|test_shared_pinned_and_unpinned_guest|^whitebox_tempest_plugin.api.compute.test_cpu_pinning.EmulatorThreadTest'
|
||||
devstack_local_conf:
|
||||
post-config:
|
||||
$NOVA_CONF:
|
||||
@ -118,7 +118,7 @@
|
||||
Runs the CPU pinning tests on single-NUMA, non-SMT, nested virt VMs. Uses
|
||||
[DEFAULT]vcpu_pin_set to configure host CPUs for pinning.
|
||||
vars:
|
||||
tempest_test_regex: 'test_live_migrate_and_reboot'
|
||||
tempest_test_regex: 'test_live_migrate_and_reboot|^whitebox_tempest_plugin.api.compute.test_cpu_pinning.EmulatorThreadTest'
|
||||
devstack_local_conf:
|
||||
post-config:
|
||||
$NOVA_CONF:
|
||||
|
@ -31,6 +31,8 @@ function configure {
|
||||
iniset $TEMPEST_CONFIG whitebox-database host $DATABASE_HOST
|
||||
|
||||
iniset $TEMPEST_CONFIG whitebox-hardware cpu_topology "$WHITEBOX_CPU_TOPOLOGY"
|
||||
iniset $TEMPEST_CONFIG whitebox-hardware dedicated_cpus_per_numa "$WHITEBOX_DEDICATED_CPUS_PER_NUMA"
|
||||
iniset $TEMPEST_CONFIG whitebox-hardware shared_cpus_per_numa "$WHITEBOX_SHARED_CPUS_PER_NUMA"
|
||||
|
||||
iniset $TEMPEST_CONFIG compute-feature-enabled virtio_rng "$COMPUTE_FEATURE_VIRTIO_RNG"
|
||||
iniset $TEMPEST_CONFIG compute-feature-enabled rbd_download "$COMPUTE_FEATURE_RBD_DOWNLOAD"
|
||||
|
@ -15,6 +15,8 @@ WHITEBOX_LIBVIRT_MASK_COMMAND=${WHITEBOX_LIBVIRT_MASK_COMMAND:-'systemctl mask l
|
||||
WHITEBOX_LIBVIRT_UNMASK_COMMAND=${WHITEBOX_LIBVIRT_UNMASK_COMMAND:-'systemctl unmask libvirtd'}
|
||||
|
||||
WHITEBOX_CPU_TOPOLOGY=${WHITEBOX_CPU_TOPOLOGY:-''}
|
||||
WHITEBOX_DEDICATED_CPUS_PER_NUMA=${WHITEBOX_DEDICATED_CPUS_PER_NUMA:-4}
|
||||
WHITEBOX_SHARED_CPUS_PER_NUMA=${WHITEBOX_SHARED_CPUS_PER_NUMA:-2}
|
||||
|
||||
COMPUTE_FEATURE_VIRTIO_RNG=${COMPUTE_FEATURE_VIRTIO_RNG:-'True'}
|
||||
COMPUTE_FEATURE_RBD_DOWNLOAD=${COMPUTE_FEATURE_RBD_DOWNLOAD:-'False'}
|
||||
|
@ -29,6 +29,23 @@ class NUMAHelperMixin(object):
|
||||
pinset |= hardware.parse_cpu_spec(pin.get('cpuset'))
|
||||
return pinset
|
||||
|
||||
def get_server_emulator_threads(self, server_id):
|
||||
"""Get the host CPU numbers to which the server's emulator threads are
|
||||
pinned.
|
||||
|
||||
:param server_id: The instance UUID to look up.
|
||||
:return emulator_threads: A set of host CPU numbers.
|
||||
"""
|
||||
root = self.get_server_xml(server_id)
|
||||
|
||||
emulatorpins = root.findall('./cputune/emulatorpin')
|
||||
emulator_threads = set()
|
||||
for pin in emulatorpins:
|
||||
emulator_threads |= hardware.parse_cpu_spec(
|
||||
pin.get('cpuset'))
|
||||
|
||||
return emulator_threads
|
||||
|
||||
def get_host_pcpus_for_guest_vcpu(self, server_id, instance_cpu_id):
|
||||
"""Search the xml vcpu element of the provided instance for its cpuset.
|
||||
Convert cpuset found into a set of integers.
|
||||
|
@ -370,22 +370,20 @@ class CPUThreadPolicyTest(BasePinningTest):
|
||||
"host have HyperThreading enabled?")
|
||||
|
||||
|
||||
class EmulatorExtraCPUTest(BasePinningTest):
|
||||
class EmulatorThreadTest(BasePinningTest, numa_helper.NUMAHelperMixin):
|
||||
|
||||
vcpus = 1
|
||||
min_microversion = '2.74'
|
||||
|
||||
def setUp(self):
|
||||
super(EmulatorExtraCPUTest, self).setUp()
|
||||
# Iterate over cpu_topology and find the NUMA Node with the most
|
||||
# pCPUs and set that as the NUMA Node to use throughout the test
|
||||
largest_numa_node = max(CONF.whitebox_hardware.cpu_topology.items(),
|
||||
key=lambda k: len(k[1]))
|
||||
self.numa_to_use = largest_numa_node[0]
|
||||
super(EmulatorThreadTest, self).setUp()
|
||||
self.dedicated_cpus_per_numa = \
|
||||
CONF.whitebox_hardware.dedicated_cpus_per_numa
|
||||
self.shared_cpus_per_numa = \
|
||||
CONF.whitebox_hardware.shared_cpus_per_numa
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(EmulatorExtraCPUTest, cls).skip_checks()
|
||||
super(EmulatorThreadTest, cls).skip_checks()
|
||||
if not utils.is_extension_enabled('OS-FLV-EXT-DATA', 'compute'):
|
||||
msg = "OS-FLV-EXT-DATA extension not enabled."
|
||||
raise cls.skipException(msg)
|
||||
@ -394,7 +392,7 @@ class EmulatorExtraCPUTest(BasePinningTest):
|
||||
raise cls.skipException(msg)
|
||||
|
||||
def create_flavor(self, threads_policy, vcpus):
|
||||
flavor = super(EmulatorExtraCPUTest,
|
||||
flavor = super(EmulatorThreadTest,
|
||||
self).create_flavor(vcpus=vcpus, disk=1)
|
||||
|
||||
specs = {
|
||||
@ -404,133 +402,63 @@ class EmulatorExtraCPUTest(BasePinningTest):
|
||||
self.flavors_client.set_flavor_extra_spec(flavor['id'], **specs)
|
||||
return flavor
|
||||
|
||||
def get_server_emulator_threads(self, server_id):
|
||||
"""Get the host CPU numbers to which the server's emulator threads are
|
||||
pinned.
|
||||
|
||||
:param server_id: The instance UUID to look up.
|
||||
:return emulator_threads: A set of host CPU numbers.
|
||||
"""
|
||||
root = self.get_server_xml(server_id)
|
||||
|
||||
emulatorpins = root.findall('./cputune/emulatorpin')
|
||||
emulator_threads = set()
|
||||
for pin in emulatorpins:
|
||||
emulator_threads |= hardware.parse_cpu_spec(
|
||||
pin.get('cpuset'))
|
||||
|
||||
return emulator_threads
|
||||
|
||||
def policy_share_cpu_shared_set(self, section, pin_set_mode):
|
||||
def test_policy_share_cpu_shared_set(self):
|
||||
"""With policy set to share and cpu_share_set set, emulator threads
|
||||
should be pinned to cpu_share_set.
|
||||
|
||||
|
||||
:param section: The nova.conf section to apply the pin_set
|
||||
configuration
|
||||
:param pin_set_mode: Which pCPU list mode to use when exposing
|
||||
dedicated pCPU's to the guest, either vcpu_pin_set or cpu_dedicated_set
|
||||
:param single_shared_cpu bool, wheter to use a single pCPU for the
|
||||
shared set or a range of pCPUs for the shared_set range.
|
||||
"""
|
||||
# NOTE: this scenario is based around upstream BP:
|
||||
# https://blueprints.launchpad.net/nova/+spec/overhead-pin-set and
|
||||
# downstream BZ https://bugzilla.redhat.com/show_bug.cgi?id=1468004#c0
|
||||
# which allows for multiple guest's emulator threads to share the same
|
||||
# cpu_shared_set range
|
||||
if len(CONF.whitebox_hardware.cpu_topology[self.numa_to_use]) < 3:
|
||||
raise self.skipException('Test requires NUMA Node with 3 or more '
|
||||
'CPUs to run')
|
||||
dedicated_set = hardware.format_cpu_spec(
|
||||
CONF.whitebox_hardware.cpu_topology[self.numa_to_use][:2])
|
||||
if self.shared_cpus_per_numa == 0:
|
||||
raise self.skipException('Test requires cpu_shared_set to be '
|
||||
'configured on the compute hosts')
|
||||
|
||||
cpu_shared_set_str = hardware.format_cpu_spec(
|
||||
CONF.whitebox_hardware.cpu_topology[self.numa_to_use][2:])
|
||||
# Create a flavor using the shared threads_policy and create an
|
||||
# instance
|
||||
flavor = self.create_flavor(threads_policy='share',
|
||||
vcpus=self.shared_cpus_per_numa)
|
||||
|
||||
hostname = self.list_compute_hosts()[0]
|
||||
host_sm = clients.NovaServiceManager(
|
||||
hostname, 'nova-compute', self.os_admin.services_client)
|
||||
server = self.create_test_server(flavor=flavor['id'])
|
||||
|
||||
# Update the compute node's cpu_shared_set to cpu_shared_set_str and
|
||||
# dedicated CPUs to the range found for dedicated_set
|
||||
with host_sm.config_options((section, pin_set_mode, dedicated_set),
|
||||
('compute', 'cpu_shared_set',
|
||||
cpu_shared_set_str)):
|
||||
# Determine the compute host the guest was scheduled to and gather
|
||||
# the cpu shared set from the host
|
||||
host = self.get_host_for_server(server['id'])
|
||||
host_sm = clients.NovaServiceManager(host, 'nova-compute',
|
||||
self.os_admin.services_client)
|
||||
cpu_shared_set = host_sm.get_cpu_shared_set()
|
||||
|
||||
# Create a flavor using the shared threads_policy and two instances
|
||||
# on the same host
|
||||
flavor = self.create_flavor(threads_policy='share',
|
||||
vcpus=self.vcpus)
|
||||
server_a = self.create_test_server(
|
||||
clients=self.os_admin,
|
||||
flavor=flavor['id'],
|
||||
host=hostname
|
||||
)
|
||||
server_b = self.create_test_server(
|
||||
clients=self.os_admin,
|
||||
flavor=flavor['id'],
|
||||
host=hostname
|
||||
)
|
||||
# Gather the emulator threads from the server
|
||||
emulator_threads = \
|
||||
self.get_server_emulator_threads(server['id'])
|
||||
|
||||
# Gather the emulator threads from both servers
|
||||
emulator_threads_a = \
|
||||
self.get_server_emulator_threads(server_a['id'])
|
||||
emulator_threads_b = \
|
||||
self.get_server_emulator_threads(server_b['id'])
|
||||
# Confirm the emulator threads from the server is equal to the host's
|
||||
# cpu_shared_set
|
||||
self.assertEqual(
|
||||
cpu_shared_set, emulator_threads,
|
||||
'Emulator threads for server %s is not the same as CPU set '
|
||||
'%s' % (emulator_threads, cpu_shared_set))
|
||||
|
||||
# Confirm the emulator threads from server's A and B are both equal
|
||||
# to cpu_shared_set
|
||||
cpu_shared_set = hardware.parse_cpu_spec(cpu_shared_set_str)
|
||||
self.assertEqual(
|
||||
emulator_threads_a, cpu_shared_set,
|
||||
'Emulator threads for server A %s are not the same as CPU set '
|
||||
'%s' % (emulator_threads_a, cpu_shared_set))
|
||||
self.delete_server(server['id'])
|
||||
|
||||
self.assertEqual(
|
||||
emulator_threads_b, cpu_shared_set,
|
||||
'Emulator threads for server B %s are not the same as CPU set '
|
||||
'%s' % (emulator_threads_b, cpu_shared_set))
|
||||
|
||||
self.delete_server(server_a['id'])
|
||||
self.delete_server(server_b['id'])
|
||||
|
||||
def policy_share_cpu_shared_unset(self, section, pin_set_mode):
|
||||
def test_policy_share_cpu_shared_unset(self):
|
||||
"""With policy set to share and cpu_share_set unset, emulator threads
|
||||
should float over the instance's pCPUs.
|
||||
|
||||
:param section: The nova.conf section to apply the pin_set
|
||||
configuration
|
||||
:param pin_set_mode: Which pCPU list mode to use when exposing
|
||||
dedicated pCPU's to the guest, either vcpu_pin_set or cpu_dedicated_set
|
||||
"""
|
||||
if len(CONF.whitebox_hardware.cpu_topology[self.numa_to_use]) < 2:
|
||||
raise self.skipException('Test requires NUMA Node with 2 or more '
|
||||
'CPUs to run')
|
||||
if self.dedicated_cpus_per_numa < 2:
|
||||
raise self.skipException(
|
||||
'Need at least 2 or more pCPUs per NUMA allocated to the '
|
||||
'cpu_dedicated_set of the compute host')
|
||||
|
||||
dedicated_set = hardware.format_cpu_spec(
|
||||
CONF.whitebox_hardware.cpu_topology[self.numa_to_use][:2])
|
||||
hostname = self.list_compute_hosts()[0]
|
||||
host_sm = clients.NovaServiceManager(
|
||||
hostname, 'nova-compute', self.os_admin.services_client)
|
||||
|
||||
# Update the compute node's cpu_shared_set to None and dedicated CPUs
|
||||
# to the range found for dedicated_set
|
||||
with host_sm.config_options((section, pin_set_mode, dedicated_set),
|
||||
('compute', 'cpu_shared_set', None)):
|
||||
with self.config_all_computes(('compute', 'cpu_shared_set', None)):
|
||||
|
||||
# Create a flavor using the shared threads_policy and two instances
|
||||
# on the same host
|
||||
flavor = self.create_flavor(threads_policy='share',
|
||||
vcpus=self.vcpus)
|
||||
server_a = self.create_test_server(
|
||||
clients=self.os_admin,
|
||||
flavor=flavor['id'],
|
||||
host=hostname
|
||||
)
|
||||
flavor = self.create_flavor(
|
||||
threads_policy='share',
|
||||
vcpus=int(self.dedicated_cpus_per_numa / 2))
|
||||
|
||||
server_a = self.create_test_server(flavor=flavor['id'])
|
||||
server_b = self.create_test_server(
|
||||
clients=self.os_admin,
|
||||
flavor=flavor['id'],
|
||||
host=hostname
|
||||
scheduler_hints={'same_host': server_a['id']}
|
||||
)
|
||||
|
||||
# Gather the emulator threads from server A and B. Then gather the
|
||||
@ -555,212 +483,84 @@ class EmulatorExtraCPUTest(BasePinningTest):
|
||||
'Threads %s not the same as CPU pins %s' % (emulator_threads_b,
|
||||
cpu_pins_b))
|
||||
|
||||
# Confirm the pinned cpus from server a to do no intersect with
|
||||
# server b
|
||||
# Confirm the pinned pCPUs from server A do not intersect with
|
||||
# the pinned pCPUs of server B
|
||||
self.assertTrue(
|
||||
cpu_pins_a.isdisjoint(cpu_pins_b),
|
||||
'Different server pins overlap: %s and %s' % (cpu_pins_a,
|
||||
cpu_pins_b))
|
||||
|
||||
self.delete_server(server_a['id'])
|
||||
self.delete_server(server_b['id'])
|
||||
|
||||
def policy_isolate(self, section, pin_set_mode):
|
||||
def test_policy_isolate(self):
|
||||
"""With policy isolate, cpu_shared_set is ignored, and emulator threads
|
||||
should be pinned to a pCPU distinct from the instance's pCPUs.
|
||||
|
||||
:param section: The nova.conf section to apply the pin_set
|
||||
configuration
|
||||
:param pin_set_mode: Which pCPU list mode to use when exposing
|
||||
dedicated pCPU's to the guest, either vcpu_pin_set or cpu_dedicated_set
|
||||
"""
|
||||
if len(CONF.whitebox_hardware.cpu_topology[self.numa_to_use]) < 4:
|
||||
raise self.skipException('Test requires NUMA Node with 4 or more '
|
||||
'CPUs to run')
|
||||
dedicated_set = \
|
||||
set(CONF.whitebox_hardware.cpu_topology[self.numa_to_use])
|
||||
dedicated_set_str = hardware.format_cpu_spec(dedicated_set)
|
||||
if self.dedicated_cpus_per_numa < 2:
|
||||
raise self.skipException(
|
||||
'Need at least 2 or more pCPUs per NUMA allocated to the '
|
||||
'cpu_dedicated_set of the compute host')
|
||||
|
||||
hostname = self.list_compute_hosts()[0]
|
||||
host_sm = clients.NovaServiceManager(
|
||||
hostname, 'nova-compute', self.os_admin.services_client)
|
||||
# Create a flavor using the isolate threads_policy and then launch
|
||||
# an instance with the flavor
|
||||
flavor = self.create_flavor(threads_policy='isolate',
|
||||
vcpus=(self.dedicated_cpus_per_numa - 1))
|
||||
|
||||
# Update the compute node's cpu_shared_set to None and dedicated CPUs
|
||||
# to the range found for dedicated_set_str
|
||||
with host_sm.config_options((section, pin_set_mode, dedicated_set_str),
|
||||
('compute', 'cpu_shared_set', None)):
|
||||
server = self.create_test_server(flavor=flavor['id'])
|
||||
|
||||
# Create a flavor using the isolate threads_policy and two
|
||||
# instances on the same host
|
||||
flavor = self.create_flavor(threads_policy='isolate',
|
||||
vcpus=self.vcpus)
|
||||
server_a = self.create_test_server(
|
||||
clients=self.os_admin,
|
||||
flavor=flavor['id'],
|
||||
host=hostname
|
||||
)
|
||||
server_b = self.create_test_server(
|
||||
clients=self.os_admin,
|
||||
flavor=flavor['id'],
|
||||
host=hostname
|
||||
)
|
||||
# Gather the emulator threads and the pinned PCPUs from the guest
|
||||
emulator_threads = \
|
||||
self.get_server_emulator_threads(server['id'])
|
||||
cpu_pins = self.get_pinning_as_set(server['id'])
|
||||
|
||||
# Gather the emulator threads from server A and B. Then gather the
|
||||
# pinned PCPUs from server A and B.
|
||||
emulator_threads_a = \
|
||||
self.get_server_emulator_threads(server_a['id'])
|
||||
emulator_threads_b = \
|
||||
self.get_server_emulator_threads(server_b['id'])
|
||||
# Determine the compute host the guest was scheduled to and gather
|
||||
# the cpu dedicated set from the host
|
||||
host = self.get_host_for_server(server['id'])
|
||||
host_sm = clients.NovaServiceManager(host, 'nova-compute',
|
||||
self.os_admin.services_client)
|
||||
cpu_dedicated_set = host_sm.get_cpu_dedicated_set()
|
||||
|
||||
cpu_pins_a = self.get_pinning_as_set(server_a['id'])
|
||||
cpu_pins_b = self.get_pinning_as_set(server_b['id'])
|
||||
# Confirm the pinned cpus from the guest are part of the dedicated
|
||||
# range of the compute host it is scheduled to
|
||||
self.assertTrue(
|
||||
cpu_pins.issubset(cpu_dedicated_set), 'Pin set value %s is not '
|
||||
'a subset of %s' % (cpu_pins, cpu_dedicated_set))
|
||||
|
||||
# Check that every value gathered is a subset of the
|
||||
# cpu_dedicate_set configured for the host
|
||||
for pin_set in [emulator_threads_a, emulator_threads_b, cpu_pins_a,
|
||||
cpu_pins_b]:
|
||||
self.assertTrue(
|
||||
pin_set.issubset(dedicated_set), 'Pin set value %s is not '
|
||||
'a subset of %s' % (pin_set, dedicated_set))
|
||||
# Validate the emulator thread is disjoined from the pinned CPUs of the
|
||||
# guest.
|
||||
self.assertTrue(
|
||||
cpu_pins.isdisjoint(emulator_threads),
|
||||
'Threads %s overlap with CPUs %s' % (emulator_threads,
|
||||
cpu_pins))
|
||||
|
||||
# Validate that all emulator thread and guest pinned CPUs are all
|
||||
# disjointed from each other
|
||||
self.assertTrue(
|
||||
cpu_pins_a.isdisjoint(emulator_threads_a),
|
||||
'Threads %s overlap with CPUs %s' % (emulator_threads_a,
|
||||
cpu_pins_a))
|
||||
self.assertTrue(
|
||||
cpu_pins_b.isdisjoint(emulator_threads_b),
|
||||
'Threads %s overlap with CPUs %s' % (emulator_threads_b,
|
||||
cpu_pins_b))
|
||||
self.assertTrue(
|
||||
cpu_pins_a.isdisjoint(cpu_pins_b),
|
||||
'Different server pins overlap: %s and %s' % (cpu_pins_a,
|
||||
cpu_pins_b))
|
||||
self.assertTrue(
|
||||
emulator_threads_a.isdisjoint(emulator_threads_b),
|
||||
'Different threads overlap: %s and %s' % (emulator_threads_a,
|
||||
emulator_threads_b))
|
||||
self.delete_server(server_a['id'])
|
||||
self.delete_server(server_b['id'])
|
||||
# Confirm the emulator thread is a subset of the compute host's cpu
|
||||
# dedicated set
|
||||
self.assertTrue(
|
||||
emulator_threads.issubset(cpu_dedicated_set), 'Emulator thread '
|
||||
'value %s is not a subset of cpu dedicated set %s' %
|
||||
(emulator_threads, cpu_dedicated_set))
|
||||
|
||||
def emulator_no_extra_cpu(self, section, pin_set_mode):
|
||||
self.delete_server(server['id'])
|
||||
|
||||
def test_emulator_no_extra_cpu(self):
|
||||
"""Create a flavor that consumes all available pCPUs for the guest.
|
||||
The flavor should also be set to isolate emulator pinning. Instance
|
||||
should fail to build, since there are no distinct pCPUs available for
|
||||
the emulator thread.
|
||||
|
||||
:param pin_set_mode: Which pCPU list mode to use when exposing
|
||||
dedicated pCPU's to the guest, either vcpu_pin_set or cpu_dedicated_set
|
||||
"""
|
||||
if len(CONF.whitebox_hardware.cpu_topology[self.numa_to_use]) < 2:
|
||||
raise self.skipException('Test requires NUMA Node with 2 or more '
|
||||
'CPUs to run')
|
||||
dedicated_set = hardware.format_cpu_spec(
|
||||
CONF.whitebox_hardware.cpu_topology[self.numa_to_use][:2])
|
||||
|
||||
hostname = self.list_compute_hosts()[0]
|
||||
host_sm = clients.NovaServiceManager(
|
||||
hostname, 'nova-compute', self.os_admin.services_client)
|
||||
# Create a dedicated flavor with a vcpu size equal to the number
|
||||
# of available pCPUs in the dedicated set. With threads_policy
|
||||
# being set to isolate, the build should fail since no more
|
||||
# pCPUs will be available.
|
||||
flavor = self.create_flavor(threads_policy='isolate',
|
||||
vcpus=self.dedicated_cpus_per_numa)
|
||||
|
||||
with host_sm.config_options((section, pin_set_mode, dedicated_set),
|
||||
('compute', 'cpu_shared_set', None)):
|
||||
|
||||
# Create a dedicated flavor with a vcpu size equal to the number
|
||||
# of available pCPUs in the dedicated set. With threads_policy
|
||||
# being set to isolate, the build should fail since no more
|
||||
# pCPUs will be available.
|
||||
flavor = self.create_flavor(threads_policy='isolate',
|
||||
vcpus=len(dedicated_set))
|
||||
|
||||
# Confirm the instance cannot be built
|
||||
self.assertRaises(BuildErrorException,
|
||||
self.create_test_server,
|
||||
clients=self.os_admin,
|
||||
flavor=flavor['id'],
|
||||
host=hostname)
|
||||
|
||||
|
||||
class VCPUPinSetEmulatorThreads(EmulatorExtraCPUTest):
|
||||
|
||||
max_microversion = '2.79'
|
||||
pin_set_mode = 'vcpu_pin_set'
|
||||
pin_section = 'DEFAULT'
|
||||
|
||||
def test_policy_share_cpu_shared_set(self):
|
||||
"""With policy set to share and cpu_share_set set, emulator threads
|
||||
should be pinned to cpu_share_set.
|
||||
"""
|
||||
super(VCPUPinSetEmulatorThreads,
|
||||
self).policy_share_cpu_shared_set(
|
||||
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
||||
|
||||
def test_policy_share_cpu_shared_unset(self):
|
||||
"""With policy set to share and cpu_share_set unset, emulator threads
|
||||
should float over the instance's pCPUs.
|
||||
"""
|
||||
super(VCPUPinSetEmulatorThreads,
|
||||
self).policy_share_cpu_shared_unset(
|
||||
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
||||
|
||||
def test_policy_isolate(self):
|
||||
"""With policy isolate, cpu_shared_set is ignored, and emulator threads
|
||||
sould be pinned to a pCPU distinct from the instance's pCPUs. pCPU's
|
||||
are exposed to the guest via vcpu_pin_set.
|
||||
"""
|
||||
super(VCPUPinSetEmulatorThreads,
|
||||
self).policy_isolate(
|
||||
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
||||
|
||||
def test_emulator_no_extra_cpu(self):
|
||||
"""With policy isolate and an instance's vCPU's consuming all available
|
||||
pCPU's from the vcpu_pin_set, build should fail since there are no
|
||||
pCPU's available for the emulator thread
|
||||
"""
|
||||
super(VCPUPinSetEmulatorThreads,
|
||||
self).emulator_no_extra_cpu(
|
||||
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
||||
|
||||
|
||||
class CPUDedicatedEmulatorThreads(EmulatorExtraCPUTest):
|
||||
|
||||
compute_min_microversion = '2.79'
|
||||
compute_max_microversion = 'latest'
|
||||
pin_set_mode = 'cpu_dedicated_set'
|
||||
pin_section = 'compute'
|
||||
|
||||
def test_policy_share_cpu_shared_set(self):
|
||||
"""With policy set to share and cpu_share_set set, emulator threads
|
||||
should be pinned to cpu_share_set.
|
||||
"""
|
||||
super(CPUDedicatedEmulatorThreads,
|
||||
self).policy_share_cpu_shared_set(
|
||||
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
||||
|
||||
def test_policy_share_cpu_shared_unset(self):
|
||||
"""With policy set to share and cpu_share_set unset, emulator threads
|
||||
should float over the instance's pCPUs.
|
||||
"""
|
||||
super(CPUDedicatedEmulatorThreads,
|
||||
self).policy_share_cpu_shared_unset(
|
||||
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
||||
|
||||
def test_policy_isolate(self):
|
||||
"""With policy isolate, cpu_shared_set is ignored, and emulator threads
|
||||
sould be pinned to a pCPU distinct from the instance's pCPUs. pCPU's
|
||||
are exposed to the guest via cpu_dedicated_set.
|
||||
"""
|
||||
super(CPUDedicatedEmulatorThreads,
|
||||
self).policy_isolate(
|
||||
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
||||
|
||||
def test_emulator_no_extra_cpu(self):
|
||||
"""With policy isolate and an instance's vCPU's consuming all available
|
||||
pCPU's from the cpu_dedicated_set, build should fail since there are no
|
||||
pCPU's available for the emulator thread
|
||||
"""
|
||||
super(CPUDedicatedEmulatorThreads,
|
||||
self).emulator_no_extra_cpu(
|
||||
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
||||
# Confirm the instance cannot be built
|
||||
self.assertRaises(BuildErrorException,
|
||||
self.create_test_server,
|
||||
flavor=flavor['id'])
|
||||
|
||||
|
||||
class NUMALiveMigrationBase(BasePinningTest):
|
||||
|
@ -225,6 +225,14 @@ hardware_opts = [
|
||||
'<List of CPUs in that node>. For example, if NUMA node 0 has '
|
||||
'CPUs 0 and 1, and NUMA node 1 has CPUs 2 and 3, the value to '
|
||||
'set would be `0: [0,1], 1: [2, 3]`.'),
|
||||
cfg.IntOpt(
|
||||
'dedicated_cpus_per_numa',
|
||||
default=0,
|
||||
help='Number of pCPUs allocated for cpu_dedicated_set per NUMA'),
|
||||
cfg.IntOpt(
|
||||
'shared_cpus_per_numa',
|
||||
default=0,
|
||||
help='Number of pCPUs allocated for cpu_shared_set per NUMA'),
|
||||
cfg.StrOpt(
|
||||
'sriov_physnet',
|
||||
default=None,
|
||||
|
Loading…
x
Reference in New Issue
Block a user