diff options
author | 2017-05-16 14:51:32 +0200 | |
---|---|---|
committer | 2017-05-16 14:51:32 +0200 | |
commit | fca143f059a0bddd7d47b8dc2df646a891b0eb0f (patch) | |
tree | 4bfeadc905c977e45e54a90c42330553b8942e4e /tools | |
parent | ce3d555e43e3795b5d9507fcfc76b7a0a92fd0d6 (diff) |
Imported Upstream version 17.05
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/cpu_layout.py | 95 | ||||
-rwxr-xr-x | tools/dpdk-devbind.py | 654 | ||||
-rwxr-xr-x | tools/dpdk-pmdinfo.py | 636 | ||||
-rwxr-xr-x | tools/dpdk-setup.sh | 634 |
4 files changed, 0 insertions, 2019 deletions
diff --git a/tools/cpu_layout.py b/tools/cpu_layout.py deleted file mode 100755 index d38d0b5a..00000000 --- a/tools/cpu_layout.py +++ /dev/null @@ -1,95 +0,0 @@ -#! /usr/bin/python -# -# BSD LICENSE -# -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -import sys - -sockets = [] -cores = [] -core_map = {} - -fd=open("/proc/cpuinfo") -lines = fd.readlines() -fd.close() - -core_details = [] -core_lines = {} -for line in lines: - if len(line.strip()) != 0: - name, value = line.split(":", 1) - core_lines[name.strip()] = value.strip() - else: - core_details.append(core_lines) - core_lines = {} - -for core in core_details: - for field in ["processor", "core id", "physical id"]: - if field not in core: - print "Error getting '%s' value from /proc/cpuinfo" % field - sys.exit(1) - core[field] = int(core[field]) - - if core["core id"] not in cores: - cores.append(core["core id"]) - if core["physical id"] not in sockets: - sockets.append(core["physical id"]) - key = (core["physical id"], core["core id"]) - if key not in core_map: - core_map[key] = [] - core_map[key].append(core["processor"]) - -print "============================================================" -print "Core and Socket Information (as reported by '/proc/cpuinfo')" -print "============================================================\n" -print "cores = ",cores -print "sockets = ", sockets -print "" - -max_processor_len = len(str(len(cores) * len(sockets) * 2 - 1)) -max_core_map_len = max_processor_len * 2 + len('[, ]') + len('Socket ') -max_core_id_len = len(str(max(cores))) - -print " ".ljust(max_core_id_len + len('Core ')), -for s in sockets: - print "Socket %s" % str(s).ljust(max_core_map_len - len('Socket ')), -print "" -print " ".ljust(max_core_id_len + len('Core ')), -for s in sockets: - print "--------".ljust(max_core_map_len), -print "" - -for c in cores: - print "Core %s" % str(c).ljust(max_core_id_len), - for s in sockets: - print str(core_map[(s,c)]).ljust(max_core_map_len), - print "" diff --git a/tools/dpdk-devbind.py b/tools/dpdk-devbind.py deleted file mode 100755 index fef59c41..00000000 --- a/tools/dpdk-devbind.py +++ /dev/null @@ -1,654 +0,0 @@ -#! /usr/bin/python -# -# BSD LICENSE -# -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -import sys -import os -import getopt -import subprocess -from os.path import exists, abspath, dirname, basename - -# The PCI base class for NETWORK devices -NETWORK_BASE_CLASS = "02" -CRYPTO_BASE_CLASS = "0b" - -# global dict ethernet devices present. Dictionary indexed by PCI address. -# Each device within this is itself a dictionary of device properties -devices = {} -# list of supported DPDK drivers -dpdk_drivers = ["igb_uio", "vfio-pci", "uio_pci_generic"] - -# command-line arg flags -b_flag = None -status_flag = False -force_flag = False -args = [] - - -def usage(): - '''Print usage information for the program''' - argv0 = basename(sys.argv[0]) - print(""" -Usage: ------- - - %(argv0)s [options] DEVICE1 DEVICE2 .... - -where DEVICE1, DEVICE2 etc, are specified via PCI "domain:bus:slot.func" syntax -or "bus:slot.func" syntax. For devices bound to Linux kernel drivers, they may -also be referred to by Linux interface name e.g. eth0, eth1, em0, em1, etc. - -Options: - --help, --usage: - Display usage information and quit - - -s, --status: - Print the current status of all known network and crypto devices. - For each device, it displays the PCI domain, bus, slot and function, - along with a text description of the device. Depending upon whether the - device is being used by a kernel driver, the igb_uio driver, or no - driver, other relevant information will be displayed: - * the Linux interface name e.g. if=eth0 - * the driver being used e.g. drv=igb_uio - * any suitable drivers not currently using that device - e.g. unused=igb_uio - NOTE: if this flag is passed along with a bind/unbind option, the - status display will always occur after the other operations have taken - place. - - -b driver, --bind=driver: - Select the driver to use or \"none\" to unbind the device - - -u, --unbind: - Unbind a device (Equivalent to \"-b none\") - - --force: - By default, network devices which are used by Linux - as indicated by having - routes in the routing table - cannot be modified. Using the --force - flag overrides this behavior, allowing active links to be forcibly - unbound. - WARNING: This can lead to loss of network connection and should be used - with caution. - -Examples: ---------- - -To display current device status: - %(argv0)s --status - -To bind eth1 from the current driver and move to use igb_uio - %(argv0)s --bind=igb_uio eth1 - -To unbind 0000:01:00.0 from using any driver - %(argv0)s -u 0000:01:00.0 - -To bind 0000:02:00.0 and 0000:02:00.1 to the ixgbe kernel driver - %(argv0)s -b ixgbe 02:00.0 02:00.1 - - """ % locals()) # replace items from local variables - - -# This is roughly compatible with check_output function in subprocess module -# which is only available in python 2.7. -def check_output(args, stderr=None): - '''Run a command and capture its output''' - return subprocess.Popen(args, stdout=subprocess.PIPE, - stderr=stderr).communicate()[0] - - -def find_module(mod): - '''find the .ko file for kernel module named mod. - Searches the $RTE_SDK/$RTE_TARGET directory, the kernel - modules directory and finally under the parent directory of - the script ''' - # check $RTE_SDK/$RTE_TARGET directory - if 'RTE_SDK' in os.environ and 'RTE_TARGET' in os.environ: - path = "%s/%s/kmod/%s.ko" % (os.environ['RTE_SDK'], - os.environ['RTE_TARGET'], mod) - if exists(path): - return path - - # check using depmod - try: - depmod_out = check_output(["modinfo", "-n", mod], - stderr=subprocess.STDOUT).lower() - if "error" not in depmod_out: - path = depmod_out.strip() - if exists(path): - return path - except: # if modinfo can't find module, it fails, so continue - pass - - # check for a copy based off current path - tools_dir = dirname(abspath(sys.argv[0])) - if (tools_dir.endswith("tools")): - base_dir = dirname(tools_dir) - find_out = check_output(["find", base_dir, "-name", mod + ".ko"]) - if len(find_out) > 0: # something matched - path = find_out.splitlines()[0] - if exists(path): - return path - - -def check_modules(): - '''Checks that igb_uio is loaded''' - global dpdk_drivers - - # list of supported modules - mods = [{"Name": driver, "Found": False} for driver in dpdk_drivers] - - # first check if module is loaded - try: - # Get list of sysfs modules (both built-in and dynamically loaded) - sysfs_path = '/sys/module/' - - # Get the list of directories in sysfs_path - sysfs_mods = [os.path.join(sysfs_path, o) for o - in os.listdir(sysfs_path) - if os.path.isdir(os.path.join(sysfs_path, o))] - - # Extract the last element of '/sys/module/abc' in the array - sysfs_mods = [a.split('/')[-1] for a in sysfs_mods] - - # special case for vfio_pci (module is named vfio-pci, - # but its .ko is named vfio_pci) - sysfs_mods = map(lambda a: - a if a != 'vfio_pci' else 'vfio-pci', sysfs_mods) - - for mod in mods: - if mod["Name"] in sysfs_mods: - mod["Found"] = True - except: - pass - - # check if we have at least one loaded module - if True not in [mod["Found"] for mod in mods] and b_flag is not None: - if b_flag in dpdk_drivers: - print("Error - no supported modules(DPDK driver) are loaded") - sys.exit(1) - else: - print("Warning - no supported modules(DPDK driver) are loaded") - - # change DPDK driver list to only contain drivers that are loaded - dpdk_drivers = [mod["Name"] for mod in mods if mod["Found"]] - - -def has_driver(dev_id): - '''return true if a device is assigned to a driver. False otherwise''' - return "Driver_str" in devices[dev_id] - - -def get_pci_device_details(dev_id): - '''This function gets additional details for a PCI device''' - device = {} - - extra_info = check_output(["lspci", "-vmmks", dev_id]).splitlines() - - # parse lspci details - for line in extra_info: - if len(line) == 0: - continue - name, value = line.decode().split("\t", 1) - name = name.strip(":") + "_str" - device[name] = value - # check for a unix interface name - device["Interface"] = "" - for base, dirs, _ in os.walk("/sys/bus/pci/devices/%s/" % dev_id): - if "net" in dirs: - device["Interface"] = \ - ",".join(os.listdir(os.path.join(base, "net"))) - break - # check if a port is used for ssh connection - device["Ssh_if"] = False - device["Active"] = "" - - return device - - -def get_nic_details(): - '''This function populates the "devices" dictionary. The keys used are - the pci addresses (domain:bus:slot.func). The values are themselves - dictionaries - one for each NIC.''' - global devices - global dpdk_drivers - - # clear any old data - devices = {} - # first loop through and read details for all devices - # request machine readable format, with numeric IDs - dev = {} - dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines() - for dev_line in dev_lines: - if (len(dev_line) == 0): - if dev["Class"][0:2] == NETWORK_BASE_CLASS: - # convert device and vendor ids to numbers, then add to global - dev["Vendor"] = int(dev["Vendor"], 16) - dev["Device"] = int(dev["Device"], 16) - # use dict to make copy of dev - devices[dev["Slot"]] = dict(dev) - else: - name, value = dev_line.decode().split("\t", 1) - dev[name.rstrip(":")] = value - - # check what is the interface if any for an ssh connection if - # any to this host, so we can mark it later. - ssh_if = [] - route = check_output(["ip", "-o", "route"]) - # filter out all lines for 169.254 routes - route = "\n".join(filter(lambda ln: not ln.startswith("169.254"), - route.decode().splitlines())) - rt_info = route.split() - for i in range(len(rt_info) - 1): - if rt_info[i] == "dev": - ssh_if.append(rt_info[i+1]) - - # based on the basic info, get extended text details - for d in devices.keys(): - # get additional info and add it to existing data - devices[d] = devices[d].copy() - devices[d].update(get_pci_device_details(d).items()) - - for _if in ssh_if: - if _if in devices[d]["Interface"].split(","): - devices[d]["Ssh_if"] = True - devices[d]["Active"] = "*Active*" - break - - # add igb_uio to list of supporting modules if needed - if "Module_str" in devices[d]: - for driver in dpdk_drivers: - if driver not in devices[d]["Module_str"]: - devices[d]["Module_str"] = \ - devices[d]["Module_str"] + ",%s" % driver - else: - devices[d]["Module_str"] = ",".join(dpdk_drivers) - - # make sure the driver and module strings do not have any duplicates - if has_driver(d): - modules = devices[d]["Module_str"].split(",") - if devices[d]["Driver_str"] in modules: - modules.remove(devices[d]["Driver_str"]) - devices[d]["Module_str"] = ",".join(modules) - - -def get_crypto_details(): - '''This function populates the "devices" dictionary. The keys used are - the pci addresses (domain:bus:slot.func). The values are themselves - dictionaries - one for each NIC.''' - global devices - global dpdk_drivers - - # clear any old data - # devices = {} - # first loop through and read details for all devices - # request machine readable format, with numeric IDs - dev = {} - dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines() - for dev_line in dev_lines: - if (len(dev_line) == 0): - if (dev["Class"][0:2] == CRYPTO_BASE_CLASS): - # convert device and vendor ids to numbers, then add to global - dev["Vendor"] = int(dev["Vendor"], 16) - dev["Device"] = int(dev["Device"], 16) - # use dict to make copy of dev - devices[dev["Slot"]] = dict(dev) - else: - name, value = dev_line.decode().split("\t", 1) - dev[name.rstrip(":")] = value - - # based on the basic info, get extended text details - for d in devices.keys(): - if devices[d]["Class"][0:2] != CRYPTO_BASE_CLASS: - continue - - # get additional info and add it to existing data - devices[d] = devices[d].copy() - devices[d].update(get_pci_device_details(d).items()) - - # add igb_uio to list of supporting modules if needed - if "Module_str" in devices[d]: - for driver in dpdk_drivers: - if driver not in devices[d]["Module_str"]: - devices[d]["Module_str"] = \ - devices[d]["Module_str"] + ",%s" % driver - else: - devices[d]["Module_str"] = ",".join(dpdk_drivers) - - # make sure the driver and module strings do not have any duplicates - if has_driver(d): - modules = devices[d]["Module_str"].split(",") - if devices[d]["Driver_str"] in modules: - modules.remove(devices[d]["Driver_str"]) - devices[d]["Module_str"] = ",".join(modules) - - -def dev_id_from_dev_name(dev_name): - '''Take a device "name" - a string passed in by user to identify a NIC - device, and determine the device id - i.e. the domain:bus:slot.func - for - it, which can then be used to index into the devices array''' - - # check if it's already a suitable index - if dev_name in devices: - return dev_name - # check if it's an index just missing the domain part - elif "0000:" + dev_name in devices: - return "0000:" + dev_name - else: - # check if it's an interface name, e.g. eth1 - for d in devices.keys(): - if dev_name in devices[d]["Interface"].split(","): - return devices[d]["Slot"] - # if nothing else matches - error - print("Unknown device: %s. " - "Please specify device in \"bus:slot.func\" format" % dev_name) - sys.exit(1) - - -def unbind_one(dev_id, force): - '''Unbind the device identified by "dev_id" from its current driver''' - dev = devices[dev_id] - if not has_driver(dev_id): - print("%s %s %s is not currently managed by any driver\n" % - (dev["Slot"], dev["Device_str"], dev["Interface"])) - return - - # prevent us disconnecting ourselves - if dev["Ssh_if"] and not force: - print("Routing table indicates that interface %s is active. " - "Skipping unbind" % (dev_id)) - return - - # write to /sys to unbind - filename = "/sys/bus/pci/drivers/%s/unbind" % dev["Driver_str"] - try: - f = open(filename, "a") - except: - print("Error: unbind failed for %s - Cannot open %s" - % (dev_id, filename)) - sys.exit(1) - f.write(dev_id) - f.close() - - -def bind_one(dev_id, driver, force): - '''Bind the device given by "dev_id" to the driver "driver". If the device - is already bound to a different driver, it will be unbound first''' - dev = devices[dev_id] - saved_driver = None # used to rollback any unbind in case of failure - - # prevent disconnection of our ssh session - if dev["Ssh_if"] and not force: - print("Routing table indicates that interface %s is active. " - "Not modifying" % (dev_id)) - return - - # unbind any existing drivers we don't want - if has_driver(dev_id): - if dev["Driver_str"] == driver: - print("%s already bound to driver %s, skipping\n" - % (dev_id, driver)) - return - else: - saved_driver = dev["Driver_str"] - unbind_one(dev_id, force) - dev["Driver_str"] = "" # clear driver string - - # if we are binding to one of DPDK drivers, add PCI id's to that driver - if driver in dpdk_drivers: - filename = "/sys/bus/pci/drivers/%s/new_id" % driver - try: - f = open(filename, "w") - except: - print("Error: bind failed for %s - Cannot open %s" - % (dev_id, filename)) - return - try: - f.write("%04x %04x" % (dev["Vendor"], dev["Device"])) - f.close() - except: - print("Error: bind failed for %s - Cannot write new PCI ID to " - "driver %s" % (dev_id, driver)) - return - - # do the bind by writing to /sys - filename = "/sys/bus/pci/drivers/%s/bind" % driver - try: - f = open(filename, "a") - except: - print("Error: bind failed for %s - Cannot open %s" - % (dev_id, filename)) - if saved_driver is not None: # restore any previous driver - bind_one(dev_id, saved_driver, force) - return - try: - f.write(dev_id) - f.close() - except: - # for some reason, closing dev_id after adding a new PCI ID to new_id - # results in IOError. however, if the device was successfully bound, - # we don't care for any errors and can safely ignore IOError - tmp = get_pci_device_details(dev_id) - if "Driver_str" in tmp and tmp["Driver_str"] == driver: - return - print("Error: bind failed for %s - Cannot bind to driver %s" - % (dev_id, driver)) - if saved_driver is not None: # restore any previous driver - bind_one(dev_id, saved_driver, force) - return - - -def unbind_all(dev_list, force=False): - """Unbind method, takes a list of device locations""" - dev_list = map(dev_id_from_dev_name, dev_list) - for d in dev_list: - unbind_one(d, force) - - -def bind_all(dev_list, driver, force=False): - """Bind method, takes a list of device locations""" - global devices - - dev_list = map(dev_id_from_dev_name, dev_list) - - for d in dev_list: - bind_one(d, driver, force) - - # when binding devices to a generic driver (i.e. one that doesn't have a - # PCI ID table), some devices that are not bound to any other driver could - # be bound even if no one has asked them to. hence, we check the list of - # drivers again, and see if some of the previously-unbound devices were - # erroneously bound. - for d in devices.keys(): - # skip devices that were already bound or that we know should be bound - if "Driver_str" in devices[d] or d in dev_list: - continue - - # update information about this device - devices[d] = dict(devices[d].items() + - get_pci_device_details(d).items()) - - # check if updated information indicates that the device was bound - if "Driver_str" in devices[d]: - unbind_one(d, force) - - -def display_devices(title, dev_list, extra_params=None): - '''Displays to the user the details of a list of devices given in - "dev_list". The "extra_params" parameter, if given, should contain a string - with %()s fields in it for replacement by the named fields in each - device's dictionary.''' - strings = [] # this holds the strings to print. We sort before printing - print("\n%s" % title) - print("="*len(title)) - if len(dev_list) == 0: - strings.append("<none>") - else: - for dev in dev_list: - if extra_params is not None: - strings.append("%s '%s' %s" % (dev["Slot"], - dev["Device_str"], extra_params % dev)) - else: - strings.append("%s '%s'" % (dev["Slot"], dev["Device_str"])) - # sort before printing, so that the entries appear in PCI order - strings.sort() - print("\n".join(strings)) # print one per line - - -def show_status(): - '''Function called when the script is passed the "--status" option. - Displays to the user what devices are bound to the igb_uio driver, the - kernel driver or to no driver''' - global dpdk_drivers - kernel_drv = [] - dpdk_drv = [] - no_drv = [] - - # split our list of network devices into the three categories above - for d in devices.keys(): - if (NETWORK_BASE_CLASS in devices[d]["Class"]): - if not has_driver(d): - no_drv.append(devices[d]) - continue - if devices[d]["Driver_str"] in dpdk_drivers: - dpdk_drv.append(devices[d]) - else: - kernel_drv.append(devices[d]) - - # print each category separately, so we can clearly see what's used by DPDK - display_devices("Network devices using DPDK-compatible driver", dpdk_drv, - "drv=%(Driver_str)s unused=%(Module_str)s") - display_devices("Network devices using kernel driver", kernel_drv, - "if=%(Interface)s drv=%(Driver_str)s " - "unused=%(Module_str)s %(Active)s") - display_devices("Other network devices", no_drv, "unused=%(Module_str)s") - - # split our list of crypto devices into the three categories above - kernel_drv = [] - dpdk_drv = [] - no_drv = [] - - for d in devices.keys(): - if (CRYPTO_BASE_CLASS in devices[d]["Class"]): - if not has_driver(d): - no_drv.append(devices[d]) - continue - if devices[d]["Driver_str"] in dpdk_drivers: - dpdk_drv.append(devices[d]) - else: - kernel_drv.append(devices[d]) - - display_devices("Crypto devices using DPDK-compatible driver", dpdk_drv, - "drv=%(Driver_str)s unused=%(Module_str)s") - display_devices("Crypto devices using kernel driver", kernel_drv, - "drv=%(Driver_str)s " - "unused=%(Module_str)s") - display_devices("Other crypto devices", no_drv, "unused=%(Module_str)s") - - -def parse_args(): - '''Parses the command-line arguments given by the user and takes the - appropriate action for each''' - global b_flag - global status_flag - global force_flag - global args - if len(sys.argv) <= 1: - usage() - sys.exit(0) - - try: - opts, args = getopt.getopt(sys.argv[1:], "b:us", - ["help", "usage", "status", "force", - "bind=", "unbind"]) - except getopt.GetoptError as error: - print(str(error)) - print("Run '%s --usage' for further information" % sys.argv[0]) - sys.exit(1) - - for opt, arg in opts: - if opt == "--help" or opt == "--usage": - usage() - sys.exit(0) - if opt == "--status" or opt == "-s": - status_flag = True - if opt == "--force": - force_flag = True - if opt == "-b" or opt == "-u" or opt == "--bind" or opt == "--unbind": - if b_flag is not None: - print("Error - Only one bind or unbind may be specified\n") - sys.exit(1) - if opt == "-u" or opt == "--unbind": - b_flag = "none" - else: - b_flag = arg - - -def do_arg_actions(): - '''do the actual action requested by the user''' - global b_flag - global status_flag - global force_flag - global args - - if b_flag is None and not status_flag: - print("Error: No action specified for devices." - "Please give a -b or -u option") - print("Run '%s --usage' for further information" % sys.argv[0]) - sys.exit(1) - - if b_flag is not None and len(args) == 0: - print("Error: No devices specified.") - print("Run '%s --usage' for further information" % sys.argv[0]) - sys.exit(1) - - if b_flag == "none" or b_flag == "None": - unbind_all(args, force_flag) - elif b_flag is not None: - bind_all(args, b_flag, force_flag) - if status_flag: - if b_flag is not None: - get_nic_details() # refresh if we have changed anything - get_crypto_details() # refresh if we have changed anything - show_status() - - -def main(): - '''program main function''' - parse_args() - check_modules() - get_nic_details() - get_crypto_details() - do_arg_actions() - -if __name__ == "__main__": - main() diff --git a/tools/dpdk-pmdinfo.py b/tools/dpdk-pmdinfo.py deleted file mode 100755 index 3db9819c..00000000 --- a/tools/dpdk-pmdinfo.py +++ /dev/null @@ -1,636 +0,0 @@ -#!/usr/bin/env python -# ------------------------------------------------------------------------- -# -# Utility to dump PMD_INFO_STRING support from an object file -# -# ------------------------------------------------------------------------- -import os -import sys -from optparse import OptionParser -import string -import json -import platform - -# For running from development directory. It should take precedence over the -# installed pyelftools. -sys.path.insert(0, '.') - - -from elftools import __version__ -from elftools.common.exceptions import ELFError -from elftools.common.py3compat import ( - ifilter, byte2int, bytes2str, itervalues, str2bytes) -from elftools.elf.elffile import ELFFile -from elftools.elf.dynamic import DynamicSection, DynamicSegment -from elftools.elf.enums import ENUM_D_TAG -from elftools.elf.segments import InterpSegment -from elftools.elf.sections import SymbolTableSection -from elftools.elf.gnuversions import ( - GNUVerSymSection, GNUVerDefSection, - GNUVerNeedSection, -) -from elftools.elf.relocation import RelocationSection -from elftools.elf.descriptions import ( - describe_ei_class, describe_ei_data, describe_ei_version, - describe_ei_osabi, describe_e_type, describe_e_machine, - describe_e_version_numeric, describe_p_type, describe_p_flags, - describe_sh_type, describe_sh_flags, - describe_symbol_type, describe_symbol_bind, describe_symbol_visibility, - describe_symbol_shndx, describe_reloc_type, describe_dyn_tag, - describe_ver_flags, -) -from elftools.elf.constants import E_FLAGS -from elftools.dwarf.dwarfinfo import DWARFInfo -from elftools.dwarf.descriptions import ( - describe_reg_name, describe_attr_value, set_global_machine_arch, - describe_CFI_instructions, describe_CFI_register_rule, - describe_CFI_CFA_rule, -) -from elftools.dwarf.constants import ( - DW_LNS_copy, DW_LNS_set_file, DW_LNE_define_file) -from elftools.dwarf.callframe import CIE, FDE - -raw_output = False -pcidb = None - -# =========================================== - - -class Vendor: - """ - Class for vendors. This is the top level class - for the devices belong to a specific vendor. - self.devices is the device dictionary - subdevices are in each device. - """ - - def __init__(self, vendorStr): - """ - Class initializes with the raw line from pci.ids - Parsing takes place inside __init__ - """ - self.ID = vendorStr.split()[0] - self.name = vendorStr.replace("%s " % self.ID, "").rstrip() - self.devices = {} - - def addDevice(self, deviceStr): - """ - Adds a device to self.devices - takes the raw line from pci.ids - """ - s = deviceStr.strip() - devID = s.split()[0] - if devID in self.devices: - pass - else: - self.devices[devID] = Device(deviceStr) - - def report(self): - print self.ID, self.name - for id, dev in self.devices.items(): - dev.report() - - def find_device(self, devid): - # convert to a hex string and remove 0x - devid = hex(devid)[2:] - try: - return self.devices[devid] - except: - return Device("%s Unknown Device" % devid) - - -class Device: - - def __init__(self, deviceStr): - """ - Class for each device. - Each vendor has its own devices dictionary. - """ - s = deviceStr.strip() - self.ID = s.split()[0] - self.name = s.replace("%s " % self.ID, "") - self.subdevices = {} - - def report(self): - print "\t%s\t%s" % (self.ID, self.name) - for subID, subdev in self.subdevices.items(): - subdev.report() - - def addSubDevice(self, subDeviceStr): - """ - Adds a subvendor, subdevice to device. - Uses raw line from pci.ids - """ - s = subDeviceStr.strip() - spl = s.split() - subVendorID = spl[0] - subDeviceID = spl[1] - subDeviceName = s.split(" ")[-1] - devID = "%s:%s" % (subVendorID, subDeviceID) - self.subdevices[devID] = SubDevice( - subVendorID, subDeviceID, subDeviceName) - - def find_subid(self, subven, subdev): - subven = hex(subven)[2:] - subdev = hex(subdev)[2:] - devid = "%s:%s" % (subven, subdev) - - try: - return self.subdevices[devid] - except: - if (subven == "ffff" and subdev == "ffff"): - return SubDevice("ffff", "ffff", "(All Subdevices)") - else: - return SubDevice(subven, subdev, "(Unknown Subdevice)") - - -class SubDevice: - """ - Class for subdevices. - """ - - def __init__(self, vendor, device, name): - """ - Class initializes with vendorid, deviceid and name - """ - self.vendorID = vendor - self.deviceID = device - self.name = name - - def report(self): - print "\t\t%s\t%s\t%s" % (self.vendorID, self.deviceID, self.name) - - -class PCIIds: - """ - Top class for all pci.ids entries. - All queries will be asked to this class. - PCIIds.vendors["0e11"].devices["0046"].\ - subdevices["0e11:4091"].name = "Smart Array 6i" - """ - - def __init__(self, filename): - """ - Prepares the directories. - Checks local data file. - Tries to load from local, if not found, downloads from web - """ - self.version = "" - self.date = "" - self.vendors = {} - self.contents = None - self.readLocal(filename) - self.parse() - - def reportVendors(self): - """Reports the vendors - """ - for vid, v in self.vendors.items(): - print v.ID, v.name - - def report(self, vendor=None): - """ - Reports everything for all vendors or a specific vendor - PCIIds.report() reports everything - PCIIDs.report("0e11") reports only "Compaq Computer Corporation" - """ - if vendor is not None: - self.vendors[vendor].report() - else: - for vID, v in self.vendors.items(): - v.report() - - def find_vendor(self, vid): - # convert vid to a hex string and remove the 0x - vid = hex(vid)[2:] - - try: - return self.vendors[vid] - except: - return Vendor("%s Unknown Vendor" % (vid)) - - def findDate(self, content): - for l in content: - if l.find("Date:") > -1: - return l.split()[-2].replace("-", "") - return None - - def parse(self): - if len(self.contents) < 1: - print "data/%s-pci.ids not found" % self.date - else: - vendorID = "" - deviceID = "" - for l in self.contents: - if l[0] == "#": - continue - elif len(l.strip()) == 0: - continue - else: - if l.find("\t\t") == 0: - self.vendors[vendorID].devices[ - deviceID].addSubDevice(l) - elif l.find("\t") == 0: - deviceID = l.strip().split()[0] - self.vendors[vendorID].addDevice(l) - else: - vendorID = l.split()[0] - self.vendors[vendorID] = Vendor(l) - - def readLocal(self, filename): - """ - Reads the local file - """ - self.contents = open(filename).readlines() - self.date = self.findDate(self.contents) - - def loadLocal(self): - """ - Loads database from local. If there is no file, - it creates a new one from web - """ - self.date = idsfile[0].split("/")[1].split("-")[0] - self.readLocal() - - -# ======================================= - -def search_file(filename, search_path): - """ Given a search path, find file with requested name """ - for path in string.split(search_path, ":"): - candidate = os.path.join(path, filename) - if os.path.exists(candidate): - return os.path.abspath(candidate) - return None - - -class ReadElf(object): - """ display_* methods are used to emit output into the output stream - """ - - def __init__(self, file, output): - """ file: - stream object with the ELF file to read - - output: - output stream to write to - """ - self.elffile = ELFFile(file) - self.output = output - - # Lazily initialized if a debug dump is requested - self._dwarfinfo = None - - self._versioninfo = None - - def _section_from_spec(self, spec): - """ Retrieve a section given a "spec" (either number or name). - Return None if no such section exists in the file. - """ - try: - num = int(spec) - if num < self.elffile.num_sections(): - return self.elffile.get_section(num) - else: - return None - except ValueError: - # Not a number. Must be a name then - return self.elffile.get_section_by_name(str2bytes(spec)) - - def pretty_print_pmdinfo(self, pmdinfo): - global pcidb - - for i in pmdinfo["pci_ids"]: - vendor = pcidb.find_vendor(i[0]) - device = vendor.find_device(i[1]) - subdev = device.find_subid(i[2], i[3]) - print("%s (%s) : %s (%s) %s" % - (vendor.name, vendor.ID, device.name, - device.ID, subdev.name)) - - def parse_pmd_info_string(self, mystring): - global raw_output - global pcidb - - optional_pmd_info = [{'id': 'params', 'tag': 'PMD PARAMETERS'}] - - i = mystring.index("=") - mystring = mystring[i + 2:] - pmdinfo = json.loads(mystring) - - if raw_output: - print(json.dumps(pmdinfo)) - return - - print("PMD NAME: " + pmdinfo["name"]) - for i in optional_pmd_info: - try: - print("%s: %s" % (i['tag'], pmdinfo[i['id']])) - except KeyError as e: - continue - - if (len(pmdinfo["pci_ids"]) != 0): - print("PMD HW SUPPORT:") - if pcidb is not None: - self.pretty_print_pmdinfo(pmdinfo) - else: - print("VENDOR\t DEVICE\t SUBVENDOR\t SUBDEVICE") - for i in pmdinfo["pci_ids"]: - print("0x%04x\t 0x%04x\t 0x%04x\t\t 0x%04x" % - (i[0], i[1], i[2], i[3])) - - print("") - - def display_pmd_info_strings(self, section_spec): - """ Display a strings dump of a section. section_spec is either a - section number or a name. - """ - section = self._section_from_spec(section_spec) - if section is None: - return - - data = section.data() - dataptr = 0 - - while dataptr < len(data): - while (dataptr < len(data) and - not (32 <= byte2int(data[dataptr]) <= 127)): - dataptr += 1 - - if dataptr >= len(data): - break - - endptr = dataptr - while endptr < len(data) and byte2int(data[endptr]) != 0: - endptr += 1 - - mystring = bytes2str(data[dataptr:endptr]) - rc = mystring.find("PMD_INFO_STRING") - if (rc != -1): - self.parse_pmd_info_string(mystring) - - dataptr = endptr - - def find_librte_eal(self, section): - for tag in section.iter_tags(): - if tag.entry.d_tag == 'DT_NEEDED': - if "librte_eal" in tag.needed: - return tag.needed - return None - - def search_for_autoload_path(self): - scanelf = self - scanfile = None - library = None - - section = self._section_from_spec(".dynamic") - try: - eallib = self.find_librte_eal(section) - if eallib is not None: - ldlibpath = os.environ.get('LD_LIBRARY_PATH') - if ldlibpath is None: - ldlibpath = "" - dtr = self.get_dt_runpath(section) - library = search_file(eallib, - dtr + ":" + ldlibpath + - ":/usr/lib64:/lib64:/usr/lib:/lib") - if library is None: - return (None, None) - if raw_output is False: - print("Scanning for autoload path in %s" % library) - scanfile = open(library, 'rb') - scanelf = ReadElf(scanfile, sys.stdout) - except AttributeError: - # Not a dynamic binary - pass - except ELFError: - scanfile.close() - return (None, None) - - section = scanelf._section_from_spec(".rodata") - if section is None: - if scanfile is not None: - scanfile.close() - return (None, None) - - data = section.data() - dataptr = 0 - - while dataptr < len(data): - while (dataptr < len(data) and - not (32 <= byte2int(data[dataptr]) <= 127)): - dataptr += 1 - - if dataptr >= len(data): - break - - endptr = dataptr - while endptr < len(data) and byte2int(data[endptr]) != 0: - endptr += 1 - - mystring = bytes2str(data[dataptr:endptr]) - rc = mystring.find("DPDK_PLUGIN_PATH") - if (rc != -1): - rc = mystring.find("=") - return (mystring[rc + 1:], library) - - dataptr = endptr - if scanfile is not None: - scanfile.close() - return (None, None) - - def get_dt_runpath(self, dynsec): - for tag in dynsec.iter_tags(): - if tag.entry.d_tag == 'DT_RUNPATH': - return tag.runpath - return "" - - def process_dt_needed_entries(self): - """ Look to see if there are any DT_NEEDED entries in the binary - And process those if there are - """ - global raw_output - runpath = "" - ldlibpath = os.environ.get('LD_LIBRARY_PATH') - if ldlibpath is None: - ldlibpath = "" - - dynsec = self._section_from_spec(".dynamic") - try: - runpath = self.get_dt_runpath(dynsec) - except AttributeError: - # dynsec is None, just return - return - - for tag in dynsec.iter_tags(): - if tag.entry.d_tag == 'DT_NEEDED': - rc = tag.needed.find("librte_pmd") - if (rc != -1): - library = search_file(tag.needed, - runpath + ":" + ldlibpath + - ":/usr/lib64:/lib64:/usr/lib:/lib") - if library is not None: - if raw_output is False: - print("Scanning %s for pmd information" % library) - with open(library, 'rb') as file: - try: - libelf = ReadElf(file, sys.stdout) - except ELFError as e: - print("%s is no an ELF file" % library) - continue - libelf.process_dt_needed_entries() - libelf.display_pmd_info_strings(".rodata") - file.close() - - -def scan_autoload_path(autoload_path): - global raw_output - - if os.path.exists(autoload_path) is False: - return - - try: - dirs = os.listdir(autoload_path) - except OSError as e: - # Couldn't read the directory, give up - return - - for d in dirs: - dpath = os.path.join(autoload_path, d) - if os.path.isdir(dpath): - scan_autoload_path(dpath) - if os.path.isfile(dpath): - try: - file = open(dpath, 'rb') - readelf = ReadElf(file, sys.stdout) - except ELFError as e: - # this is likely not an elf file, skip it - continue - except IOError as e: - # No permission to read the file, skip it - continue - - if raw_output is False: - print("Hw Support for library %s" % d) - readelf.display_pmd_info_strings(".rodata") - file.close() - - -def scan_for_autoload_pmds(dpdk_path): - """ - search the specified application or path for a pmd autoload path - then scan said path for pmds and report hw support - """ - global raw_output - - if (os.path.isfile(dpdk_path) is False): - if raw_output is False: - print("Must specify a file name") - return - - file = open(dpdk_path, 'rb') - try: - readelf = ReadElf(file, sys.stdout) - except ElfError as e: - if raw_output is False: - print("Unable to parse %s" % file) - return - - (autoload_path, scannedfile) = readelf.search_for_autoload_path() - if (autoload_path is None or autoload_path is ""): - if (raw_output is False): - print("No autoload path configured in %s" % dpdk_path) - return - if (raw_output is False): - if (scannedfile is None): - scannedfile = dpdk_path - print("Found autoload path %s in %s" % (autoload_path, scannedfile)) - - file.close() - if (raw_output is False): - print("Discovered Autoload HW Support:") - scan_autoload_path(autoload_path) - return - - -def main(stream=None): - global raw_output - global pcidb - - pcifile_default = "./pci.ids" # for unknown OS's assume local file - if platform.system() == 'Linux': - pcifile_default = "/usr/share/hwdata/pci.ids" - elif platform.system() == 'FreeBSD': - pcifile_default = "/usr/local/share/pciids/pci.ids" - if not os.path.exists(pcifile_default): - pcifile_default = "/usr/share/misc/pci_vendors" - - optparser = OptionParser( - usage='usage: %prog [-hrtp] [-d <pci id file] <elf-file>', - description="Dump pmd hardware support info", - add_help_option=True) - optparser.add_option('-r', '--raw', - action='store_true', dest='raw_output', - help='Dump raw json strings') - optparser.add_option("-d", "--pcidb", dest="pcifile", - help="specify a pci database " - "to get vendor names from", - default=pcifile_default, metavar="FILE") - optparser.add_option("-t", "--table", dest="tblout", - help="output information on hw support as a hex table", - action='store_true') - optparser.add_option("-p", "--plugindir", dest="pdir", - help="scan dpdk for autoload plugins", - action='store_true') - - options, args = optparser.parse_args() - - if options.raw_output: - raw_output = True - - if options.pcifile: - pcidb = PCIIds(options.pcifile) - if pcidb is None: - print("Pci DB file not found") - exit(1) - - if options.tblout: - options.pcifile = None - pcidb = None - - if (len(args) == 0): - optparser.print_usage() - exit(1) - - if options.pdir is True: - exit(scan_for_autoload_pmds(args[0])) - - ldlibpath = os.environ.get('LD_LIBRARY_PATH') - if (ldlibpath is None): - ldlibpath = "" - - if (os.path.exists(args[0]) is True): - myelffile = args[0] - else: - myelffile = search_file( - args[0], ldlibpath + ":/usr/lib64:/lib64:/usr/lib:/lib") - - if (myelffile is None): - print("File not found") - sys.exit(1) - - with open(myelffile, 'rb') as file: - try: - readelf = ReadElf(file, sys.stdout) - readelf.process_dt_needed_entries() - readelf.display_pmd_info_strings(".rodata") - sys.exit(0) - - except ELFError as ex: - sys.stderr.write('ELF error: %s\n' % ex) - sys.exit(1) - - -# ------------------------------------------------------------------------- -if __name__ == '__main__': - main() diff --git a/tools/dpdk-setup.sh b/tools/dpdk-setup.sh deleted file mode 100755 index 14ed5907..00000000 --- a/tools/dpdk-setup.sh +++ /dev/null @@ -1,634 +0,0 @@ -#! /bin/bash - -# BSD LICENSE -# -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# -# Run with "source /path/to/dpdk-setup.sh" -# - -# -# Change to DPDK directory ( <this-script's-dir>/.. ), and export it as RTE_SDK -# -cd $(dirname ${BASH_SOURCE[0]})/.. -export RTE_SDK=$PWD -echo "------------------------------------------------------------------------------" -echo " RTE_SDK exported as $RTE_SDK" -echo "------------------------------------------------------------------------------" - -HUGEPGSZ=`cat /proc/meminfo | grep Hugepagesize | cut -d : -f 2 | tr -d ' '` - -# -# Application EAL parameters for setting memory options (amount/channels/ranks). -# -EAL_PARAMS='-n 4' - -# -# Sets QUIT variable so script will finish. -# -quit() -{ - QUIT=$1 -} - -# Shortcut for quit. -q() -{ - quit -} - -# -# Sets up environmental variables for ICC. -# -setup_icc() -{ - DEFAULT_PATH=/opt/intel/bin/iccvars.sh - param=$1 - shpath=`which iccvars.sh 2> /dev/null` - if [ $? -eq 0 ] ; then - echo "Loading iccvars.sh from $shpath for $param" - source $shpath $param - elif [ -f $DEFAULT_PATH ] ; then - echo "Loading iccvars.sh from $DEFAULT_PATH for $param" - source $DEFAULT_PATH $param - else - echo "## ERROR: cannot find 'iccvars.sh' script to set up ICC." - echo "## To fix, please add the directory that contains" - echo "## iccvars.sh to your 'PATH' environment variable." - quit - fi -} - -# -# Sets RTE_TARGET and does a "make install". -# -setup_target() -{ - option=$1 - export RTE_TARGET=${TARGETS[option]} - - compiler=${RTE_TARGET##*-} - if [ "$compiler" == "icc" ] ; then - platform=${RTE_TARGET%%-*} - if [ "$platform" == "x86_64" ] ; then - setup_icc intel64 - else - setup_icc ia32 - fi - fi - if [ "$QUIT" == "0" ] ; then - make install T=${RTE_TARGET} - fi - echo "------------------------------------------------------------------------------" - echo " RTE_TARGET exported as $RTE_TARGET" - echo "------------------------------------------------------------------------------" -} - -# -# Creates hugepage filesystem. -# -create_mnt_huge() -{ - echo "Creating /mnt/huge and mounting as hugetlbfs" - sudo mkdir -p /mnt/huge - - grep -s '/mnt/huge' /proc/mounts > /dev/null - if [ $? -ne 0 ] ; then - sudo mount -t hugetlbfs nodev /mnt/huge - fi -} - -# -# Removes hugepage filesystem. -# -remove_mnt_huge() -{ - echo "Unmounting /mnt/huge and removing directory" - grep -s '/mnt/huge' /proc/mounts > /dev/null - if [ $? -eq 0 ] ; then - sudo umount /mnt/huge - fi - - if [ -d /mnt/huge ] ; then - sudo rm -R /mnt/huge - fi -} - -# -# Unloads igb_uio.ko. -# -remove_igb_uio_module() -{ - echo "Unloading any existing DPDK UIO module" - /sbin/lsmod | grep -s igb_uio > /dev/null - if [ $? -eq 0 ] ; then - sudo /sbin/rmmod igb_uio - fi -} - -# -# Loads new igb_uio.ko (and uio module if needed). -# -load_igb_uio_module() -{ - if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko ];then - echo "## ERROR: Target does not have the DPDK UIO Kernel Module." - echo " To fix, please try to rebuild target." - return - fi - - remove_igb_uio_module - - /sbin/lsmod | grep -s uio > /dev/null - if [ $? -ne 0 ] ; then - modinfo uio > /dev/null - if [ $? -eq 0 ]; then - echo "Loading uio module" - sudo /sbin/modprobe uio - fi - fi - - # UIO may be compiled into kernel, so it may not be an error if it can't - # be loaded. - - echo "Loading DPDK UIO module" - sudo /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko - if [ $? -ne 0 ] ; then - echo "## ERROR: Could not load kmod/igb_uio.ko." - quit - fi -} - -# -# Unloads VFIO modules. -# -remove_vfio_module() -{ - echo "Unloading any existing VFIO module" - /sbin/lsmod | grep -s vfio > /dev/null - if [ $? -eq 0 ] ; then - sudo /sbin/rmmod vfio-pci - sudo /sbin/rmmod vfio_iommu_type1 - sudo /sbin/rmmod vfio - fi -} - -# -# Loads new vfio-pci (and vfio module if needed). -# -load_vfio_module() -{ - remove_vfio_module - - VFIO_PATH="kernel/drivers/vfio/pci/vfio-pci.ko" - - echo "Loading VFIO module" - /sbin/lsmod | grep -s vfio_pci > /dev/null - if [ $? -ne 0 ] ; then - if [ -f /lib/modules/$(uname -r)/$VFIO_PATH ] ; then - sudo /sbin/modprobe vfio-pci - fi - fi - - # make sure regular users can read /dev/vfio - echo "chmod /dev/vfio" - sudo chmod a+x /dev/vfio - if [ $? -ne 0 ] ; then - echo "FAIL" - quit - fi - echo "OK" - - # check if /dev/vfio/vfio exists - that way we - # know we either loaded the module, or it was - # compiled into the kernel - if [ ! -e /dev/vfio/vfio ] ; then - echo "## ERROR: VFIO not found!" - fi -} - -# -# Unloads the rte_kni.ko module. -# -remove_kni_module() -{ - echo "Unloading any existing DPDK KNI module" - /sbin/lsmod | grep -s rte_kni > /dev/null - if [ $? -eq 0 ] ; then - sudo /sbin/rmmod rte_kni - fi -} - -# -# Loads the rte_kni.ko module. -# -load_kni_module() -{ - # Check that the KNI module is already built. - if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko ];then - echo "## ERROR: Target does not have the DPDK KNI Module." - echo " To fix, please try to rebuild target." - return - fi - - # Unload existing version if present. - remove_kni_module - - # Now try load the KNI module. - echo "Loading DPDK KNI module" - sudo /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko - if [ $? -ne 0 ] ; then - echo "## ERROR: Could not load kmod/rte_kni.ko." - quit - fi -} - -# -# Sets appropriate permissions on /dev/vfio/* files -# -set_vfio_permissions() -{ - # make sure regular users can read /dev/vfio - echo "chmod /dev/vfio" - sudo chmod a+x /dev/vfio - if [ $? -ne 0 ] ; then - echo "FAIL" - quit - fi - echo "OK" - - # make sure regular user can access everything inside /dev/vfio - echo "chmod /dev/vfio/*" - sudo chmod 0666 /dev/vfio/* - if [ $? -ne 0 ] ; then - echo "FAIL" - quit - fi - echo "OK" - - # since permissions are only to be set when running as - # regular user, we only check ulimit here - # - # warn if regular user is only allowed - # to memlock <64M of memory - MEMLOCK_AMNT=`ulimit -l` - - if [ "$MEMLOCK_AMNT" != "unlimited" ] ; then - MEMLOCK_MB=`expr $MEMLOCK_AMNT / 1024` - echo "" - echo "Current user memlock limit: ${MEMLOCK_MB} MB" - echo "" - echo "This is the maximum amount of memory you will be" - echo "able to use with DPDK and VFIO if run as current user." - echo -n "To change this, please adjust limits.conf memlock " - echo "limit for current user." - - if [ $MEMLOCK_AMNT -lt 65536 ] ; then - echo "" - echo "## WARNING: memlock limit is less than 64MB" - echo -n "## DPDK with VFIO may not be able to initialize " - echo "if run as current user." - fi - fi -} - -# -# Removes all reserved hugepages. -# -clear_huge_pages() -{ - echo > .echo_tmp - for d in /sys/devices/system/node/node? ; do - echo "echo 0 > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp - done - echo "Removing currently reserved hugepages" - sudo sh .echo_tmp - rm -f .echo_tmp - - remove_mnt_huge -} - -# -# Creates hugepages. -# -set_non_numa_pages() -{ - clear_huge_pages - - echo "" - echo " Input the number of ${HUGEPGSZ} hugepages" - echo " Example: to have 128MB of hugepages available in a 2MB huge page system," - echo " enter '64' to reserve 64 * 2MB pages" - echo -n "Number of pages: " - read Pages - - echo "echo $Pages > /sys/kernel/mm/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" > .echo_tmp - - echo "Reserving hugepages" - sudo sh .echo_tmp - rm -f .echo_tmp - - create_mnt_huge -} - -# -# Creates hugepages on specific NUMA nodes. -# -set_numa_pages() -{ - clear_huge_pages - - echo "" - echo " Input the number of ${HUGEPGSZ} hugepages for each node" - echo " Example: to have 128MB of hugepages available per node in a 2MB huge page system," - echo " enter '64' to reserve 64 * 2MB pages on each node" - - echo > .echo_tmp - for d in /sys/devices/system/node/node? ; do - node=$(basename $d) - echo -n "Number of pages for $node: " - read Pages - echo "echo $Pages > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp - done - echo "Reserving hugepages" - sudo sh .echo_tmp - rm -f .echo_tmp - - create_mnt_huge -} - -# -# Run unit test application. -# -run_test_app() -{ - echo "" - echo " Enter hex bitmask of cores to execute test app on" - echo " Example: to execute app on cores 0 to 7, enter 0xff" - echo -n "bitmask: " - read Bitmask - echo "Launching app" - sudo ${RTE_TARGET}/app/test -c $Bitmask $EAL_PARAMS -} - -# -# Run unit testpmd application. -# -run_testpmd_app() -{ - echo "" - echo " Enter hex bitmask of cores to execute testpmd app on" - echo " Example: to execute app on cores 0 to 7, enter 0xff" - echo -n "bitmask: " - read Bitmask - echo "Launching app" - sudo ${RTE_TARGET}/app/testpmd -c $Bitmask $EAL_PARAMS -- -i -} - -# -# Print hugepage information. -# -grep_meminfo() -{ - grep -i huge /proc/meminfo -} - -# -# Calls dpdk-devbind.py --status to show the devices and what they -# are all bound to, in terms of drivers. -# -show_devices() -{ - if [ -d /sys/module/vfio_pci -o -d /sys/module/igb_uio ]; then - ${RTE_SDK}/tools/dpdk-devbind.py --status - else - echo "# Please load the 'igb_uio' or 'vfio-pci' kernel module before " - echo "# querying or adjusting device bindings" - fi -} - -# -# Uses dpdk-devbind.py to move devices to work with vfio-pci -# -bind_devices_to_vfio() -{ - if [ -d /sys/module/vfio_pci ]; then - ${RTE_SDK}/tools/dpdk-devbind.py --status - echo "" - echo -n "Enter PCI address of device to bind to VFIO driver: " - read PCI_PATH - sudo ${RTE_SDK}/tools/dpdk-devbind.py -b vfio-pci $PCI_PATH && - echo "OK" - else - echo "# Please load the 'vfio-pci' kernel module before querying or " - echo "# adjusting device bindings" - fi -} - -# -# Uses dpdk-devbind.py to move devices to work with igb_uio -# -bind_devices_to_igb_uio() -{ - if [ -d /sys/module/igb_uio ]; then - ${RTE_SDK}/tools/dpdk-devbind.py --status - echo "" - echo -n "Enter PCI address of device to bind to IGB UIO driver: " - read PCI_PATH - sudo ${RTE_SDK}/tools/dpdk-devbind.py -b igb_uio $PCI_PATH && echo "OK" - else - echo "# Please load the 'igb_uio' kernel module before querying or " - echo "# adjusting device bindings" - fi -} - -# -# Uses dpdk-devbind.py to move devices to work with kernel drivers again -# -unbind_devices() -{ - ${RTE_SDK}/tools/dpdk-devbind.py --status - echo "" - echo -n "Enter PCI address of device to unbind: " - read PCI_PATH - echo "" - echo -n "Enter name of kernel driver to bind the device to: " - read DRV - sudo ${RTE_SDK}/tools/dpdk-devbind.py -b $DRV $PCI_PATH && echo "OK" -} - -# -# Options for building a target. Note that this step MUST be first as it sets -# up TARGETS[] starting from 1, and this is accessed in setup_target using the -# user entered option. -# -step1_func() -{ - TITLE="Select the DPDK environment to build" - CONFIG_NUM=1 - for cfg in config/defconfig_* ; do - cfg=${cfg/config\/defconfig_/} - TEXT[$CONFIG_NUM]="$cfg" - TARGETS[$CONFIG_NUM]=$cfg - FUNC[$CONFIG_NUM]="setup_target" - let "CONFIG_NUM+=1" - done -} - -# -# Options for setting up environment. -# -step2_func() -{ - TITLE="Setup linuxapp environment" - - TEXT[1]="Insert IGB UIO module" - FUNC[1]="load_igb_uio_module" - - TEXT[2]="Insert VFIO module" - FUNC[2]="load_vfio_module" - - TEXT[3]="Insert KNI module" - FUNC[3]="load_kni_module" - - TEXT[4]="Setup hugepage mappings for non-NUMA systems" - FUNC[4]="set_non_numa_pages" - - TEXT[5]="Setup hugepage mappings for NUMA systems" - FUNC[5]="set_numa_pages" - - TEXT[6]="Display current Ethernet/Crypto device settings" - FUNC[6]="show_devices" - - TEXT[7]="Bind Ethernet/Crypto device to IGB UIO module" - FUNC[7]="bind_devices_to_igb_uio" - - TEXT[8]="Bind Ethernet/Crypto device to VFIO module" - FUNC[8]="bind_devices_to_vfio" - - TEXT[9]="Setup VFIO permissions" - FUNC[9]="set_vfio_permissions" -} - -# -# Options for running applications. -# -step3_func() -{ - TITLE="Run test application for linuxapp environment" - - TEXT[1]="Run test application (\$RTE_TARGET/app/test)" - FUNC[1]="run_test_app" - - TEXT[2]="Run testpmd application in interactive mode (\$RTE_TARGET/app/testpmd)" - FUNC[2]="run_testpmd_app" -} - -# -# Other options -# -step4_func() -{ - TITLE="Other tools" - - TEXT[1]="List hugepage info from /proc/meminfo" - FUNC[1]="grep_meminfo" - -} - -# -# Options for cleaning up the system -# -step5_func() -{ - TITLE="Uninstall and system cleanup" - - TEXT[1]="Unbind devices from IGB UIO or VFIO driver" - FUNC[1]="unbind_devices" - - TEXT[2]="Remove IGB UIO module" - FUNC[2]="remove_igb_uio_module" - - TEXT[3]="Remove VFIO module" - FUNC[3]="remove_vfio_module" - - TEXT[4]="Remove KNI module" - FUNC[4]="remove_kni_module" - - TEXT[5]="Remove hugepage mappings" - FUNC[5]="clear_huge_pages" -} - -STEPS[1]="step1_func" -STEPS[2]="step2_func" -STEPS[3]="step3_func" -STEPS[4]="step4_func" -STEPS[5]="step5_func" - -QUIT=0 - -while [ "$QUIT" == "0" ]; do - OPTION_NUM=1 - - for s in $(seq ${#STEPS[@]}) ; do - ${STEPS[s]} - - echo "----------------------------------------------------------" - echo " Step $s: ${TITLE}" - echo "----------------------------------------------------------" - - for i in $(seq ${#TEXT[@]}) ; do - echo "[$OPTION_NUM] ${TEXT[i]}" - OPTIONS[$OPTION_NUM]=${FUNC[i]} - let "OPTION_NUM+=1" - done - - # Clear TEXT and FUNC arrays before next step - unset TEXT - unset FUNC - - echo "" - done - - echo "[$OPTION_NUM] Exit Script" - OPTIONS[$OPTION_NUM]="quit" - echo "" - echo -n "Option: " - read our_entry - echo "" - ${OPTIONS[our_entry]} ${our_entry} - - if [ "$QUIT" == "0" ] ; then - echo - echo -n "Press enter to continue ..."; read - fi - -done |