summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHemanth Nakkina <hemanth.nakkina@canonical.com>2020-09-01 09:36:51 +0530
committerHemanth Nakkina <hemanth.nakkina@canonical.com>2021-05-25 16:15:52 +0530
commit420df86e23acf050e78b64315f1058ae9704c6d0 (patch)
tree82ca5dcc3c55682ac6e67a86a78aac6db99e513b
parent5aa7f3b4e6241e21c69dc103bb7be847b500429c (diff)
downloadnova-420df86e23acf050e78b64315f1058ae9704c6d0.tar.gz
Update pci stat pools based on PCI device changes
At start up of nova-compute service, the PCI stat pools are populated based on information in pci_devices table in Nova database. The pools are updated only when new device is added or removed but not on any device changes like device type. If an existing device is configured as SRIOV and nova-compute is restarted, the pci_devices table gets updated but the device is still listed under the old pool in pci_tracker.stats.pool (in-memory object). This patch looks for device type updates in existing devices and updates the pools accordingly. Change-Id: Id4ebb06e634a612c8be4be6c678d8265e0b99730 Closes-Bug: #1892361 (cherry picked from commit b8695de6da56db42b83b9d9d4c330148766644be) (cherry picked from commit d8b8a8193b6b8228f6e7d6bde68b5ea6bb53dd8b) (cherry picked from commit f58399cf496566e39d11f82a61e0b47900f2eafa) (cherry picked from commit 8378785f995dd4bec2a5a20f7bf5946b3075120d) (cherry picked from commit 73e631862a81e85fdf9305f3d15b201d780c8743) (cherry picked from commit 1fb4cc03e315f5b4dbebc521f0d1299273c7c396)
-rw-r--r--nova/pci/manager.py1
-rw-r--r--nova/pci/stats.py26
-rw-r--r--nova/tests/unit/pci/test_stats.py24
-rw-r--r--releasenotes/notes/bug-1892361-pci-deivce-type-update-c407a66fd37f6405.yaml12
4 files changed, 63 insertions, 0 deletions
diff --git a/nova/pci/manager.py b/nova/pci/manager.py
index ff161e38ca..3e8ed3ee25 100644
--- a/nova/pci/manager.py
+++ b/nova/pci/manager.py
@@ -225,6 +225,7 @@ class PciDevTracker(object):
self.stale[new_value['address']] = new_value
else:
existed.update_device(new_value)
+ self.stats.update_device(existed)
# Track newly discovered devices.
for dev in [dev for dev in devices if
diff --git a/nova/pci/stats.py b/nova/pci/stats.py
index 40736ef726..9f8d249050 100644
--- a/nova/pci/stats.py
+++ b/nova/pci/stats.py
@@ -97,6 +97,32 @@ class PciDeviceStats(object):
pool.update(tags)
return pool
+ def _get_pool_with_device_type_mismatch(self, dev):
+ """Check for device type mismatch in the pools for a given device.
+
+ Return (pool, device) if device type does not match or a single None
+ if the device type matches.
+ """
+ for pool in self.pools:
+ for device in pool['devices']:
+ if device.address == dev.address:
+ if dev.dev_type != pool["dev_type"]:
+ return pool, device
+ return None
+
+ return None
+
+ def update_device(self, dev):
+ """Update a device to its matching pool."""
+ pool_device_info = self._get_pool_with_device_type_mismatch(dev)
+ if pool_device_info is None:
+ return
+
+ pool, device = pool_device_info
+ pool['devices'].remove(device)
+ self._decrease_pool_count(self.pools, pool)
+ self.add_device(dev)
+
def add_device(self, dev):
"""Add a device to its matching pool."""
dev_pool = self._create_pool_keys_from_dev(dev)
diff --git a/nova/tests/unit/pci/test_stats.py b/nova/tests/unit/pci/test_stats.py
index be867783fb..0375ccc63f 100644
--- a/nova/tests/unit/pci/test_stats.py
+++ b/nova/tests/unit/pci/test_stats.py
@@ -533,6 +533,30 @@ class PciDeviceStatsWithTagsTestCase(test.NoDBTestCase):
self.pci_stats.remove_device(dev2)
self._assertPools()
+ def test_update_device(self):
+ # Update device type of one of the device from type-PCI to
+ # type-PF. Verify if the existing pool is updated and a new
+ # pool is created with dev_type type-PF.
+ self._create_pci_devices()
+ dev1 = self.pci_tagged_devices.pop()
+ dev1.dev_type = 'type-PF'
+ self.pci_stats.update_device(dev1)
+ self.assertEqual(3, len(self.pci_stats.pools))
+ self._assertPoolContent(self.pci_stats.pools[0], '1137', '0072',
+ len(self.pci_untagged_devices))
+ self.assertEqual(self.pci_untagged_devices,
+ self.pci_stats.pools[0]['devices'])
+ self._assertPoolContent(self.pci_stats.pools[1], '1137', '0071',
+ len(self.pci_tagged_devices),
+ physical_network='physnet1')
+ self.assertEqual(self.pci_tagged_devices,
+ self.pci_stats.pools[1]['devices'])
+ self._assertPoolContent(self.pci_stats.pools[2], '1137', '0071',
+ 1,
+ physical_network='physnet1')
+ self.assertEqual(dev1,
+ self.pci_stats.pools[2]['devices'][0])
+
class PciDeviceVFPFStatsTestCase(test.NoDBTestCase):
diff --git a/releasenotes/notes/bug-1892361-pci-deivce-type-update-c407a66fd37f6405.yaml b/releasenotes/notes/bug-1892361-pci-deivce-type-update-c407a66fd37f6405.yaml
new file mode 100644
index 0000000000..ba35c25b02
--- /dev/null
+++ b/releasenotes/notes/bug-1892361-pci-deivce-type-update-c407a66fd37f6405.yaml
@@ -0,0 +1,12 @@
+---
+fixes:
+ - |
+ Fixes `bug 1892361`_ in which the pci stat pools are not updated when an
+ existing device is enabled with SRIOV capability. Restart of nova-compute
+ service updates the pci device type from type-PCI to type-PF but the pools
+ still maintain the device type as type-PCI. And so the PF is considered for
+ allocation to instance that requests vnic_type=direct. With this fix, the
+ pci device type updates are detected and the pci stat pools are updated
+ properly.
+
+ .. _bug 1892361: https://bugs.launchpad.net/nova/+bug/1892361