Adding the class and mac approach as dpdk-devargs in mellanox ConnectX-3
Some NICs (i.e. Mellanox ConnectX-3) have only one PCI address associated with multiple ports. Using a PCI address as dpdk-devargs in OvsDpdkPort won't work. Instead, class and mac approach is used dpdk-devargs="class=eth,mac=<MAC>" see this http://docs.openvswitch.org/en/latest/howto/dpdk/ Change-Id: I29de6e82a0897ee46953a1e6a966e9c5790068c9
This commit is contained in:
parent
9e785a4ce0
commit
aeaa6fe62b
|
@ -304,12 +304,13 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
||||||
data += "OVS_BRIDGE=%s\n" % base_opt.bridge_name
|
data += "OVS_BRIDGE=%s\n" % base_opt.bridge_name
|
||||||
# Validation of DPDK port having only one interface is done prior
|
# Validation of DPDK port having only one interface is done prior
|
||||||
# to this. So accesing the interface name statically.
|
# to this. So accesing the interface name statically.
|
||||||
# Also pci_address would be valid here, since
|
# Also dpdk_devargs would be valid here, since
|
||||||
# bind_dpdk_interfaces() is invoked before this.
|
# bind_dpdk_interfaces() is invoked before this.
|
||||||
pci_address = utils.get_stored_pci_address(
|
dpdk_devargs = utils.get_dpdk_devargs(
|
||||||
base_opt.members[0].name, self.noop)
|
base_opt.members[0].name, self.noop)
|
||||||
|
|
||||||
ovs_extra.append("set Interface $DEVICE options:dpdk-devargs="
|
ovs_extra.append("set Interface $DEVICE options:dpdk-devargs="
|
||||||
"%s" % pci_address)
|
"%s" % dpdk_devargs)
|
||||||
if base_opt.mtu:
|
if base_opt.mtu:
|
||||||
ovs_extra.append("set Interface $DEVICE mtu_request=$MTU")
|
ovs_extra.append("set Interface $DEVICE mtu_request=$MTU")
|
||||||
if base_opt.rx_queue:
|
if base_opt.rx_queue:
|
||||||
|
@ -332,13 +333,13 @@ class IfcfgNetConfig(os_net_config.NetConfig):
|
||||||
for bond_member in base_opt.members:
|
for bond_member in base_opt.members:
|
||||||
# Validation of DPDK port having only one interface is done
|
# Validation of DPDK port having only one interface is done
|
||||||
# prior to this. So accesing the interface name statically.
|
# prior to this. So accesing the interface name statically.
|
||||||
# Also pci_address would be valid here, since
|
# Also dpdk_devargs would be valid here, since
|
||||||
# bind_dpdk_interfaces () is invoked before this.
|
# bind_dpdk_interfaces () is invoked before this.
|
||||||
pci_address = utils.get_stored_pci_address(
|
dpdk_devargs = utils.get_dpdk_devargs(
|
||||||
bond_member.members[0].name, self.noop)
|
bond_member.members[0].name, self.noop)
|
||||||
ovs_extra.append("set Interface %s options:"
|
ovs_extra.append("set Interface %s options:"
|
||||||
"dpdk-devargs=%s"
|
"dpdk-devargs=%s"
|
||||||
% (bond_member.name, pci_address))
|
% (bond_member.name, dpdk_devargs))
|
||||||
members = [member.name for member in base_opt.members]
|
members = [member.name for member in base_opt.members]
|
||||||
data += ("BOND_IFACES=\"%s\"\n" % " ".join(members))
|
data += ("BOND_IFACES=\"%s\"\n" % " ".join(members))
|
||||||
# MTU configuration given for the OvsDpdkbond shall be applied
|
# MTU configuration given for the OvsDpdkbond shall be applied
|
||||||
|
|
|
@ -209,6 +209,32 @@ class TestUtils(base.TestCase):
|
||||||
pci = utils.get_stored_pci_address('eth1', False)
|
pci = utils.get_stored_pci_address('eth1', False)
|
||||||
self.assertEqual(None, pci)
|
self.assertEqual(None, pci)
|
||||||
|
|
||||||
|
def test_get_vendor_id_success(self):
|
||||||
|
mocked_open = mock.mock_open(read_data='0x15b3\n')
|
||||||
|
with mock.patch('os_net_config.utils.open', mocked_open, create=True):
|
||||||
|
vendor = utils.get_vendor_id('nic2')
|
||||||
|
self.assertEqual('0x15b3', vendor)
|
||||||
|
|
||||||
|
def test_get_vendor_id_exception(self):
|
||||||
|
mocked_open = mock.mock_open()
|
||||||
|
mocked_open.side_effect = IOError
|
||||||
|
with mock.patch('os_net_config.utils.open', mocked_open, create=True):
|
||||||
|
vendor = utils.get_vendor_id('nic2')
|
||||||
|
self.assertEqual(None, vendor)
|
||||||
|
|
||||||
|
def test_get_device_id_success(self):
|
||||||
|
mocked_open = mock.mock_open(read_data='0x1003\n')
|
||||||
|
with mock.patch('os_net_config.utils.open', mocked_open, create=True):
|
||||||
|
device = utils.get_device_id('nic2')
|
||||||
|
self.assertEqual('0x1003', device)
|
||||||
|
|
||||||
|
def test_get_device_id_exception(self):
|
||||||
|
mocked_open = mock.mock_open()
|
||||||
|
mocked_open.side_effect = IOError
|
||||||
|
with mock.patch('os_net_config.utils.open', mocked_open, create=True):
|
||||||
|
device = utils.get_device_id('nic2')
|
||||||
|
self.assertEqual(None, device)
|
||||||
|
|
||||||
def test_bind_dpdk_interfaces(self):
|
def test_bind_dpdk_interfaces(self):
|
||||||
def test_execute(name, dummy1, dummy2=None, dummy3=None):
|
def test_execute(name, dummy1, dummy2=None, dummy3=None):
|
||||||
if 'ethtool' in name:
|
if 'ethtool' in name:
|
||||||
|
|
|
@ -336,6 +336,40 @@ def translate_ifname_to_pci_address(ifname, noop):
|
||||||
return pci_address
|
return pci_address
|
||||||
|
|
||||||
|
|
||||||
|
def get_vendor_id(ifname):
|
||||||
|
try:
|
||||||
|
with open('%s/%s/device/vendor' % (_SYS_CLASS_NET, ifname),
|
||||||
|
'r') as f:
|
||||||
|
out = f.read().strip()
|
||||||
|
return out
|
||||||
|
except IOError:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def get_device_id(ifname):
|
||||||
|
try:
|
||||||
|
with open('%s/%s/device/device' % (_SYS_CLASS_NET, ifname),
|
||||||
|
'r') as f:
|
||||||
|
out = f.read().strip()
|
||||||
|
return out
|
||||||
|
except IOError:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
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=<MAC>"
|
||||||
|
dpdk_devargs = "class=eth,mac=%s" % interface_mac(ifname)
|
||||||
|
else:
|
||||||
|
dpdk_devargs = get_stored_pci_address(ifname, noop)
|
||||||
|
return dpdk_devargs
|
||||||
|
|
||||||
|
|
||||||
# Once the interface is bound to a DPDK driver, all the references to the
|
# Once the interface is bound to a DPDK driver, all the references to the
|
||||||
# interface including '/sys' and '/proc', will be removed. And there is no
|
# interface including '/sys' and '/proc', will be removed. And there is no
|
||||||
# way to identify the nic name after it is bound. So, the DPDK bound nic info
|
# way to identify the nic name after it is bound. So, the DPDK bound nic info
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adding dpdk support in meallnox nics.
|
||||||
|
Dpdk now fully suuported in mellanox nics.
|
Loading…
Reference in New Issue