Merge "Add CPU pinning data to InstanceNUMACell object"
This commit is contained in:
@@ -17,22 +17,42 @@ from oslo.serialization import jsonutils
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova.objects import base
|
||||
from nova.objects import fields
|
||||
from nova.objects import fields as obj_fields
|
||||
from nova.virt import hardware
|
||||
|
||||
|
||||
class InstanceNUMACell(base.NovaObject):
|
||||
# Version 1.0: Initial version
|
||||
# Version 1.1: Add pagesize field
|
||||
VERSION = '1.1'
|
||||
# Version 1.2: Add cpu_pinning_raw and topology fields
|
||||
VERSION = '1.2'
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(read_only=True),
|
||||
'cpuset': fields.SetOfIntegersField(),
|
||||
'memory': fields.IntegerField(),
|
||||
'pagesize': fields.IntegerField(nullable=True),
|
||||
'id': obj_fields.IntegerField(read_only=True),
|
||||
'cpuset': obj_fields.SetOfIntegersField(),
|
||||
'memory': obj_fields.IntegerField(),
|
||||
'pagesize': obj_fields.IntegerField(nullable=True),
|
||||
'cpu_topology': obj_fields.ObjectField('VirtCPUTopology',
|
||||
nullable=True),
|
||||
'cpu_pinning_raw': obj_fields.DictOfIntegersField(nullable=True)
|
||||
}
|
||||
|
||||
obj_relationships = {
|
||||
'cpu_topology': [('1.2', '1.0')]
|
||||
}
|
||||
|
||||
cpu_pinning = obj_fields.DictProxyField('cpu_pinning_raw')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(InstanceNUMACell, self).__init__(**kwargs)
|
||||
if 'cpu_topology' not in kwargs:
|
||||
self.cpu_topology = None
|
||||
if 'cpu_pinning' not in kwargs:
|
||||
self.cpu_pinning = None
|
||||
|
||||
def __len__(self):
|
||||
return len(self.cpuset)
|
||||
|
||||
def _to_dict(self):
|
||||
# NOTE(sahid): Used as legacy, could be renamed in
|
||||
# _legacy_to_dict_ to the future to avoid confusing.
|
||||
@@ -53,6 +73,29 @@ class InstanceNUMACell(base.NovaObject):
|
||||
return cls(id=cell_id, cpuset=cpuset,
|
||||
memory=memory, pagesize=pagesize)
|
||||
|
||||
@property
|
||||
def siblings(self):
|
||||
cpu_list = sorted(list(self.cpuset))
|
||||
|
||||
threads = 0
|
||||
if self.cpu_topology:
|
||||
threads = self.cpu_topology.threads
|
||||
if threads == 1:
|
||||
threads = 0
|
||||
|
||||
return map(set, zip(*[iter(cpu_list)] * threads))
|
||||
|
||||
def pin(self, vcpu, pcpu):
|
||||
if vcpu not in self.cpuset:
|
||||
return
|
||||
pinning_dict = self.cpu_pinning or {}
|
||||
pinning_dict[vcpu] = pcpu
|
||||
self.cpu_pinning = pinning_dict
|
||||
|
||||
def pin_vcpus(self, *cpu_pairs):
|
||||
for vcpu, pcpu in cpu_pairs:
|
||||
self.pin(vcpu, pcpu)
|
||||
|
||||
|
||||
class InstanceNUMATopology(base.NovaObject):
|
||||
# Version 1.0: Initial version
|
||||
@@ -62,9 +105,9 @@ class InstanceNUMATopology(base.NovaObject):
|
||||
fields = {
|
||||
# NOTE(danms): The 'id' field is no longer used and should be
|
||||
# removed in the future when convenient
|
||||
'id': fields.IntegerField(),
|
||||
'instance_uuid': fields.UUIDField(),
|
||||
'cells': fields.ListOfObjectsField('InstanceNUMACell'),
|
||||
'id': obj_fields.IntegerField(),
|
||||
'instance_uuid': obj_fields.UUIDField(),
|
||||
'cells': obj_fields.ListOfObjectsField('InstanceNUMACell'),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
|
@@ -92,6 +92,44 @@ class _TestInstanceNUMATopology(object):
|
||||
objects.InstanceNUMATopology.get_by_instance_uuid,
|
||||
self.context, 'fake_uuid')
|
||||
|
||||
def test_siblings(self):
|
||||
topo = objects.VirtCPUTopology(sockets=1, cores=3, threads=0)
|
||||
inst_cell = objects.InstanceNUMACell(
|
||||
cpuset=set([0, 1, 2]), topology=topo)
|
||||
self.assertEqual([], inst_cell.siblings)
|
||||
|
||||
# One thread actually means no threads
|
||||
topo = objects.VirtCPUTopology(sockets=1, cores=3, threads=1)
|
||||
inst_cell = objects.InstanceNUMACell(
|
||||
cpuset=set([0, 1, 2]), cpu_topology=topo)
|
||||
self.assertEqual([], inst_cell.siblings)
|
||||
|
||||
topo = objects.VirtCPUTopology(sockets=1, cores=2, threads=2)
|
||||
inst_cell = objects.InstanceNUMACell(
|
||||
cpuset=set([0, 1, 2, 3]), cpu_topology=topo)
|
||||
self.assertEqual([set([0, 1]), set([2, 3])], inst_cell.siblings)
|
||||
|
||||
topo = objects.VirtCPUTopology(sockets=1, cores=1, threads=4)
|
||||
inst_cell = objects.InstanceNUMACell(
|
||||
cpuset=set([0, 1, 2, 3]), cpu_topology=topo)
|
||||
self.assertEqual([set([0, 1, 2, 3])], inst_cell.siblings)
|
||||
|
||||
def test_pin(self):
|
||||
inst_cell = objects.InstanceNUMACell(cpuset=set([0, 1, 2, 3]),
|
||||
cpu_pinning=None)
|
||||
inst_cell.pin(0, 14)
|
||||
self.assertEqual({0: 14}, inst_cell.cpu_pinning)
|
||||
inst_cell.pin(12, 14)
|
||||
self.assertEqual({0: 14}, inst_cell.cpu_pinning)
|
||||
inst_cell.pin(1, 16)
|
||||
self.assertEqual({0: 14, 1: 16}, inst_cell.cpu_pinning)
|
||||
|
||||
def test_pin_vcpus(self):
|
||||
inst_cell = objects.InstanceNUMACell(cpuset=set([0, 1, 2, 3]),
|
||||
cpu_pinning=None)
|
||||
inst_cell.pin_vcpus((0, 14), (1, 15), (2, 16), (3, 17))
|
||||
self.assertEqual({0: 14, 1: 15, 2: 16, 3: 17}, inst_cell.cpu_pinning)
|
||||
|
||||
|
||||
class TestInstanceNUMATopology(test_objects._LocalTest,
|
||||
_TestInstanceNUMATopology):
|
||||
|
@@ -1103,7 +1103,7 @@ object_data = {
|
||||
'InstanceGroupList': '1.6-c6b78f3c9d9080d33c08667e80589817',
|
||||
'InstanceInfoCache': '1.5-ef64b604498bfa505a8c93747a9d8b2f',
|
||||
'InstanceList': '1.13-179093360c48747a41694cc2f326d75d',
|
||||
'InstanceNUMACell': '1.1-8d2a13c8360cc9ea1b68c9c6c4476857',
|
||||
'InstanceNUMACell': '1.2-5d2dfa36e9ecca9b63f24bf3bc958ea4',
|
||||
'InstanceNUMATopology': '1.1-86b95d263c4c68411d44c6741b8d2bb0',
|
||||
'InstancePCIRequest': '1.1-e082d174f4643e5756ba098c47c1510f',
|
||||
'InstancePCIRequests': '1.1-bc7c6684d8579ee49d6a3b8aef756918',
|
||||
@@ -1152,6 +1152,7 @@ object_relationships = {
|
||||
'TagList': '1.0',
|
||||
'SecurityGroupList': '1.0',
|
||||
'InstancePCIRequests': '1.1'},
|
||||
'InstanceNUMACell': {'VirtCPUTopology': '1.0'},
|
||||
'MyObj': {'MyOwnedObject': '1.0'},
|
||||
'SecurityGroupRule': {'SecurityGroup': '1.1'},
|
||||
'Service': {'ComputeNode': '1.6'},
|
||||
|
Reference in New Issue
Block a user