Merge "Add CPU pinning data to InstanceNUMACell object"

This commit is contained in:
Jenkins
2014-12-04 21:24:53 +00:00
committed by Gerrit Code Review
3 changed files with 92 additions and 10 deletions

View File

@@ -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

View File

@@ -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):

View File

@@ -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'},