From 271d9ab0c69787979a09da8bc8c042096a8fc6dc Mon Sep 17 00:00:00 2001 From: David Vallee Delisle Date: Thu, 6 Feb 2020 23:42:50 -0500 Subject: [PATCH] We need to use the MAC instead of PCI Address for Mellanox cards Since Mellanox cards are already bound, they are not added to the dpdk mapping file. The set devargs command is never run. This patch ensures that get_dpdk_devargs returns the devargs, even on newer Mellanox interfaces. Change-Id: I6f4c3716c7ee74d7bd2c48e598e5c6de4332d726 Closes-Bug: 1862298 (cherry picked from commit 11d9a23600e43de0071f05e716ec6f7e1ee80670) (cherry picked from commit 74d32121f6b807ef646f6dc58ad8693233503f1e) (cherry picked from commit de626b2609f531727c336513faf2fa27ea377e5b) --- os_net_config/tests/test_utils.py | 38 +++++++++++++++++++++++++++++++ os_net_config/utils.py | 24 +++++++++++++------ 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/os_net_config/tests/test_utils.py b/os_net_config/tests/test_utils.py index 35cb812d..6c45c46e 100644 --- a/os_net_config/tests/test_utils.py +++ b/os_net_config/tests/test_utils.py @@ -584,6 +584,44 @@ class TestUtils(base.TestCase): def test_interface_mac_raises(self): self.assertRaises(IOError, utils.interface_mac, 'ens20f2p3') + def test_get_dpdk_devargs_mlnx(self): + def test_execute(name, dummy1, dummy2=None, dummy3=None): + if 'ethtool' in name: + out = _PCI_OUTPUT + return out, None + + def test_get_stored_pci_address(ifname, noop): + return "0000:00:07.0" + + self.stub_out('oslo_concurrency.processutils.execute', test_execute) + self.stub_out('os_net_config.utils.get_stored_pci_address', + test_get_stored_pci_address) + tmpdir = tempfile.mkdtemp() + self.stub_out('os_net_config.utils._SYS_CLASS_NET', tmpdir) + nic = 'p4p1' + nic_path = os.path.join(tmpdir, nic) + os.makedirs(nic_path) + os.makedirs(os.path.join(nic_path, 'device')) + # Testing standard Mellanox Connect-X cards + with open(os.path.join(nic_path, 'operstate'), 'w') as f: + f.write('up') + with open(os.path.join(nic_path, 'address'), 'w') as f: + f.write('00:0f:21:69:39:14') + with open(os.path.join(nic_path, 'device', 'vendor'), 'w') as f: + f.write('0x15b3') + self.assertEqual(utils.get_dpdk_devargs(nic, False), + '0000:00:19.0') + # now testing the Mellanox CX3 + with open(os.path.join(nic_path, 'device', 'device'), 'w') as f: + f.write('0x1007') + self.assertEqual(utils.get_dpdk_devargs(nic, False), + 'class=eth,mac=00:0f:21:69:39:14') + with open(os.path.join(nic_path, 'device', 'vendor'), 'w') as f: + f.write('0x15b4') + self.assertEqual(utils.get_dpdk_devargs(nic, False), + '0000:00:07.0') + shutil.rmtree(tmpdir) + def test_is_active_nic_for_sriov_vf(self): tmpdir = tempfile.mkdtemp() diff --git a/os_net_config/utils.py b/os_net_config/utils.py index 6e346c84..b02ba91d 100644 --- a/os_net_config/utils.py +++ b/os_net_config/utils.py @@ -105,14 +105,14 @@ def get_file_data(filename): def interface_mac(name): try: # If the iface is part of a Linux bond, the real MAC is only here. - with open('/sys/class/net/%s/bonding_slave/perm_hwaddr' % name, + with open(_SYS_CLASS_NET + '/%s/bonding_slave/perm_hwaddr' % name, 'r') as f: return f.read().rstrip() except IOError: pass # Iface is not part of a bond, continue try: - with open('/sys/class/net/%s/address' % name, 'r') as f: + with open(_SYS_CLASS_NET + '/%s/address' % name, 'r') as f: return f.read().rstrip() except IOError: # If the interface is bound to a DPDK driver, get the mac address from @@ -385,13 +385,23 @@ def get_dpdk_devargs(ifname, noop): if not noop: vendor_id = get_vendor_id(ifname) device_id = get_device_id(ifname) - if vendor_id == "0x15b3" and device_id == "0x1007": - # Some NICs (i.e. Mellanox ConnectX-3) have only one PCI address - # associated with multiple ports. Using a PCI device won’t work. - # Instead, we should use "class=eth,mac=" - dpdk_devargs = "class=eth,mac=%s" % interface_mac(ifname) + if vendor_id == "0x15b3": + logger.info("Getting devargs for Mellanox cards") + if device_id == "0x1007": + # Some NICs (i.e. Mellanox ConnectX-3) have only one PCI + # address associated with multiple ports. Using a PCI + # device won’t work. Instead, we should use + # "class=eth,mac=" + dpdk_devargs = "class=eth,mac=%s" % interface_mac(ifname) + elif is_active_nic(ifname): + # Other Mellanox devices are active and they are not stored + # in dpdk_mapping.yaml file, so we need to get their pci + # address with ethtool. + dpdk_devargs = get_pci_address(ifname, noop) else: + logger.info("Getting stored PCI address as devarg") dpdk_devargs = get_stored_pci_address(ifname, noop) + logger.debug("Devargs found: %s" % (dpdk_devargs)) return dpdk_devargs