diff options
-rw-r--r-- | conf/02_vswitch.conf | 5 | ||||
-rw-r--r-- | conf/03_traffic.conf | 4 | ||||
-rw-r--r-- | conf/04_vnf.conf | 5 | ||||
-rw-r--r-- | conf/06_pktfwd.conf | 5 | ||||
-rw-r--r-- | conf/10_custom.conf | 3 | ||||
-rwxr-xr-x | docs/configguide/installation.rst | 24 | ||||
-rw-r--r-- | docs/configguide/trafficgen.rst | 2 | ||||
-rwxr-xr-x | docs/userguide/testusage.rst | 7 | ||||
-rwxr-xr-x | systems/centos/build_base_machine.sh | 2 | ||||
-rwxr-xr-x | systems/fedora/20/build_base_machine.sh | 6 | ||||
-rwxr-xr-x | systems/fedora/21/build_base_machine.sh | 4 | ||||
-rwxr-xr-x | systems/fedora/22/build_base_machine.sh | 6 | ||||
-rwxr-xr-x | systems/rhel/7.2/build_base_machine.sh | 4 | ||||
-rwxr-xr-x | systems/ubuntu/14.04/build_base_machine.sh | 4 | ||||
-rwxr-xr-x | systems/ubuntu/build_base_machine.sh | 2 | ||||
-rw-r--r-- | testcases/testcase.py | 92 | ||||
-rw-r--r-- | tools/hugepages.py | 112 | ||||
-rw-r--r-- | tools/namespace.py | 4 | ||||
-rw-r--r-- | tools/pkt_gen/moongen/moongen.py | 48 | ||||
-rw-r--r-- | tools/pkt_gen/xena/XenaDriver.py | 16 | ||||
-rw-r--r-- | vnfs/qemu/qemu_pci_passthrough.py | 4 | ||||
-rwxr-xr-x | vsperf | 6 |
22 files changed, 313 insertions, 52 deletions
diff --git a/conf/02_vswitch.conf b/conf/02_vswitch.conf index 79f0afbd..e5736138 100644 --- a/conf/02_vswitch.conf +++ b/conf/02_vswitch.conf @@ -100,6 +100,11 @@ VSWITCH_BRIDGE_NAME = 'br0' # directory where hugepages will be mounted on system init HUGEPAGE_DIR = '/dev/hugepages' +# If no hugepages are available, try to allocate HUGEPAGE_RAM_ALLOCATION. +# Default is 2 x 1048576 = 2097152 kB. +# 10 GB (10485760 kB) or more is recommended for PVP & PVVP testing scenarios. +HUGEPAGE_RAM_ALLOCATION = 2097152 + # Sets OVS PMDs core mask to 30 for affinitization to 5th and 6th CPU core. # Note that the '0x' notation should not be used. VSWITCH_PMD_CPU_MASK = '30' diff --git a/conf/03_traffic.conf b/conf/03_traffic.conf index fb9ce837..a5a8629d 100644 --- a/conf/03_traffic.conf +++ b/conf/03_traffic.conf @@ -182,10 +182,14 @@ TRAFFICGEN_XENA_PORT1_GATEWAY = '192.168.199.1' ################################################### # MoonGen Configuration and Connection Info-- BEGIN +# Ex: TRAFFICGEN_MOONGEN_HOST_IP_ADDR = "192.10.1.1" TRAFFICGEN_MOONGEN_HOST_IP_ADDR = '' TRAFFICGEN_MOONGEN_USER = '' TRAFFICGEN_MOONGEN_BASE_DIR = '' TRAFFICGEN_MOONGEN_PORTS = '' +# Ex. 10 Gbps: TRAFFICGEN_MOONGEN_LINE_SPEED_GBPS = '10' +# Today only 10 Gbps is supported +TRAFFICGEN_MOONGEN_LINE_SPEED_GBPS = '' # MoonGen Configuration and Connection Info-- END ################################################### diff --git a/conf/04_vnf.conf b/conf/04_vnf.conf index 0a80c1af..ff110d93 100644 --- a/conf/04_vnf.conf +++ b/conf/04_vnf.conf @@ -35,7 +35,10 @@ GUEST_IMAGE = ['', ''] # For 2 VNFs you may use [180, 180] GUEST_TIMEOUT = [180, 180] -# packet forwarding mode: io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho +# packet forwarding mode supported by testpmd; Please see DPDK documentation +# for comprehensive list of modes supported by your version. +# e.g. io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho|... +# Note: Option "mac_retry" has been changed to "mac retry" since DPDK v16.07 GUEST_TESTPMD_FWD_MODE = 'csum' # guest loopback application method; supported options are: diff --git a/conf/06_pktfwd.conf b/conf/06_pktfwd.conf index d6a83d07..6175aa6a 100644 --- a/conf/06_pktfwd.conf +++ b/conf/06_pktfwd.conf @@ -24,7 +24,10 @@ PKTFWD = 'TestPMD' # ############################ TESTPMD_ARGS = [] -# packet forwarding mode: io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho +# packet forwarding mode supported by testpmd; Please see DPDK documentation +# for comprehensive list of modes supported by your version. +# e.g. io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho|... +# Note: Option "mac_retry" has been changed to "mac retry" since DPDK v16.07 TESTPMD_FWD_MODE = 'csum' # checksum calculation layer: ip|udp|tcp|sctp|outer-ip TESTPMD_CSUM_LAYER = 'ip' diff --git a/conf/10_custom.conf b/conf/10_custom.conf index 044339fc..fdb5031a 100644 --- a/conf/10_custom.conf +++ b/conf/10_custom.conf @@ -87,6 +87,9 @@ TRAFFICGEN_MOONGEN_HOST_IP_ADDR = "" TRAFFICGEN_MOONGEN_USER = "root" TRAFFICGEN_MOONGEN_BASE_DIR = "/root/MoonGen" TRAFFICGEN_MOONGEN_PORTS = "{0,1}" +# Ex. 10 Gbps: TRAFFICGEN_MOONGEN_LINE_SPEED_GBPS = '10' +# Today only 10 Gbps is supported +TRAFFICGEN_MOONGEN_LINE_SPEED_GBPS = '10' # MoonGen Configuration and Connection Info-- END ################################################### diff --git a/docs/configguide/installation.rst b/docs/configguide/installation.rst index c426dcea..70572b07 100755 --- a/docs/configguide/installation.rst +++ b/docs/configguide/installation.rst @@ -42,6 +42,12 @@ download at OPNFV website. vloop-vnf changelog: ==================== +* `vloop-vnf-ubuntu-14.04_20160804`_ + + * Linux kernel 4.4.0 installed + * libnuma-dev installed + * security updates applied + * `vloop-vnf-ubuntu-14.04_20160303`_ * snmpd service is disabled by default to avoid error messages during VM boot @@ -144,6 +150,7 @@ running any of the above. For example: .. _a link: http://www.softwarecollections.org/en/scls/rhscl/python33/ .. _virtualenv: https://virtualenv.readthedocs.org/en/latest/ +.. _vloop-vnf-ubuntu-14.04_20160804: http://artifacts.opnfv.org/vswitchperf/vnf/vloop-vnf-ubuntu-14.04_20160804.qcow2 .. _vloop-vnf-ubuntu-14.04_20160303: http://artifacts.opnfv.org/vswitchperf/vnf/vloop-vnf-ubuntu-14.04_20160303.qcow2 .. _vloop-vnf-ubuntu-14.04_20151216: http://artifacts.opnfv.org/vswitchperf/vnf/vloop-vnf-ubuntu-14.04_20151216.qcow2 @@ -179,9 +186,19 @@ parameter. In recent vswitchd versions, option VSWITCHD_DPDK_CONFIG will be used to configure vswitchd via ovs-vsctl calls. With the --socket-mem argument set to use 1 hugepage on the specified sockets as -seen above, the configuration will need 9 hugepages total to run all tests +seen above, the configuration will need 10 hugepages total to run all tests within vsperf if the pagesize is set correctly to 1GB. +VSPerf will verify hugepage amounts are free before executing test +environments. In case of hugepage amounts not being free, test initialization +will fail and testing will stop. + +**Please Note**: In some instances on a test failure dpdk resources may not +release hugepages used in dpdk configuration. It is recommended to configure a +few extra hugepages to prevent a false detection by VSPerf that not enough free +hugepages are available to execute the test environment. Normally dpdk would use +previously allocated hugepages upon initialization. + Depending on your OS selection configuration of hugepages may vary. Please refer to your OS documentation to set hugepages correctly. It is recommended to set the required amount of hugepages to be allocated by default on reboots. @@ -194,3 +211,8 @@ You can review your hugepage amounts by executing the following command .. code:: bash cat /proc/meminfo | grep Huge + +If no hugepages are available vsperf will try to automatically allocate some. +Allocation is controlled by HUGEPAGE_RAM_ALLOCATION configuration parameter in +``02_vswitch.conf`` file. Default is 2GB, resulting in either 2 1GB hugepages +or 1024 2MB hugepages. diff --git a/docs/configguide/trafficgen.rst b/docs/configguide/trafficgen.rst index 798248ac..939b6cad 100644 --- a/docs/configguide/trafficgen.rst +++ b/docs/configguide/trafficgen.rst @@ -385,6 +385,8 @@ can be found here: https://github.com/emmericp/MoonGen +* Note: Today, MoonGen with VSPERF only supports 10Gbps line speeds. + For VSPerf use, MoonGen should be cloned from here (as opposed to the afore mentioned GitHub): diff --git a/docs/userguide/testusage.rst b/docs/userguide/testusage.rst index d807590d..b5f47998 100755 --- a/docs/userguide/testusage.rst +++ b/docs/userguide/testusage.rst @@ -396,7 +396,7 @@ Execution of test with PCI passthrough with vswitch disabled: .. code-block:: console $ ./vsperf --conf-file=<path_to_custom_conf>/10_custom.conf - --vswtich none --vnf QemuPciPassthrough pvp_tput + --vswitch none --vnf QemuPciPassthrough pvp_tput Any of supported guest-loopback-application_ can be used inside VM with PCI passthrough support. @@ -526,7 +526,10 @@ for selected Packet Forwarder: # testpmd configuration TESTPMD_ARGS = [] - # packet forwarding mode: io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho + # packet forwarding mode supported by testpmd; Please see DPDK documentation + # for comprehensive list of modes supported by your version. + # e.g. io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho|... + # Note: Option "mac_retry" has been changed to "mac retry" since DPDK v16.07 TESTPMD_FWD_MODE = 'csum' # checksum calculation layer: ip|udp|tcp|sctp|outer-ip TESTPMD_CSUM_LAYER = 'ip' diff --git a/systems/centos/build_base_machine.sh b/systems/centos/build_base_machine.sh index d3ac3e2b..d94dc975 100755 --- a/systems/centos/build_base_machine.sh +++ b/systems/centos/build_base_machine.sh @@ -58,6 +58,8 @@ zlib-devel glib2-devel pixman-devel socat +numactl +numactl-devel # install gvim vim-X11 diff --git a/systems/fedora/20/build_base_machine.sh b/systems/fedora/20/build_base_machine.sh index 96bb17df..839d2bee 100755 --- a/systems/fedora/20/build_base_machine.sh +++ b/systems/fedora/20/build_base_machine.sh @@ -62,6 +62,10 @@ libreport-python3 abrt-python3 abrt-addon-python3 +# libs +numactl +numactl-devel + # install git-review tool git-review -" | grep -v ^#)
\ No newline at end of file +" | grep -v ^#) diff --git a/systems/fedora/21/build_base_machine.sh b/systems/fedora/21/build_base_machine.sh index 69b067f9..e4969893 100755 --- a/systems/fedora/21/build_base_machine.sh +++ b/systems/fedora/21/build_base_machine.sh @@ -65,6 +65,10 @@ libreport-python3 abrt-python3 abrt-addon-python3 +# libs +numactl +numactl-devel + # install git-review tool git-review " | grep -v ^#) || exit 1 diff --git a/systems/fedora/22/build_base_machine.sh b/systems/fedora/22/build_base_machine.sh index 0ca565f3..3cfe0c78 100755 --- a/systems/fedora/22/build_base_machine.sh +++ b/systems/fedora/22/build_base_machine.sh @@ -66,9 +66,13 @@ libreport-python3 abrt-python3 abrt-addon-python3 +# libs +numactl +numactl-devel + # install git-review tool git-review " | grep -v ^#) # Create hugepage dirs -mkdir -p /dev/hugepages
\ No newline at end of file +mkdir -p /dev/hugepages diff --git a/systems/rhel/7.2/build_base_machine.sh b/systems/rhel/7.2/build_base_machine.sh index 86608066..2319535b 100755 --- a/systems/rhel/7.2/build_base_machine.sh +++ b/systems/rhel/7.2/build_base_machine.sh @@ -50,6 +50,8 @@ pkglist=( socat\ tk-devel\ wget\ + numactl\ + numactl-devel\ ) # python tools for proper QEMU, DPDK, and OVS make @@ -95,4 +97,4 @@ rm -f Python-3.4.2.tar.xz pip3.4 install virtualenv # Create hugepage dirs -mkdir -p /dev/hugepages
\ No newline at end of file +mkdir -p /dev/hugepages diff --git a/systems/ubuntu/14.04/build_base_machine.sh b/systems/ubuntu/14.04/build_base_machine.sh index 9fa8511c..04f4a7e1 100755 --- a/systems/ubuntu/14.04/build_base_machine.sh +++ b/systems/ubuntu/14.04/build_base_machine.sh @@ -77,6 +77,10 @@ python3-tk libpython3.4 python3-reportlab +# libs +libnuma1 +libnuma-dev + # install git-review tool git-review " | grep -v ^#) diff --git a/systems/ubuntu/build_base_machine.sh b/systems/ubuntu/build_base_machine.sh index a2b48a26..1b42a790 100755 --- a/systems/ubuntu/build_base_machine.sh +++ b/systems/ubuntu/build_base_machine.sh @@ -44,6 +44,8 @@ apt-get -y install autoconf libtool apt-get -y install libpcap-dev apt-get -y install libglib2.0 apt-get -y install libfuse-dev +apt-get -y install libnuma1 +apt-get -y install libnuma-dev # Some useful tools you may optionally install #apt-get -y install ctags diff --git a/testcases/testcase.py b/testcases/testcase.py index 5f5c9358..d88840d7 100644 --- a/testcases/testcase.py +++ b/testcases/testcase.py @@ -14,14 +14,18 @@ """TestCase base class """ +from collections import OrderedDict +import copy import csv +import logging +import math import os +import re import time -import logging import subprocess -import copy -from collections import OrderedDict +from conf import settings as S +from conf import get_test_param import core.component_factory as component_factory from core.loader import Loader from core.results.results_constants import ResultsConstants @@ -29,8 +33,7 @@ from tools import tasks from tools import hugepages from tools import functions from tools.pkt_gen.trafficgen.trafficgenhelper import TRAFFIC_DEFAULTS -from conf import settings as S -from conf import get_test_param + class TestCase(object): """TestCase base class @@ -189,6 +192,10 @@ class TestCase(object): # mount hugepages if needed self._mount_hugepages() + # verify enough hugepages are free to run the testcase + if not self._check_for_enough_hugepages(): + raise RuntimeError('Not enough hugepages free to run test.') + # copy sources of l2 forwarding tools into VM shared dir if needed self._copy_fwd_tools_for_all_guests() @@ -391,7 +398,6 @@ class TestCase(object): except subprocess.CalledProcessError: self._logger.error('Unable to copy DPDK and l2fwd to shared directory') - def _mount_hugepages(self): """Mount hugepages if usage of DPDK or Qemu is detected """ @@ -411,6 +417,80 @@ class TestCase(object): hugepages.umount_hugepages() self._hugepages_mounted = False + def _check_for_enough_hugepages(self): + """Check to make sure enough hugepages are free to satisfy the + test environment. + """ + hugepages_needed = 0 + hugepage_size = hugepages.get_hugepage_size() + # get hugepage amounts per guest + for guest in range(self.deployment.count('v')): + hugepages_needed += math.ceil((int(S.getValue( + 'GUEST_MEMORY')[guest]) * 1000) / hugepage_size) + + # get hugepage amounts for each socket on dpdk + sock0_mem, sock1_mem = 0, 0 + if S.getValue('VSWITCH').lower().count('dpdk'): + # the import below needs to remain here and not put into the module + # imports because of an exception due to settings not yet loaded + from vswitches import ovs_dpdk_vhost + if ovs_dpdk_vhost.OvsDpdkVhost.old_dpdk_config(): + match = re.search( + '-socket-mem\s+(\d+),(\d+)', + ''.join(S.getValue('VSWITCHD_DPDK_ARGS'))) + if match: + sock0_mem, sock1_mem = (int(match.group(1)) / 1024, + int(match.group(2)) / 1024) + else: + logging.info( + 'Could not parse socket memory config in dpdk params.') + else: + sock0_mem, sock1_mem = ( + S.getValue( + 'VSWITCHD_DPDK_CONFIG')['dpdk-socket-mem'].split(',')) + sock0_mem, sock1_mem = (int(sock0_mem) / 1024, + int(sock1_mem) / 1024) + + # If hugepages needed, verify the amounts are free + if any([hugepages_needed, sock0_mem, sock1_mem]): + free_hugepages = hugepages.get_free_hugepages() + if hugepages_needed: + logging.info('Need %s hugepages free for guests', + hugepages_needed) + result1 = free_hugepages >= hugepages_needed + free_hugepages -= hugepages_needed + else: + result1 = True + + if sock0_mem: + logging.info('Need %s hugepages free for dpdk socket 0', + sock0_mem) + result2 = hugepages.get_free_hugepages('0') >= sock0_mem + free_hugepages -= sock0_mem + else: + result2 = True + + if sock1_mem: + logging.info('Need %s hugepages free for dpdk socket 1', + sock1_mem) + result3 = hugepages.get_free_hugepages('1') >= sock1_mem + free_hugepages -= sock1_mem + else: + result3 = True + + logging.info('Need a total of {} total hugepages'.format( + hugepages_needed + sock1_mem + sock0_mem)) + + # The only drawback here is sometimes dpdk doesn't release + # its hugepages on a test failure. This could cause a test + # to fail when dpdk would be OK to start because it will just + # use the previously allocated hugepages. + result4 = True if free_hugepages >= 0 else False + + return all([result1, result2, result3, result4]) + else: + return True + @staticmethod def write_result_to_file(results, output): """Write list of dictionaries to a CSV file. diff --git a/tools/hugepages.py b/tools/hugepages.py index 3a434d6e..02e4f29c 100644 --- a/tools/hugepages.py +++ b/tools/hugepages.py @@ -20,6 +20,7 @@ import re import subprocess import logging import locale +import math from tools import tasks from conf import settings @@ -31,29 +32,105 @@ _LOGGER = logging.getLogger(__name__) # +def get_hugepage_size(): + """Return the size of the configured hugepages + """ + hugepage_size_re = re.compile(r'^Hugepagesize:\s+(?P<size_hp>\d+)\s+kB', + re.IGNORECASE) + with open('/proc/meminfo', 'r') as fh: + data = fh.readlines() + for line in data: + match = hugepage_size_re.search(line) + if match: + _LOGGER.info('Hugepages size: %s', match.group('size_hp')) + return int(match.group('size_hp')) + else: + _LOGGER.error('Could not parse for hugepage size') + return 0 + + +def allocate_hugepages(): + """Allocate hugepages on the fly + """ + hp_size = get_hugepage_size() + + if hp_size > 0: + nr_hp = int(math.ceil(settings.getValue('HUGEPAGE_RAM_ALLOCATION')/hp_size)) + _LOGGER.info('Will allocate %s hugepages.', nr_hp) + + nr_hugepages = 'vm.nr_hugepages=' + str(nr_hp) + try: + tasks.run_task(['sudo', 'sysctl', nr_hugepages], + _LOGGER, 'Trying to allocate hugepages..', True) + except subprocess.CalledProcessError: + _LOGGER.error('Unable to allocate hugepages.') + return False + return True + + else: + _LOGGER.error('Division by 0 will be supported in next release') + return False + + +def get_free_hugepages(socket=None): + """Get the free hugepage totals on the system. + + :param socket: optional socket param to get free hugepages on a socket. To + be passed a string. + :returns: hugepage amount as int + """ + hugepage_free_re = re.compile(r'HugePages_Free:\s+(?P<free_hp>\d+)$') + if socket: + if os.path.exists( + '/sys/devices/system/node/node{}/meminfo'.format(socket)): + meminfo_path = '/sys/devices/system/node/node{}/meminfo'.format( + socket) + else: + _LOGGER.info('No hugepage info found for socket {}'.format(socket)) + return 0 + else: + meminfo_path = '/proc/meminfo' + + with open(meminfo_path, 'r') as fh: + data = fh.readlines() + for line in data: + match = hugepage_free_re.search(line) + if match: + _LOGGER.info('Hugepages free: %s %s', match.group('free_hp'), + 'on socket {}'.format(socket) if socket else '') + return int(match.group('free_hp')) + else: + _LOGGER.info('Could not parse for hugepage size') + return 0 + + def is_hugepage_available(): - """Check if hugepages are available on the system. + """Check if hugepages are configured/available on the system. """ - hugepage_re = re.compile(r'^HugePages_Free:\s+(?P<num_hp>\d+)$') + hugepage_size_re = re.compile(r'^Hugepagesize:\s+(?P<size_hp>\d+)\s+kB', + re.IGNORECASE) # read in meminfo with open('/proc/meminfo') as mem_file: mem_info = mem_file.readlines() - # first check if module is loaded + # see if the hugepage size is the recommended value for line in mem_info: - result = hugepage_re.match(line) - if not result: - continue - - num_huge = result.group('num_hp') - if not num_huge: - _LOGGER.info('No free hugepages.') - else: - _LOGGER.info('Found \'%s\' free hugepage(s).', num_huge) - return True - - return False + match_size = hugepage_size_re.match(line) + if match_size: + if match_size.group('size_hp') != '1048576': + _LOGGER.info( + '%s%s%s kB', + 'Hugepages not configured for recommend 1GB size. ', + 'Currently set at ', match_size.group('size_hp')) + num_huge = get_free_hugepages() + if num_huge == 0: + _LOGGER.info('No free hugepages.') + if not allocate_hugepages(): + return False + else: + _LOGGER.info('Found \'%s\' free hugepage(s).', num_huge) + return True def is_hugepage_mounted(): @@ -69,10 +146,11 @@ def is_hugepage_mounted(): def mount_hugepages(): - """Ensure hugepages are mounted. + """Ensure hugepages are mounted. Raises RuntimeError if no configured + hugepages are available. """ if not is_hugepage_available(): - return + raise RuntimeError('No Hugepages configured.') if is_hugepage_mounted(): return diff --git a/tools/namespace.py b/tools/namespace.py index e6bcd819..9131398f 100644 --- a/tools/namespace.py +++ b/tools/namespace.py @@ -108,8 +108,8 @@ def get_system_namespace_list(): Return tuple of strings for namespaces on the system :return: tuple of namespaces as string """ - return tuple(os.listdir('/var/run/netns')) - + return tuple(os.listdir('/var/run/netns')) if os.path.exists( + '/var/run/netns') else tuple() def get_vsperf_namespace_list(): """ diff --git a/tools/pkt_gen/moongen/moongen.py b/tools/pkt_gen/moongen/moongen.py index 47f288a4..86a39a77 100644 --- a/tools/pkt_gen/moongen/moongen.py +++ b/tools/pkt_gen/moongen/moongen.py @@ -20,10 +20,11 @@ Moongen Traffic Generator Model """ # python imports -import logging from collections import OrderedDict -import subprocess +import logging +import math import re +import subprocess # VSPerf imports from conf import settings @@ -49,6 +50,13 @@ class Moongen(ITrafficGenerator): self._moongen_user = settings.getValue('TRAFFICGEN_MOONGEN_USER') self._moongen_ports = settings.getValue('TRAFFICGEN_MOONGEN_PORTS') + if settings.getValue('TRAFFICGEN_MOONGEN_LINE_SPEED_GBPS') == '10': + self._moongen_line_speed = math.pow(10, 10) + else: + raise RuntimeError( + 'MOONGEN: Invalid line speed in configuration ' + \ + 'file (today 10Gbps supported)') + @property def traffic_defaults(self): """Default traffic values. @@ -157,10 +165,17 @@ class Moongen(ITrafficGenerator): if one_shot: out_file.write("oneShot = true,\n") - # Assume 10G line rates at the moment. Need to convert VSPERF - # frame_rate (percentage of line rate) to Mpps for Moongen + # Need to convert VSPERF frame_rate (percentage of line rate) + # to Mpps for Moongen + start_rate = str( + (traffic['frame_rate'] / 100) * (self._moongen_line_speed / \ + (8 * (traffic['l2']['framesize'] + 20)) / math.pow(10, 6))) + + logging.debug("startRate = " + start_rate) + + out_file.write("startRate = " + \ + start_rate + "\n") - out_file.write("startRate = " + str((traffic['frame_rate'] / 100) * 14.88) + "\n") out_file.write("}" + "\n") out_file.close() @@ -473,10 +488,21 @@ class Moongen(ITrafficGenerator): 'PARAMETERS section of Moongen log file') frame_size = 0 - if results_match and parameters_match: + # Each packet stream in the MoonGen report is prefaced with the + # words '[REPORT]Device'. Count the instances of this string to + # get the total aggregrate throughput. For example: + # + # - If num_traffic_streams = 1, there is a single + # unidirectional stream + # + # - If num_traffic_streams = 2, there is a bidirectional + # traffic stream + num_traffic_streams = mytext.count('[REPORT]Device') + + if results_match and parameters_match and num_traffic_streams: # Assume for now 10G link speed - max_theoretical_mfps = ( - (10000000000 / 8) / (frame_size + 20)) + max_theoretical_fps = ( + num_traffic_streams * (10000000000 / 8) / (frame_size + 20)) moongen_results[ResultsConstants.THROUGHPUT_RX_FPS] = ( float(results_match.group(6)) * 1000000) @@ -485,8 +511,7 @@ class Moongen(ITrafficGenerator): (float(results_match.group(6)) * frame_size + 20) * 8) moongen_results[ResultsConstants.THROUGHPUT_RX_PERCENT] = ( - float(results_match.group(6)) * \ - 1000000 / max_theoretical_mfps * 100) + (100 * float(results_match.group(6)) * 1000000) / max_theoretical_fps) moongen_results[ResultsConstants.TX_RATE_FPS] = ( float(results_match.group(5)) * 1000000) @@ -495,8 +520,7 @@ class Moongen(ITrafficGenerator): float(results_match.group(5)) * (frame_size + 20) * 8) moongen_results[ResultsConstants.TX_RATE_PERCENT] = ( - float(results_match.group(5)) * - 1000000 / max_theoretical_mfps * 100) + (100 * float(results_match.group(5)) * 1000000) / max_theoretical_fps) moongen_results[ResultsConstants.B2B_TX_COUNT] = ( float(results_match.group(1))) diff --git a/tools/pkt_gen/xena/XenaDriver.py b/tools/pkt_gen/xena/XenaDriver.py index aa8443c9..d3862312 100644 --- a/tools/pkt_gen/xena/XenaDriver.py +++ b/tools/pkt_gen/xena/XenaDriver.py @@ -1001,9 +1001,21 @@ class XenaTXStats(object): mydict = statdict return mydict - def aggregate_stats(stat1, stat2): """ + Judge whether stat1 and stat2 both have same key, if both have same key, + call the aggregate fuction, else use the stat1's value + """ + newstat = dict() + for keys in stat1.keys(): + if keys in stat2 and isinstance(stat1[keys], dict): + newstat[keys] = aggregate(stat1[keys], stat2[keys]) + else: + newstat[keys] = stat1[keys] + return newstat + +def aggregate(stat1, stat2): + """ Recursive function to aggregate two sets of statistics. This is used when bi directional traffic is done and statistics need to be calculated based on two sets of statistics. @@ -1014,7 +1026,7 @@ def aggregate_stats(stat1, stat2): newstat = dict() for (keys1, keys2) in zip(stat1.keys(), stat2.keys()): if isinstance(stat1[keys1], dict): - newstat[keys1] = aggregate_stats(stat1[keys1], stat2[keys2]) + newstat[keys1] = aggregate(stat1[keys1], stat2[keys2]) else: if not isinstance(stat1[keys1], int) and not isinstance( [keys1], float): diff --git a/vnfs/qemu/qemu_pci_passthrough.py b/vnfs/qemu/qemu_pci_passthrough.py index 14810f0a..951d6086 100644 --- a/vnfs/qemu/qemu_pci_passthrough.py +++ b/vnfs/qemu/qemu_pci_passthrough.py @@ -44,8 +44,8 @@ class QemuPciPassthrough(IVnfQemu): # in case of SRIOV and PCI passthrough we must ensure, that MAC addresses are swapped if S.getValue('SRIOV_ENABLED') and not self._testpmd_fwd_mode.startswith('mac'): self._logger.info("SRIOV detected, forwarding mode of testpmd was changed from '%s' to '%s'", - self._testpmd_fwd_mode, 'mac_retry') - self._testpmd_fwd_mode = 'mac_retry' + self._testpmd_fwd_mode, 'mac') + self._testpmd_fwd_mode = 'mac' for nic in self._nics: self._cmd += ['-device', 'vfio-pci,host=' + nic['pci']] @@ -557,13 +557,13 @@ def main(): _LOGGER.error("Cannot specify tests with both positional args and --test.") sys.exit(1) - # sriov handling - settings.setValue('SRIOV_ENABLED', enable_sriov(settings.getValue('WHITELIST_NICS'))) - # modify NIC configuration to decode enhanced PCI IDs wl_nics_orig = list(networkcard.check_pci(pci) for pci in settings.getValue('WHITELIST_NICS')) settings.setValue('WHITELIST_NICS_ORIG', wl_nics_orig) + # sriov handling is performed on checked/expanded PCI IDs + settings.setValue('SRIOV_ENABLED', enable_sriov(wl_nics_orig)) + nic_list = [] for nic in wl_nics_orig: tmp_nic = networkcard.get_nic_info(nic) |