Add CPU pinning data to InstanceNUMACell object
We will use this object to hold the data about CPU pinning for each instance. We add the CPU pinning and topology information to each InstanceNUMACell. We will use this information to track pinning of each instance. Change-Id: Ic299e474ea210c9028a046b2665c0021fb2baf06 Blueprint: virt-driver-cpu-pinning
This commit is contained in:
parent
79603e3e95
commit
139529a90e
|
@ -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'},
|
||||
|
|
Loading…
Reference in New Issue