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
This commit is contained in:
Kevin Benton 2016-12-07 11:33:46 -08:00
parent f448cccabb
commit 1a2a71baf3
2 changed files with 20 additions and 2 deletions

View File

@ -174,8 +174,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)
@ -198,6 +196,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

View File

@ -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)])