07a07c6bcc
Create an agent which runs on each worker node to do pci interrupt affinity work. nova-sriov installed by this new package instead of old nova-utils. Below test done and pass, see detailed test spec in story link. 1) deployment test with/without openstack application 2) Periodic audit pci irq affinity 3) Remove VM without sriov pci port 4) Remove VM with sriov pci port 5) Add VM without sriov pci port 6) Add VM with sriov pci port 7) Add VM without pci_irq_affinity_mask 8) Add VM without cpu policy set 9) VM resize test 10) Remove one pci port for VM Code framework is like below +------------+ +--------------+ +------------+ | | | | | | | | | | | | | Agent.py | -----> | affinity.py | -----> | driver.py | | | | | | | | Daemon | | Conduct | | Drv | | | | | | | +------------+ +--------------+ +------------+ Story: 2004600 Task: 28850 Depends-on: https://review.opendev.org/#/c/640263/ Depends-on: https://review.opendev.org/#/c/654415/ Change-Id: Ie668036efe4d0013fed8cd45805f0321692c76f0 Signed-off-by: zhipengl <zhipengs.liu@intel.com>
118 lines
3.4 KiB
Python
Executable File
118 lines
3.4 KiB
Python
Executable File
#! /usr/bin/python
|
|
|
|
#
|
|
# Copyright (c) 2015 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
|
|
import sys
|
|
import os
|
|
import json
|
|
import fnmatch
|
|
|
|
|
|
def usage():
|
|
argv0 = os.path.basename(sys.argv[0])
|
|
print """
|
|
Usage:
|
|
------
|
|
%(argv0)s pci_pt_whitelist pci_sriov_whitelist
|
|
|
|
Where pci_pt_whitelist is a list of passthrough devices and the
|
|
pci_sriov_whitelist is a list of SR-IOV interfaces. The format of the lists
|
|
are as follows:
|
|
|
|
pci_pt_whitelist:
|
|
[{"address": "0000:09:00.0"}, ..]
|
|
|
|
pci_sriov_whitelist:
|
|
[{"sriov_numvfs": 16, "physical_network": "group0-nic0",
|
|
"address": "0000:02:00.0"}, ..]
|
|
|
|
""" % locals() # replace items from local variables
|
|
|
|
|
|
def get_vf_whitelist(sriov_if):
|
|
'''For the given PF PCI address and provider network, generate the list of VF
|
|
PCI addresses to create a VF based whitelist'''
|
|
|
|
pf_addr = sriov_if.get('address')
|
|
dirpcidev = '/sys/bus/pci/devices/' + pf_addr
|
|
|
|
# Attempt to configure the requested number of VFs if the device supports
|
|
# setting the number of VFs via sysfs
|
|
# Need to write 0 to sriov_numvfs before writing a new value.
|
|
numvfs = sriov_if.get('sriov_numvfs')
|
|
if numvfs is not None:
|
|
numvfs_path = os.path.join(dirpcidev, 'sriov_numvfs')
|
|
if os.path.isfile(numvfs_path):
|
|
with open(numvfs_path, 'w') as f:
|
|
f.write('0')
|
|
f.flush()
|
|
f.write(str(numvfs))
|
|
|
|
virtfn_links = len(fnmatch.filter(os.listdir(dirpcidev), 'virtfn*'))
|
|
|
|
# Some devices (for e.g. Coleto Creek) don't support configuration of the
|
|
# number of VFs. Use all the VFs present in this case.
|
|
if numvfs is not None:
|
|
if virtfn_links != numvfs:
|
|
print 'Configured number of VFs is different than the present ones', \
|
|
'(if:%s conf:%d present:%d)' % (pf_addr, numvfs, virtfn_links)
|
|
exit(1)
|
|
else:
|
|
numvfs = virtfn_links
|
|
|
|
pci_sriov_vf_whitelist = []
|
|
i = 0
|
|
while i < int(numvfs):
|
|
lvf = dirpcidev + '/virtfn' + str(i)
|
|
try:
|
|
vf_addr = os.path.basename(os.readlink(lvf))
|
|
except:
|
|
print("virtfn link %s non-existent (numvfs=%s)" % (lvf, numvfs))
|
|
sys.exit(1)
|
|
|
|
device = {'address': vf_addr}
|
|
|
|
# Some devices (for e.g. Coleto Creek) are not associated with a
|
|
# physical network.
|
|
providernets = sriov_if.get('physical_network')
|
|
if providernets:
|
|
device.update({'physical_network': providernets})
|
|
|
|
pci_sriov_vf_whitelist.append(device)
|
|
i += 1
|
|
|
|
return pci_sriov_vf_whitelist
|
|
|
|
|
|
def main():
|
|
''' The goal of this script is to properly discover SR-IOV VF PCI addresses
|
|
for interfaces that were configured for SR-IOV. It is used by the
|
|
nova-compute puppet manifest and is run at manifest application time. This
|
|
script should be run after the VF driver is loaded and the VF PCI addresses
|
|
are visible in the system.'''
|
|
|
|
if len(sys.argv) < 3:
|
|
usage()
|
|
sys.exit(1)
|
|
|
|
try:
|
|
pci_pt_whitelist = json.loads(sys.argv[1])
|
|
pci_sriov_whitelist = json.loads(sys.argv[2])
|
|
except:
|
|
usage()
|
|
exit(1)
|
|
|
|
for sriov_if in pci_sriov_whitelist:
|
|
pci_sriov_vf_whitelist = get_vf_whitelist(sriov_if)
|
|
pci_pt_whitelist.extend(pci_sriov_vf_whitelist)
|
|
|
|
return pci_pt_whitelist
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print json.dumps(main())
|