]> xenbits.xensource.com Git - osstest/openstack-nova.git/commitdiff
pci: remove pci device from claims and allocations when freeing it
authorMoshe Levi <moshele@mellanox.com>
Tue, 13 Sep 2016 06:30:59 +0000 (09:30 +0300)
committerDaniel Berrange <berrange@redhat.com>
Thu, 3 Nov 2016 14:20:27 +0000 (14:20 +0000)
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

nova/pci/manager.py
nova/tests/unit/pci/test_manager.py

index 1c9790aa9e67e4fe6a43f931b242b24145b019ca..499117edc86775b550bdf51c71816cea2d702469 100644 (file)
@@ -261,10 +261,27 @@ class PciDevTracker(object):
                          is allocated to
         """
         for pci_dev in self.pci_devs:
-            # find the matching pci device in the pci resource tracker
-            # pci device. Once found one free it.
+            # Find the matching pci device in the pci resource tracker.
+            # Once found, free it.
             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)
+                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):
         freed_devs = dev.free(instance)
index ecfecfe7f365f9731d6875d104db6de5da3a9ca7..96b6fe623c0eb296fc574498c6899e055ec11061 100644 (file)
@@ -474,24 +474,24 @@ class PciDevTrackerTestCase(test.NoDBTestCase):
 
     def test_free_device(self):
         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,
                                     pci_requests_obj, None)
         self.tracker.update_pci_for_instance(None, self.inst, sign=1)
         free_pci_device_ids = (
             [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)
-        pci_device_a = allocated_devs[0]
-        pci_device_b = copy.deepcopy(allocated_devs[1])
-        self.assertNotIn(pci_device_a.id, free_pci_device_ids)
-        self.assertNotIn(pci_device_b.id, free_pci_device_ids)
-        for pci_device in (pci_device_a, pci_device_b):
-            self.tracker.free_device(pci_device, self.inst)
-            free_pci_device_ids = (
-                [dev.id for dev in self.tracker.pci_stats.get_free_devs()])
-            self.assertIn(pci_device.id, free_pci_device_ids)
+        pci_device = allocated_devs[0]
+        self.assertNotIn(pci_device.id, free_pci_device_ids)
+        instance_uuid = self.inst['uuid']
+        self.assertIn(pci_device, self.tracker.allocations[instance_uuid])
+        self.tracker.free_device(pci_device, self.inst)
+        free_pci_device_ids = (
+            [dev.id for dev in self.tracker.pci_stats.get_free_devs()])
         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):