]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
SR-IOV: Update eswitch manager to support rate
authorMoshe Levi <moshele@mellanox.com>
Sun, 2 Aug 2015 09:58:54 +0000 (12:58 +0300)
committerIhar Hrachyshka <ihrachys@redhat.com>
Wed, 5 Aug 2015 15:35:13 +0000 (17:35 +0200)
This patch update the eswitch manager to support
max rate on VF, moreover it updates the eswitch
manager to be singleton so it can be called from the
SR-IOV qos driver.

Partially-Implements: blueprint ml2-qos
Change-Id: I3e0d0a3fe2effade4e7bcd94018313ab2beb8f28

neutron/plugins/ml2/drivers/mech_sriov/agent/eswitch_manager.py
neutron/plugins/ml2/drivers/mech_sriov/agent/sriov_nic_agent.py
neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_eswitch_manager.py

index 8664769771f1e63aac22751dc25a85188b0417d5..ada37b2de3b1d655fc656395ce318cc37bb427c4 100644 (file)
@@ -144,11 +144,7 @@ class EmbSwitch(object):
 
         @param pci_slot: Virtual Function address
         """
-        vf_index = self.pci_slot_map.get(pci_slot)
-        if vf_index is None:
-            LOG.warning(_LW("Cannot find vf index for pci slot %s"),
-                        pci_slot)
-            raise exc.InvalidPciSlotError(pci_slot=pci_slot)
+        vf_index = self._get_vf_index(pci_slot)
         return self.pci_dev_wrapper.get_vf_state(vf_index)
 
     def set_device_state(self, pci_slot, state):
@@ -157,12 +153,25 @@ class EmbSwitch(object):
         @param pci_slot: Virtual Function address
         @param state: link state
         """
+        vf_index = self._get_vf_index(pci_slot)
+        return self.pci_dev_wrapper.set_vf_state(vf_index, state)
+
+    def set_device_max_rate(self, pci_slot, max_kbps):
+        """Set device max rate.
+
+        @param pci_slot: Virtual Function address
+        @param max_kbps: device max rate in kbps
+        """
+        vf_index = self._get_vf_index(pci_slot)
+        return self.pci_dev_wrapper.set_vf_max_rate(vf_index, max_kbps)
+
+    def _get_vf_index(self, pci_slot):
         vf_index = self.pci_slot_map.get(pci_slot)
         if vf_index is None:
             LOG.warning(_LW("Cannot find vf index for pci slot %s"),
                         pci_slot)
             raise exc.InvalidPciSlotError(pci_slot=pci_slot)
-        return self.pci_dev_wrapper.set_vf_state(vf_index, state)
+        return vf_index
 
     def set_device_spoofcheck(self, pci_slot, enabled):
         """Set device spoofchecking
@@ -194,7 +203,13 @@ class EmbSwitch(object):
 class ESwitchManager(object):
     """Manages logical Embedded Switch entities for physical network."""
 
-    def __init__(self, device_mappings, exclude_devices):
+    def __new__(cls):
+        # make it a singleton
+        if not hasattr(cls, '_instance'):
+            cls._instance = super(ESwitchManager, cls).__new__(cls)
+        return cls._instance
+
+    def __init__(self):
         """Constructor.
 
         Create Embedded Switch logical entities for all given device mappings,
@@ -203,8 +218,6 @@ class ESwitchManager(object):
         self.emb_switches_map = {}
         self.pci_slot_map = {}
 
-        self._discover_devices(device_mappings, exclude_devices)
-
     def device_exists(self, device_mac, pci_slot):
         """Verify if device exists.
 
@@ -250,6 +263,19 @@ class ESwitchManager(object):
             return embedded_switch.get_device_state(pci_slot)
         return False
 
+    def set_device_max_rate(self, device_mac, pci_slot, max_kbps):
+        """Set device max rate
+
+        Sets the device max rate in kbps
+        @param device_mac: device mac
+        @param pci_slot: pci slot
+        @param max_kbps: device max rate in kbps
+        """
+        embedded_switch = self._get_emb_eswitch(device_mac, pci_slot)
+        if embedded_switch:
+            embedded_switch.set_device_max_rate(pci_slot,
+                                                max_kbps)
+
     def set_device_state(self, device_mac, pci_slot, admin_state_up):
         """Set device state
 
@@ -276,7 +302,7 @@ class ESwitchManager(object):
             embedded_switch.set_device_spoofcheck(pci_slot,
                                                   enabled)
 
-    def _discover_devices(self, device_mappings, exclude_devices):
+    def discover_devices(self, device_mappings, exclude_devices):
         """Discover which Virtual functions to manage.
 
         Discover devices, and create embedded switch object for network device
index e1dd7247bfbb3dc5b5120b93b1fb868668cc0bc2..7bf297955541df4f120a76bc129eba0e93e98026 100644 (file)
@@ -130,7 +130,8 @@ class SriovNicSwitchAgent(object):
             LOG.exception(_LE("Failed reporting state!"))
 
     def setup_eswitch_mgr(self, device_mappings, exclude_devices={}):
-        self.eswitch_mgr = esm.ESwitchManager(device_mappings, exclude_devices)
+        self.eswitch_mgr = esm.ESwitchManager()
+        self.eswitch_mgr.discover_devices(device_mappings, exclude_devices)
 
     def scan_devices(self, registered_devices, updated_devices):
         curr_devices = self.eswitch_mgr.get_assigned_devices()
index a9a5b3a67a906ec3465a83706ace3c8a65fa9ac4..e131dc1ebf2f7d62259e4491b9e55238e9ac7b30 100644 (file)
@@ -42,7 +42,8 @@ class TestCreateESwitchManager(base.BaseTestCase):
                            return_value=True):
 
             with testtools.ExpectedException(exc.InvalidDeviceError):
-                esm.ESwitchManager(device_mappings, None)
+                esm.ESwitchManager().discover_devices(
+                    device_mappings, None)
 
     def test_create_eswitch_mgr_ok(self):
         device_mappings = {'physnet1': 'p6p1'}
@@ -53,7 +54,7 @@ class TestCreateESwitchManager(base.BaseTestCase):
                            "eswitch_manager.PciOsWrapper.is_assigned_vf",
                            return_value=True):
 
-            esm.ESwitchManager(device_mappings, None)
+            esm.ESwitchManager().discover_devices(device_mappings, None)
 
 
 class TestESwitchManagerApi(base.BaseTestCase):
@@ -75,7 +76,8 @@ class TestESwitchManagerApi(base.BaseTestCase):
                 mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
                            "eswitch_manager.PciOsWrapper.is_assigned_vf",
                            return_value=True):
-            self.eswitch_mgr = esm.ESwitchManager(device_mappings, None)
+            self.eswitch_mgr = esm.ESwitchManager()
+            self.eswitch_mgr.discover_devices(device_mappings, None)
 
     def test_get_assigned_devices(self):
         with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
@@ -132,6 +134,19 @@ class TestESwitchManagerApi(base.BaseTestCase):
             self.eswitch_mgr.set_device_state(self.ASSIGNED_MAC,
                                               self.PCI_SLOT, True)
 
+    def test_set_device_max_rate(self):
+        with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
+                        "eswitch_manager.EmbSwitch.get_pci_device",
+                        return_value=self.ASSIGNED_MAC) as get_pci_mock,\
+                mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
+                           "eswitch_manager.EmbSwitch.set_device_max_rate")\
+                as set_device_max_rate_mock:
+            self.eswitch_mgr.set_device_max_rate(self.ASSIGNED_MAC,
+                                                 self.PCI_SLOT, 1000)
+            get_pci_mock.assert_called_once_with(self.PCI_SLOT)
+            set_device_max_rate_mock.assert_called_once_with(
+                self.PCI_SLOT, 1000)
+
     def test_set_device_status_mismatch(self):
         with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
                         "eswitch_manager.EmbSwitch.get_pci_device",
@@ -260,6 +275,18 @@ class TestEmbSwitch(base.BaseTestCase):
                               self.emb_switch.set_device_spoofcheck,
                               self.WRONG_PCI_SLOT, True)
 
+    def test_set_device_max_rate_ok(self):
+        with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent.pci_lib."
+                        "PciDeviceIPWrapper.set_vf_max_rate"):
+            self.emb_switch.set_device_max_rate(self.PCI_SLOT, 1000)
+
+    def test_set_device_max_rate_fail(self):
+        with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent.pci_lib."
+                        "PciDeviceIPWrapper.set_vf_max_rate"):
+            self.assertRaises(exc.InvalidPciSlotError,
+                              self.emb_switch.set_device_max_rate,
+                              self.WRONG_PCI_SLOT, 1000)
+
     def test_get_pci_device(self):
         with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent.pci_lib."
                         "PciDeviceIPWrapper.get_assigned_macs",