From 151af89ddc9cf36e6811776f955758957155feac Mon Sep 17 00:00:00 2001 From: Kevin Benton Date: Wed, 7 Dec 2016 11:33:46 -0800 Subject: [PATCH] SRIOV: don't block report_state with device count The device count process can be quite slow on a system with lots of interfaces. Doing this during report_state can block it long enough that the agent will be reported as dead and bindings will fail. This adjusts the logic to only update the configuration during the normal device retrieval for the scan loop. This will leave the report_state loop unblocked by the operation so the agent doesn't get reported as dead (which blocks port binding). Closes-Bug: #1648206 Change-Id: Iff45fb6617974b1eceeed238a8d9e958f874f12b (cherry picked from commit 1a2a71baf3904209679fc5448814a0e7940fe44d) --- .../mech_sriov/agent/sriov_nic_agent.py | 3 +-- .../mech_sriov/agent/test_sriov_nic_agent.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/neutron/plugins/ml2/drivers/mech_sriov/agent/sriov_nic_agent.py b/neutron/plugins/ml2/drivers/mech_sriov/agent/sriov_nic_agent.py index 4705bf2e410..388fb850ff9 100644 --- a/neutron/plugins/ml2/drivers/mech_sriov/agent/sriov_nic_agent.py +++ b/neutron/plugins/ml2/drivers/mech_sriov/agent/sriov_nic_agent.py @@ -173,8 +173,6 @@ class SriovNicSwitchAgent(object): def _report_state(self): try: - devices = len(self.eswitch_mgr.get_assigned_devices_info()) - self.agent_state.get('configurations')['devices'] = devices self.state_rpc.report_state(self.context, self.agent_state) @@ -197,6 +195,7 @@ class SriovNicSwitchAgent(object): def scan_devices(self, registered_devices, updated_devices): curr_devices = self.eswitch_mgr.get_assigned_devices_info() + self.agent_state.get('configurations')['devices'] = len(curr_devices) device_info = {} device_info['current'] = curr_devices device_info['added'] = curr_devices - registered_devices diff --git a/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_sriov_nic_agent.py b/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_sriov_nic_agent.py index f175ca50589..f7e8b500b18 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_sriov_nic_agent.py +++ b/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_sriov_nic_agent.py @@ -55,6 +55,25 @@ class TestSriovAgent(base.BaseTestCase): self.agent = sriov_nic_agent.SriovNicSwitchAgent({}, {}, 0) + @mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent.eswitch_manager" + ".ESwitchManager.get_assigned_devices_info", return_value=set()) + @mock.patch.object(agent_rpc.PluginReportStateAPI, 'report_state') + def test_cached_device_count_report_state(self, report_state, get_dev): + self.agent._report_state() + agent_conf = self.agent.agent_state['configurations'] + # ensure devices aren't calculated until first scan_devices call + self.assertNotIn('devices', agent_conf) + self.agent.scan_devices(set(), set()) + self.assertEqual(0, agent_conf['devices']) + # ensure report_state doesn't call get_dev + get_dev.reset_mock() + get_dev.return_value = set(['dev1', 'dev2']) + self.agent._report_state() + self.assertEqual(0, agent_conf['devices']) + # after a device scan, conf should bump to 2 + self.agent.scan_devices(set(), set()) + self.assertEqual(2, agent_conf['devices']) + @mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent.pci_lib." "PciDeviceIPWrapper.get_assigned_macs", return_value=[(DEVICE_MAC, PCI_SLOT)])