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
This commit is contained in:
David Vallee Delisle 2020-02-06 23:42:50 -05:00
parent c9d3ba4cc4
commit 11d9a23600
2 changed files with 55 additions and 7 deletions

View File

@ -591,6 +591,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()

View File

@ -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 wont work.
# Instead, we should use "class=eth,mac=<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 wont work. Instead, we should use
# "class=eth,mac=<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