Itsuro Oda b0a66719b9 upgrade DPDK version to v20.02
networking-spp has not been able to upgrade DPDK/SPP version from
v18.08 because DPDK v18.11 and later have a problem that secondary
processes can not use vhost PMD.
Now the problem is fixed in DPDK v20.02, this patch makes Neutron
SPP driver use DPDK/SPP v20.02.

Change-Id: Ic51071c10bf8f7b954586c82bbf85421918be55e
Blueprint: upgrade-dpdk-2002
2020-07-20 07:35:55 +09:00

176 lines
5.2 KiB
Python

# Copyright 2017 NTT
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import etcd3
import json
import os
import sys
import yaml
SPP_ROOT = "/spp/openstack/"
def config_path(host):
return SPP_ROOT + "configuration/" + host
def vhost_path(host, phys_net, vhost):
return SPP_ROOT + "vhost/%s/%s/%d" % (host, phys_net, vhost)
def mirror_path(host, mirror_id):
return SPP_ROOT + "mirror/%s/%d" % (host, mirror_id)
def get_cores(core_mask):
mask = int(core_mask, base=16)
cores = []
for i in range(32):
if mask & (1 << i):
cores.append(i)
cores.pop(0)
return cores
# port name conventions
def _nic_port(sec_id):
return "phy:%d" % (sec_id - 1)
def _vhost_port(vhost_id):
return "vhost:%d" % vhost_id
def _rx_ring_port(vhost_id):
return "ring:%d" % (vhost_id * 2)
def _tx_ring_port(vhost_id):
return "ring:%d" % (vhost_id * 2 + 1)
def conf_components(sec_id, start_vhost_id, num_vhost, cores):
components = []
tx_port = []
rx_port = []
for vhost_id in range(start_vhost_id, start_vhost_id + num_vhost):
components.append({"core": cores.pop(0),
"type": "forward",
"name": "forward_%d_tx" % vhost_id,
"rx_port": [_rx_ring_port(vhost_id)],
"tx_port": [_vhost_port(vhost_id)]})
components.append({"core": cores.pop(0),
"type": "forward",
"name": "forward_%d_rx" % vhost_id,
"rx_port": [_vhost_port(vhost_id)],
"tx_port": [_tx_ring_port(vhost_id)]})
tx_port.append(_rx_ring_port(vhost_id))
rx_port.append(_tx_ring_port(vhost_id))
components.append({"core": cores.pop(0),
"type": "classifier",
"name": "classifier",
"rx_port": [_nic_port(sec_id)],
"tx_port": tx_port})
components.append({"core": cores.pop(0),
"type": "merge",
"name": "merger",
"rx_port": rx_port,
"tx_port": [_nic_port(sec_id)]})
return components
def mirror_components(num_vhost, num_mirror, cores):
ring_id = num_vhost * 2
components = []
for i in range(num_mirror):
components.append({"core": cores.pop(0),
"ports": ["ring:%d" % ring_id,
"ring:%d" % (ring_id + 1)]})
ring_id += 2
return components
def main():
dpdk_port_mappings = os.environ.get("DPDK_PORT_MAPPINGS")
host = os.environ.get("SPP_HOST")
etcd_host = os.environ.get("ETCD_HOST")
etcd_port = os.environ.get("ETCD_PORT")
if (dpdk_port_mappings is None or host is None or
etcd_host is None or etcd_port is None):
print("DPDK_PORT_MAPPINGS, SPP_HOST, ETCD_HOST and ETCD_PORT"
" must be defined.")
return 1
component_conf = os.environ.get("SPP_COMPONENT_CONF")
spp_mirror = os.environ.get("SPP_MIRROR")
def_vfs = []
def_mirror = {}
if component_conf:
with open(component_conf, 'r') as f:
def_confs = yaml.load(f)
def_vfs = def_confs['vf']
if spp_mirror:
def_mirror = def_confs['mirror']
vfs = []
sec_id = 1
vhost_id = 0
for map in dpdk_port_mappings.split(','):
pci, phys, num_vhost, core_mask = map.split('#')
num_vhost = int(num_vhost)
cores = get_cores(core_mask)
if def_vfs:
components = def_vfs[sec_id - 1]['components']
else:
components = conf_components(sec_id, vhost_id, num_vhost, cores)
vf = {'physical_network': phys, 'pci_address': pci,
'num_vhost': num_vhost, 'core_mask': core_mask,
'components': components}
vfs.append(vf)
sec_id += 1
vhost_id += num_vhost
host_conf = {'vf': vfs}
if spp_mirror:
if def_mirror:
mirror = def_mirror
else:
num_mirror, core_mask = spp_mirror.split('#')
num_mirror = int(num_mirror)
cores = get_cores(core_mask)
mirror = mirror_components(vhost_id, num_mirror, cores)
host_conf['mirror'] = mirror
etcd = etcd3.client(etcd_host, etcd_port)
etcd.put(config_path(host), json.dumps(host_conf))
num = 0
for vf in vfs:
phys = vf['physical_network']
for i in range(vf['num_vhost']):
etcd.put(vhost_path(host, phys, num), 'None')
num += 1
if spp_mirror:
for i in range(len(mirror)):
etcd.put(mirror_path(host, i), 'None')
if __name__ == "__main__":
sys.exit(main())