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 db
from nova import exception from nova import exception
from nova.objects import base from nova.objects import base
from nova.objects import fields from nova.objects import fields as obj_fields
from nova.virt import hardware from nova.virt import hardware
class InstanceNUMACell(base.NovaObject): class InstanceNUMACell(base.NovaObject):
# Version 1.0: Initial version # Version 1.0: Initial version
# Version 1.1: Add pagesize field # Version 1.1: Add pagesize field
VERSION = '1.1' # Version 1.2: Add cpu_pinning_raw and topology fields
VERSION = '1.2'
fields = { fields = {
'id': fields.IntegerField(read_only=True), 'id': obj_fields.IntegerField(read_only=True),
'cpuset': fields.SetOfIntegersField(), 'cpuset': obj_fields.SetOfIntegersField(),
'memory': fields.IntegerField(), 'memory': obj_fields.IntegerField(),
'pagesize': fields.IntegerField(nullable=True), '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): def _to_dict(self):
# NOTE(sahid): Used as legacy, could be renamed in # NOTE(sahid): Used as legacy, could be renamed in
# _legacy_to_dict_ to the future to avoid confusing. # _legacy_to_dict_ to the future to avoid confusing.
@@ -53,6 +73,29 @@ class InstanceNUMACell(base.NovaObject):
return cls(id=cell_id, cpuset=cpuset, return cls(id=cell_id, cpuset=cpuset,
memory=memory, pagesize=pagesize) 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): class InstanceNUMATopology(base.NovaObject):
# Version 1.0: Initial version # Version 1.0: Initial version
@@ -62,9 +105,9 @@ class InstanceNUMATopology(base.NovaObject):
fields = { fields = {
# NOTE(danms): The 'id' field is no longer used and should be # NOTE(danms): The 'id' field is no longer used and should be
# removed in the future when convenient # removed in the future when convenient
'id': fields.IntegerField(), 'id': obj_fields.IntegerField(),
'instance_uuid': fields.UUIDField(), 'instance_uuid': obj_fields.UUIDField(),
'cells': fields.ListOfObjectsField('InstanceNUMACell'), 'cells': obj_fields.ListOfObjectsField('InstanceNUMACell'),
} }
@classmethod @classmethod

View File

@@ -92,6 +92,44 @@ class _TestInstanceNUMATopology(object):
objects.InstanceNUMATopology.get_by_instance_uuid, objects.InstanceNUMATopology.get_by_instance_uuid,
self.context, 'fake_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, class TestInstanceNUMATopology(test_objects._LocalTest,
_TestInstanceNUMATopology): _TestInstanceNUMATopology):

View File

@@ -1103,7 +1103,7 @@ object_data = {
'InstanceGroupList': '1.6-c6b78f3c9d9080d33c08667e80589817', 'InstanceGroupList': '1.6-c6b78f3c9d9080d33c08667e80589817',
'InstanceInfoCache': '1.5-ef64b604498bfa505a8c93747a9d8b2f', 'InstanceInfoCache': '1.5-ef64b604498bfa505a8c93747a9d8b2f',
'InstanceList': '1.13-179093360c48747a41694cc2f326d75d', 'InstanceList': '1.13-179093360c48747a41694cc2f326d75d',
'InstanceNUMACell': '1.1-8d2a13c8360cc9ea1b68c9c6c4476857', 'InstanceNUMACell': '1.2-5d2dfa36e9ecca9b63f24bf3bc958ea4',
'InstanceNUMATopology': '1.1-86b95d263c4c68411d44c6741b8d2bb0', 'InstanceNUMATopology': '1.1-86b95d263c4c68411d44c6741b8d2bb0',
'InstancePCIRequest': '1.1-e082d174f4643e5756ba098c47c1510f', 'InstancePCIRequest': '1.1-e082d174f4643e5756ba098c47c1510f',
'InstancePCIRequests': '1.1-bc7c6684d8579ee49d6a3b8aef756918', 'InstancePCIRequests': '1.1-bc7c6684d8579ee49d6a3b8aef756918',
@@ -1152,6 +1152,7 @@ object_relationships = {
'TagList': '1.0', 'TagList': '1.0',
'SecurityGroupList': '1.0', 'SecurityGroupList': '1.0',
'InstancePCIRequests': '1.1'}, 'InstancePCIRequests': '1.1'},
'InstanceNUMACell': {'VirtCPUTopology': '1.0'},
'MyObj': {'MyOwnedObject': '1.0'}, 'MyObj': {'MyOwnedObject': '1.0'},
'SecurityGroupRule': {'SecurityGroup': '1.1'}, 'SecurityGroupRule': {'SecurityGroup': '1.1'},
'Service': {'ComputeNode': '1.6'}, 'Service': {'ComputeNode': '1.6'},