Merge "hardware: Update and correct typing information"
This commit is contained in:
commit
1c3dd7ce0a
|
@ -1 +1,2 @@
|
||||||
|
nova/virt/hardware.py
|
||||||
nova/virt/libvirt/__init__.py
|
nova/virt/libvirt/__init__.py
|
||||||
|
|
|
@ -1185,6 +1185,32 @@ class NUMATopologyTest(test.NoDBTestCase):
|
||||||
},
|
},
|
||||||
"expect": exception.ImageNUMATopologyIncomplete,
|
"expect": exception.ImageNUMATopologyIncomplete,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
# Request missing mem.1
|
||||||
|
"flavor": objects.Flavor(vcpus=8, memory_mb=2048,
|
||||||
|
extra_specs={
|
||||||
|
"hw:numa_nodes": 2,
|
||||||
|
"hw:numa_cpus.0": "0-3",
|
||||||
|
"hw:numa_cpus.1": "4-7",
|
||||||
|
"hw:numa_mem.0": "1576",
|
||||||
|
}),
|
||||||
|
"image": {
|
||||||
|
},
|
||||||
|
"expect": exception.ImageNUMATopologyIncomplete,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Request missing cpu.1
|
||||||
|
"flavor": objects.Flavor(vcpus=8, memory_mb=2048,
|
||||||
|
extra_specs={
|
||||||
|
"hw:numa_nodes": 2,
|
||||||
|
"hw:numa_cpus.0": "0-3",
|
||||||
|
"hw:numa_mem.0": "1024",
|
||||||
|
"hw:numa_mem.1": "1024",
|
||||||
|
}),
|
||||||
|
"image": {
|
||||||
|
},
|
||||||
|
"expect": exception.ImageNUMATopologyIncomplete,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
# Image attempts to override flavor
|
# Image attempts to override flavor
|
||||||
"flavor": objects.Flavor(vcpus=8, memory_mb=2048,
|
"flavor": objects.Flavor(vcpus=8, memory_mb=2048,
|
||||||
|
|
|
@ -17,7 +17,7 @@ import fractions
|
||||||
import itertools
|
import itertools
|
||||||
import math
|
import math
|
||||||
import re
|
import re
|
||||||
from typing import List, Optional, Set, Tuple
|
import typing as ty
|
||||||
|
|
||||||
import os_resource_classes as orc
|
import os_resource_classes as orc
|
||||||
import os_traits
|
import os_traits
|
||||||
|
@ -90,7 +90,7 @@ def get_cpu_shared_set():
|
||||||
return shared_ids
|
return shared_ids
|
||||||
|
|
||||||
|
|
||||||
def parse_cpu_spec(spec):
|
def parse_cpu_spec(spec: str) -> ty.Set[int]:
|
||||||
"""Parse a CPU set specification.
|
"""Parse a CPU set specification.
|
||||||
|
|
||||||
Each element in the list is either a single CPU number, a range of
|
Each element in the list is either a single CPU number, a range of
|
||||||
|
@ -101,8 +101,8 @@ def parse_cpu_spec(spec):
|
||||||
|
|
||||||
:returns: a set of CPU indexes
|
:returns: a set of CPU indexes
|
||||||
"""
|
"""
|
||||||
cpuset_ids = set()
|
cpuset_ids: ty.Set[int] = set()
|
||||||
cpuset_reject_ids = set()
|
cpuset_reject_ids: ty.Set[int] = set()
|
||||||
for rule in spec.split(','):
|
for rule in spec.split(','):
|
||||||
rule = rule.strip()
|
rule = rule.strip()
|
||||||
# Handle multi ','
|
# Handle multi ','
|
||||||
|
@ -152,7 +152,10 @@ def parse_cpu_spec(spec):
|
||||||
return cpuset_ids
|
return cpuset_ids
|
||||||
|
|
||||||
|
|
||||||
def format_cpu_spec(cpuset, allow_ranges=True):
|
def format_cpu_spec(
|
||||||
|
cpuset: ty.Set[int],
|
||||||
|
allow_ranges: bool = True,
|
||||||
|
) -> str:
|
||||||
"""Format a libvirt CPU range specification.
|
"""Format a libvirt CPU range specification.
|
||||||
|
|
||||||
Format a set/list of CPU indexes as a libvirt CPU range
|
Format a set/list of CPU indexes as a libvirt CPU range
|
||||||
|
@ -161,6 +164,8 @@ def format_cpu_spec(cpuset, allow_ranges=True):
|
||||||
index explicitly.
|
index explicitly.
|
||||||
|
|
||||||
:param cpuset: set (or list) of CPU indexes
|
:param cpuset: set (or list) of CPU indexes
|
||||||
|
:param allow_ranges: Whether we should attempt to detect continuous ranges
|
||||||
|
of CPUs.
|
||||||
|
|
||||||
:returns: a formatted CPU range string
|
:returns: a formatted CPU range string
|
||||||
"""
|
"""
|
||||||
|
@ -168,7 +173,7 @@ def format_cpu_spec(cpuset, allow_ranges=True):
|
||||||
# trying to do range negations to minimize the overall
|
# trying to do range negations to minimize the overall
|
||||||
# spec string length
|
# spec string length
|
||||||
if allow_ranges:
|
if allow_ranges:
|
||||||
ranges = []
|
ranges: ty.List[ty.List[int]] = []
|
||||||
previndex = None
|
previndex = None
|
||||||
for cpuindex in sorted(cpuset):
|
for cpuindex in sorted(cpuset):
|
||||||
if previndex is None or previndex != (cpuindex - 1):
|
if previndex is None or previndex != (cpuindex - 1):
|
||||||
|
@ -552,7 +557,9 @@ def _sort_possible_cpu_topologies(possible, wanttopology):
|
||||||
# We don't use python's sort(), since we want to
|
# We don't use python's sort(), since we want to
|
||||||
# preserve the sorting done when populating the
|
# preserve the sorting done when populating the
|
||||||
# 'possible' list originally
|
# 'possible' list originally
|
||||||
scores = collections.defaultdict(list)
|
scores: ty.Dict[int, ty.List['objects.VirtCPUTopology']] = (
|
||||||
|
collections.defaultdict(list)
|
||||||
|
)
|
||||||
for topology in possible:
|
for topology in possible:
|
||||||
score = _score_cpu_topology(topology, wanttopology)
|
score = _score_cpu_topology(topology, wanttopology)
|
||||||
scores[score].append(topology)
|
scores[score].append(topology)
|
||||||
|
@ -731,7 +738,9 @@ def _pack_instance_onto_cores(host_cell, instance_cell,
|
||||||
# We build up a data structure that answers the question: 'Given the
|
# We build up a data structure that answers the question: 'Given the
|
||||||
# number of threads I want to pack, give me a list of all the available
|
# number of threads I want to pack, give me a list of all the available
|
||||||
# sibling sets (or groups thereof) that can accommodate it'
|
# sibling sets (or groups thereof) that can accommodate it'
|
||||||
sibling_sets = collections.defaultdict(list)
|
sibling_sets: ty.Dict[int, ty.List[ty.Set[int]]] = (
|
||||||
|
collections.defaultdict(list)
|
||||||
|
)
|
||||||
for sib in host_cell.free_siblings:
|
for sib in host_cell.free_siblings:
|
||||||
for threads_no in range(1, len(sib) + 1):
|
for threads_no in range(1, len(sib) + 1):
|
||||||
sibling_sets[threads_no].append(sib)
|
sibling_sets[threads_no].append(sib)
|
||||||
|
@ -1175,7 +1184,12 @@ def _numa_fit_instance_cell(host_cell, instance_cell, limit_cell=None,
|
||||||
return instance_cell
|
return instance_cell
|
||||||
|
|
||||||
|
|
||||||
def _get_flavor_image_meta(key, flavor, image_meta, default=None):
|
def _get_flavor_image_meta(
|
||||||
|
key: str,
|
||||||
|
flavor: 'objects.Flavor',
|
||||||
|
image_meta: 'objects.ImageMeta',
|
||||||
|
default: ty.Any = None,
|
||||||
|
) -> ty.Tuple[ty.Any, ty.Any]:
|
||||||
"""Extract both flavor- and image-based variants of metadata."""
|
"""Extract both flavor- and image-based variants of metadata."""
|
||||||
flavor_key = ':'.join(['hw', key])
|
flavor_key = ':'.join(['hw', key])
|
||||||
image_key = '_'.join(['hw', key])
|
image_key = '_'.join(['hw', key])
|
||||||
|
@ -1186,7 +1200,11 @@ def _get_flavor_image_meta(key, flavor, image_meta, default=None):
|
||||||
return flavor_policy, image_policy
|
return flavor_policy, image_policy
|
||||||
|
|
||||||
|
|
||||||
def get_mem_encryption_constraint(flavor, image_meta, machine_type=None):
|
def get_mem_encryption_constraint(
|
||||||
|
flavor: 'objects.Flavor',
|
||||||
|
image_meta: 'objects.ImageMeta',
|
||||||
|
machine_type: ty.Optional[str] = None,
|
||||||
|
) -> bool:
|
||||||
"""Return a boolean indicating whether encryption of guest memory was
|
"""Return a boolean indicating whether encryption of guest memory was
|
||||||
requested, either via the hw:mem_encryption extra spec or the
|
requested, either via the hw:mem_encryption extra spec or the
|
||||||
hw_mem_encryption image property (or both).
|
hw_mem_encryption image property (or both).
|
||||||
|
@ -1323,7 +1341,10 @@ def _check_mem_encryption_machine_type(image_meta, machine_type=None):
|
||||||
reason=_("q35 type is required for SEV to work"))
|
reason=_("q35 type is required for SEV to work"))
|
||||||
|
|
||||||
|
|
||||||
def _get_numa_pagesize_constraint(flavor, image_meta):
|
def _get_numa_pagesize_constraint(
|
||||||
|
flavor: 'objects.Flavor',
|
||||||
|
image_meta: 'objects.ImageMeta',
|
||||||
|
) -> ty.Optional[int]:
|
||||||
"""Return the requested memory page size
|
"""Return the requested memory page size
|
||||||
|
|
||||||
:param flavor: a Flavor object to read extra specs from
|
:param flavor: a Flavor object to read extra specs from
|
||||||
|
@ -1388,8 +1409,10 @@ def _get_constraint_mappings_from_flavor(flavor, key, func):
|
||||||
return hw_numa_map or None
|
return hw_numa_map or None
|
||||||
|
|
||||||
|
|
||||||
def _get_numa_cpu_constraint(flavor, image_meta):
|
def _get_numa_cpu_constraint(
|
||||||
# type: (objects.Flavor, objects.ImageMeta) -> Optional[List[Set[int]]]
|
flavor: 'objects.Flavor',
|
||||||
|
image_meta: 'objects.ImageMeta',
|
||||||
|
) -> ty.Optional[ty.List[ty.Set[int]]]:
|
||||||
"""Validate and return the requested guest NUMA-guest CPU mapping.
|
"""Validate and return the requested guest NUMA-guest CPU mapping.
|
||||||
|
|
||||||
Extract the user-provided mapping of guest CPUs to guest NUMA nodes. For
|
Extract the user-provided mapping of guest CPUs to guest NUMA nodes. For
|
||||||
|
@ -1418,8 +1441,10 @@ def _get_numa_cpu_constraint(flavor, image_meta):
|
||||||
return flavor_cpu_list
|
return flavor_cpu_list
|
||||||
|
|
||||||
|
|
||||||
def _get_numa_mem_constraint(flavor, image_meta):
|
def _get_numa_mem_constraint(
|
||||||
# type: (objects.Flavor, objects.ImageMeta) -> Optional[List[Set[int]]]
|
flavor: 'objects.Flavor',
|
||||||
|
image_meta: 'objects.ImageMeta',
|
||||||
|
) -> ty.Optional[ty.List[int]]:
|
||||||
"""Validate and return the requested guest NUMA-guest memory mapping.
|
"""Validate and return the requested guest NUMA-guest memory mapping.
|
||||||
|
|
||||||
Extract the user-provided mapping of guest memory to guest NUMA nodes. For
|
Extract the user-provided mapping of guest memory to guest NUMA nodes. For
|
||||||
|
@ -1448,8 +1473,10 @@ def _get_numa_mem_constraint(flavor, image_meta):
|
||||||
return flavor_mem_list
|
return flavor_mem_list
|
||||||
|
|
||||||
|
|
||||||
def _get_numa_node_count_constraint(flavor, image_meta):
|
def _get_numa_node_count_constraint(
|
||||||
# type: (objects.Flavor, objects.ImageMeta) -> Optional[int]
|
flavor: 'objects.Flavor',
|
||||||
|
image_meta: 'objects.ImageMeta',
|
||||||
|
) -> ty.Optional[int]:
|
||||||
"""Validate and return the requested NUMA nodes.
|
"""Validate and return the requested NUMA nodes.
|
||||||
|
|
||||||
:param flavor: ``nova.objects.Flavor`` instance
|
:param flavor: ``nova.objects.Flavor`` instance
|
||||||
|
@ -1475,8 +1502,10 @@ def _get_numa_node_count_constraint(flavor, image_meta):
|
||||||
|
|
||||||
|
|
||||||
# NOTE(stephenfin): This must be public as it's used elsewhere
|
# NOTE(stephenfin): This must be public as it's used elsewhere
|
||||||
def get_cpu_policy_constraint(flavor, image_meta):
|
def get_cpu_policy_constraint(
|
||||||
# type: (objects.Flavor, objects.ImageMeta) -> Optional[str]
|
flavor: 'objects.Flavor',
|
||||||
|
image_meta: 'objects.ImageMeta',
|
||||||
|
) -> ty.Optional[str]:
|
||||||
"""Validate and return the requested CPU policy.
|
"""Validate and return the requested CPU policy.
|
||||||
|
|
||||||
:param flavor: ``nova.objects.Flavor`` instance
|
:param flavor: ``nova.objects.Flavor`` instance
|
||||||
|
@ -1517,8 +1546,10 @@ def get_cpu_policy_constraint(flavor, image_meta):
|
||||||
|
|
||||||
|
|
||||||
# NOTE(stephenfin): This must be public as it's used elsewhere
|
# NOTE(stephenfin): This must be public as it's used elsewhere
|
||||||
def get_cpu_thread_policy_constraint(flavor, image_meta):
|
def get_cpu_thread_policy_constraint(
|
||||||
# type: (objects.Flavor, objects.ImageMeta) -> Optional[str]
|
flavor: 'objects.Flavor',
|
||||||
|
image_meta: 'objects.ImageMeta',
|
||||||
|
) -> ty.Optional[str]:
|
||||||
"""Validate and return the requested CPU thread policy.
|
"""Validate and return the requested CPU thread policy.
|
||||||
|
|
||||||
:param flavor: ``nova.objects.Flavor`` instance
|
:param flavor: ``nova.objects.Flavor`` instance
|
||||||
|
@ -1616,8 +1647,9 @@ def is_realtime_enabled(flavor):
|
||||||
return strutils.bool_from_string(flavor_rt)
|
return strutils.bool_from_string(flavor_rt)
|
||||||
|
|
||||||
|
|
||||||
def _get_vcpu_pcpu_resources(flavor):
|
def _get_vcpu_pcpu_resources(
|
||||||
# type: (objects.Flavor) -> Tuple[bool, bool]
|
flavor: 'objects.Flavor',
|
||||||
|
) -> ty.Tuple[int, int]:
|
||||||
requested_vcpu = 0
|
requested_vcpu = 0
|
||||||
requested_pcpu = 0
|
requested_pcpu = 0
|
||||||
|
|
||||||
|
@ -1635,11 +1667,13 @@ def _get_vcpu_pcpu_resources(flavor):
|
||||||
# this is handled elsewhere
|
# this is handled elsewhere
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return (requested_vcpu, requested_pcpu)
|
return requested_vcpu, requested_pcpu
|
||||||
|
|
||||||
|
|
||||||
def _get_hyperthreading_trait(flavor, image_meta):
|
def _get_hyperthreading_trait(
|
||||||
# type: (objects.Flavor, objects.ImageMeta) -> Optional[str]
|
flavor: 'objects.Flavor',
|
||||||
|
image_meta: 'objects.ImageMeta',
|
||||||
|
) -> ty.Optional[str]:
|
||||||
for key, val in flavor.get('extra_specs', {}).items():
|
for key, val in flavor.get('extra_specs', {}).items():
|
||||||
if re.match('trait([1-9][0-9]*)?:%s' % os_traits.HW_CPU_HYPERTHREADING,
|
if re.match('trait([1-9][0-9]*)?:%s' % os_traits.HW_CPU_HYPERTHREADING,
|
||||||
key):
|
key):
|
||||||
|
@ -1649,9 +1683,13 @@ def _get_hyperthreading_trait(flavor, image_meta):
|
||||||
'traits_required', []):
|
'traits_required', []):
|
||||||
return 'required'
|
return 'required'
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def _get_realtime_constraint(flavor, image_meta):
|
|
||||||
# type: (objects.Flavor, objects.ImageMeta) -> Optional[str]
|
def _get_realtime_constraint(
|
||||||
|
flavor: 'objects.Flavor',
|
||||||
|
image_meta: 'objects.ImageMeta',
|
||||||
|
) -> ty.Optional[str]:
|
||||||
"""Validate and return the requested realtime CPU mask.
|
"""Validate and return the requested realtime CPU mask.
|
||||||
|
|
||||||
:param flavor: ``nova.objects.Flavor`` instance
|
:param flavor: ``nova.objects.Flavor`` instance
|
||||||
|
@ -1666,15 +1704,17 @@ def _get_realtime_constraint(flavor, image_meta):
|
||||||
return image_mask or flavor_mask
|
return image_mask or flavor_mask
|
||||||
|
|
||||||
|
|
||||||
def vcpus_realtime_topology(flavor, image_meta):
|
def vcpus_realtime_topology(
|
||||||
# type: (objects.Flavor, objects.ImageMeta) -> List[int]
|
flavor: 'objects.Flavor',
|
||||||
|
image_meta: 'objects.ImageMeta',
|
||||||
|
) -> ty.Set[int]:
|
||||||
"""Determines instance vCPUs used as RT for a given spec.
|
"""Determines instance vCPUs used as RT for a given spec.
|
||||||
|
|
||||||
:param flavor: ``nova.objects.Flavor`` instance
|
:param flavor: ``nova.objects.Flavor`` instance
|
||||||
:param image_meta: ``nova.objects.ImageMeta`` instance
|
:param image_meta: ``nova.objects.ImageMeta`` instance
|
||||||
:raises: exception.RealtimeMaskNotFoundOrInvalid if mask was not found or
|
:raises: exception.RealtimeMaskNotFoundOrInvalid if mask was not found or
|
||||||
is invalid.
|
is invalid.
|
||||||
:returns: The realtime CPU mask requested, else None.
|
:returns: The realtime CPU mask requested.
|
||||||
"""
|
"""
|
||||||
mask = _get_realtime_constraint(flavor, image_meta)
|
mask = _get_realtime_constraint(flavor, image_meta)
|
||||||
if not mask:
|
if not mask:
|
||||||
|
@ -1688,8 +1728,9 @@ def vcpus_realtime_topology(flavor, image_meta):
|
||||||
|
|
||||||
|
|
||||||
# NOTE(stephenfin): This must be public as it's used elsewhere
|
# NOTE(stephenfin): This must be public as it's used elsewhere
|
||||||
def get_emulator_thread_policy_constraint(flavor):
|
def get_emulator_thread_policy_constraint(
|
||||||
# type: (objects.Flavor) -> Optional[str]
|
flavor: 'objects.Flavor',
|
||||||
|
) -> ty.Optional[str]:
|
||||||
"""Validate and return the requested emulator threads policy.
|
"""Validate and return the requested emulator threads policy.
|
||||||
|
|
||||||
:param flavor: ``nova.objects.Flavor`` instance
|
:param flavor: ``nova.objects.Flavor`` instance
|
||||||
|
@ -1701,7 +1742,7 @@ def get_emulator_thread_policy_constraint(flavor):
|
||||||
'hw:emulator_threads_policy')
|
'hw:emulator_threads_policy')
|
||||||
|
|
||||||
if not emu_threads_policy:
|
if not emu_threads_policy:
|
||||||
return
|
return None
|
||||||
|
|
||||||
if emu_threads_policy not in fields.CPUEmulatorThreadsPolicy.ALL:
|
if emu_threads_policy not in fields.CPUEmulatorThreadsPolicy.ALL:
|
||||||
raise exception.InvalidEmulatorThreadsPolicy(
|
raise exception.InvalidEmulatorThreadsPolicy(
|
||||||
|
@ -1794,22 +1835,20 @@ def numa_get_constraints(flavor, image_meta):
|
||||||
cpu_list = _get_numa_cpu_constraint(flavor, image_meta)
|
cpu_list = _get_numa_cpu_constraint(flavor, image_meta)
|
||||||
mem_list = _get_numa_mem_constraint(flavor, image_meta)
|
mem_list = _get_numa_mem_constraint(flavor, image_meta)
|
||||||
|
|
||||||
# If one property list is specified both must be
|
if cpu_list is None and mem_list is None:
|
||||||
if ((cpu_list is None and mem_list is not None) or
|
|
||||||
(cpu_list is not None and mem_list is None)):
|
|
||||||
raise exception.ImageNUMATopologyIncomplete()
|
|
||||||
|
|
||||||
# If any node has data set, all nodes must have data set
|
|
||||||
if ((cpu_list is not None and len(cpu_list) != nodes) or
|
|
||||||
(mem_list is not None and len(mem_list) != nodes)):
|
|
||||||
raise exception.ImageNUMATopologyIncomplete()
|
|
||||||
|
|
||||||
if cpu_list is None:
|
|
||||||
numa_topology = _get_numa_topology_auto(
|
numa_topology = _get_numa_topology_auto(
|
||||||
nodes, flavor)
|
nodes, flavor)
|
||||||
else:
|
elif cpu_list is not None and mem_list is not None:
|
||||||
|
# If any node has data set, all nodes must have data set
|
||||||
|
if len(cpu_list) != nodes or len(mem_list) != nodes:
|
||||||
|
raise exception.ImageNUMATopologyIncomplete()
|
||||||
|
|
||||||
numa_topology = _get_numa_topology_manual(
|
numa_topology = _get_numa_topology_manual(
|
||||||
nodes, flavor, cpu_list, mem_list)
|
nodes, flavor, cpu_list, mem_list
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# If one property list is specified both must be
|
||||||
|
raise exception.ImageNUMATopologyIncomplete()
|
||||||
|
|
||||||
# We currently support same pagesize for all cells.
|
# We currently support same pagesize for all cells.
|
||||||
for c in numa_topology.cells:
|
for c in numa_topology.cells:
|
||||||
|
@ -1912,11 +1951,10 @@ def numa_get_constraints(flavor, image_meta):
|
||||||
|
|
||||||
|
|
||||||
def _numa_cells_support_network_metadata(
|
def _numa_cells_support_network_metadata(
|
||||||
host_topology, # type: objects.NUMATopology
|
host_topology: 'objects.NUMATopology',
|
||||||
chosen_host_cells, # type: List[objects.NUMACell]
|
chosen_host_cells: ty.List['objects.NUMACell'],
|
||||||
network_metadata # type: objects.NetworkMetadata
|
network_metadata: 'objects.NetworkMetadata',
|
||||||
):
|
) -> bool:
|
||||||
# type: (...) -> bool
|
|
||||||
"""Determine whether the cells can accept the network requests.
|
"""Determine whether the cells can accept the network requests.
|
||||||
|
|
||||||
:param host_topology: The entire host topology, used to find non-chosen
|
:param host_topology: The entire host topology, used to find non-chosen
|
||||||
|
@ -1932,12 +1970,12 @@ def _numa_cells_support_network_metadata(
|
||||||
if not network_metadata:
|
if not network_metadata:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
required_physnets = None # type: Set[str]
|
required_physnets: ty.Set[str] = set()
|
||||||
if 'physnets' in network_metadata:
|
if 'physnets' in network_metadata:
|
||||||
# use set() to avoid modifying the original data structure
|
# use set() to avoid modifying the original data structure
|
||||||
required_physnets = set(network_metadata.physnets)
|
required_physnets = set(network_metadata.physnets)
|
||||||
|
|
||||||
required_tunnel = False # type: bool
|
required_tunnel: bool = False
|
||||||
if 'tunneled' in network_metadata:
|
if 'tunneled' in network_metadata:
|
||||||
required_tunnel = network_metadata.tunneled
|
required_tunnel = network_metadata.tunneled
|
||||||
|
|
||||||
|
@ -2045,8 +2083,8 @@ def numa_fit_instance_to_host(
|
||||||
# depending on whether we want packing/spreading over NUMA nodes
|
# depending on whether we want packing/spreading over NUMA nodes
|
||||||
for host_cell_perm in itertools.permutations(
|
for host_cell_perm in itertools.permutations(
|
||||||
host_cells, len(instance_topology)):
|
host_cells, len(instance_topology)):
|
||||||
chosen_instance_cells = []
|
chosen_instance_cells: ty.List['objects.InstanceNUMACell'] = []
|
||||||
chosen_host_cells = []
|
chosen_host_cells: ty.List['objects.NUMACell'] = []
|
||||||
for host_cell, instance_cell in zip(
|
for host_cell, instance_cell in zip(
|
||||||
host_cell_perm, instance_topology.cells):
|
host_cell_perm, instance_topology.cells):
|
||||||
try:
|
try:
|
||||||
|
@ -2096,14 +2134,14 @@ def numa_get_reserved_huge_pages():
|
||||||
|
|
||||||
:raises: exception.InvalidReservedMemoryPagesOption when
|
:raises: exception.InvalidReservedMemoryPagesOption when
|
||||||
reserved_huge_pages option is not correctly set.
|
reserved_huge_pages option is not correctly set.
|
||||||
:returns: a list of dict ordered by NUMA node ids; keys of dict
|
:returns: A dict of dicts keyed by NUMA node IDs; keys of child dict
|
||||||
are pages size and values of the number reserved.
|
are pages size and values of the number reserved.
|
||||||
"""
|
"""
|
||||||
if not CONF.reserved_huge_pages:
|
if not CONF.reserved_huge_pages:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bucket = collections.defaultdict(dict)
|
bucket: ty.Dict[int, ty.Dict[int, int]] = collections.defaultdict(dict)
|
||||||
for cfg in CONF.reserved_huge_pages:
|
for cfg in CONF.reserved_huge_pages:
|
||||||
try:
|
try:
|
||||||
pagesize = int(cfg['size'])
|
pagesize = int(cfg['size'])
|
||||||
|
|
Loading…
Reference in New Issue