pci: remove pci device from claims and allocations when freeing it

In drop_move_claim we call free pci device when we need to drop a
specific device from the src/dest node. This is done by calling
pci manager free_device. The current code just update the device
status to available in database but doesn't remove it from the
pci manager claims and allocations lists. This patch adds the
removal as well.

Closes-Bug: #1622854

Change-Id: If1cd6f3a635759cd55d116a34ca164630c61e085
This commit is contained in:
Moshe Levi 2016-09-13 09:30:59 +03:00 committed by Daniel Berrange
parent 40f9b0ad16
commit 6689c96cdf
2 changed files with 30 additions and 13 deletions

View File

@ -261,10 +261,27 @@ class PciDevTracker(object):
is allocated to is allocated to
""" """
for pci_dev in self.pci_devs: for pci_dev in self.pci_devs:
# find the matching pci device in the pci resource tracker # Find the matching pci device in the pci resource tracker.
# pci device. Once found one free it. # Once found, free it.
if dev.id == pci_dev.id and dev.instance_uuid == instance['uuid']: if dev.id == pci_dev.id and dev.instance_uuid == instance['uuid']:
self._remove_device_from_pci_mapping(
instance['uuid'], pci_dev, self.allocations)
self._remove_device_from_pci_mapping(
instance['uuid'], pci_dev, self.claims)
self._free_device(pci_dev) self._free_device(pci_dev)
break
def _remove_device_from_pci_mapping(
self, instance_uuid, pci_device, pci_mapping):
"""Remove a PCI device from allocations or claims.
If there are no more PCI devices, pop the uuid.
"""
pci_devices = pci_mapping.get(instance_uuid, [])
if pci_device in pci_devices:
pci_devices.remove(pci_device)
if len(pci_devices) == 0:
pci_mapping.pop(instance_uuid, None)
def _free_device(self, dev, instance=None): def _free_device(self, dev, instance=None):
freed_devs = dev.free(instance) freed_devs = dev.free(instance)

View File

@ -474,24 +474,24 @@ class PciDevTrackerTestCase(test.NoDBTestCase):
def test_free_device(self): def test_free_device(self):
pci_requests_obj = self._create_pci_requests_object( pci_requests_obj = self._create_pci_requests_object(
[{'count': 2, 'spec': [{'vendor_id': 'v'}]}]) [{'count': 1, 'spec': [{'vendor_id': 'v'}]}])
self.tracker.claim_instance(mock.sentinel.context, self.tracker.claim_instance(mock.sentinel.context,
pci_requests_obj, None) pci_requests_obj, None)
self.tracker.update_pci_for_instance(None, self.inst, sign=1) self.tracker.update_pci_for_instance(None, self.inst, sign=1)
free_pci_device_ids = ( free_pci_device_ids = (
[dev.id for dev in self.tracker.pci_stats.get_free_devs()]) [dev.id for dev in self.tracker.pci_stats.get_free_devs()])
self.assertEqual(1, len(free_pci_device_ids)) self.assertEqual(2, len(free_pci_device_ids))
allocated_devs = manager.get_instance_pci_devs(self.inst) allocated_devs = manager.get_instance_pci_devs(self.inst)
pci_device_a = allocated_devs[0] pci_device = allocated_devs[0]
pci_device_b = copy.deepcopy(allocated_devs[1]) self.assertNotIn(pci_device.id, free_pci_device_ids)
self.assertNotIn(pci_device_a.id, free_pci_device_ids) instance_uuid = self.inst['uuid']
self.assertNotIn(pci_device_b.id, free_pci_device_ids) self.assertIn(pci_device, self.tracker.allocations[instance_uuid])
for pci_device in (pci_device_a, pci_device_b): self.tracker.free_device(pci_device, self.inst)
self.tracker.free_device(pci_device, self.inst) free_pci_device_ids = (
free_pci_device_ids = ( [dev.id for dev in self.tracker.pci_stats.get_free_devs()])
[dev.id for dev in self.tracker.pci_stats.get_free_devs()])
self.assertIn(pci_device.id, free_pci_device_ids)
self.assertEqual(3, len(free_pci_device_ids)) self.assertEqual(3, len(free_pci_device_ids))
self.assertIn(pci_device.id, free_pci_device_ids)
self.assertIsNone(self.tracker.allocations.get(instance_uuid))
class PciGetInstanceDevs(test.NoDBTestCase): class PciGetInstanceDevs(test.NoDBTestCase):