summaryrefslogtreecommitdiff
path: root/usertools/dpdk-setup.sh
diff options
context:
space:
mode:
Diffstat (limited to 'usertools/dpdk-setup.sh')
-rwxr-xr-xusertools/dpdk-setup.sh634
1 files changed, 634 insertions, 0 deletions
diff --git a/usertools/dpdk-setup.sh b/usertools/dpdk-setup.sh
new file mode 100755
index 0000000..c4fec5a
--- /dev/null
+++ b/usertools/dpdk-setup.sh
@@ -0,0 +1,634 @@
+#! /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}/usertools/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}/usertools/dpdk-devbind.py --status
+ echo ""
+ echo -n "Enter PCI address of device to bind to VFIO driver: "
+ read PCI_PATH
+ sudo ${RTE_SDK}/usertools/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}/usertools/dpdk-devbind.py --status
+ echo ""
+ echo -n "Enter PCI address of device to bind to IGB UIO driver: "
+ read PCI_PATH
+ sudo ${RTE_SDK}/usertools/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}/usertools/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}/usertools/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