sdk/apps/virtual-ethernet/scripts/virtual_ethernet_setup.py (104 lines of code) (raw):

#!/usr/bin/env python3 # Amazon FPGA Hardware Development Kit # # Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Amazon Software License (the "License"). You may not use # this file except in compliance with the License. A copy of the License is # located at # # http://aws.amazon.com/asl/ # # or in the "license" file accompanying this file. This file is distributed on # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or # implied. See the License for the specific language governing permissions and # limitations under the License. from __future__ import print_function import os import sys import distro import glob import argparse import subprocess import logging dpdk_devbind = "./usertools/dpdk-devbind.py" num_2MB_hugepages = 16384 # Logger logger = logging.getLogger('logger') def print_success(dpdk_path): print("") print("DPDK setup complete!") print("A simple loopback test may be run via the following steps:") print(" cd %s" % (dpdk_path)) print(" sudo ./build/app/dpdk-testpmd -l 0-1 -- --port-topology=loop --auto-start --tx-first --stats-period=3") def check_output(args, stderr=None): return subprocess.Popen(args, stdout=subprocess.PIPE, stderr=stderr).communicate()[0] def cmd_exec(cmd, check_return=True): # Execute the cmd, check the return and exit on failures ret = os.system(cmd) if check_return == True and ret != 0: logger.error("cmd='%s' failed with ret=%d, exiting" % (cmd, ret)) sys.exit(1) def load_uio(): installed_distro = distro.name() if (installed_distro == "Ubuntu"): cmd_exec("modprobe uio") else: cmd_exec("modprobe uio_pci_generic") def fpga_slot_str2dbdf(fpga_slot_str): dbdf = "None" found = False cmd = "fpga-describe-local-image-slots" # Exec the command first to give an error message # if the SDK hasn't been installed. cmd_exec("%s >/dev/null 2>&1" % (cmd)) fpga_slots = check_output(cmd).splitlines() for slot_str in fpga_slots: logger.debug("slot_str=%s" % slot_str) _,slot_num,_,_,dbdf = slot_str.split() if slot_num.decode() == fpga_slot_str: found = True break if found == False: logger.error("Could not find fpga_slot_str=%s" % fpga_slot_str) return dbdf.decode() def setup_dpdk(dpdk_path, fpga_slot_str, eni_dbdf, eni_ethdev): logger.debug("setup_dpdk: dpdk_path=%s, fpga_slot_str=%s" % (dpdk_path, fpga_slot_str)) if os.path.exists(dpdk_path) == False: logger.error("dpdk_path=%s does not exist." % (dpdk_path)) logger.error("Please specify a dpdk directory that was installed via virtual-ethernet-install.py, exiting") sys.exit(1) fpga_dbdf = fpga_slot_str2dbdf(fpga_slot_str) if fpga_dbdf == "None": logger.error("Could not get DBDF for fpga_slot_str=%s" % fpga_slot_str) sys.exit(1) # Stash away the current working directory cwd = os.getcwd() scripts_path = os.path.dirname(os.path.abspath(sys.argv[0])) logger.debug("scripts directory path is %s" % (scripts_path)) # cd to the dpdk_path directory os.chdir("%s" % (dpdk_path)) if os.path.exists(dpdk_devbind) == False: logger.error("dpdk_devbind=%s does not exist." % (dpdk_devbind)) logger.error("Please specify a dpdk directory that was installed via virtual-ethernet-install.py, exiting") sys.exit(1) # Mount '/mnt/huge', if needed if os.path.exists("/mnt/huge") == False: cmd_exec("mkdir /mnt/huge") cmd_exec("mount -t hugetlbfs nodev /mnt/huge") # Configure hugepages cmd_exec("echo %d > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages" % (num_2MB_hugepages)) # Load distro-specific uio load_uio() # Remove then load igb_uio.ko cmd_exec("rmmod ./build/kernel/linux/igb_uio/igb_uio.ko >/dev/null 2>&1", False) cmd_exec("insmod ./build/kernel/linux/igb_uio/igb_uio.ko") # Bind the FPGA to to DPDK cmd_exec("%s --bind=igb_uio %s" % (dpdk_devbind, fpga_dbdf)) # Bind the ENI device to to DPDK (optional) if eni_dbdf != "None" and eni_ethdev != "None": cmd_exec("ip link set %s down" % (eni_ethdev)) cmd_exec("%s --bind=igb_uio %s" % (dpdk_devbind, eni_dbdf)) # cd back to the original directory os.chdir("%s" % (cwd)) # Print a success message print_success(dpdk_path) def main(): parser = argparse.ArgumentParser( description="Sets up DPDK for SPP PMD use.") parser.add_argument('dpdk_path', metavar='DPDK_DIR', type=str, help = "specify the full DPDK directory path") parser.add_argument('fpga_slot', metavar='FPGA_IMAGE_SLOT', type=str, help = "specify the fpga-image-slot. See fpga-describe-local-image --fpga-image-slot for more info.") parser.add_argument('--eni_dbdf', metavar='ENI_DBDF', type=str, default="None", help = "specify the ENI DBDF. e.g. see lspci output 0000:00:04.0 Ethernet controller: Device 1d0f:ec20") parser.add_argument('--eni_ethdev', metavar='ENI_ETHDEV', type=str, default="None", help = "specify the ENI Ethernet device'. e.g. see ifconfig output for eth1") parser.add_argument('--debug', action='store_true', required=False, help = 'Enable debug messages') args = parser.parse_args() logging_level = logging.INFO if args.debug: logging_level = logging.DEBUG logging_format = '%(levelname)s:%(asctime)s: %(message)s' logger.setLevel(logging_level) fh = logging.StreamHandler() fh.setLevel(logging_level) formatter = logging.Formatter(logging_format) fh.setFormatter(formatter) logger.addHandler(fh) setup_dpdk(args.dpdk_path, args.fpga_slot, args.eni_dbdf, args.eni_ethdev) if __name__ == '__main__': main()